Skip to content

Commit

Permalink
Moves @types/prettier to this repository (#14212)
Browse files Browse the repository at this point in the history
* Rename `types` to `thirs-party-types`

* Copy `index.d.ts` from `@types/prettier`

* Make public APIs async

* Add missing `formatAST`

* Fix `CustomParser`

* Fix `Parser.parse` signature

* Add comment

* Add `standalonw.d.ts`

* first implement

* Fix path

* Add missing parser `.d.ts`

* Fix

* Fix path

* Introduce valid tests

* Add unit tests for dts files

* Add unit tests

* Simplify unit testing

* Tweaks structures

* Revert needless change

* Fix types path

* Introduce `ts-expect`

* Fix doc utils api

* Add AstPath API

* Fix API

* Fix tests

* Fix changelog

* Move dts

* Update module specifiers

* Remove generate dts config file

* Update build scripts

* Fix type errors

* Refactor with namespace imports

* Update comments

* Fix build script

* Improve build script

* `typing` -> `types`

* Clean up

* Minor tweak

* Minor tweak

* Modify `exports` field

* Fix paths in builder

* Refactor

* Refactor

* Address review

* Update changelog

* Address reviews

* Remove `since` from tests

* Improve utils type def

* Mark deprecated methods

* Address review

* Move docs types

* Address review

* Update c8 config

* Minor tweak

---------

Co-authored-by: fisker Cheung <lionkay@gmail.com>
  • Loading branch information
sosukesuzuki and fisker committed Feb 23, 2023
1 parent 164eab2 commit 813df18
Show file tree
Hide file tree
Showing 33 changed files with 1,899 additions and 60 deletions.
1 change: 1 addition & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ module.exports = {
"tests/format/**/jsfmt.spec.js",
"tests/integration/**/*.js",
"tests/unit/**/*.js",
"tests/dts/unit/**/*.js",
"scripts/release/__tests__/**/*.spec.js",
],
env: {
Expand Down
3 changes: 3 additions & 0 deletions changelog_unreleased/api/14212.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#### Add `.d.ts` files (#14212 by @sosukesuzuki, @fisker)

Add type definition files required to use Prettier's JavaScript API from TypeScript. This eliminates the need for users to install `@types/prettier`.
1 change: 1 addition & 0 deletions jest.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const config = {
"<rootDir>/tests/format/**/jsfmt.spec.js",
"<rootDir>/tests/integration/__tests__/**/*.js",
"<rootDir>/tests/unit/**/*.js",
"<rootDir>/tests/dts/unit/**/*.js",
],
testPathIgnorePatterns,
// collectCoverage: ENABLE_CODE_COVERAGE,
Expand Down
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"exports": {
".": {
"require": "./src/index.cjs",
"types": "./src/index.d.ts",
"default": "./src/index.js"
},
"./*": "./*"
Expand Down Expand Up @@ -147,7 +148,8 @@
"semver": "7.3.8",
"serialize-javascript": "6.0.1",
"snapshot-diff": "0.10.0",
"tempy": "3.0.0"
"tempy": "3.0.0",
"ts-expect": "1.3.0"
},
"resolutions": {
"trim": "1.0.1"
Expand Down Expand Up @@ -192,7 +194,8 @@
"src/index.cjs",
"src/document/debug.js",
"src/utils/unexpected-node-error.js",
"src/language-js/types/estree.d.ts"
"src/language-js/types/estree.d.ts",
"src/**/**/*.d.ts"
]
},
"browserslist": [
Expand Down
2 changes: 1 addition & 1 deletion scripts/build/build-license.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ async function buildLicense({ file, files, shouldCollectLicenses }) {
return;
}

const javascriptFiles = files.filter((file) => !file.isMetaFile);
const javascriptFiles = files.filter((file) => file.kind === "javascript");
if (javascriptFiles.some((file) => !Array.isArray(file.dependencies))) {
return { skipped: true };
}
Expand Down
8 changes: 5 additions & 3 deletions scripts/build/build-package-json.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import {
writeJson,
} from "../utils/index.mjs";

async function buildPackageJson({ files }) {
const packageJson = await readJson(path.join(PROJECT_ROOT, "package.json"));
async function buildPackageJson({ file, files }) {
const packageJson = await readJson(path.join(PROJECT_ROOT, file.input));

const bin = files.find(
(file) =>
Expand All @@ -20,6 +20,7 @@ async function buildPackageJson({ files }) {
packageJson.exports = {
".": {
require: "./index.cjs",
types: "./index.d.ts",
default: "./index.mjs",
},
"./*": "./*",
Expand All @@ -32,6 +33,7 @@ async function buildPackageJson({ files }) {
file.isPlugin ? `./plugins/${basename}` : `./${basename}`,
{
require: `./${file.output.file}`,
types: `./${file.output.file.replace(/\.js$/, ".d.ts")}`,
default: `./${file.output.file.replace(/\.js$/, ".mjs")}`,
},
];
Expand Down Expand Up @@ -74,7 +76,7 @@ async function buildPackageJson({ files }) {
};
packageJson.files = files.map(({ output: { file } }) => file).sort();

await writeJson(path.join(DIST_DIR, "package.json"), packageJson);
await writeJson(path.join(DIST_DIR, file.output.file), packageJson);
}

export default buildPackageJson;
3 changes: 2 additions & 1 deletion scripts/build/build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ async function buildFile({ file, files, shouldCollectLicenses, cliOptions }) {
let displayName = file.output.file;
if (
(file.platform === "universal" && file.output.format !== "esm") ||
(file.output.file.startsWith("index.") && file.output.format !== "esm")
(file.output.file.startsWith("index.") && file.output.format !== "esm") ||
file.kind === "types"
) {
displayName = ` ${displayName}`;
}
Expand Down
160 changes: 107 additions & 53 deletions scripts/build/config.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import path from "node:path";
import url from "node:url";
import fs from "node:fs";
import { createRequire } from "node:module";
import createEsmUtils from "esm-utils";
import { PROJECT_ROOT, DIST_DIR, copyFile } from "../utils/index.mjs";
import {
PROJECT_ROOT,
DIST_DIR,
copyFile,
writeFile,
} from "../utils/index.mjs";
import buildJavascriptModule from "./build-javascript-module.js";
import buildPackageJson from "./build-package-json.js";
import buildLicense from "./build-license.js";
Expand All @@ -16,6 +22,58 @@ const {
} = createEsmUtils(import.meta);
const resolveEsmModulePath = async (specifier) =>
url.fileURLToPath(await importMetaResolve(specifier));
const copyFileBuilder = ({ file }) =>
copyFile(
path.join(PROJECT_ROOT, file.input),
path.join(DIST_DIR, file.output.file)
);

async function typesFileBuilder({ file }) {
/**
* @typedef {{ from: string, to: string }} ImportPathReplacement
* @typedef {{ [input: string]: Array<ImportPathReplacement> }} ReplacementMap
*/

/** @type {Array<ImportPathReplacement>} */
const jsParsersImportReplacement = [
{ from: "../../index.js", to: "../index.js" },
];
/** @type {ReplacementMap} */
const pathReplacementMap = {
"src/index.d.ts": [{ from: "./document/index.js", to: "./doc.js" }],
"src/language-js/parse/acorn-and-espree.d.ts": jsParsersImportReplacement,
"src/language-js/parse/angular.d.ts": jsParsersImportReplacement,
"src/language-js/parse/babel.d.ts": jsParsersImportReplacement,
"src/language-js/parse/flow.d.ts": jsParsersImportReplacement,
"src/language-js/parse/meriyah.d.ts": jsParsersImportReplacement,
"src/language-js/parse/typescript.d.ts": jsParsersImportReplacement,
};
const replacements = pathReplacementMap[file.input] ?? [];
let data = await fs.promises.readFile(file.input, "utf8");
for (const { from, to } of replacements) {
data = data.replaceAll(
new RegExp(` from "${from}";`, "g"),
` from "${to}";`
);
}
await writeFile(path.join(DIST_DIR, file.output.file), data);
}

function getTypesFileConfig({ input: jsFileInput, outputBaseName }) {
const input = jsFileInput.replace(/\.[cm]?js$/, ".d.ts");
if (!fs.existsSync(path.join(PROJECT_ROOT, input))) {
return;
}

return {
input,
output: {
file: outputBaseName + ".d.ts",
},
kind: "types",
build: typesFileBuilder,
};
}

/**
* @typedef {Object} BuildOptions
Expand All @@ -25,18 +83,18 @@ const resolveEsmModulePath = async (specifier) =>
* @property {boolean?} minify - disable code minification
*
* @typedef {Object} Output
* @property {'esm' | 'umd' | 'cjs' | 'text' | 'json'} format - File format
* @property {"esm" | "umd" | "cjs" | "text" | "json"} format - File format
* @property {string} file - path of the output file in the `dist/` folder
* @property {string?} umdVariableName - name for the UMD file (for plugins, it'll be `prettierPlugins.${name}`)
*
* @typedef {Object} File
* @property {string?} input - input of the file
* @property {string} input - input of the file
* @property {Output} output - output of the file
* @property {"javascript" | "types" | "meta"} kind - file kind
* @property {function} build - file generate function
* @property {'node' | 'universal'} platform - ESBuild platform
* @property {"node" | "universal"} platform - ESBuild platform
* @property {BuildOptions} buildOptions - ESBuild options
* @property {boolean?} isPlugin - file is a plugin
* @property {boolean?} isMeta - file is a meta file (package.json, LICENSE README.md)
*/

/*
Expand Down Expand Up @@ -400,22 +458,27 @@ const universalFiles = [...nonPluginUniversalFiles, ...pluginFiles].flatMap(
outputBaseName ??= path.basename(input);

return [
{
format: "esm",
file: `${outputBaseName}${extensions.esm}`,
},
{
format: "umd",
file: `${outputBaseName}${extensions.umd}`,
umdVariableName,
},
].map((output) => ({
input,
output,
platform: "universal",
buildOptions,
isPlugin,
}));
...[
{
format: "esm",
file: `${outputBaseName}${extensions.esm}`,
},
{
format: "umd",
file: `${outputBaseName}${extensions.umd}`,
umdVariableName,
},
].map((output) => ({
input,
output,
platform: "universal",
buildOptions,
isPlugin,
build: buildJavascriptModule,
kind: "javascript",
})),
getTypesFileConfig({ input, outputBaseName }),
];
}
);

Expand Down Expand Up @@ -481,59 +544,50 @@ const nodejsFiles = [
},
],
},
].map((file) => {
].flatMap((file) => {
let { input, output, outputBaseName, ...buildOptions } = file;

const format = input.endsWith(".cjs") ? "cjs" : "esm";
outputBaseName ??= path.basename(input, path.extname(input));

return {
input,
output: {
format,
file: `${outputBaseName}${extensions[format]}`,
return [
{
input,
output: {
format,
file: `${outputBaseName}${extensions[format]}`,
},
platform: "node",
buildOptions,
build: buildJavascriptModule,
kind: "javascript",
},
platform: "node",
buildOptions,
};
getTypesFileConfig({ input, outputBaseName }),
];
});

const metaFiles = [
{
input: "package.json",
output: {
format: "json",
file: "package.json",
},
build: buildPackageJson,
},
{
output: {
format: "text",
file: "README.md",
},
async build() {
await copyFile(
path.join(PROJECT_ROOT, "README.md"),
path.join(DIST_DIR, "README.md")
);
},
input: "README.md",
build: copyFileBuilder,
},
{
output: {
format: "text",
file: "LICENSE",
},
input: "LICENSE",
build: buildLicense,
},
].map((file) => ({ ...file, isMetaFile: true }));
].map((file) => ({
...file,
output: { file: file.input, ...file.output },
kind: "meta",
}));

/** @type {Files[]} */
const files = [
...[...nodejsFiles, ...universalFiles].map((file) => ({
...file,
build: buildJavascriptModule,
})),
...metaFiles,
];
const files = [...nodejsFiles, ...universalFiles, ...metaFiles].filter(Boolean);
export default files;
1 change: 1 addition & 0 deletions src/cli/prettier-internal.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-expect-error
import { __internal as sharedWithCli } from "../index.js";

export const {
Expand Down
1 change: 1 addition & 0 deletions src/cli/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import fs from "node:fs/promises";
import path from "node:path";
import sdbm from "sdbm";
// @ts-expect-error
import { __internal as sharedWithCli } from "../index.js";

const { arrayify, isNonEmptyArray, partition } = sharedWithCli.utils;
Expand Down

0 comments on commit 813df18

Please sign in to comment.