Merge branch 'main' into next

This commit is contained in:
Sosuke Suzuki committed 2023-12-10 16:42:41 +09:00
commit 80f2578b1d
71 files changed
+1273 -575

No files matched your search

-1
View File
@@ -325,7 +325,6 @@ module.exports = {
path.resolve(__dirname, "src/**"),
`!${path.resolve(__dirname, "src/cli/**")}`,
`!${path.resolve(__dirname, "src/index.js")}`,
`!${path.resolve(__dirname, "src/common/mockable.js")}`,
],
message: "Don't use code from other directory.",
},
+3
View File
@@ -0,0 +1,3 @@
#### Improve config file search (#15663 by @fisker)
The Prettier config file search performance has been improved by more effective cache strategy.
+5
View File
@@ -0,0 +1,5 @@
#### Skip explicitly passed symbolic links with `--no-error-on-unmatched-pattern` (#15533 by @sanmai-NL)
Since Prettier v3, we stopped following symbolic links, however in some use cases, the symbolic link patterns can't be filtered out, and there is no way to prevent Prettier from throwing errors.
In Prettier main, you can use `--no-error-on-unmatched-pattern` to simply skip symbolic links.
+16
View File
@@ -0,0 +1,16 @@
#### Keep curly braces and `from` keyword in empty `import` statements (#15756 by @fisker)
<!-- prettier-ignore -->
```js
// Input
import { } from 'foo';
import { /* comment */ } from 'bar';
// Prettier stable
import {} from "foo";
import /* comment */ "bar";
// Prettier main
import {} from "foo";
import {} from /* comment */ "bar";
```
+16
View File
@@ -0,0 +1,16 @@
#### Keep empty import attributes and assertions (#15757 by @fisker)
<!-- prettier-ignore -->
```js
// Input
import foo from "foo" with {};
import bar from "bar" assert {};
// Prettier stable
import foo from "foo";
import bar from "bar";
// Prettier main
import foo from "foo" with {};
import bar from "bar" assert {};
```
+3
View File
@@ -0,0 +1,3 @@
#### Fix false claim in docs that cursorOffset is incompatible with rangeStart/rangeEnd (#15750 by @ExplodingCabbage)
The cursorOffset option has in fact been compatible with rangeStart/rangeEnd for over 5 years, thanks to work by @ds300. However, Prettier's documentation (including the CLI `--help` text) continued to claim otherwise, falsely. The documentation is now fixed.
+7
View File
@@ -0,0 +1,7 @@
#### Support "Import Attributes" (#15718 by @fisker)
[TypeScript 5.3](https://devblogs.microsoft.com/typescript/announcing-typescript-5-3/#import-attributes) supports the latest updates to the [import attributes](https://github.com/tc39/proposal-import-attributes) proposal.
```tsx
import something from "./something.json" with { type: "json" };
```
+4
View File
@@ -97,6 +97,10 @@ ifBreak(";", " ");
`groupId` can be used to check another _already printed_ group instead of the current group.
If a [`hardline`](#hardline) or [`breakParent`](#breakParent) is present within the possible contents, the parent groups will be broken regardless of said content being printed, which might not be desireable. This behaviour is a design limitation. Usually the desired result can be achieved in a different way.
In the rare case that `hardline` is definitely needed, consider using [`hardlineWithoutBreakParent`](#hardlinewithoutbreakparent-and-literallinewithoutbreakparent) instead to avoid an unwanted group break propagation.
### `breakParent`
```ts
+2 -2
View File
@@ -26,7 +26,7 @@ await prettier.format("foo ( );", { semi: false, parser: "babel" });
`formatWithCursor` both formats the code, and translates a cursor position from unformatted code to formatted code. This is useful for editor integrations, to prevent the cursor from moving when code is formatted.
The `cursorOffset` option should be provided, to specify where the cursor is. This option cannot be used with `rangeStart` and `rangeEnd`.
The `cursorOffset` option should be provided, to specify where the cursor is.
```js
await prettier.formatWithCursor(" 1", { cursorOffset: 2, parser: "babel" });
@@ -66,7 +66,7 @@ If `options.editorconfig` is `true` and an [`.editorconfig` file](https://editor
The promise will be rejected if there was an error parsing the configuration file.
The search starts at `process.cwd()`, or at `fileUrlOrPath` if provided. Please see the [lilconfig docs](https://github.com/antonk52/lilconfig) for details on how the resolving works.
The search starts at `process.cwd()`, or at the directory of `fileUrlOrPath` if provided.
```js
const configFile = await prettier.resolveConfigFile(filePath);
+1 -1
View File
@@ -3,7 +3,7 @@ id: configuration
title: Configuration File
---
Prettier uses [lilconfig](https://github.com/antonk52/lilconfig) for configuration file support. This means you can configure Prettier via (in order of precedence):
You can configure Prettier via (in order of precedence):
- A `"prettier"` key in your `package.json` file.
- A `.prettierrc` file written in JSON or YAML.
-2
View File
@@ -254,8 +254,6 @@ These two options can be used to format code starting and ending at a given char
- Backwards to the start of the first line containing the selected statement.
- Forwards to the end of the selected statement.
These options cannot be used with `cursorOffset`.
| Default | CLI Override | API Override |
| ---------- | --------------------- | ------------------- |
| `0` | `--range-start <int>` | `rangeStart: <int>` |
+12 -13
View File
@@ -31,16 +31,16 @@
],
"dependencies": {
"@angular/compiler": "17.0.2",
"@babel/code-frame": "7.22.13",
"@babel/parser": "7.23.4",
"@babel/types": "7.23.3",
"@babel/code-frame": "7.23.5",
"@babel/parser": "7.23.5",
"@babel/types": "7.23.5",
"@glimmer/syntax": "0.85.13",
"@iarna/toml": "2.2.5",
"@prettier/cli": "0.1.5",
"@prettier/is-es5-identifier-name": "0.2.0",
"@prettier/parse-srcset": "3.1.0",
"@typescript-eslint/typescript-estree": "6.10.0",
"@typescript-eslint/visitor-keys": "6.10.0",
"@typescript-eslint/typescript-estree": "6.13.2",
"@typescript-eslint/visitor-keys": "6.13.2",
"acorn": "8.11.2",
"acorn-jsx": "5.3.2",
"angular-estree-parser": "9.0.0",
@@ -61,11 +61,11 @@
"fast-json-stable-stringify": "2.1.0",
"file-entry-cache": "7.0.2",
"find-cache-dir": "5.0.0",
"flow-parser": "0.222.0",
"flow-parser": "0.223.3",
"get-east-asian-width": "1.2.0",
"get-stdin": "9.0.0",
"graphql": "16.8.1",
"hermes-parser": "0.17.1",
"hermes-parser": "0.18.0",
"html-element-attributes": "3.3.0",
"html-tag-names": "2.1.0",
"html-ua-styles": "0.0.3",
@@ -76,7 +76,6 @@
"js-yaml": "4.1.0",
"json5": "2.2.3",
"leven": "4.0.0",
"lilconfig": "2.1.0",
"lines-and-columns": "2.0.4",
"linguist-languages": "7.27.0",
"mem": "9.0.2",
@@ -87,7 +86,7 @@
"outdent": "0.8.0",
"parse-json": "8.1.0",
"please-upgrade-node": "3.2.0",
"postcss": "8.4.31",
"postcss": "8.4.32",
"postcss-less": "6.0.0",
"postcss-media-query-parser": "0.2.3",
"postcss-scss": "4.0.9",
@@ -100,7 +99,7 @@
"sdbm": "2.0.0",
"strip-ansi": "7.1.0",
"to-fast-properties": "4.0.0",
"typescript": "5.2.2",
"typescript": "5.3.2",
"unicode-regex": "4.0.0",
"unified": "9.2.2",
"url-or-path": "2.3.0",
@@ -109,13 +108,13 @@
"yaml-unist-parser": "2.0.1"
},
"devDependencies": {
"@babel/generator": "7.23.3",
"@babel/generator": "7.23.5",
"@glimmer/reference": "0.85.13",
"@types/estree": "1.0.5",
"@types/file-entry-cache": "5.0.4",
"@types/find-cache-dir": "3.2.1",
"@types/jest": "29.5.8",
"@typescript-eslint/eslint-plugin": "6.10.0",
"@typescript-eslint/eslint-plugin": "6.13.2",
"benchmark": "2.1.4",
"browserslist-to-esbuild": "1.2.0",
"c8": "8.0.1",
@@ -126,7 +125,7 @@
"esbuild-plugins-node-modules-polyfill": "1.6.1",
"esbuild-visualizer": "0.4.1",
"eslint": "8.53.0",
"eslint-config-prettier": "9.0.0",
"eslint-config-prettier": "9.1.0",
"eslint-formatter-friendly": "7.0.0",
"eslint-plugin-compat": "4.2.0",
"eslint-plugin-import": "2.29.0",
-11
View File
@@ -635,17 +635,6 @@ const nodejsFiles = [
external: ["benchmark"],
replaceModule: [replaceDiffPackageEntry("lib/patch/create.js")],
},
{
input: "src/common/mockable.js",
outputBaseName: "internal/internal",
replaceModule: [
{
module: require.resolve("lilconfig"),
find: "exports.lilconfigSync = lilconfigSync;",
replacement: "",
},
],
},
].flatMap((file) => {
let { input, output, outputBaseName, ...buildOptions } = file;
+10
View File
@@ -198,6 +198,13 @@ function modifyTypescriptModule(text) {
}
}
// server
for (const module of source.modules) {
if (module.path.startsWith("src/server/")) {
source.removeModule(module);
}
}
// `transformers`
source.removeModule("src/compiler/transformer.ts");
for (const module of source.modules) {
@@ -268,6 +275,9 @@ function modifyTypescriptModule(text) {
`,
);
// `pnp`
source.removeModule("src/compiler/pnp.ts");
/* spell-checker: disable */
// `ts.createParenthesizerRules`
source.replaceAlignedCode({
+9 -3
View File
@@ -69,9 +69,15 @@ async function* expandPatternsInternal(context) {
const stat = await lstatSafe(absolutePath);
if (stat) {
if (stat.isSymbolicLink()) {
yield {
error: `Explicitly specified pattern "${pattern}" is a symbolic link.`,
};
if (context.argv.errorOnUnmatchedPattern !== false) {
yield {
error: `Explicitly specified pattern "${pattern}" is a symbolic link.`,
};
} else {
context.logger.debug(
`Skipping pattern "${pattern}", as it is a symbolic link.`,
);
}
} else if (stat.isFile()) {
entries.push({
type: "file",
+5 -2
View File
@@ -3,8 +3,11 @@ import path from "node:path";
import chalk from "chalk";
import { createTwoFilesPatch } from "diff";
import * as prettier from "../index.js";
import mockable from "../common/mockable.js";
import { createIsIgnoredFunction, errors } from "./prettier-internal.js";
import {
createIsIgnoredFunction,
errors,
mockable,
} from "./prettier-internal.js";
import { expandPatterns } from "./expand-patterns.js";
import getOptionsForFile from "./options/get-options-for-file.js";
import isTTY from "./is-tty.js";
+1 -1
View File
@@ -1,4 +1,4 @@
import mockable from "../common/mockable.js";
import { mockable } from "./prettier-internal.js";
// Some CI pipelines incorrectly report process.stdout.isTTY status,
// which causes unwanted lines in the output. An additional check for isCI() helps.
+1
View File
@@ -11,4 +11,5 @@ export const {
normalizeOptionSettings,
vnopts,
fastGlob,
mockable,
} = sharedWithCli;
+2 -2
View File
@@ -1,5 +1,4 @@
import fs from "node:fs/promises";
import { lilconfig } from "lilconfig";
import getStdin from "get-stdin";
import { isCI } from "ci-info";
@@ -8,7 +7,8 @@ function writeFormattedFile(file, data) {
}
const mockable = {
lilconfig,
// eslint-disable-next-line unicorn/no-useless-undefined
getPrettierConfigSearchStopDirectory: () => undefined,
getStdin,
isCI: () => isCI,
writeFormattedFile,
-112
View File
@@ -1,112 +0,0 @@
import { pathToFileURL } from "node:url";
import parseToml from "@iarna/toml/parse-async.js";
import parseJson5 from "json5/lib/parse.js";
import yaml from "js-yaml";
import parseJson from "parse-json";
import mockable from "../common/mockable.js";
import loadExternalConfig from "./load-external-config.js";
const { lilconfig } = mockable;
const searchPlaces = [
"package.json",
".prettierrc",
".prettierrc.json",
".prettierrc.yaml",
".prettierrc.yml",
".prettierrc.json5",
".prettierrc.js",
".prettierrc.mjs",
".prettierrc.cjs",
"prettier.config.js",
"prettier.config.mjs",
"prettier.config.cjs",
".prettierrc.toml",
];
async function loadJs(filepath /*, content*/) {
const module = await import(pathToFileURL(filepath).href);
return module.default;
}
function loadYaml(filepath, content) {
try {
return yaml.load(content);
} catch (/** @type {any} */ error) {
error.message = `YAML Error in ${filepath}:\n${error.message}`;
throw error;
}
}
const loaders = {
async ".toml"(filePath, content) {
try {
return await parseToml(content);
} catch (/** @type {any} */ error) {
error.message = `TOML Error in ${filePath}:\n${error.message}`;
throw error;
}
},
".json5"(filePath, content) {
try {
return parseJson5(content);
} catch (/** @type {any} */ error) {
error.message = `JSON5 Error in ${filePath}:\n${error.message}`;
throw error;
}
},
".json"(filePath, content) {
try {
return parseJson(content);
} catch (/** @type {any} */ error) {
error.message = `JSON Error in ${filePath}:\n${error.message}`;
throw error;
}
},
".js": loadJs,
".mjs": loadJs,
".yaml": loadYaml,
".yml": loadYaml,
noExt: loadYaml,
};
async function transform(result) {
if (!result?.config) {
return result;
}
let { config, filepath } = result;
/*
We support external config
```json
{
"prettier": "my-prettier-config-package-or-file"
}
```
*/
if (typeof config === "string") {
config = await loadExternalConfig(config, filepath);
result.config = config;
}
if (typeof config !== "object") {
throw new TypeError(
"Config is only allowed to be an object, " +
`but received ${typeof config} in "${filepath}"`,
);
}
delete config.$schema;
return result;
}
/**
* @return {ReturnType<import("lilconfig").lilconfig>}
*/
function getExplorer() {
return lilconfig("prettier", { searchPlaces, loaders, transform });
}
export default getExplorer;
@@ -0,0 +1,119 @@
import path from "node:path";
import iterateDirectoryUp from "iterate-directory-up";
import isFile from "../../utils/is-file.js";
import { loadConfigFromPackageJson } from "./loaders.js";
const CONFIG_FILE_NAMES = [
"package.json",
".prettierrc",
".prettierrc.json",
".prettierrc.yaml",
".prettierrc.yml",
".prettierrc.json5",
".prettierrc.js",
".prettierrc.mjs",
".prettierrc.cjs",
"prettier.config.js",
"prettier.config.mjs",
"prettier.config.cjs",
".prettierrc.toml",
];
async function isPackageJsonFileWithPrettierConfig(file) {
try {
return Boolean(await loadConfigFromPackageJson(file));
} catch {
return false;
}
}
async function searchConfigInDirectory(directory) {
for (const fileName of CONFIG_FILE_NAMES) {
const file = path.join(directory, fileName);
if (!(await isFile(file))) {
continue;
}
if (
fileName !== "package.json" ||
(await isPackageJsonFileWithPrettierConfig(file))
) {
return file;
}
}
}
function createCachedSearchConfigInDirectory() {
const cache = new Map();
return async function (fileOrDirectory) {
if (cache.has(fileOrDirectory)) {
return cache.get(fileOrDirectory);
}
const promise = searchConfigInDirectory(fileOrDirectory);
cache.set(fileOrDirectory, promise);
const result = await promise;
cache.set(fileOrDirectory, result);
return result;
};
}
/** @type {Map} */ // @ts-expect-error -- intentionally not add the `get` method
const noopMap = { has: () => false, set() {} };
class ConfigSearcher {
#shouldCache;
#stopDirectory;
#searchedFilesStore;
#searchConfigInDirectory;
constructor({ stopDirectory, shouldCache }) {
this.#shouldCache = shouldCache;
this.#stopDirectory = stopDirectory;
this.#searchConfigInDirectory = shouldCache
? createCachedSearchConfigInDirectory()
: searchConfigInDirectory;
this.#searchedFilesStore = shouldCache ? new Map() : noopMap;
}
async #searchConfigInDirectories(startDirectory) {
const store = this.#searchedFilesStore;
for (const directory of iterateDirectoryUp(
startDirectory,
this.#stopDirectory,
)) {
// The parent directory may already searched
if (store.has(directory)) {
return store.get(directory);
}
const file = await this.#searchConfigInDirectory(directory);
if (file) {
return file;
}
}
}
async search(startDirectory) {
const store = this.#searchedFilesStore;
if (store.has(startDirectory)) {
return store.get(startDirectory);
}
const configFile = await this.#searchConfigInDirectories(startDirectory);
// Directories between startDirectory and configFile directory should has the same result
if (this.#shouldCache) {
for (const directory of iterateDirectoryUp(
startDirectory,
configFile ? path.dirname(configFile) : startDirectory,
)) {
store.set(directory, configFile);
}
}
return configFile;
}
}
export default ConfigSearcher;
@@ -0,0 +1,64 @@
import path from "node:path";
import mockable from "../../common/mockable.js";
import loadConfigWithoutCache from "./load-config.js";
import ConfigSearcher from "./config-searcher.js";
const loadCache = new Map();
const searchCache = new Map();
function clearCache() {
loadCache.clear();
searchCache.clear();
}
/**
* @param {string} configFile
* @param {{shouldCache?: boolean}} param1
* @returns {Promise<ReturnType<loadConfigWithoutCache>>}
*/
function loadConfig(configFile, { shouldCache }) {
configFile = path.resolve(configFile);
if (!shouldCache || !loadCache.has(configFile)) {
const promise = loadConfigWithoutCache(configFile);
// Even if `shouldCache` is false, we still cache it, so we can use it later
loadCache.set(configFile, promise);
return promise;
}
return loadCache.get(configFile);
}
/**
* @param {{shouldCache?: boolean, stopDirectory?: string}} param0
*/
function getSearchFunction({ shouldCache, stopDirectory }) {
stopDirectory = stopDirectory ? path.resolve(stopDirectory) : undefined;
const searchCacheKey = JSON.stringify({ shouldCache, stopDirectory });
if (!searchCache.has(searchCacheKey)) {
const searcher = new ConfigSearcher({ shouldCache, stopDirectory });
const searchFunction = searcher.search.bind(searcher);
searchCache.set(searchCacheKey, searchFunction);
}
return searchCache.get(searchCacheKey);
}
/**
* @param {string} startDirectory
* @param {{shouldCache?: boolean, stopDirectory?: string}} options
* @returns {Promise<string>}
*/
function searchConfig(startDirectory, options = {}) {
startDirectory = startDirectory
? path.resolve(startDirectory)
: process.cwd();
options.stopDirectory = mockable.getPrettierConfigSearchStopDirectory();
const search = getSearchFunction(options);
return search(startDirectory);
}
export { searchConfig, loadConfig, clearCache };
@@ -0,0 +1,48 @@
import path from "node:path";
import loadExternalConfig from "./load-external-config.js";
import loaders, { loadConfigFromPackageJson } from "./loaders.js";
async function loadConfig(configFile) {
const { base: fileName, ext: extension } = path.parse(configFile);
const load =
fileName === "package.json"
? loadConfigFromPackageJson
: loaders[extension];
if (!load) {
throw new Error(
`No loader specified for extension "${extension || "noExt"}"`,
);
}
let config = await load(configFile);
if (!config) {
return;
}
/*
We support external config
```json
{
"prettier": "my-prettier-config-package-or-file"
}
```
*/
if (typeof config === "string") {
config = await loadExternalConfig(config, configFile);
}
if (typeof config !== "object") {
throw new TypeError(
"Config is only allowed to be an object, " +
`but received ${typeof config} in "${configFile}"`,
);
}
delete config.$schema;
return config;
}
export default loadConfig;
@@ -1,12 +1,12 @@
import requireFromFile from "../utils/require-from-file.js";
import importFromFile from "../utils/import-from-file.js";
import requireFromFile from "../../utils/require-from-file.js";
import importFromFile from "../../utils/import-from-file.js";
const requireErrorCodesShouldBeIgnored = new Set([
"MODULE_NOT_FOUND",
"ERR_REQUIRE_ESM",
"ERR_PACKAGE_PATH_NOT_EXPORTED",
]);
async function loadExternalConfig(config, filepath) {
async function loadExternalConfig(externalConfig, configFile) {
/*
Try `require()` first, this is how it works in Prettier v2.
Kept this because the external config path or package may can't load with `import()`:
@@ -15,14 +15,14 @@ async function loadExternalConfig(config, filepath) {
3. is a dirname with index.js inside
*/
try {
return requireFromFile(config, filepath);
return requireFromFile(externalConfig, configFile);
} catch (/** @type {any} */ error) {
if (!requireErrorCodesShouldBeIgnored.has(error?.code)) {
throw error;
}
}
const module = await importFromFile(config, filepath);
const module = await importFromFile(externalConfig, configFile);
return module.default;
}
@@ -0,0 +1,68 @@
import { pathToFileURL } from "node:url";
import parseToml from "@iarna/toml/parse-async.js";
import parseJson5 from "json5/lib/parse.js";
import jsYaml from "js-yaml";
import parseJson from "parse-json";
import readFile from "../../utils/read-file.js";
async function readJson(file) {
const content = await readFile(file);
try {
return parseJson(content);
} catch (/** @type {any} */ error) {
error.message = `JSON Error in ${file}:\n${error.message}`;
throw error;
}
}
async function loadJs(file) {
const module = await import(pathToFileURL(file).href);
return module.default;
}
async function loadConfigFromPackageJson(file) {
const { prettier } = await readJson(file);
return prettier;
}
async function loadYaml(file) {
const content = await readFile(file);
try {
return jsYaml.load(content);
} catch (/** @type {any} */ error) {
error.message = `YAML Error in ${file}:\n${error.message}`;
throw error;
}
}
const loaders = {
async ".toml"(file) {
const content = await readFile(file);
try {
return await parseToml(content);
} catch (/** @type {any} */ error) {
error.message = `TOML Error in ${file}:\n${error.message}`;
throw error;
}
},
async ".json5"(file) {
const content = await readFile(file);
try {
return parseJson5(content);
} catch (/** @type {any} */ error) {
error.message = `JSON5 Error in ${file}:\n${error.message}`;
throw error;
}
},
".json": readJson,
".js": loadJs,
".mjs": loadJs,
".cjs": loadJs,
".yaml": loadYaml,
".yml": loadYaml,
// No extension
"": loadYaml,
};
export default loaders;
export { readJson, loadConfigFromPackageJson };
+25 -23
View File
@@ -3,15 +3,16 @@ import micromatch from "micromatch";
import mem, { memClear } from "mem";
import { toPath } from "url-or-path";
import partition from "../utils/partition.js";
import {
searchConfig as searchPrettierConfig,
loadConfig as loadPrettierConfigFile,
clearCache as clearPrettierConfigCache,
} from "./prettier-config-explorer/index.js";
import loadEditorConfigWithoutCache from "./resolve-editorconfig.js";
import getPrettierConfigExplorerWithoutCache from "./get-prettier-config-explorer.js";
const getPrettierConfigExplorer = mem(getPrettierConfigExplorerWithoutCache, {
cacheKey: ([options]) => options.cache,
});
const memoizedLoadEditorConfig = mem(loadEditorConfigWithoutCache);
function clearCache() {
memClear(getPrettierConfigExplorer);
clearPrettierConfigCache();
memClear(memoizedLoadEditorConfig);
}
@@ -25,22 +26,24 @@ function loadEditorConfig(filePath, options) {
)(filePath);
}
function loadPrettierConfig(filePath, options) {
const { useCache, config: configPath } = options;
const { load, search } = getPrettierConfigExplorer({
cache: Boolean(useCache),
});
async function loadPrettierConfig(filePath, options) {
const shouldCache = options.useCache;
let configFile = options.config;
if (configPath) {
return load(configPath);
if (!configFile) {
const directory = filePath
? path.dirname(path.resolve(filePath))
: undefined;
configFile = await searchPrettierConfig(directory, { shouldCache });
}
if (!filePath) {
return search();
if (!configFile) {
return;
}
const dirname = path.dirname(path.resolve(filePath));
return search(dirname);
const config = await loadPrettierConfigFile(configFile, { shouldCache });
return { config, configFile };
}
async function resolveConfig(fileUrlOrPath, options) {
@@ -64,7 +67,7 @@ async function resolveConfig(fileUrlOrPath, options) {
if (Array.isArray(merged.plugins)) {
merged.plugins = merged.plugins.map((value) =>
typeof value === "string" && value.startsWith(".") // relative path
? path.resolve(path.dirname(result.filepath), value)
? path.resolve(path.dirname(result.configFile), value)
: value,
);
}
@@ -73,19 +76,18 @@ async function resolveConfig(fileUrlOrPath, options) {
}
async function resolveConfigFile(fileUrlOrPath) {
const { search } = getPrettierConfigExplorerWithoutCache();
const dirname = fileUrlOrPath
const directory = fileUrlOrPath
? path.dirname(path.resolve(toPath(fileUrlOrPath)))
: undefined;
const result = await search(dirname);
return result?.filepath ?? null;
const result = await searchPrettierConfig(directory, { shouldCache: false });
return result ?? null;
}
function mergeOverrides(configResult, filePath) {
const { config, filepath: configPath } = configResult || {};
const { config, configFile } = configResult || {};
const { overrides, ...options } = config || {};
if (filePath && overrides) {
const relativeFilePath = path.relative(path.dirname(configPath), filePath);
const relativeFilePath = path.relative(path.dirname(configFile), filePath);
for (const override of overrides) {
if (
pathMatchesGlobs(
+1 -3
View File
@@ -548,8 +548,6 @@ export interface CursorOptions extends Options {
* Specify where the cursor is.
*/
cursorOffset: number;
rangeStart?: never;
rangeEnd?: never;
}
export interface CursorResult {
@@ -572,7 +570,7 @@ export function check(source: string, options?: Options): Promise<boolean>;
* `formatWithCursor` both formats the code, and translates a cursor position from unformatted code to formatted code.
* This is useful for editor integrations, to prevent the cursor from moving when code is formatted.
*
* The `cursorOffset` option should be provided, to specify where the cursor is. This option cannot be used with `rangeStart` and `rangeEnd`.
* The `cursorOffset` option should be provided, to specify where the cursor is.
*/
export function formatWithCursor(
source: string,
+3
View File
@@ -26,6 +26,7 @@ import normalizeOptions from "./main/normalize-options.js";
import partition from "./utils/partition.js";
import isNonEmptyArray from "./utils/is-non-empty-array.js";
import omit from "./utils/object-omit.js";
import mockable from "./common/mockable.js";
/**
* @param {*} fn
@@ -106,6 +107,7 @@ const sharedWithCli = {
partition,
omit,
},
mockable,
};
const debugApis = {
@@ -114,6 +116,7 @@ const debugApis = {
formatDoc: withPlugins(core.formatDoc),
printToDoc: withPlugins(core.printToDoc),
printDocToString: withPlugins(core.printDocToString),
mockable,
};
export {
+5 -5
View File
@@ -97,10 +97,10 @@ function postprocess(ast, options) {
ast.extra = { ...ast.extra, __isUsingHackPipeline: true };
break;
// TODO: Remove this when https://github.com/meriyah/meriyah/issues/200 get fixed
case "ExportAllDeclaration": {
const { exported } = node;
if (parser === "meriyah" && exported?.type === "Identifier") {
case "ExportAllDeclaration":
// TODO: Remove this when https://github.com/meriyah/meriyah/issues/200 get fixed
if (parser === "meriyah" && node.exported?.type === "Identifier") {
const { exported } = node;
const raw = text.slice(locStart(exported), locEnd(exported));
if (raw.startsWith('"') || raw.startsWith("'")) {
node.exported = {
@@ -112,7 +112,7 @@ function postprocess(ast, options) {
}
}
break;
}
// In Flow parser, it doesn't generate union/intersection types for single type
case "TSUnionType":
case "TSIntersectionType":
+1
View File
@@ -17,6 +17,7 @@ const baseParseOptions = {
tokens: true,
loggerFn: false,
project: [],
jsDocParsingMode: "none",
// TODO: Use new properties when update printer
suppressDeprecatedPropertyWarnings: true,
};
+107 -25
View File
@@ -1,3 +1,4 @@
import assert from "node:assert";
import isNonEmptyArray from "../../utils/is-non-empty-array.js";
import UnexpectedNodeError from "../../utils/unexpected-node-error.js";
import {
@@ -20,7 +21,7 @@ import {
rawText,
createTypeCheckFunction,
} from "../utils/index.js";
import { locStart, hasSameLoc } from "../loc.js";
import { locStart, hasSameLoc, locEnd } from "../loc.js";
import { printDecoratorsBeforeExport } from "./decorators.js";
import { printDeclareToken } from "./misc.js";
@@ -147,7 +148,7 @@ function printModuleSource(path, options, print) {
/** @type{Doc[]} */
const parts = [];
if (!shouldNotPrintSpecifiers(node, options)) {
if (shouldPrintSpecifiers(node, options)) {
parts.push(" from");
}
parts.push(" ", print("source"));
@@ -158,7 +159,7 @@ function printModuleSource(path, options, print) {
function printModuleSpecifiers(path, options, print) {
const { node } = path;
if (shouldNotPrintSpecifiers(node, options)) {
if (!shouldPrintSpecifiers(node, options)) {
return "";
}
@@ -230,21 +231,96 @@ function printModuleSpecifiers(path, options, print) {
return parts;
}
function shouldNotPrintSpecifiers(node, options) {
const { type, importKind, source, specifiers } = node;
function shouldPrintSpecifiers(node, options) {
if (
type !== "ImportDeclaration" ||
isNonEmptyArray(specifiers) ||
importKind === "type"
node.type !== "ImportDeclaration" ||
isNonEmptyArray(node.specifiers) ||
node.importKind === "type"
) {
return true;
}
const text = getTextWithoutComments(
options,
locStart(node),
locStart(node.source),
);
return text.trimEnd().endsWith("from");
}
function shouldPrintAttributes(node, options) {
if (!node.source) {
return false;
}
// TODO: check tokens
return !/{\s*}/.test(
options.originalText.slice(locStart(node), locStart(source)),
if (isNonEmptyArray(node.attributes) || isNonEmptyArray(node.assertions)) {
return true;
}
const text = getTextWithoutComments(
options,
locEnd(node.source),
locEnd(node),
).trimStart();
return text.startsWith("with") || text.startsWith("assert");
}
function getTextWithoutComments(options, start, end) {
let text = options.originalText.slice(start, end);
for (const comment of options[Symbol.for("comments")]) {
const commentStart = locStart(comment);
// Comments are sorted, we can escape if the comment is after the range
if (commentStart > end) {
break;
}
const commentEnd = locEnd(comment);
if (commentEnd < start) {
continue;
}
const commentLength = commentEnd - commentStart;
text =
text.slice(0, commentStart - start) +
" ".repeat(commentLength) +
text.slice(commentEnd - start);
}
if (process.env.NODE_ENV !== "production") {
assert(text.length === end - start);
}
return text;
}
function getImportAttributesOrAssertionsKeyword(node, options) {
if (
// Babel parser add this property to indicate the keyword is `assert`
node.extra?.deprecatedAssertSyntax ||
(isNonEmptyArray(node.assertions) && !isNonEmptyArray(node.attributes))
) {
return "assert";
}
if (!isNonEmptyArray(node.assertions) && isNonEmptyArray(node.attributes)) {
return "with";
}
const firstAttribute = node.attributes?.[0] ?? node.assertions?.[0];
const textBetweenSourceAndAttributes = getTextWithoutComments(
options,
locEnd(node.source),
firstAttribute ? locStart(firstAttribute) : locEnd(node),
);
if (textBetweenSourceAndAttributes.trimStart().startsWith("assert")) {
return "assert";
}
return "with";
}
/**
@@ -254,27 +330,33 @@ function shouldNotPrintSpecifiers(node, options) {
function printImportAttributes(path, options, print) {
const { node } = path;
if (!shouldPrintAttributes(node, options)) {
return "";
}
const keyword = getImportAttributesOrAssertionsKeyword(node, options);
/** @type{Doc[]} */
const parts = [` ${keyword} {`];
const property = isNonEmptyArray(node.attributes)
? "attributes"
: isNonEmptyArray(node.assertions)
? "assertions"
: undefined;
if (property) {
if (options.bracketSpacing) {
parts.push(" ");
}
if (!property) {
return "";
parts.push(join(", ", path.map(print, property)));
if (options.bracketSpacing) {
parts.push(" ");
}
}
parts.push("}");
const keyword =
property === "assertions" || node.extra?.deprecatedAssertSyntax
? "assert"
: "with";
return [
` ${keyword} {`,
options.bracketSpacing ? " " : "",
join(", ", path.map(print, property)),
options.bracketSpacing ? " " : "",
"}",
];
return parts;
}
function printModuleSpecifier(path, options, print) {
@@ -61,10 +61,6 @@ const excludeKeys = {
// Flow parser changed `.types` to `.elementTypes` https://github.com/facebook/flow/commit/5b60e6a81dc277dfab2e88fa3737a4dc9aafdcab
// TupleTypeAnnotation: ["types"],
PropertyDefinition: ["tsModifiers"],
// From `babelVisitorKeys`
DeclareInterface: ["mixins", "implements"],
InterfaceDeclaration: ["mixins", "implements"],
};
const visitorKeys = Object.fromEntries(
+2 -6
View File
@@ -49,10 +49,8 @@ const options = {
type: "int",
default: -1,
range: { start: -1, end: Number.POSITIVE_INFINITY, step: 1 },
description: outdent`
Print (to stderr) where a cursor at the given position would move to after formatting.
This option cannot be used with --range-start and --range-end.
`,
description:
"Print (to stderr) where a cursor at the given position would move to after formatting.",
cliCategory: CATEGORY_EDITOR,
},
endOfLine: {
@@ -160,7 +158,6 @@ const options = {
description: outdent`
Format code ending at a given character offset (exclusive).
The range will extend forwards to the end of the selected statement.
This option cannot be used with --cursor-offset.
`,
cliCategory: CATEGORY_EDITOR,
},
@@ -172,7 +169,6 @@ const options = {
description: outdent`
Format code starting at a given character offset.
The range will extend backwards to the start of the first line containing the selected statement.
This option cannot be used with --cursor-offset.
`,
cliCategory: CATEGORY_EDITOR,
},
+1 -1
View File
@@ -4,7 +4,7 @@ import { CursorOptions, CursorResult, Options, SupportInfo } from "./index.js";
* formatWithCursor both formats the code, and translates a cursor position from unformatted code to formatted code.
* This is useful for editor integrations, to prevent the cursor from moving when code is formatted
*
* The cursorOffset option should be provided, to specify where the cursor is. This option cannot be used with rangeStart and rangeEnd.
* The cursorOffset option should be provided, to specify where the cursor is.
*
* ```js
* await prettier.formatWithCursor(" 1", { cursorOffset: 2, parser: "babel" });
+22
View File
@@ -0,0 +1,22 @@
import fs from "node:fs/promises";
import { toPath } from "url-or-path";
/**
* @param {string | URL} file
* @param {{allowSymlinks: boolean}} [options]
* @returns {Promise<boolean>}
*/
async function isFile(file, options) {
const allowSymlinks = options?.allowSymlinks ?? true;
let stats;
try {
stats = await (allowSymlinks ? fs.stat : fs.lstat)(toPath(file));
} catch {
return false;
}
return stats.isFile();
}
export default isFile;
-2
View File
@@ -4,13 +4,11 @@ prettierStandalone.formatWithCursor(" 1", { cursorOffset: 2, parser: "babel" });
prettierStandalone.formatWithCursor(" 1", {
cursorOffset: 2,
parser: "babel",
// @ts-expect-error
rangeStart: 2,
});
prettierStandalone.formatWithCursor(" 1", {
cursorOffset: 2,
parser: "babel",
// @ts-expect-error
rangeEnd: 2,
});
prettierStandalone.format(" 1", { parser: "babel" });
+13 -1
View File
@@ -29,6 +29,18 @@ describe("Unit tests for dts files", () => {
/** @type {import("typescript").Diagnostic[]} */
const diagnostics = ts.getPreEmitDiagnostics(program);
expect(diagnostics).toEqual([]);
expect(diagnostics.map(formatDiagnostic)).toEqual([]);
});
});
/**
* @param {import("typescript").Diagnostic} diagnostic
*/
function formatDiagnostic({ file, start, code, messageText }) {
let location = "";
if (file) {
const { line, character } = ts.getLineAndCharacterOfPosition(file, start);
location = `${file.fileName}:${line + 1}:${character + 1} `;
}
return `${location}TS${code}: ${messageText}`;
}
@@ -742,17 +742,6 @@ exports[`valid-for-using-binding-of-of.js [meriyah] format 1`] = `
Cause: [2:21]: Invalid left-hand side in for-of"
`;
exports[`valid-for-using-binding-of-of.js [typescript] format 1`] = `
"')' expected. (2:26)
1 | async function f() {
> 2 | for (await using of of of);
| ^
3 | for await (await using of of of);
4 | }
5 |
Cause: ')' expected."
`;
exports[`valid-for-using-binding-of-of.js format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
@@ -32,9 +32,6 @@ run_spec(import.meta, ["babel", "flow", "typescript"], {
"valid-await-using-comments.js",
"using-declarations.js",
// https://github.com/microsoft/TypeScript/issues/55555
"valid-for-using-binding-of-of.js",
// TypeScript does not support module expr
"valid-module-block-top-level-using-binding.js",
"valid-module-block-top-level-await-using-binding.js",
@@ -86,12 +86,12 @@ import * as bar from "bar.json" assert { }
import * as baz from "baz.json" assert { /* comment */ }
=====================================output=====================================
export * as foo from "foo.json";
export * as bar from "bar.json";
export * as baz from "baz.json" /* comment */;
export * as bar from "bar.json" assert {};
export * as baz from "baz.json" /* comment */ assert {};
import * as foo from "foo.json";
import * as bar from "bar.json";
import * as baz from "baz.json" /* comment */;
import * as bar from "bar.json" assert {};
import * as baz from "baz.json" /* comment */ assert {};
================================================================================
`;
@@ -69,7 +69,7 @@ printWidth: 80
=====================================input======================================
export * as bar from "bar.json" assert { }
=====================================output=====================================
export * as bar from "bar.json";
export * as bar from "bar.json" assert {};
================================================================================
`;
@@ -71,17 +71,6 @@ exports[`empty.js [meriyah] format 1`] = `
Cause: [2:36]: Unexpected token: 'with'"
`;
exports[`empty.js [typescript] format 1`] = `
"';' expected. (2:33)
1 | export * as foo from "foo.json"
> 2 | export * as bar from "bar.json" with { }
| ^
3 | export * as baz from "baz.json" with { /* comment */ }
4 |
5 | import * as foo from "foo.json"
Cause: ';' expected."
`;
exports[`empty.js format 1`] = `
====================================options=====================================
parsers: ["babel", "typescript"]
@@ -98,12 +87,74 @@ import * as baz from "baz.json" with { /* comment */ }
=====================================output=====================================
export * as foo from "foo.json";
export * as bar from "bar.json";
export * as baz from "baz.json" /* comment */;
export * as bar from "bar.json" with {};
export * as baz from "baz.json" /* comment */ with {};
import * as foo from "foo.json";
import * as bar from "bar.json";
import * as baz from "baz.json" /* comment */;
import * as bar from "bar.json" with {};
import * as baz from "baz.json" /* comment */ with {};
================================================================================
`;
exports[`keyword-detect.js [acorn] format 1`] = `
"Unexpected token (1:35)
> 1 | import "./test.json" /* assert */ with /* assert */ { type: "json" }
| ^
2 | import {} from "./test.json" /* assert */ with /* assert */ { type: "json" }
3 | import "./test.json" /* with */ assert /* with */ { type: "json" }
4 | import {} from "./test.json" /* with */ assert /* with */ { type: "json" }
Cause: Unexpected token (1:34)"
`;
exports[`keyword-detect.js [espree] format 1`] = `
"Unexpected token with (1:35)
> 1 | import "./test.json" /* assert */ with /* assert */ { type: "json" }
| ^
2 | import {} from "./test.json" /* assert */ with /* assert */ { type: "json" }
3 | import "./test.json" /* with */ assert /* with */ { type: "json" }
4 | import {} from "./test.json" /* with */ assert /* with */ { type: "json" }
Cause: Unexpected token with"
`;
exports[`keyword-detect.js [meriyah] format 1`] = `
"Unexpected token: 'with' (1:38)
> 1 | import "./test.json" /* assert */ with /* assert */ { type: "json" }
| ^
2 | import {} from "./test.json" /* assert */ with /* assert */ { type: "json" }
3 | import "./test.json" /* with */ assert /* with */ { type: "json" }
4 | import {} from "./test.json" /* with */ assert /* with */ { type: "json" }
Cause: [1:38]: Unexpected token: 'with'"
`;
exports[`keyword-detect.js format 1`] = `
====================================options=====================================
parsers: ["babel", "typescript"]
printWidth: 80
| printWidth
=====================================input======================================
import "./test.json" /* assert */ with /* assert */ { type: "json" }
import {} from "./test.json" /* assert */ with /* assert */ { type: "json" }
import "./test.json" /* with */ assert /* with */ { type: "json" }
import {} from "./test.json" /* with */ assert /* with */ { type: "json" }
export {} from "./test.json" /* assert */ with /* assert */ { type: "json" }
export {} from "./test.json" /* with */ assert /* with */ { type: "json" }
export * from "./test.json" /* assert */ with /* assert */ { type: "json" }
export * from "./test.json" /* with */ assert /* with */ { type: "json" }
=====================================output=====================================
import "./test.json" /* assert */ /* assert */ with { type: "json" };
import {} from "./test.json" /* assert */ /* assert */ with { type: "json" };
import "./test.json" /* with */ /* with */ assert { type: "json" };
import {} from "./test.json" /* with */ /* with */ assert { type: "json" };
export {} from "./test.json" /* assert */ /* assert */ with { type: "json" };
export {} from "./test.json" /* with */ /* with */ assert { type: "json" };
export * from "./test.json" /* assert */ /* assert */ with { type: "json" };
export * from "./test.json" /* with */ /* with */ assert { type: "json" };
================================================================================
`;
@@ -132,14 +183,6 @@ exports[`multi-types.js [meriyah] format 1`] = `
Cause: [1:34]: Unexpected token: 'with'"
`;
exports[`multi-types.js [typescript] format 1`] = `
"';' expected. (1:31)
> 1 | import json from "./foo.json" with { type: "json", type: "bar" };
| ^
2 |
Cause: ';' expected."
`;
exports[`multi-types.js format 1`] = `
====================================options=====================================
parsers: ["babel", "typescript"]
@@ -178,14 +221,6 @@ exports[`non-type.js [meriyah] format 1`] = `
Cause: [1:31]: Unexpected token: 'with'"
`;
exports[`non-type.js [typescript] format 1`] = `
"';' expected. (1:28)
> 1 | import foo from "foo.json" with { lazy: "true" };
| ^
2 |
Cause: ';' expected."
`;
exports[`non-type.js format 1`] = `
====================================options=====================================
parsers: ["babel", "typescript"]
@@ -230,16 +265,6 @@ exports[`re-export.js [meriyah] format 1`] = `
Cause: [1:47]: Unexpected token: 'with'"
`;
exports[`re-export.js [typescript] format 1`] = `
"';' expected. (1:44)
> 1 | export { default as foo2 } from "foo.json" with { type: "json" };
| ^
2 | export * from "foo.json" with { type: "json" };
3 | export * as foo3 from "foo.json" with { type: "json" };
4 |
Cause: ';' expected."
`;
exports[`re-export.js format 1`] = `
====================================options=====================================
parsers: ["babel", "typescript"]
@@ -282,14 +307,6 @@ exports[`static-import.js [meriyah] format 1`] = `
Cause: [1:34]: Unexpected token: 'with'"
`;
exports[`static-import.js [typescript] format 1`] = `
"';' expected. (1:31)
> 1 | import json from "./foo.json" with { type: "json" };
| ^
2 |
Cause: ';' expected."
`;
exports[`static-import.js format 1`] = `
====================================options=====================================
parsers: ["babel", "typescript"]
@@ -328,14 +345,6 @@ exports[`without-from.js [meriyah] format 1`] = `
Cause: [1:17]: Unexpected token: 'with'"
`;
exports[`without-from.js [typescript] format 1`] = `
"';' expected. (1:14)
> 1 | import "foo" with { type: "json" }
| ^
2 |
Cause: ';' expected."
`;
exports[`without-from.js format 1`] = `
====================================options=====================================
parsers: ["babel", "typescript"]
@@ -69,7 +69,7 @@ printWidth: 80
=====================================input======================================
export * as bar from "bar.json" with { }
=====================================output=====================================
export * as bar from "bar.json";
export * as bar from "bar.json" with {};
================================================================================
`;
@@ -8,6 +8,7 @@ run_spec(import.meta, ["babel", "typescript"], {
"re-export.js",
"without-from.js",
"non-type.js",
"keyword-detect.js",
],
espree: [
"dynamic-import.js",
@@ -17,6 +18,7 @@ run_spec(import.meta, ["babel", "typescript"], {
"re-export.js",
"without-from.js",
"non-type.js",
"keyword-detect.js",
],
meriyah: [
"dynamic-import.js",
@@ -26,14 +28,7 @@ run_spec(import.meta, ["babel", "typescript"], {
"re-export.js",
"without-from.js",
"non-type.js",
],
typescript: [
"empty.js",
"multi-types.js",
"static-import.js",
"re-export.js",
"without-from.js",
"non-type.js",
"keyword-detect.js",
],
},
});
@@ -0,0 +1,10 @@
import "./test.json" /* assert */ with /* assert */ { type: "json" }
import {} from "./test.json" /* assert */ with /* assert */ { type: "json" }
import "./test.json" /* with */ assert /* with */ { type: "json" }
import {} from "./test.json" /* with */ assert /* with */ { type: "json" }
export {} from "./test.json" /* assert */ with /* assert */ { type: "json" }
export {} from "./test.json" /* with */ assert /* with */ { type: "json" }
export * from "./test.json" /* assert */ with /* assert */ { type: "json" }
export * from "./test.json" /* with */ assert /* with */ { type: "json" }
@@ -286,9 +286,92 @@ printWidth: 80
| printWidth
=====================================input======================================
import { } from '@types/googlemaps';
import 'a';
import /* comment */ 'a';
import // comment
'a';
import { /* comment */ } from 'a';
import /* comment */ {} from 'a';
import {} /* comment */ from 'a';
import {} from /* comment */ 'a';
import /* comment */ {/* comment */} /* comment */ from /* comment */ 'a';
import {
// comment
} from 'a';
import // comment
{} from 'a';
import {}
// comment
from 'a';
import {} from
// comment
'a';
import
// comment
{
// comment
}
// comment
from
// comment
'a';
import // {} from
'a';
import {} from // comment ends with from
'a';
import {} from /* comment ends with from */ 'a';
import {} from // comment not ends with from ___
'a';
import {} from /* comment not ends with from ___ */ 'a';
import // comment ends with from
'a';
import /* comment ends with from */ 'a';
import // comment not ends with from ___
'a';
import /* comment not ends with from ___ */ 'a';
=====================================output=====================================
import {} from "@types/googlemaps";
import "a";
import /* comment */ "a";
import // comment
"a";
import {} from /* comment */ "a";
import {} from /* comment */ "a";
import {} from /* comment */ "a";
import {} from /* comment */ "a";
import {} from /* comment */ /* comment */ /* comment */ /* comment */ "a";
import {} from // comment
"a";
import {} from // comment
"a";
import {} from // comment
"a";
import {} from // comment
"a";
import {} from // comment
// comment
// comment
// comment
"a";
import // {} from
"a";
import {} from // comment ends with from
"a";
import {} from /* comment ends with from */ "a";
import {} from // comment not ends with from ___
"a";
import {} from /* comment not ends with from ___ */ "a";
import // comment ends with from
"a";
import /* comment ends with from */ "a";
import // comment not ends with from ___
"a";
import /* comment not ends with from ___ */ "a";
================================================================================
`;
@@ -300,9 +383,92 @@ printWidth: 80
| printWidth
=====================================input======================================
import { } from '@types/googlemaps';
import 'a';
import /* comment */ 'a';
import // comment
'a';
import { /* comment */ } from 'a';
import /* comment */ {} from 'a';
import {} /* comment */ from 'a';
import {} from /* comment */ 'a';
import /* comment */ {/* comment */} /* comment */ from /* comment */ 'a';
import {
// comment
} from 'a';
import // comment
{} from 'a';
import {}
// comment
from 'a';
import {} from
// comment
'a';
import
// comment
{
// comment
}
// comment
from
// comment
'a';
import // {} from
'a';
import {} from // comment ends with from
'a';
import {} from /* comment ends with from */ 'a';
import {} from // comment not ends with from ___
'a';
import {} from /* comment not ends with from ___ */ 'a';
import // comment ends with from
'a';
import /* comment ends with from */ 'a';
import // comment not ends with from ___
'a';
import /* comment not ends with from ___ */ 'a';
=====================================output=====================================
import {} from "@types/googlemaps";
import "a";
import /* comment */ "a";
import // comment
"a";
import {} from /* comment */ "a";
import {} from /* comment */ "a";
import {} from /* comment */ "a";
import {} from /* comment */ "a";
import {} from /* comment */ /* comment */ /* comment */ /* comment */ "a";
import {} from // comment
"a";
import {} from // comment
"a";
import {} from // comment
"a";
import {} from // comment
"a";
import {} from // comment
// comment
// comment
// comment
"a";
import // {} from
"a";
import {} from // comment ends with from
"a";
import {} from /* comment ends with from */ "a";
import {} from // comment not ends with from ___
"a";
import {} from /* comment not ends with from ___ */ "a";
import // comment ends with from
"a";
import /* comment ends with from */ "a";
import // comment not ends with from ___
"a";
import /* comment not ends with from ___ */ "a";
================================================================================
`;
+45
View File
@@ -1 +1,46 @@
import { } from '@types/googlemaps';
import 'a';
import /* comment */ 'a';
import // comment
'a';
import { /* comment */ } from 'a';
import /* comment */ {} from 'a';
import {} /* comment */ from 'a';
import {} from /* comment */ 'a';
import /* comment */ {/* comment */} /* comment */ from /* comment */ 'a';
import {
// comment
} from 'a';
import // comment
{} from 'a';
import {}
// comment
from 'a';
import {} from
// comment
'a';
import
// comment
{
// comment
}
// comment
from
// comment
'a';
import // {} from
'a';
import {} from // comment ends with from
'a';
import {} from /* comment ends with from */ 'a';
import {} from // comment not ends with from ___
'a';
import {} from /* comment not ends with from ___ */ 'a';
import // comment ends with from
'a';
import /* comment ends with from */ 'a';
import // comment not ends with from ___
'a';
import /* comment not ends with from ___ */ 'a';
@@ -465,7 +465,7 @@ This is similar to the \`--list-different\` parameter in the CLI and is useful f
\`formatWithCursor\` both formats the code, and translates a cursor position from unformatted code to formatted code.
This is useful for editor integrations, to prevent the cursor from moving when code is formatted.
The \`cursorOffset\` option should be provided, to specify where the cursor is. This option cannot be used with \`rangeStart\` and \`rangeEnd\`.
The \`cursorOffset\` option should be provided, to specify where the cursor is.
\`\`\`js
prettier.formatWithCursor(" 1", { cursorOffset: 2 });
@@ -646,8 +646,6 @@ These two options can be used to format code starting and ending at a given char
* Backwards to the start of the first line containing the selected statement.
* Forwards to the end of the selected statement.
These options cannot be used with \`cursorOffset\`.
Default | CLI Override | API Override
--------|--------------|-------------
\`0\` | \`--range-start <int>\`| \`rangeStart: <int>\`
@@ -1454,7 +1452,6 @@ unformatted code to formatted code. This is useful for editor integrations, to
prevent the cursor from moving when code is formatted.
The \`cursorOffset\` option should be provided, to specify where the cursor is.
This option cannot be used with \`rangeStart\` and \`rangeEnd\`.
\`\`\`js
prettier.formatWithCursor(' 1', { cursorOffset: 2 });
@@ -1670,8 +1667,6 @@ character offset (inclusive and exclusive, respectively). The range will extend:
- Backwards to the start of the first line containing the selected statement.
- Forwards to the end of the selected statement.
These options cannot be used with \`cursorOffset\`.
| Default | CLI Override | API Override |
| ---------- | --------------------- | ------------------- |
| \`0\` | \`--range-start <int>\` | \`rangeStart: <int>\` |
@@ -2442,7 +2437,7 @@ This is similar to the \`--list-different\` parameter in the CLI and is useful f
\`formatWithCursor\` both formats the code, and translates a cursor position from unformatted code to formatted code.
This is useful for editor integrations, to prevent the cursor from moving when code is formatted.
The \`cursorOffset\` option should be provided, to specify where the cursor is. This option cannot be used with \`rangeStart\` and \`rangeEnd\`.
The \`cursorOffset\` option should be provided, to specify where the cursor is.
\`\`\`js
prettier.formatWithCursor(" 1", { cursorOffset: 2 });
@@ -2623,8 +2618,6 @@ These two options can be used to format code starting and ending at a given char
* Backwards to the start of the first line containing the selected statement.
* Forwards to the end of the selected statement.
These options cannot be used with \`cursorOffset\`.
Default | CLI Override | API Override
--------|--------------|-------------
\`0\` | \`--range-start <int>\`| \`rangeStart: <int>\`
@@ -3431,7 +3424,6 @@ unformatted code to formatted code. This is useful for editor integrations, to
prevent the cursor from moving when code is formatted.
The \`cursorOffset\` option should be provided, to specify where the cursor is.
This option cannot be used with \`rangeStart\` and \`rangeEnd\`.
\`\`\`js
prettier.formatWithCursor(" 1", { cursorOffset: 2 });
@@ -3647,8 +3639,6 @@ character offset (inclusive and exclusive, respectively). The range will extend:
- Backwards to the start of the first line containing the selected statement.
- Forwards to the end of the selected statement.
These options cannot be used with \`cursorOffset\`.
| Default | CLI Override | API Override |
| ---------- | --------------------- | ------------------- |
| \`0\` | \`--range-start <int>\` | \`rangeStart: <int>\` |
@@ -455,7 +455,7 @@ This is similar to the `--list-different` parameter in the CLI and is useful for
`formatWithCursor` both formats the code, and translates a cursor position from unformatted code to formatted code.
This is useful for editor integrations, to prevent the cursor from moving when code is formatted.
The `cursorOffset` option should be provided, to specify where the cursor is. This option cannot be used with `rangeStart` and `rangeEnd`.
The `cursorOffset` option should be provided, to specify where the cursor is.
```js
prettier.formatWithCursor(" 1", { cursorOffset: 2 });
@@ -636,8 +636,6 @@ These two options can be used to format code starting and ending at a given char
* Backwards to the start of the first line containing the selected statement.
* Forwards to the end of the selected statement.
These options cannot be used with `cursorOffset`.
Default | CLI Override | API Override
--------|--------------|-------------
`0` | `--range-start <int>`| `rangeStart: <int>`
@@ -47,11 +47,11 @@ Cause: Unexpected token. Did you mean \`{'>'}\` or \`&gt;\`?"
`;
exports[`module-attributes-static.ts [typescript] format 1`] = `
"';' expected. (1:28)
"'{' expected. (1:33)
> 1 | import foo from "foo.json" with type: "json";
| ^
| ^
2 |
Cause: ';' expected."
Cause: '{' expected."
`;
exports[`newline-before-arrow.ts [typescript] format 1`] = `
@@ -1,5 +1,102 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`empty-import.ts format 1`] = `
====================================options=====================================
parsers: ["typescript"]
printWidth: 80
| printWidth
=====================================input======================================
import type { } from '@types/googlemaps';
import 'a';
import /* comment */ 'a';
import // comment
'a';
import type { /* comment */ } from 'a';
import /* comment */ type {} from 'a';
import type {} /* comment */ from 'a';
import type {} from /* comment */ 'a';
import /* comment */ type {/* comment */} /* comment */ from /* comment */ 'a';
import type {
// comment
} from 'a';
import // comment
type {} from 'a';
import type {}
// comment
from 'a';
import type {} from
// comment
'a';
import type
// comment
{
// comment
}
// comment
from
// comment
'a';
import // {} from
'a';
import type {} from // comment ends with from
'a';
import type {} from /* comment ends with from */ 'a';
import type {} from // comment not ends with from ___
'a';
import type {} from /* comment not ends with from ___ */ 'a';
import // comment ends with from
'a';
import /* comment ends with from */ 'a';
import // comment not ends with from ___
'a';
import /* comment not ends with from ___ */ 'a';
=====================================output=====================================
import type {} from "@types/googlemaps";
import "a";
import /* comment */ "a";
import // comment
"a";
import type {} from /* comment */ "a";
import type {} from /* comment */ "a";
import type {} from /* comment */ "a";
import type {} from /* comment */ "a";
import type {} from /* comment */ /* comment */ /* comment */ /* comment */ "a";
import type {} from // comment
"a";
import type {} from // comment
"a";
import type {} from // comment
"a";
import type {} from // comment
"a";
import type {} from // comment
// comment
// comment
// comment
"a";
import // {} from
"a";
import type {} from // comment ends with from
"a";
import type {} from /* comment ends with from */ "a";
import type {} from // comment not ends with from ___
"a";
import type {} from /* comment not ends with from ___ */ "a";
import // comment ends with from
"a";
import /* comment ends with from */ "a";
import // comment not ends with from ___
"a";
import /* comment not ends with from ___ */ "a";
================================================================================
`;
exports[`type-modifier.ts format 1`] = `
====================================options=====================================
parsers: ["typescript"]
@@ -0,0 +1,46 @@
import type { } from '@types/googlemaps';
import 'a';
import /* comment */ 'a';
import // comment
'a';
import type { /* comment */ } from 'a';
import /* comment */ type {} from 'a';
import type {} /* comment */ from 'a';
import type {} from /* comment */ 'a';
import /* comment */ type {/* comment */} /* comment */ from /* comment */ 'a';
import type {
// comment
} from 'a';
import // comment
type {} from 'a';
import type {}
// comment
from 'a';
import type {} from
// comment
'a';
import type
// comment
{
// comment
}
// comment
from
// comment
'a';
import // {} from
'a';
import type {} from // comment ends with from
'a';
import type {} from /* comment ends with from */ 'a';
import type {} from // comment not ends with from ___
'a';
import type {} from /* comment not ends with from ___ */ 'a';
import // comment ends with from
'a';
import /* comment ends with from */ 'a';
import // comment not ends with from ___
'a';
import /* comment not ends with from ___ */ 'a';
@@ -63,7 +63,7 @@ exports[`throw error with invalid config precedence option (configPrecedence) (w
exports[`throw error with invalid config target (directory) (stderr) 1`] = `
"[error] Invalid configuration:
[error] EISDIR: illegal operation on a directory, read"
[error] Unable to read '<cli>/config/invalid/folder/.prettierrc': EISDIR: illegal operation on a directory, read"
`;
exports[`throw error with invalid config target (directory) (stdout) 1`] = `""`;
@@ -107,15 +107,12 @@ Config options:
Editor options:
--cursor-offset <int> Print (to stderr) where a cursor at the given position would move to after formatting.
This option cannot be used with --range-start and --range-end.
Defaults to -1.
--range-end <int> Format code ending at a given character offset (exclusive).
The range will extend forwards to the end of the selected statement.
This option cannot be used with --cursor-offset.
Defaults to Infinity.
--range-start <int> Format code starting at a given character offset.
The range will extend backwards to the start of the first line containing the selected statement.
This option cannot be used with --cursor-offset.
Defaults to 0.
Other options:
@@ -274,15 +271,12 @@ Config options:
Editor options:
--cursor-offset <int> Print (to stderr) where a cursor at the given position would move to after formatting.
This option cannot be used with --range-start and --range-end.
Defaults to -1.
--range-end <int> Format code ending at a given character offset (exclusive).
The range will extend forwards to the end of the selected statement.
This option cannot be used with --cursor-offset.
Defaults to Infinity.
--range-start <int> Format code starting at a given character offset.
The range will extend backwards to the start of the first line containing the selected statement.
This option cannot be used with --cursor-offset.
Defaults to 0.
Other options:
@@ -136,7 +136,6 @@ exports[`show detailed usage with --help cursor-offset (stdout) 1`] = `
"--cursor-offset <int>
Print (to stderr) where a cursor at the given position would move to after formatting.
This option cannot be used with --range-start and --range-end.
Default: -1"
`;
@@ -505,7 +504,6 @@ exports[`show detailed usage with --help range-end (stdout) 1`] = `
Format code ending at a given character offset (exclusive).
The range will extend forwards to the end of the selected statement.
This option cannot be used with --cursor-offset.
Default: Infinity"
`;
@@ -519,7 +517,6 @@ exports[`show detailed usage with --help range-start (stdout) 1`] = `
Format code starting at a given character offset.
The range will extend backwards to the start of the first line containing the selected statement.
This option cannot be used with --cursor-offset.
Default: 0"
`;
@@ -36,8 +36,7 @@ exports[`schema 1`] = `
},
"cursorOffset": {
"default": -1,
"description": "Print (to stderr) where a cursor at the given position would move to after formatting.
This option cannot be used with --range-start and --range-end.",
"description": "Print (to stderr) where a cursor at the given position would move to after formatting.",
"type": "integer",
},
"embeddedLanguageFormatting": {
@@ -345,15 +344,13 @@ This option cannot be used with --range-start and --range-end.",
"rangeEnd": {
"default": Infinity,
"description": "Format code ending at a given character offset (exclusive).
The range will extend forwards to the end of the selected statement.
This option cannot be used with --cursor-offset.",
The range will extend forwards to the end of the selected statement.",
"type": "integer",
},
"rangeStart": {
"default": 0,
"description": "Format code starting at a given character offset.
The range will extend backwards to the start of the first line containing the selected statement.
This option cannot be used with --cursor-offset.",
The range will extend backwards to the start of the first line containing the selected statement.",
"type": "integer",
},
"requirePragma": {
@@ -806,7 +806,7 @@ exports[`CLI --support-info (stdout) 1`] = `
{
"category": "Special",
"default": -1,
"description": "Print (to stderr) where a cursor at the given position would move to after formatting.\\nThis option cannot be used with --range-start and --range-end.",
"description": "Print (to stderr) where a cursor at the given position would move to after formatting.",
"name": "cursorOffset",
"pluginDefaults": {},
"range": { "end": null, "start": -1, "step": 1 },
@@ -1001,7 +1001,7 @@ exports[`CLI --support-info (stdout) 1`] = `
{
"category": "Special",
"default": null,
"description": "Format code ending at a given character offset (exclusive).\\nThe range will extend forwards to the end of the selected statement.\\nThis option cannot be used with --cursor-offset.",
"description": "Format code ending at a given character offset (exclusive).\\nThe range will extend forwards to the end of the selected statement.",
"name": "rangeEnd",
"pluginDefaults": {},
"range": { "end": null, "start": 0, "step": 1 },
@@ -1010,7 +1010,7 @@ exports[`CLI --support-info (stdout) 1`] = `
{
"category": "Special",
"default": 0,
"description": "Format code starting at a given character offset.\\nThe range will extend backwards to the start of the first line containing the selected statement.\\nThis option cannot be used with --cursor-offset.",
"description": "Format code starting at a given character offset.\\nThe range will extend backwards to the start of the first line containing the selected statement.",
"name": "rangeStart",
"pluginDefaults": {},
"range": { "end": null, "start": 0, "step": 1 },
+3 -1
View File
@@ -118,7 +118,9 @@ test("Commonjs version", () => {
expect(typeof prettierCommonjsVersion.util.getStringWidth).toBe("function");
expect(Object.keys(prettierCommonjsVersion.__debug).sort()).toEqual(
Object.keys(prettier.__debug).sort(),
Object.keys(prettier.__debug)
.filter((key) => key !== "mockable")
.sort(),
);
expect(typeof prettierCommonjsVersion.__debug.parse).toBe("function");
@@ -1,3 +1,4 @@
import fs from "node:fs/promises";
import outdent from "outdent";
import jestPathSerializer from "../path-serializer.js";
@@ -178,3 +179,31 @@ describe("Invalid config value", () => {
stderr: "",
});
});
// Can't put a invalid `package.json` file in the test dir
test("Invalid package.json", async () => {
const packageJsonFile = new URL(
"../cli/config/invalid/broken-package-json/package.json",
import.meta.url,
);
try {
await fs.writeFile(packageJsonFile, '{"prettier":{}}');
const { stdout: configFileForValidPackageJson } = await runCli(
"cli/config/invalid/broken-package-json",
["--find-config-path", "foo.js"],
);
expect(configFileForValidPackageJson).toBe("package.json");
await fs.writeFile(packageJsonFile, '{"prettier":{');
const { stdout: configFileForInvalidPackageJson } = await runCli(
"cli/config/invalid/broken-package-json",
["--find-config-path", "foo.js"],
);
expect(configFileForInvalidPackageJson).toBe(".prettierrc");
} finally {
await fs.rm(packageJsonFile, { force: true });
}
});
+4 -57
View File
@@ -1,60 +1,7 @@
import path from "node:path";
import { pathToFileURL } from "node:url";
import createEsmUtils from "esm-utils";
import { mockable } from "../env.js";
import prettier from "../../config/prettier-entry.js";
const { __dirname } = createEsmUtils(import.meta);
const { mockable } = prettier.__debug;
// This don't has to be the same result as `prettier.resolveConfig`,
// Because we are testing with default `lilconfigOptions`
describe("lilconfig", () => {
let lilconfig;
beforeAll(async () => {
({
default: { lilconfig },
} = await import(pathToFileURL(mockable)));
});
const configs = [
{
title: "prettier.config.cjs",
dirname: path.join(__dirname, "../cli/config/js/"),
file: path.join(__dirname, "../cli/config/js/prettier.config.cjs"),
value: {
endOfLine: "auto",
tabWidth: 8,
},
},
{
title: "package.json",
dirname: path.join(__dirname, "../cli/config/package/"),
file: path.join(__dirname, "../cli/config/package/package.json"),
value: {
tabWidth: 3,
overrides: [
{
files: "*.ts",
options: {
tabWidth: 5,
},
},
],
},
},
];
for (const { title, dirname, file, value } of configs) {
test(`async version ${title}`, async () => {
const { config, filepath } = await lilconfig("prettier").search(dirname);
expect(config).toEqual(value);
expect(filepath).toBe(file);
});
}
});
test("isCI", async () => {
const {
default: { isCI },
} = await import(pathToFileURL(mockable));
expect(typeof isCI()).toBe("boolean");
test("isCI", () => {
expect(typeof mockable.isCI()).toBe("boolean");
});
@@ -321,6 +321,25 @@ function isSymlinkSupported() {
{ stdout: "test-a/symlink-to-directory-b/b.js" },
base,
);
testPatterns(
"",
[
"test-a/symlink-to-file-b",
"--no-error-on-unmatched-pattern",
"--log-level",
"debug",
],
{
status: 0,
stdout: "",
stderr:
'[debug] normalized argv: {"":["test-a/symlink-to-file-b"],"cache":false,"color":true,"editorconfig":true,"errorOnUnmatchedPattern":false,"logLevel":"debug","ignorePath":[".prettierignore"],"configPrecedence":"cli-override","debugRepeat":0,"plugins":[],"listDifferent":true,"_":["test-a/symlink-to-file-b"],"__raw":{"_":["test-a/symlink-to-file-b"],"cache":false,"color":true,"editorconfig":true,"error-on-unmatched-pattern":false,"l":true,"log-level":"debug","ignore-path":".prettierignore","config-precedence":"cli-override","debug-repeat":0,"plugin":[]}}' +
"\n" +
'[debug] Skipping pattern "test-a/symlink-to-file-b", as it is a symbolic link.',
},
base,
);
});
function testPatterns(
+5 -10
View File
@@ -3,8 +3,7 @@ import fs from "node:fs";
import path from "node:path";
import url from "node:url";
import readline from "node:readline";
import { lilconfig } from "lilconfig";
import { prettierCli, mockable as mockableModuleFile } from "./env.js";
import { prettierCli, prettierMainEntry } from "./env.js";
const normalizeToPosix =
path.sep === "\\"
@@ -56,9 +55,8 @@ async function run() {
process.stdin.isTTY = Boolean(options.isTTY);
process.stdout.isTTY = Boolean(options.stdoutIsTTY);
const { default: mockable } = await import(
url.pathToFileURL(mockableModuleFile)
);
const prettier = await import(url.pathToFileURL(prettierMainEntry));
const { mockable } = prettier.__debug;
// We cannot use `jest.setMock("get-stream", impl)` here, because in the
// production build everything is bundled into one file so there is no
@@ -66,11 +64,8 @@ async function run() {
// eslint-disable-next-line require-await
mockable.getStdin = async () => options.input || "";
mockable.isCI = () => Boolean(options.ci);
mockable.lilconfig = (moduleName, options) =>
lilconfig(moduleName, {
...options,
stopDir: url.fileURLToPath(new URL("./cli", import.meta.url)),
});
mockable.getPrettierConfigSearchStopDirectory = () =>
url.fileURLToPath(new URL("./cli", import.meta.url));
// eslint-disable-next-line require-await
mockable.writeFormattedFile = async (filename, content) => {
filename = normalizeToPosix(path.relative(process.cwd(), filename));
@@ -0,0 +1,2 @@
# will be created by test
package.json
+4 -4
View File
@@ -11,10 +11,10 @@ const prettierCli = path.join(
typeof bin === "object" ? bin.prettier : bin,
);
const mockable = isProduction
? path.join(PRETTIER_DIR, "./internal/internal.mjs")
: path.join(PRETTIER_DIR, "./src/common/mockable.js");
const prettierMainEntry = isProduction
? path.join(PRETTIER_DIR, "./index.mjs")
: path.join(PRETTIER_DIR, "./src/index.js");
const projectRoot = path.join(__dirname, "../..");
export { isProduction, mockable, prettierCli, projectRoot };
export { isProduction, prettierMainEntry, prettierCli, projectRoot };
+1 -2
View File
@@ -80,8 +80,7 @@ const animalName =
pet.isScary() ?
'wolf'
: 'dog'
: pet.canMeow() ?
'cat'
: pet.canMeow() ? 'cat'
: 'probably a bunny';
```
+63 -2
View File
@@ -104,7 +104,15 @@ class Playground extends React.Component {
this.setContent = (content) => this.setState({ content });
this.clearContent = this.setContent.bind(this, "");
this.resetOptions = () => this.setState({ options: defaultOptions });
this.setSelection = (selection) => this.setState({ selection });
this.setSelection = (selection) => {
this.setState({ selection });
if (this.state.trackCursorOffset) {
this.handleOptionValueChange(
this.cursorOffsetOption,
util.convertSelectionToRange(selection, this.state.content)[0],
);
}
};
this.setSelectionAsRange = () => {
const { selection, content, options } = this.state;
const [rangeStart, rangeEnd] = util.convertSelectionToRange(
@@ -126,6 +134,9 @@ class Playground extends React.Component {
this.rangeEndOption = props.availableOptions.find(
(opt) => opt.name === "rangeEnd",
);
this.cursorOffsetOption = props.availableOptions.find(
(opt) => opt.name === "cursorOffset",
);
this.formatInput = this.formatInput.bind(this);
this.insertDummyId = this.insertDummyId.bind(this);
@@ -172,6 +183,7 @@ class Playground extends React.Component {
...ENABLED_OPTIONS,
"rangeStart",
"rangeEnd",
"cursorOffset",
]);
const cliOptions = util.buildCliArgs(orderedOptions, options);
@@ -247,7 +259,7 @@ class Playground extends React.Component {
reformat={editorState.showSecondFormat}
rethrowEmbedErrors={editorState.rethrowEmbedErrors}
>
{({ formatted, debug }) => {
{({ formatted, debug, cursorOffset }) => {
const fullReport = this.getMarkdown({
formatted,
reformatted: debug.reformatted,
@@ -294,6 +306,49 @@ class Playground extends React.Component {
Set selected text as range
</Button>
</SidebarCategory>
<SidebarCategory title="Cursor">
<Option
option={this.cursorOffsetOption}
value={
options.cursorOffset >= 0
? options.cursorOffset
: ""
}
onChange={this.handleOptionValueChange}
/>
<div
style={{
display: "flex",
alignItems: "baseline",
gap: "10px",
}}
>
<Checkbox
label="track"
checked={Boolean(this.state.trackCursorOffset)}
onChange={() =>
this.setState((state) => ({
trackCursorOffset: !state.trackCursorOffset,
}))
}
/>
{options.cursorOffset >= 0 && (
<>
<Button
onClick={() => {
this.handleOptionValueChange(
this.cursorOffsetOption,
-1,
);
}}
>
Reset
</Button>
<label>Result: {cursorOffset}</label>
</>
)}
</div>
</SidebarCategory>
<SidebarCategory title="Debug">
<Checkbox
label="show input"
@@ -419,6 +474,12 @@ class Playground extends React.Component {
mode={util.getCodemirrorMode(options.parser)}
value={formatted}
ruler={options.printWidth}
overlayStart={
cursorOffset === -1 ? undefined : cursorOffset
}
overlayEnd={
cursorOffset === -1 ? undefined : cursorOffset + 1
}
/>
)
) : null}
+4 -4
View File
@@ -97,10 +97,10 @@ class CodeMirrorPanel extends React.Component {
}
updateOverlay() {
if (!this.props.readOnly) {
if (this._overlay) {
this._codeMirror.removeOverlay(this._overlay);
}
if (this._overlay) {
this._codeMirror.removeOverlay(this._overlay);
}
if (this.props.overlayStart !== undefined) {
const [start, end] = getIndexPosition(this.props.value, [
this.props.overlayStart,
this.props.overlayEnd,
+1 -1
View File
@@ -27,7 +27,7 @@ await prettier.format("foo ( );", { semi: false, parser: "babel" });
`formatWithCursor` both formats the code, and translates a cursor position from unformatted code to formatted code. This is useful for editor integrations, to prevent the cursor from moving when code is formatted.
The `cursorOffset` option should be provided, to specify where the cursor is. This option cannot be used with `rangeStart` and `rangeEnd`.
The `cursorOffset` option should be provided, to specify where the cursor is.
```js
await prettier.formatWithCursor(" 1", { cursorOffset: 2, parser: "babel" });
@@ -255,8 +255,6 @@ These two options can be used to format code starting and ending at a given char
- Backwards to the start of the first line containing the selected statement.
- Forwards to the end of the selected statement.
These options cannot be used with `cursorOffset`.
| Default | CLI Override | API Override |
| ---------- | --------------------- | ------------------- |
| `0` | `--range-start <int>` | `rangeStart: <int>` |
+104 -145
View File
@@ -45,23 +45,13 @@ __metadata:
languageName: node
linkType: hard
"@babel/code-frame@npm:7.22.13":
version: 7.22.13
resolution: "@babel/code-frame@npm:7.22.13"
dependencies:
"@babel/highlight": ^7.22.13
chalk: ^2.4.2
checksum: 22e342c8077c8b77eeb11f554ecca2ba14153f707b85294fcf6070b6f6150aae88a7b7436dd88d8c9289970585f3fe5b9b941c5aa3aa26a6d5a8ef3f292da058
languageName: node
linkType: hard
"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.21.4, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.23.4":
version: 7.23.4
resolution: "@babel/code-frame@npm:7.23.4"
"@babel/code-frame@npm:7.23.5, @babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.21.4, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.23.4":
version: 7.23.5
resolution: "@babel/code-frame@npm:7.23.5"
dependencies:
"@babel/highlight": ^7.23.4
chalk: ^2.4.2
checksum: 29999d08c3dbd803f3c296dae7f4f40af1f9e381d6bbc76e5a75327c4b8b023bcb2e209843d292f5d71c3b5c845df1da959d415ed862d6a68e0ad6c5c9622d37
checksum: d90981fdf56a2824a9b14d19a4c0e8db93633fd488c772624b4e83e0ceac6039a27cd298a247c3214faa952bf803ba23696172ae7e7235f3b97f43ba278c569a
languageName: node
linkType: hard
@@ -95,27 +85,15 @@ __metadata:
languageName: node
linkType: hard
"@babel/generator@npm:7.23.3":
version: 7.23.3
resolution: "@babel/generator@npm:7.23.3"
"@babel/generator@npm:7.23.5, @babel/generator@npm:^7.23.3, @babel/generator@npm:^7.23.4, @babel/generator@npm:^7.7.2":
version: 7.23.5
resolution: "@babel/generator@npm:7.23.5"
dependencies:
"@babel/types": ^7.23.3
"@babel/types": ^7.23.5
"@jridgewell/gen-mapping": ^0.3.2
"@jridgewell/trace-mapping": ^0.3.17
jsesc: ^2.5.1
checksum: b6e71cca852d4e1aa01a28a30b8c74ffc3b8d56ccb7ae3ee783028ee015f63ad861a2e386c3eb490a9a8634db485a503a33521680f4af510151e90346c46da17
languageName: node
linkType: hard
"@babel/generator@npm:^7.23.3, @babel/generator@npm:^7.23.4, @babel/generator@npm:^7.7.2":
version: 7.23.4
resolution: "@babel/generator@npm:7.23.4"
dependencies:
"@babel/types": ^7.23.4
"@jridgewell/gen-mapping": ^0.3.2
"@jridgewell/trace-mapping": ^0.3.17
jsesc: ^2.5.1
checksum: 7403717002584eaeb58559f4d0de19b79e924ef2735711278f7cb5206d081428bf3960578566d6fa4102b7b30800d44f70acffea5ecef83f0cb62361c2a23062
checksum: 845ddda7cf38a3edf4be221cc8a439dee9ea6031355146a1a74047aa8007bc030305b27d8c68ec9e311722c910610bde38c0e13a9ce55225251e7cb7e7f3edc8
languageName: node
linkType: hard
@@ -207,7 +185,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/helper-string-parser@npm:^7.22.5, @babel/helper-string-parser@npm:^7.23.4":
"@babel/helper-string-parser@npm:^7.23.4":
version: 7.23.4
resolution: "@babel/helper-string-parser@npm:7.23.4"
checksum: c0641144cf1a7e7dc93f3d5f16d5327465b6cf5d036b48be61ecba41e1eece161b48f46b7f960951b67f8c3533ce506b16dece576baef4d8b3b49f8c65410f90
@@ -239,7 +217,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/highlight@npm:^7.0.0, @babel/highlight@npm:^7.22.13, @babel/highlight@npm:^7.23.4":
"@babel/highlight@npm:^7.0.0, @babel/highlight@npm:^7.23.4":
version: 7.23.4
resolution: "@babel/highlight@npm:7.23.4"
dependencies:
@@ -250,12 +228,12 @@ __metadata:
languageName: node
linkType: hard
"@babel/parser@npm:7.23.4, @babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.3, @babel/parser@npm:^7.23.4":
version: 7.23.4
resolution: "@babel/parser@npm:7.23.4"
"@babel/parser@npm:7.23.5, @babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.3, @babel/parser@npm:^7.23.4":
version: 7.23.5
resolution: "@babel/parser@npm:7.23.5"
bin:
parser: ./bin/babel-parser.js
checksum: 1d90e17d966085b8ea12f357ffcc76568969364481254f0ae3e7ed579e9421d31c7fd3876ccb3b215a5b2ada48251b0c2d0f21ba225ee194f0e18295b49085f2
checksum: ea763629310f71580c4a3ea9d3705195b7ba994ada2cc98f9a584ebfdacf54e92b2735d351672824c2c2b03c7f19206899f4d95650d85ce514a822b19a8734c7
languageName: node
linkType: hard
@@ -442,25 +420,14 @@ __metadata:
languageName: node
linkType: hard
"@babel/types@npm:7.23.3":
version: 7.23.3
resolution: "@babel/types@npm:7.23.3"
dependencies:
"@babel/helper-string-parser": ^7.22.5
"@babel/helper-validator-identifier": ^7.22.20
to-fast-properties: ^2.0.0
checksum: b96f1ec495351aeb2a5f98dd494aafa17df02a351548ae96999460f35c933261c839002a34c1e83552ff0d9f5e94d0b5b8e105d38131c7c9b0f5a6588676f35d
languageName: node
linkType: hard
"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.3, @babel/types@npm:^7.23.4, @babel/types@npm:^7.3.3, @babel/types@npm:^7.8.3":
version: 7.23.4
resolution: "@babel/types@npm:7.23.4"
"@babel/types@npm:7.23.5, @babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.3, @babel/types@npm:^7.23.4, @babel/types@npm:^7.23.5, @babel/types@npm:^7.3.3, @babel/types@npm:^7.8.3":
version: 7.23.5
resolution: "@babel/types@npm:7.23.5"
dependencies:
"@babel/helper-string-parser": ^7.23.4
"@babel/helper-validator-identifier": ^7.22.20
to-fast-properties: ^2.0.0
checksum: 8a1ab20da663d202b1c090fdef4b157d3c7d8cb1cf60ea548f887d7b674935371409804d6cba52f870c22ced7685fcb41b0578d3edde720990de00cbb328da54
checksum: 3d21774480a459ef13b41c2e32700d927af649e04b70c5d164814d8e04ab584af66a93330602c2925e1a6925c2b829cc153418a613a4e7d79d011be1f29ad4b2
languageName: node
linkType: hard
@@ -1967,15 +1934,15 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/eslint-plugin@npm:6.10.0":
version: 6.10.0
resolution: "@typescript-eslint/eslint-plugin@npm:6.10.0"
"@typescript-eslint/eslint-plugin@npm:6.13.2":
version: 6.13.2
resolution: "@typescript-eslint/eslint-plugin@npm:6.13.2"
dependencies:
"@eslint-community/regexpp": ^4.5.1
"@typescript-eslint/scope-manager": 6.10.0
"@typescript-eslint/type-utils": 6.10.0
"@typescript-eslint/utils": 6.10.0
"@typescript-eslint/visitor-keys": 6.10.0
"@typescript-eslint/scope-manager": 6.13.2
"@typescript-eslint/type-utils": 6.13.2
"@typescript-eslint/utils": 6.13.2
"@typescript-eslint/visitor-keys": 6.13.2
debug: ^4.3.4
graphemer: ^1.4.0
ignore: ^5.2.4
@@ -1988,7 +1955,7 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
checksum: eaf1f66ae1915426dad8d229c8cb80d2b320572a30c3fbc57d560d40edc2d17d004101a2fcbe331bc458df19a00f8b705f2442ee02e028bb595f4e9f9152e99d
checksum: e50cbbe7104eecef59faf3355ab981d9f353b19327f0b4607dfd829b4726f9e694b536fe43ab55f50bb00fbfdd2e4268a7e2a568b28d5fcd0d2a32a8d2466218
languageName: node
linkType: hard
@@ -2002,22 +1969,22 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/scope-manager@npm:6.10.0":
version: 6.10.0
resolution: "@typescript-eslint/scope-manager@npm:6.10.0"
"@typescript-eslint/scope-manager@npm:6.13.2":
version: 6.13.2
resolution: "@typescript-eslint/scope-manager@npm:6.13.2"
dependencies:
"@typescript-eslint/types": 6.10.0
"@typescript-eslint/visitor-keys": 6.10.0
checksum: c9b9483082ae853f10b888cf04d4a14f666ac55e749bfdb7b7f726fc51127a6340b5e2f50d93f134a8854ddcc41f7b116b214753251a8b033d0d84c600439c54
"@typescript-eslint/types": 6.13.2
"@typescript-eslint/visitor-keys": 6.13.2
checksum: ff8fd64ddf324e296e2e0e34a8f73149c9a5f14d1761ea8e8665fc5998faa2b0bbbd1a5d416aa10d725f13c804032d532f68e39a0ca6cc36d1c9b9c0aea94311
languageName: node
linkType: hard
"@typescript-eslint/type-utils@npm:6.10.0":
version: 6.10.0
resolution: "@typescript-eslint/type-utils@npm:6.10.0"
"@typescript-eslint/type-utils@npm:6.13.2":
version: 6.13.2
resolution: "@typescript-eslint/type-utils@npm:6.13.2"
dependencies:
"@typescript-eslint/typescript-estree": 6.10.0
"@typescript-eslint/utils": 6.10.0
"@typescript-eslint/typescript-estree": 6.13.2
"@typescript-eslint/utils": 6.13.2
debug: ^4.3.4
ts-api-utils: ^1.0.1
peerDependencies:
@@ -2025,7 +1992,7 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
checksum: cfe9520cf0c0f50b115d2591acb2abf99ffe5789b3536268ca65b624c8498812d91f187e80c41bea7cf2cebad9c38f69ef27440f872a20fb53c59856d8f5df38
checksum: ba54e5746139f778c35e4058e523ec8c20b68cf6472b3a7784170328e48c228f0761d2fc7e43dab053ca7d85ac4378b6965567774e6afedf551e600638404215
languageName: node
linkType: hard
@@ -2036,10 +2003,10 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/types@npm:6.10.0":
version: 6.10.0
resolution: "@typescript-eslint/types@npm:6.10.0"
checksum: e63a9e05eb3d736d02a09131627d5cb89394bf0d9d6b46fb4b620be902d89d73554720be65acbc194787bff9ffcd518c9a6cf88fd63e418232b4181e8d8438df
"@typescript-eslint/types@npm:6.13.2":
version: 6.13.2
resolution: "@typescript-eslint/types@npm:6.13.2"
checksum: 4493ff06fa07c68c5adbcbd842f6dd6f5c88f14d160b53c3379b6b703e6f62808fab7fdebcc06ff06a56f20ab432b6ceeb0afb8931dc97d4061cb417e787f2c1
languageName: node
linkType: hard
@@ -2061,12 +2028,12 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/typescript-estree@npm:6.10.0":
version: 6.10.0
resolution: "@typescript-eslint/typescript-estree@npm:6.10.0"
"@typescript-eslint/typescript-estree@npm:6.13.2":
version: 6.13.2
resolution: "@typescript-eslint/typescript-estree@npm:6.13.2"
dependencies:
"@typescript-eslint/types": 6.10.0
"@typescript-eslint/visitor-keys": 6.10.0
"@typescript-eslint/types": 6.13.2
"@typescript-eslint/visitor-keys": 6.13.2
debug: ^4.3.4
globby: ^11.1.0
is-glob: ^4.0.3
@@ -2075,24 +2042,24 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
checksum: 15bd8d9239a557071d6b03e7aa854b769fcc2dbdff587ed94be7ee8060dabdb05bcae4251df22432f625f82087e7f6986e9aab04f7eea35af694d4edd76a21af
checksum: 0c18ee5ef594a2411a788fe9d7bc6d51a03bce38d9d764bcb24ab557e5bc1942c2ddf9bd6fb4877eb102b0ae488974fb7b7fe72daa70a2054bf04d3cc6803546
languageName: node
linkType: hard
"@typescript-eslint/utils@npm:6.10.0":
version: 6.10.0
resolution: "@typescript-eslint/utils@npm:6.10.0"
"@typescript-eslint/utils@npm:6.13.2":
version: 6.13.2
resolution: "@typescript-eslint/utils@npm:6.13.2"
dependencies:
"@eslint-community/eslint-utils": ^4.4.0
"@types/json-schema": ^7.0.12
"@types/semver": ^7.5.0
"@typescript-eslint/scope-manager": 6.10.0
"@typescript-eslint/types": 6.10.0
"@typescript-eslint/typescript-estree": 6.10.0
"@typescript-eslint/scope-manager": 6.13.2
"@typescript-eslint/types": 6.13.2
"@typescript-eslint/typescript-estree": 6.13.2
semver: ^7.5.4
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
checksum: b6bd4d68623fb8d616ae63a88f2954258411a0cc113029fba801d1e74b4c0319fdfbcac0070527afe5cc38c012c8718e4faecd1603000924d7b89e8fefc3f24d
checksum: b66bcf2a945e9c55f3dccb48af49565863d974837ee23b2f01ce7f3fb2462eb8a5871784d4a2fcc80dac7d5cd4ed90c8d01431cd177c0249de89a448f6663fc8
languageName: node
linkType: hard
@@ -2124,13 +2091,13 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/visitor-keys@npm:6.10.0":
version: 6.10.0
resolution: "@typescript-eslint/visitor-keys@npm:6.10.0"
"@typescript-eslint/visitor-keys@npm:6.13.2":
version: 6.13.2
resolution: "@typescript-eslint/visitor-keys@npm:6.13.2"
dependencies:
"@typescript-eslint/types": 6.10.0
"@typescript-eslint/types": 6.13.2
eslint-visitor-keys: ^3.4.1
checksum: 9640bfae41e6109ffba31e68b1720382de0538d021261e2fc9e514c83c703084393c0818ca77ed26b950273e45e593371120281e8d4bbd09cb8c2d46c9fe4f03
checksum: 4b4def7acd7451e6a18dab3ee13f06504b3d23e51f195fced7c544f2203ee8a83426c82fa57ab6b58725c70fdedaf7a3eccb69793180be35756eed0f2c69fe04
languageName: node
linkType: hard
@@ -3790,14 +3757,14 @@ __metadata:
languageName: node
linkType: hard
"eslint-config-prettier@npm:9.0.0":
version: 9.0.0
resolution: "eslint-config-prettier@npm:9.0.0"
"eslint-config-prettier@npm:9.1.0":
version: 9.1.0
resolution: "eslint-config-prettier@npm:9.1.0"
peerDependencies:
eslint: ">=7.0.0"
bin:
eslint-config-prettier: bin/cli.js
checksum: 362e991b6cb343f79362bada2d97c202e5303e6865888918a7445c555fb75e4c078b01278e90be98aa98ae22f8597d8e93d48314bec6824f540f7efcab3ce451
checksum: 9229b768c879f500ee54ca05925f31b0c0bafff3d9f5521f98ff05127356de78c81deb9365c86a5ec4efa990cb72b74df8612ae15965b14136044c73e1f6a907
languageName: node
linkType: hard
@@ -4397,10 +4364,10 @@ __metadata:
languageName: node
linkType: hard
"flow-parser@npm:0.222.0":
version: 0.222.0
resolution: "flow-parser@npm:0.222.0"
checksum: 286fbd397e86eca7c2aaf7d280e2385670d261f986b24122471b153d8c646d924b3679807103aacb6e60282ad7ed8fb0f4112ecff89f6d0995b59021f73c0c40
"flow-parser@npm:0.223.3":
version: 0.223.3
resolution: "flow-parser@npm:0.223.3"
checksum: 4c0df178ff2e9140f57b5e7321b11e1cb827e00fbad6f342742c5834bd313f1bb0fe84d919d36e0c593e916c4ae5c8a93fcdb42c4328d6c5d77d75c8eed12090
languageName: node
linkType: hard
@@ -4802,19 +4769,19 @@ __metadata:
languageName: node
linkType: hard
"hermes-estree@npm:0.17.1":
version: 0.17.1
resolution: "hermes-estree@npm:0.17.1"
checksum: ffa6f997ad0b2a0dfe8ec782fc8cc5224a0d943b330944e62fe58c93c1f590afb67ba064d5a308c51a824b0db6e1bdc1654bfaf6bdfb4b0de4fb8f9cd8cf1050
"hermes-estree@npm:0.18.0":
version: 0.18.0
resolution: "hermes-estree@npm:0.18.0"
checksum: c99ef2daf0e838bd738aa53e037e66b04c6e2bdc5426c460743a63fa55113d16a91045f2706e3ea99977e2291dd1a23746aeb0c9fe1bfe8d2fbced1a513e2740
languageName: node
linkType: hard
"hermes-parser@npm:0.17.1":
version: 0.17.1
resolution: "hermes-parser@npm:0.17.1"
"hermes-parser@npm:0.18.0":
version: 0.18.0
resolution: "hermes-parser@npm:0.18.0"
dependencies:
hermes-estree: 0.17.1
checksum: 0a8fd611c708ec076654e9b7aed4b8c5b4302bdef87402a66e9c09ec3f925aa3c12718c80ebc52154ec5712a348ad375a69838f243c9bc2189ec6459415d6760
hermes-estree: 0.18.0
checksum: 163202f1916f1df34a560148d626eb9a82eb2b9738882cff350853051f4ebf5c56472c64029f17408ce1b1ea88309108970687dd586630febb57fea9af7e1b56
languageName: node
linkType: hard
@@ -6363,13 +6330,6 @@ __metadata:
languageName: node
linkType: hard
"lilconfig@npm:2.1.0":
version: 2.1.0
resolution: "lilconfig@npm:2.1.0"
checksum: 8549bb352b8192375fed4a74694cd61ad293904eee33f9d4866c2192865c44c4eb35d10782966242634e0cbc1e91fe62b1247f148dc5514918e3a966da7ea117
languageName: node
linkType: hard
"lines-and-columns@npm:2.0.4, lines-and-columns@npm:^2.0.3":
version: 2.0.4
resolution: "lines-and-columns@npm:2.0.4"
@@ -6778,7 +6738,7 @@ __metadata:
languageName: node
linkType: hard
"nanoid@npm:^3.3.6":
"nanoid@npm:^3.3.7":
version: 3.3.7
resolution: "nanoid@npm:3.3.7"
bin:
@@ -7420,14 +7380,14 @@ __metadata:
languageName: node
linkType: hard
"postcss@npm:8.4.31":
version: 8.4.31
resolution: "postcss@npm:8.4.31"
"postcss@npm:8.4.32":
version: 8.4.32
resolution: "postcss@npm:8.4.32"
dependencies:
nanoid: ^3.3.6
nanoid: ^3.3.7
picocolors: ^1.0.0
source-map-js: ^1.0.2
checksum: 1d8611341b073143ad90486fcdfeab49edd243377b1f51834dc4f6d028e82ce5190e4f11bb2633276864503654fb7cab28e67abdc0fbf9d1f88cad4a0ff0beea
checksum: 220d9d0bf5d65be7ed31006c523bfb11619461d296245c1231831f90150aeb4a31eab9983ac9c5c89759a3ca8b60b3e0d098574964e1691673c3ce5c494305ae
languageName: node
linkType: hard
@@ -7452,10 +7412,10 @@ __metadata:
resolution: "prettier@workspace:."
dependencies:
"@angular/compiler": 17.0.2
"@babel/code-frame": 7.22.13
"@babel/generator": 7.23.3
"@babel/parser": 7.23.4
"@babel/types": 7.23.3
"@babel/code-frame": 7.23.5
"@babel/generator": 7.23.5
"@babel/parser": 7.23.5
"@babel/types": 7.23.5
"@glimmer/reference": 0.85.13
"@glimmer/syntax": 0.85.13
"@iarna/toml": 2.2.5
@@ -7466,9 +7426,9 @@ __metadata:
"@types/file-entry-cache": 5.0.4
"@types/find-cache-dir": 3.2.1
"@types/jest": 29.5.8
"@typescript-eslint/eslint-plugin": 6.10.0
"@typescript-eslint/typescript-estree": 6.10.0
"@typescript-eslint/visitor-keys": 6.10.0
"@typescript-eslint/eslint-plugin": 6.13.2
"@typescript-eslint/typescript-estree": 6.13.2
"@typescript-eslint/visitor-keys": 6.13.2
acorn: 8.11.2
acorn-jsx: 5.3.2
angular-estree-parser: 9.0.0
@@ -7494,7 +7454,7 @@ __metadata:
esbuild-visualizer: 0.4.1
escape-string-regexp: 5.0.0
eslint: 8.53.0
eslint-config-prettier: 9.0.0
eslint-config-prettier: 9.1.0
eslint-formatter-friendly: 7.0.0
eslint-plugin-compat: 4.2.0
eslint-plugin-import: 2.29.0
@@ -7511,11 +7471,11 @@ __metadata:
fast-json-stable-stringify: 2.1.0
file-entry-cache: 7.0.2
find-cache-dir: 5.0.0
flow-parser: 0.222.0
flow-parser: 0.223.3
get-east-asian-width: 1.2.0
get-stdin: 9.0.0
graphql: 16.8.1
hermes-parser: 0.17.1
hermes-parser: 0.18.0
html-element-attributes: 3.3.0
html-tag-names: 2.1.0
html-ua-styles: 0.0.3
@@ -7531,7 +7491,6 @@ __metadata:
js-yaml: 4.1.0
json5: 2.2.3
leven: 4.0.0
lilconfig: 2.1.0
lines-and-columns: 2.0.4
linguist-languages: 7.27.0
magic-string: 0.30.5
@@ -7544,7 +7503,7 @@ __metadata:
outdent: 0.8.0
parse-json: 8.1.0
please-upgrade-node: 3.2.0
postcss: 8.4.31
postcss: 8.4.32
postcss-less: 6.0.0
postcss-media-query-parser: 0.2.3
postcss-scss: 4.0.9
@@ -7565,7 +7524,7 @@ __metadata:
tempy: 3.1.0
to-fast-properties: 4.0.0
ts-expect: 1.3.0
typescript: 5.2.2
typescript: 5.3.2
unicode-regex: 4.0.0
unified: 9.2.2
url-or-path: 2.3.0
@@ -9020,23 +8979,23 @@ __metadata:
languageName: node
linkType: hard
"typescript@npm:5.2.2":
version: 5.2.2
resolution: "typescript@npm:5.2.2"
"typescript@npm:5.3.2":
version: 5.3.2
resolution: "typescript@npm:5.3.2"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
checksum: 7912821dac4d962d315c36800fe387cdc0a6298dba7ec171b350b4a6e988b51d7b8f051317786db1094bd7431d526b648aba7da8236607febb26cf5b871d2d3c
checksum: d92534dda639eb825db013203404c1fabca8ac630564283c9e7dc9e64fd9c9346c2de95ecebdf3e6e8c1c32941bca1cfe0da37877611feb9daf8feeaea58d230
languageName: node
linkType: hard
"typescript@patch:typescript@5.2.2#~builtin<compat/typescript>":
version: 5.2.2
resolution: "typescript@patch:typescript@npm%3A5.2.2#~builtin<compat/typescript>::version=5.2.2&hash=f3b441"
"typescript@patch:typescript@5.3.2#~builtin<compat/typescript>":
version: 5.3.2
resolution: "typescript@patch:typescript@npm%3A5.3.2#~builtin<compat/typescript>::version=5.3.2&hash=e012d7"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
checksum: 0f4da2f15e6f1245e49db15801dbee52f2bbfb267e1c39225afdab5afee1a72839cd86000e65ee9d7e4dfaff12239d28beaf5ee431357fcced15fb08583d72ca
checksum: 47b2e63418ea7ef7dd0bf359ee41c6fca852c680826089269c5d03673ead471e052b172561f377f9e51212054e5f0fe19dd58085ff7db7b168449a6af704c784
languageName: node
linkType: hard