openapi-typesafe-migrate 1.0.0-rc.6 → 1.0.0-rc.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +47 -0
- package/README.md +30 -15
- package/dist/cli/main.mjs +718 -220
- package/dist/cli/main.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cli/main.mjs
CHANGED
|
@@ -737,7 +737,9 @@ function indexUses(file, bindings) {
|
|
|
737
737
|
if (declaration !== void 0 && !isDeclaredName(node, declaration)) {
|
|
738
738
|
uses.set(declaration, [...uses.get(declaration) ?? [], node]);
|
|
739
739
|
}
|
|
740
|
-
|
|
740
|
+
for (const child of node.getChildren(file)) {
|
|
741
|
+
visit(child);
|
|
742
|
+
}
|
|
741
743
|
};
|
|
742
744
|
visit(file);
|
|
743
745
|
return uses;
|
|
@@ -812,18 +814,23 @@ function constantOptions(name, bindings, outerTypes) {
|
|
|
812
814
|
return { kind: "shared", options: found.value };
|
|
813
815
|
}
|
|
814
816
|
const declared = declaration.type;
|
|
815
|
-
const
|
|
816
|
-
...outerTypes,
|
|
817
|
+
const ownTypes = [
|
|
817
818
|
...found.types,
|
|
818
819
|
...declared === void 0 ? [] : [declared],
|
|
819
820
|
...jsDocTypes(declaration)
|
|
820
821
|
];
|
|
821
|
-
|
|
822
|
+
const annotations = [...outerTypes, ...ownTypes];
|
|
823
|
+
return {
|
|
824
|
+
kind: "own",
|
|
825
|
+
options: found.value,
|
|
826
|
+
annotations,
|
|
827
|
+
isContextuallyTyped: ownTypes.length > 0
|
|
828
|
+
};
|
|
822
829
|
}
|
|
823
830
|
function optionsOf(argument, bindings) {
|
|
824
831
|
const { value, types } = unwrapped(argument);
|
|
825
832
|
if (ts.isObjectLiteralExpression(value)) {
|
|
826
|
-
return { kind: "own", options: value, annotations: types };
|
|
833
|
+
return { kind: "own", options: value, annotations: types, isContextuallyTyped: true };
|
|
827
834
|
}
|
|
828
835
|
return ts.isIdentifier(value) ? constantOptions(value, bindings, types) : { kind: "unknown", expression: argument };
|
|
829
836
|
}
|
|
@@ -1434,6 +1441,9 @@ function removalEdits(removed, text) {
|
|
|
1434
1441
|
const TRANSFORM = "transform";
|
|
1435
1442
|
const LEGACY_ONLY_CALLBACKS = ["postTransform", "transformProperty"];
|
|
1436
1443
|
const IR_CALLBACKS_OPTION = "irCallbacks";
|
|
1444
|
+
const IR_CALLBACKS_TRUE = "true";
|
|
1445
|
+
const IR_CALLBACKS_TRUE_CONST = "true as const";
|
|
1446
|
+
const IR_CALLBACKS_TRUE_CONST_JS = "/** @type {const} */ (true)";
|
|
1437
1447
|
const noFindings = () => ({
|
|
1438
1448
|
edits: [],
|
|
1439
1449
|
changes: [],
|
|
@@ -1472,10 +1482,17 @@ function transformEdits(property, names, text) {
|
|
|
1472
1482
|
}
|
|
1473
1483
|
return edits;
|
|
1474
1484
|
}
|
|
1475
|
-
function
|
|
1485
|
+
function irCallbacksValue(options) {
|
|
1486
|
+
if (options.isContextuallyTyped) {
|
|
1487
|
+
return IR_CALLBACKS_TRUE;
|
|
1488
|
+
}
|
|
1489
|
+
const isJavaScript = (options.options.flags & ts.NodeFlags.JavaScriptFile) !== 0;
|
|
1490
|
+
return isJavaScript ? IR_CALLBACKS_TRUE_CONST_JS : IR_CALLBACKS_TRUE_CONST;
|
|
1491
|
+
}
|
|
1492
|
+
function irCallbacksOption(text, transformStart, value) {
|
|
1476
1493
|
const lineStart = text.lastIndexOf("\n", transformStart - 1) + 1;
|
|
1477
1494
|
const before = text.slice(lineStart, transformStart);
|
|
1478
|
-
const option = `${IR_CALLBACKS_OPTION}:
|
|
1495
|
+
const option = `${IR_CALLBACKS_OPTION}: ${value},`;
|
|
1479
1496
|
return /^\s*$/.test(before) ? `${option}
|
|
1480
1497
|
${before}` : `${option} `;
|
|
1481
1498
|
}
|
|
@@ -1518,7 +1535,9 @@ function migrateOptions(options, text, names) {
|
|
|
1518
1535
|
findings.manualSteps.push({ kind: "transform-not-rewritten", line, reason: result });
|
|
1519
1536
|
return findings;
|
|
1520
1537
|
}
|
|
1521
|
-
|
|
1538
|
+
const at = transform.getStart(void 0, true);
|
|
1539
|
+
const option = irCallbacksOption(text, at, irCallbacksValue(options));
|
|
1540
|
+
findings.edits.push({ start: at, end: at, text: option }, ...result.edits);
|
|
1522
1541
|
findings.typeReferences.push(...result.typeReferences);
|
|
1523
1542
|
findings.changes.push({ kind: "transform-rewritten", line });
|
|
1524
1543
|
return findings;
|
|
@@ -1667,7 +1686,7 @@ function isModuleSpecifier(literal) {
|
|
|
1667
1686
|
}
|
|
1668
1687
|
return ts.isExternalModuleReference(parent);
|
|
1669
1688
|
}
|
|
1670
|
-
function stringValue
|
|
1689
|
+
function stringValue(node, file) {
|
|
1671
1690
|
return ts.isTemplateExpression(node) ? file.text.slice(node.getStart(file) + 1, node.getEnd() - 1) : node.text;
|
|
1672
1691
|
}
|
|
1673
1692
|
function collectStrings(root, file, offset, found) {
|
|
@@ -1678,7 +1697,7 @@ function collectStrings(root, file, offset, found) {
|
|
|
1678
1697
|
found.set(start, {
|
|
1679
1698
|
start,
|
|
1680
1699
|
end,
|
|
1681
|
-
value: stringValue
|
|
1700
|
+
value: stringValue(node, file),
|
|
1682
1701
|
isModuleSpecifier: isModuleSpecifier(node)
|
|
1683
1702
|
});
|
|
1684
1703
|
}
|
|
@@ -1887,6 +1906,150 @@ function createYamlTextReader() {
|
|
|
1887
1906
|
return { read };
|
|
1888
1907
|
}
|
|
1889
1908
|
|
|
1909
|
+
const PACKAGE_RENAMES = /* @__PURE__ */ new Map([
|
|
1910
|
+
["openapi-typescript", "openapi-typesafe"],
|
|
1911
|
+
["openapi-fetch", "openapi-typesafe-fetch"],
|
|
1912
|
+
["openapi-react-query", "openapi-typesafe-react-query"],
|
|
1913
|
+
["openapi-typescript-helpers", "openapi-typesafe-helpers"]
|
|
1914
|
+
]);
|
|
1915
|
+
function namesOriginalPackage(text) {
|
|
1916
|
+
return [...PACKAGE_RENAMES.keys()].some((name) => text.includes(name));
|
|
1917
|
+
}
|
|
1918
|
+
const GENERATOR_COMMAND = "openapi-typescript";
|
|
1919
|
+
const MIGRATED_GENERATOR_COMMAND = "openapi-typesafe";
|
|
1920
|
+
const FLAG_RENAMES = /* @__PURE__ */ new Map([
|
|
1921
|
+
["--immutable-types", "--immutable"],
|
|
1922
|
+
["-it", "--immutable"],
|
|
1923
|
+
["--support-array-length", "--array-length"],
|
|
1924
|
+
["--redoc", "--redocly"],
|
|
1925
|
+
["-ap", "--additional-properties"]
|
|
1926
|
+
]);
|
|
1927
|
+
const DEPENDENCY_FIELDS = [
|
|
1928
|
+
"dependencies",
|
|
1929
|
+
"devDependencies",
|
|
1930
|
+
"peerDependencies",
|
|
1931
|
+
"optionalDependencies"
|
|
1932
|
+
];
|
|
1933
|
+
const NAME_KEYED_FIELDS = ["peerDependenciesMeta", "dependenciesMeta"];
|
|
1934
|
+
const NAME_LIST_FIELDS = ["bundleDependencies", "bundledDependencies"];
|
|
1935
|
+
const CATALOG_FIELD = "catalog";
|
|
1936
|
+
const NAMED_CATALOGS_FIELD = "catalogs";
|
|
1937
|
+
const WORKSPACES_FIELD = "workspaces";
|
|
1938
|
+
const OVERRIDE_FIELDS = ["overrides", "resolutions"];
|
|
1939
|
+
const PNPM_SETTINGS_FIELD = "pnpm";
|
|
1940
|
+
const OLD_PEER_DEPENDENTS = /* @__PURE__ */ new Map([
|
|
1941
|
+
["swr-openapi", { peer: "openapi-fetch", range: ">=0.15" }]
|
|
1942
|
+
]);
|
|
1943
|
+
const PATH_SEPARATOR$9 = "/";
|
|
1944
|
+
const QUERY_START = "?";
|
|
1945
|
+
function renamedSpecifier(value) {
|
|
1946
|
+
const ends = [value.indexOf(PATH_SEPARATOR$9), value.indexOf(QUERY_START)].filter(
|
|
1947
|
+
(at) => at !== -1
|
|
1948
|
+
);
|
|
1949
|
+
const name = value.slice(0, ends.length === 0 ? value.length : Math.min(...ends));
|
|
1950
|
+
const renamed = PACKAGE_RENAMES.get(name);
|
|
1951
|
+
if (renamed === void 0) {
|
|
1952
|
+
return void 0;
|
|
1953
|
+
}
|
|
1954
|
+
const rest = value.slice(name.length);
|
|
1955
|
+
const subpath = rest.split(QUERY_START, 1)[0] ?? rest;
|
|
1956
|
+
return { to: `${renamed}${rest}`, isDeep: subpath !== "" && subpath !== PATH_SEPARATOR$9 };
|
|
1957
|
+
}
|
|
1958
|
+
const NODE_MODULES_FOLDER = "node_modules/";
|
|
1959
|
+
function oldPackageInNodeModules(path) {
|
|
1960
|
+
return [...PACKAGE_RENAMES.keys()].find(
|
|
1961
|
+
(name) => path.includes(`${NODE_MODULES_FOLDER}${name}${PATH_SEPARATOR$9}`)
|
|
1962
|
+
);
|
|
1963
|
+
}
|
|
1964
|
+
|
|
1965
|
+
const isMap = (node) => node?.kind === "map";
|
|
1966
|
+
const isScalar = (node) => node.kind === "scalar";
|
|
1967
|
+
function textEntries(map) {
|
|
1968
|
+
return map.entries.flatMap(({ key, value }) => isScalar(key) ? [{ key, value }] : []);
|
|
1969
|
+
}
|
|
1970
|
+
function valuesAt(map, key) {
|
|
1971
|
+
return textEntries(map).filter((entry) => entry.key.value === key).map((entry) => entry.value);
|
|
1972
|
+
}
|
|
1973
|
+
function mapsAt(map, key) {
|
|
1974
|
+
return valuesAt(map, key).filter(isMap);
|
|
1975
|
+
}
|
|
1976
|
+
function stringsBelow(node, path) {
|
|
1977
|
+
switch (node.kind) {
|
|
1978
|
+
case "scalar":
|
|
1979
|
+
return [{ ...node, path }];
|
|
1980
|
+
case "list":
|
|
1981
|
+
return node.items.flatMap((item, index) => stringsBelow(item, [...path, index]));
|
|
1982
|
+
case "map":
|
|
1983
|
+
return textEntries(node).flatMap(
|
|
1984
|
+
({ key, value }) => stringsBelow(value, [...path, key.value])
|
|
1985
|
+
);
|
|
1986
|
+
default:
|
|
1987
|
+
return [];
|
|
1988
|
+
}
|
|
1989
|
+
}
|
|
1990
|
+
function documentStrings(documents) {
|
|
1991
|
+
return documents.flatMap((document) => stringsBelow(document, []));
|
|
1992
|
+
}
|
|
1993
|
+
function ownerKey(path) {
|
|
1994
|
+
return path.findLast((part) => typeof part === "string");
|
|
1995
|
+
}
|
|
1996
|
+
function unreadableConfig(text, offset) {
|
|
1997
|
+
if (!namesOriginalPackage(text)) {
|
|
1998
|
+
return unchanged(text);
|
|
1999
|
+
}
|
|
2000
|
+
const position = offset === void 0 ? void 0 : { line: lineAt(text, offset), column: columnAt(text, offset) };
|
|
2001
|
+
return { ...unchanged(text), manualSteps: [{ kind: "config-unreadable", position }] };
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
const SEPARATOR = "/";
|
|
2005
|
+
const CURRENT_FOLDER = ".";
|
|
2006
|
+
const PARENT_FOLDER = "..";
|
|
2007
|
+
const URL_SCHEME = /^[a-z][a-z\d+.-]*:/i;
|
|
2008
|
+
function resolvedPath(fromPath, reference) {
|
|
2009
|
+
const parts = fromPath.split(SEPARATOR).slice(0, -1);
|
|
2010
|
+
for (const part of reference.split(SEPARATOR)) {
|
|
2011
|
+
if (part === PARENT_FOLDER) {
|
|
2012
|
+
if (parts.pop() === void 0) {
|
|
2013
|
+
return void 0;
|
|
2014
|
+
}
|
|
2015
|
+
} else if (part !== CURRENT_FOLDER && part !== "") {
|
|
2016
|
+
parts.push(part);
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
return parts.join(SEPARATOR);
|
|
2020
|
+
}
|
|
2021
|
+
function referencedProjectPath(fromPath, reference) {
|
|
2022
|
+
const isOutside = URL_SCHEME.test(reference) || reference.startsWith(SEPARATOR);
|
|
2023
|
+
const path = isOutside ? void 0 : resolvedPath(fromPath, reference);
|
|
2024
|
+
return path === "" ? void 0 : path;
|
|
2025
|
+
}
|
|
2026
|
+
|
|
2027
|
+
const API_DESCRIPTION_KEYS = [
|
|
2028
|
+
"openapi",
|
|
2029
|
+
"swagger",
|
|
2030
|
+
"asyncapi",
|
|
2031
|
+
"overlay",
|
|
2032
|
+
"arazzo"
|
|
2033
|
+
];
|
|
2034
|
+
const API_DESCRIPTION_KEY_SET = new Set(API_DESCRIPTION_KEYS);
|
|
2035
|
+
const DESCRIPTION_KEY_LINE_RE = new RegExp(
|
|
2036
|
+
`^[ \\t{]*["']?(?:${API_DESCRIPTION_KEYS.join("|")})["']?[ \\t]*:`,
|
|
2037
|
+
"m"
|
|
2038
|
+
);
|
|
2039
|
+
const mayBeApiDescription = (text) => DESCRIPTION_KEY_LINE_RE.test(text);
|
|
2040
|
+
const isApiDescription = (documents) => documents.some(
|
|
2041
|
+
(root) => isMap(root) && textEntries(root).some(({ key }) => API_DESCRIPTION_KEY_SET.has(key.value))
|
|
2042
|
+
);
|
|
2043
|
+
const REF_KEY = "$ref";
|
|
2044
|
+
const FRAGMENT_START = "#";
|
|
2045
|
+
function referencedFiles(path, documents) {
|
|
2046
|
+
return documentStrings(documents).filter((string) => string.path.at(-1) === REF_KEY).flatMap(({ value }) => {
|
|
2047
|
+
const file = value.split(FRAGMENT_START)[0] ?? "";
|
|
2048
|
+
const referenced = referencedProjectPath(path, file);
|
|
2049
|
+
return referenced === void 0 ? [] : [referenced];
|
|
2050
|
+
});
|
|
2051
|
+
}
|
|
2052
|
+
|
|
1890
2053
|
const NONE = /* @__PURE__ */ new Set();
|
|
1891
2054
|
const PACKAGE_OPTIONS = /* @__PURE__ */ new Set(["-p", "--package"]);
|
|
1892
2055
|
const PACKAGE_MANAGER_OPTIONS = /* @__PURE__ */ new Set([
|
|
@@ -2030,8 +2193,8 @@ const COMMAND_SEPARATORS = /* @__PURE__ */ new Set([
|
|
|
2030
2193
|
"\n"
|
|
2031
2194
|
]);
|
|
2032
2195
|
const WORD_BREAKS = /* @__PURE__ */ new Set([" ", " ", "\r", "<", ">"]);
|
|
2033
|
-
const BACKSLASH$
|
|
2034
|
-
const DOUBLE_QUOTE_ESCAPES = /* @__PURE__ */ new Set(["$", "`", '"', BACKSLASH$
|
|
2196
|
+
const BACKSLASH$2 = "\\";
|
|
2197
|
+
const DOUBLE_QUOTE_ESCAPES = /* @__PURE__ */ new Set(["$", "`", '"', BACKSLASH$2, "\n"]);
|
|
2035
2198
|
function singleQuoted(text, start) {
|
|
2036
2199
|
const close = text.indexOf("'", start + 1);
|
|
2037
2200
|
const end = close === -1 ? text.length : close + 1;
|
|
@@ -2042,13 +2205,13 @@ function doubleQuoted(text, start) {
|
|
|
2042
2205
|
let index = start + 1;
|
|
2043
2206
|
while (index < text.length && text[index] !== '"') {
|
|
2044
2207
|
const next = text[index + 1] ?? "";
|
|
2045
|
-
const isEscape = text[index] === BACKSLASH$
|
|
2208
|
+
const isEscape = text[index] === BACKSLASH$2 && DOUBLE_QUOTE_ESCAPES.has(next);
|
|
2046
2209
|
value += isEscape ? next === "\n" ? "" : next : text[index];
|
|
2047
2210
|
index += isEscape ? 2 : 1;
|
|
2048
2211
|
}
|
|
2049
2212
|
return { end: Math.min(index + 1, text.length), value };
|
|
2050
2213
|
}
|
|
2051
|
-
const isLineContinuation = (text, index) => text[index] === BACKSLASH$
|
|
2214
|
+
const isLineContinuation = (text, index) => text[index] === BACKSLASH$2 && (text[index + 1] === "\n" || text.startsWith("\r\n", index + 1));
|
|
2052
2215
|
const ARITHMETIC_OPEN = "$((";
|
|
2053
2216
|
const NESTING_OPEN = "(";
|
|
2054
2217
|
const NESTING_CLOSE = ")";
|
|
@@ -2063,11 +2226,48 @@ function arithmeticExpansion(text, start) {
|
|
|
2063
2226
|
}
|
|
2064
2227
|
return void 0;
|
|
2065
2228
|
}
|
|
2229
|
+
const PARAMETER_OPEN = "${";
|
|
2230
|
+
const PARAMETER_CLOSE = "}";
|
|
2231
|
+
function parameterExpansionEnd(text, start) {
|
|
2232
|
+
let depth = 1;
|
|
2233
|
+
for (let index = start + PARAMETER_OPEN.length; index < text.length; ) {
|
|
2234
|
+
if (text.startsWith(PARAMETER_OPEN, index)) {
|
|
2235
|
+
depth += 1;
|
|
2236
|
+
index += PARAMETER_OPEN.length;
|
|
2237
|
+
} else if (text[index] === PARAMETER_CLOSE) {
|
|
2238
|
+
depth -= 1;
|
|
2239
|
+
index += 1;
|
|
2240
|
+
if (depth === 0) {
|
|
2241
|
+
return index;
|
|
2242
|
+
}
|
|
2243
|
+
} else {
|
|
2244
|
+
index = quotedOrEscapedEnd(text, index) ?? index + 1;
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
return void 0;
|
|
2248
|
+
}
|
|
2249
|
+
function quotedOrEscapedEnd(text, index) {
|
|
2250
|
+
const char = text[index];
|
|
2251
|
+
if (char === "'") {
|
|
2252
|
+
return singleQuoted(text, index).end;
|
|
2253
|
+
}
|
|
2254
|
+
if (char === '"') {
|
|
2255
|
+
return doubleQuoted(text, index).end;
|
|
2256
|
+
}
|
|
2257
|
+
return char === BACKSLASH$2 ? index + 2 : void 0;
|
|
2258
|
+
}
|
|
2259
|
+
function expansionPart(text, index) {
|
|
2260
|
+
if (text.startsWith(ARITHMETIC_OPEN, index)) {
|
|
2261
|
+
return arithmeticExpansion(text, index);
|
|
2262
|
+
}
|
|
2263
|
+
const end = text.startsWith(PARAMETER_OPEN, index) ? parameterExpansionEnd(text, index) : void 0;
|
|
2264
|
+
return end === void 0 ? void 0 : { end, value: text.slice(index, end) };
|
|
2265
|
+
}
|
|
2066
2266
|
function wordPart(text, index) {
|
|
2067
2267
|
const char = text[index];
|
|
2068
|
-
const
|
|
2069
|
-
if (
|
|
2070
|
-
return
|
|
2268
|
+
const expansion = expansionPart(text, index);
|
|
2269
|
+
if (expansion !== void 0) {
|
|
2270
|
+
return expansion;
|
|
2071
2271
|
}
|
|
2072
2272
|
if (char === "'") {
|
|
2073
2273
|
return singleQuoted(text, index);
|
|
@@ -2075,11 +2275,23 @@ function wordPart(text, index) {
|
|
|
2075
2275
|
if (char === '"') {
|
|
2076
2276
|
return doubleQuoted(text, index);
|
|
2077
2277
|
}
|
|
2078
|
-
if (char === BACKSLASH$
|
|
2278
|
+
if (char === BACKSLASH$2 && index + 1 < text.length) {
|
|
2079
2279
|
return { end: index + 2, value: text[index + 1] };
|
|
2080
2280
|
}
|
|
2081
2281
|
return { end: index + 1, value: char };
|
|
2082
2282
|
}
|
|
2283
|
+
const ARRAY_HEAD_RE = /^[A-Za-z_][A-Za-z0-9_]*\+?=$/;
|
|
2284
|
+
function arrayListEnd(text, index) {
|
|
2285
|
+
let depth = 0;
|
|
2286
|
+
for (let at = index; at < text.length; ) {
|
|
2287
|
+
depth += text[at] === NESTING_OPEN ? 1 : text[at] === NESTING_CLOSE ? -1 : 0;
|
|
2288
|
+
if (depth === 0) {
|
|
2289
|
+
return at + 1;
|
|
2290
|
+
}
|
|
2291
|
+
at = quotedOrEscapedEnd(text, at) ?? at + 1;
|
|
2292
|
+
}
|
|
2293
|
+
return void 0;
|
|
2294
|
+
}
|
|
2083
2295
|
const endsWord = (text, index) => {
|
|
2084
2296
|
const char = text[index];
|
|
2085
2297
|
return WORD_BREAKS.has(char) || COMMAND_SEPARATORS.has(char) || isLineContinuation(text, index);
|
|
@@ -2087,8 +2299,13 @@ const endsWord = (text, index) => {
|
|
|
2087
2299
|
function readWord(text, start) {
|
|
2088
2300
|
let value = "";
|
|
2089
2301
|
let index = start;
|
|
2090
|
-
while (index < text.length
|
|
2091
|
-
const
|
|
2302
|
+
while (index < text.length) {
|
|
2303
|
+
const isArrayList = text[index] === NESTING_OPEN && ARRAY_HEAD_RE.test(text.slice(start, index));
|
|
2304
|
+
const list = isArrayList ? arrayListEnd(text, index) : void 0;
|
|
2305
|
+
if (list === void 0 && endsWord(text, index)) {
|
|
2306
|
+
break;
|
|
2307
|
+
}
|
|
2308
|
+
const part = list === void 0 ? wordPart(text, index) : { end: list, value: text.slice(index, list) };
|
|
2092
2309
|
value += part.value;
|
|
2093
2310
|
index = part.end;
|
|
2094
2311
|
}
|
|
@@ -2119,11 +2336,17 @@ function shellAssignments(command) {
|
|
|
2119
2336
|
return name === void 0 ? [] : [{ name, value: word.value.slice(name.length + 1), word }];
|
|
2120
2337
|
});
|
|
2121
2338
|
}
|
|
2339
|
+
const ARRAY_OPEN = "(";
|
|
2340
|
+
const ARRAY_CLOSE = ")";
|
|
2341
|
+
const isArrayAssignment = (assignment) => assignment.word.raw.startsWith(ARRAY_OPEN, assignment.name.length + 1);
|
|
2122
2342
|
function assignmentValueText(assignment) {
|
|
2123
2343
|
const at = assignment.name.length + 1;
|
|
2124
2344
|
const raw = assignment.word.raw.slice(at);
|
|
2125
2345
|
const start = assignment.word.start + at;
|
|
2126
2346
|
const quote = raw[0] ?? "";
|
|
2347
|
+
if (isArrayAssignment(assignment)) {
|
|
2348
|
+
return raw.endsWith(ARRAY_CLOSE) ? { text: raw.slice(1, -1), start: start + 1 } : void 0;
|
|
2349
|
+
}
|
|
2127
2350
|
if (QUOTES$3.has(quote)) {
|
|
2128
2351
|
const isOneString = raw.length > 1 && raw.endsWith(quote) && wordPart(raw, 0).end === raw.length;
|
|
2129
2352
|
return isOneString ? { text: raw.slice(1, -1), start: start + 1 } : void 0;
|
|
@@ -2192,62 +2415,6 @@ function commandRoles(words) {
|
|
|
2192
2415
|
return { program: void 0, packages };
|
|
2193
2416
|
}
|
|
2194
2417
|
|
|
2195
|
-
const PACKAGE_RENAMES = /* @__PURE__ */ new Map([
|
|
2196
|
-
["openapi-typescript", "openapi-typesafe"],
|
|
2197
|
-
["openapi-fetch", "openapi-typesafe-fetch"],
|
|
2198
|
-
["openapi-react-query", "openapi-typesafe-react-query"],
|
|
2199
|
-
["openapi-typescript-helpers", "openapi-typesafe-helpers"]
|
|
2200
|
-
]);
|
|
2201
|
-
function namesOriginalPackage(text) {
|
|
2202
|
-
return [...PACKAGE_RENAMES.keys()].some((name) => text.includes(name));
|
|
2203
|
-
}
|
|
2204
|
-
const GENERATOR_COMMAND = "openapi-typescript";
|
|
2205
|
-
const MIGRATED_GENERATOR_COMMAND = "openapi-typesafe";
|
|
2206
|
-
const FLAG_RENAMES = /* @__PURE__ */ new Map([
|
|
2207
|
-
["--immutable-types", "--immutable"],
|
|
2208
|
-
["-it", "--immutable"],
|
|
2209
|
-
["--support-array-length", "--array-length"],
|
|
2210
|
-
["--redoc", "--redocly"],
|
|
2211
|
-
["-ap", "--additional-properties"]
|
|
2212
|
-
]);
|
|
2213
|
-
const DEPENDENCY_FIELDS = [
|
|
2214
|
-
"dependencies",
|
|
2215
|
-
"devDependencies",
|
|
2216
|
-
"peerDependencies",
|
|
2217
|
-
"optionalDependencies"
|
|
2218
|
-
];
|
|
2219
|
-
const NAME_KEYED_FIELDS = ["peerDependenciesMeta", "dependenciesMeta"];
|
|
2220
|
-
const NAME_LIST_FIELDS = ["bundleDependencies", "bundledDependencies"];
|
|
2221
|
-
const CATALOG_FIELD = "catalog";
|
|
2222
|
-
const NAMED_CATALOGS_FIELD = "catalogs";
|
|
2223
|
-
const WORKSPACES_FIELD = "workspaces";
|
|
2224
|
-
const OVERRIDE_FIELDS = ["overrides", "resolutions"];
|
|
2225
|
-
const PNPM_SETTINGS_FIELD = "pnpm";
|
|
2226
|
-
const OLD_PEER_DEPENDENTS = /* @__PURE__ */ new Map([
|
|
2227
|
-
["swr-openapi", { peer: "openapi-fetch", range: ">=0.15" }]
|
|
2228
|
-
]);
|
|
2229
|
-
const PATH_SEPARATOR$9 = "/";
|
|
2230
|
-
const QUERY_START = "?";
|
|
2231
|
-
function renamedSpecifier(value) {
|
|
2232
|
-
const ends = [value.indexOf(PATH_SEPARATOR$9), value.indexOf(QUERY_START)].filter(
|
|
2233
|
-
(at) => at !== -1
|
|
2234
|
-
);
|
|
2235
|
-
const name = value.slice(0, ends.length === 0 ? value.length : Math.min(...ends));
|
|
2236
|
-
const renamed = PACKAGE_RENAMES.get(name);
|
|
2237
|
-
if (renamed === void 0) {
|
|
2238
|
-
return void 0;
|
|
2239
|
-
}
|
|
2240
|
-
const rest = value.slice(name.length);
|
|
2241
|
-
const subpath = rest.split(QUERY_START, 1)[0] ?? rest;
|
|
2242
|
-
return { to: `${renamed}${rest}`, isDeep: subpath !== "" && subpath !== PATH_SEPARATOR$9 };
|
|
2243
|
-
}
|
|
2244
|
-
const NODE_MODULES_FOLDER = "node_modules/";
|
|
2245
|
-
function oldPackageInNodeModules(path) {
|
|
2246
|
-
return [...PACKAGE_RENAMES.keys()].find(
|
|
2247
|
-
(name) => path.includes(`${NODE_MODULES_FOLDER}${name}${PATH_SEPARATOR$9}`)
|
|
2248
|
-
);
|
|
2249
|
-
}
|
|
2250
|
-
|
|
2251
2418
|
function packageReference(value) {
|
|
2252
2419
|
const bare = value.startsWith(NPM_SPECIFIER_PREFIX) ? value.slice(NPM_SPECIFIER_PREFIX.length) : value;
|
|
2253
2420
|
const at = bare.indexOf("@", 1);
|
|
@@ -2282,10 +2449,62 @@ function runsGenerator(command) {
|
|
|
2282
2449
|
return word !== void 0 && packageReference(word.value).name === GENERATOR_COMMAND;
|
|
2283
2450
|
}
|
|
2284
2451
|
|
|
2452
|
+
const EXPANSION_HEAD_RE = /^\$\{([A-Za-z_][A-Za-z0-9_]*):?([-=+])/;
|
|
2453
|
+
const USES = {
|
|
2454
|
+
"-": "default",
|
|
2455
|
+
"=": "assign",
|
|
2456
|
+
"+": "alternative"
|
|
2457
|
+
};
|
|
2458
|
+
const SINGLE_QUOTE = "'";
|
|
2459
|
+
const BACKSLASH$1 = "\\";
|
|
2460
|
+
function expansionAt(text, start) {
|
|
2461
|
+
const head = EXPANSION_HEAD_RE.exec(text.slice(start));
|
|
2462
|
+
const end = head === null ? void 0 : parameterExpansionEnd(text, start);
|
|
2463
|
+
if (head === null || end === void 0) {
|
|
2464
|
+
return void 0;
|
|
2465
|
+
}
|
|
2466
|
+
const wordStart = start + head[0].length;
|
|
2467
|
+
return {
|
|
2468
|
+
name: head[1],
|
|
2469
|
+
use: USES[head[2]],
|
|
2470
|
+
text: text.slice(wordStart, end - 1),
|
|
2471
|
+
start: wordStart,
|
|
2472
|
+
expansionStart: start,
|
|
2473
|
+
expansionEnd: end
|
|
2474
|
+
};
|
|
2475
|
+
}
|
|
2476
|
+
function wordExpansions(raw) {
|
|
2477
|
+
const found = [];
|
|
2478
|
+
for (let index = 0; index < raw.length; ) {
|
|
2479
|
+
const char = raw[index];
|
|
2480
|
+
if (char === SINGLE_QUOTE) {
|
|
2481
|
+
const close = raw.indexOf(SINGLE_QUOTE, index + 1);
|
|
2482
|
+
index = close === -1 ? raw.length : close + 1;
|
|
2483
|
+
} else if (char === BACKSLASH$1) {
|
|
2484
|
+
index += 2;
|
|
2485
|
+
} else if (raw.startsWith(PARAMETER_OPEN, index)) {
|
|
2486
|
+
const expansion = expansionAt(raw, index);
|
|
2487
|
+
found.push(...expansion === void 0 ? [] : [expansion]);
|
|
2488
|
+
index = expansion?.expansionEnd ?? index + PARAMETER_OPEN.length;
|
|
2489
|
+
} else {
|
|
2490
|
+
index += 1;
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
return found;
|
|
2494
|
+
}
|
|
2495
|
+
const DOUBLE_QUOTE = '"';
|
|
2496
|
+
function wholeWordExpansion(raw) {
|
|
2497
|
+
const isQuoted = raw.length > 1 && raw.startsWith(DOUBLE_QUOTE) && raw.endsWith(DOUBLE_QUOTE);
|
|
2498
|
+
const inner = isQuoted ? 1 : 0;
|
|
2499
|
+
const [expansion] = wordExpansions(raw);
|
|
2500
|
+
const isWhole = expansion?.expansionStart === inner && expansion.expansionEnd === raw.length - inner;
|
|
2501
|
+
return isWhole ? expansion : void 0;
|
|
2502
|
+
}
|
|
2503
|
+
|
|
2285
2504
|
const HEREDOC_OPERATOR = "<<";
|
|
2286
2505
|
const HERE_STRING_OPERATOR = "<<<";
|
|
2287
2506
|
const STRIP_TABS = "-";
|
|
2288
|
-
const LINE_BREAK$
|
|
2507
|
+
const LINE_BREAK$4 = "\n";
|
|
2289
2508
|
const LEADING_TABS_RE = /^\t+/;
|
|
2290
2509
|
const CARRIAGE_RETURN_RE = /\r$/;
|
|
2291
2510
|
function heredocAt(text, index, where) {
|
|
@@ -2317,7 +2536,7 @@ function isDelimiterLine(text, lineStart, end, heredoc) {
|
|
|
2317
2536
|
function readBody(text, start, heredoc) {
|
|
2318
2537
|
let lineStart = start;
|
|
2319
2538
|
while (lineStart < text.length) {
|
|
2320
|
-
const lineEnd = text.indexOf(LINE_BREAK$
|
|
2539
|
+
const lineEnd = text.indexOf(LINE_BREAK$4, lineStart);
|
|
2321
2540
|
const end = lineEnd === -1 ? text.length : lineEnd;
|
|
2322
2541
|
if (isDelimiterLine(text, lineStart, end, heredoc)) {
|
|
2323
2542
|
const body = { command: heredoc.command, start, text: text.slice(start, lineStart) };
|
|
@@ -2339,7 +2558,7 @@ function readBodies(text, start, pending) {
|
|
|
2339
2558
|
}
|
|
2340
2559
|
|
|
2341
2560
|
const COMMENT = "#";
|
|
2342
|
-
const LINE_BREAK$
|
|
2561
|
+
const LINE_BREAK$3 = "\n";
|
|
2343
2562
|
function skipTrivia(text, index) {
|
|
2344
2563
|
const char = text[index];
|
|
2345
2564
|
if (WORD_BREAKS.has(char)) {
|
|
@@ -2369,7 +2588,7 @@ function topLevelCommands(text, indent) {
|
|
|
2369
2588
|
index = heredoc.end;
|
|
2370
2589
|
} else if (afterTrivia !== index) {
|
|
2371
2590
|
index = afterTrivia;
|
|
2372
|
-
} else if (text[index] === LINE_BREAK$
|
|
2591
|
+
} else if (text[index] === LINE_BREAK$3 && pending.length > 0) {
|
|
2373
2592
|
const read = readBodies(text, index + 1, pending);
|
|
2374
2593
|
heredocs.push(...read.bodies);
|
|
2375
2594
|
pending = [];
|
|
@@ -2434,18 +2653,18 @@ const DOCKER_RUN = "RUN";
|
|
|
2434
2653
|
const PASS_THROUGH = "cat";
|
|
2435
2654
|
const PATH_SEPARATOR$8 = "/";
|
|
2436
2655
|
const OPTION_PREFIX$1 = "-";
|
|
2437
|
-
const programName = (command) => command[0]?.value.split(PATH_SEPARATOR$8).at(-1) ?? "";
|
|
2656
|
+
const programName$1 = (command) => command[0]?.value.split(PATH_SEPARATOR$8).at(-1) ?? "";
|
|
2438
2657
|
const isOption = (word) => word.value.startsWith(OPTION_PREFIX$1);
|
|
2439
|
-
const isScriptShell = (command) => SHELLS$1.has(programName(command)) && command.slice(1).every(isOption);
|
|
2658
|
+
const isScriptShell = (command) => SHELLS$1.has(programName$1(command)) && command.slice(1).every(isOption);
|
|
2440
2659
|
function readsScript(command) {
|
|
2441
|
-
if (programName(command) !== DOCKER_RUN) {
|
|
2660
|
+
if (programName$1(command) !== DOCKER_RUN) {
|
|
2442
2661
|
return isScriptShell(command);
|
|
2443
2662
|
}
|
|
2444
2663
|
const after = command.slice(1);
|
|
2445
2664
|
const shell = after.slice(after.findIndex((word) => !isOption(word)));
|
|
2446
2665
|
return after.every(isOption) || isScriptShell(shell);
|
|
2447
2666
|
}
|
|
2448
|
-
const passesThrough = (command) => programName(command) === PASS_THROUGH && command.slice(1).every(isOption);
|
|
2667
|
+
const passesThrough = (command) => programName$1(command) === PASS_THROUGH && command.slice(1).every(isOption);
|
|
2449
2668
|
function scriptsRunBy(top, index, command) {
|
|
2450
2669
|
const previous = index - 1;
|
|
2451
2670
|
const isPipedScript = top.pipes.has(previous) && isScriptShell(command) && passesThrough(simpleCommand(top.commands[previous] ?? []));
|
|
@@ -2457,16 +2676,20 @@ const shifted = (words, offset) => words.map((word) => ({ ...word, start: word.s
|
|
|
2457
2676
|
function shellCommandsAt(text, offset, indent = 0) {
|
|
2458
2677
|
return shellCommands(text, indent).map((words) => shifted(words, offset));
|
|
2459
2678
|
}
|
|
2679
|
+
const expansionCommands = (word) => wordExpansions(word.raw).flatMap(
|
|
2680
|
+
(expansion) => shellCommandsAt(expansion.text, word.start + expansion.start)
|
|
2681
|
+
);
|
|
2460
2682
|
function innerCommands(command) {
|
|
2461
|
-
const
|
|
2683
|
+
const assignments = new Map(shellAssignments(command).map((found) => [found.word, found]));
|
|
2684
|
+
return command.flatMap((word) => {
|
|
2462
2685
|
const inner = nestedCommandText(word);
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
const
|
|
2467
|
-
|
|
2686
|
+
if (inner !== void 0) {
|
|
2687
|
+
return shellCommandsAt(inner, word.start + 1);
|
|
2688
|
+
}
|
|
2689
|
+
const assignment = assignments.get(word);
|
|
2690
|
+
const value = assignment === void 0 ? void 0 : assignmentValueText(assignment);
|
|
2691
|
+
return value === void 0 ? expansionCommands(word) : shellCommandsAt(value.text, value.start);
|
|
2468
2692
|
});
|
|
2469
|
-
return [...quoted, ...assigned];
|
|
2470
2693
|
}
|
|
2471
2694
|
function shellCommands(text, indent = 0) {
|
|
2472
2695
|
const top = topLevelCommands(text, indent);
|
|
@@ -2540,19 +2763,27 @@ function expandedName(text) {
|
|
|
2540
2763
|
const match = SHELL_VARIABLE_RE.exec(text);
|
|
2541
2764
|
return match === null ? void 0 : match[1] ?? match[2];
|
|
2542
2765
|
}
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2766
|
+
const textRunsGenerator = (text) => shellCommands(text).some(runsGenerator);
|
|
2767
|
+
function textDefinition(name, text) {
|
|
2768
|
+
const target = expandedName(text.trim());
|
|
2769
|
+
return target === void 0 ? { name, kind: "command", runsGenerator: textRunsGenerator(text) } : { name, kind: "reference", target };
|
|
2770
|
+
}
|
|
2771
|
+
function expansionDefinitions(name, expansion) {
|
|
2772
|
+
const word = textDefinition(name, expansion.text);
|
|
2773
|
+
const isOutside = expansion.use === "alternative" || expansion.name === name;
|
|
2774
|
+
const variable = isOutside ? { name, kind: "command", runsGenerator: false } : { name, kind: "reference", target: expansion.name };
|
|
2775
|
+
return [word, variable];
|
|
2776
|
+
}
|
|
2777
|
+
function programDefinitions$1({ name, value }) {
|
|
2778
|
+
const expansion = wholeWordExpansion(value.trim());
|
|
2779
|
+
return expansion === void 0 ? [textDefinition(name, value)] : expansionDefinitions(name, expansion);
|
|
2549
2780
|
}
|
|
2550
2781
|
function shellVariables(definitions) {
|
|
2551
2782
|
const values = /* @__PURE__ */ new Map();
|
|
2552
2783
|
for (const { name, value } of definitions) {
|
|
2553
2784
|
values.set(name, [values.get(name), value].filter((part) => part !== void 0).join(" "));
|
|
2554
2785
|
}
|
|
2555
|
-
const programs = variablePrograms(definitions.
|
|
2786
|
+
const programs = variablePrograms(definitions.flatMap(programDefinitions$1));
|
|
2556
2787
|
const nameAt = (word) => expandedName(word.raw);
|
|
2557
2788
|
return {
|
|
2558
2789
|
programAt: (program) => {
|
|
@@ -2573,8 +2804,15 @@ function combinedUse(left, right) {
|
|
|
2573
2804
|
}
|
|
2574
2805
|
return left.program === right.program ? left : { ...left, program: "generator-or-other" };
|
|
2575
2806
|
}
|
|
2807
|
+
function assignedByExpansions(commands) {
|
|
2808
|
+
return commands.flat().flatMap((word) => wordExpansions(word.raw)).filter((expansion) => expansion.use === "assign").flatMap(({ name, text }) => [
|
|
2809
|
+
{ name, value: text },
|
|
2810
|
+
{ name, value: "" }
|
|
2811
|
+
]);
|
|
2812
|
+
}
|
|
2576
2813
|
function withShellAssignments(commands, file) {
|
|
2577
|
-
const
|
|
2814
|
+
const assigned = commands.flatMap(shellAssignments).filter((found) => !isArrayAssignment(found));
|
|
2815
|
+
const definitions = [...assigned, ...assignedByExpansions(commands)];
|
|
2578
2816
|
if (definitions.length === 0) {
|
|
2579
2817
|
return file;
|
|
2580
2818
|
}
|
|
@@ -2584,6 +2822,35 @@ function withShellAssignments(commands, file) {
|
|
|
2584
2822
|
referenceAt: (word) => own.referenceAt(word) ?? file.referenceAt(word)
|
|
2585
2823
|
};
|
|
2586
2824
|
}
|
|
2825
|
+
const joinedProgram = (left, right) => left === right ? left : "generator-or-other";
|
|
2826
|
+
function expansionUse(word, variables) {
|
|
2827
|
+
const expansion = wholeWordExpansion(word.raw);
|
|
2828
|
+
if (expansion === void 0) {
|
|
2829
|
+
return void 0;
|
|
2830
|
+
}
|
|
2831
|
+
const programOf = (name) => (name === void 0 ? void 0 : variables.programAt({ ...word, raw: `$${name}` })?.program) ?? "other";
|
|
2832
|
+
const target = expandedName(expansion.text.trim());
|
|
2833
|
+
const textProgram = textRunsGenerator(expansion.text) ? "generator" : "other";
|
|
2834
|
+
const own = target === void 0 ? textProgram : programOf(target);
|
|
2835
|
+
const variable = programOf(expansion.use === "alternative" ? void 0 : expansion.name);
|
|
2836
|
+
return { written: word.raw, program: joinedProgram(own, variable) };
|
|
2837
|
+
}
|
|
2838
|
+
function withWordExpansions(variables) {
|
|
2839
|
+
return {
|
|
2840
|
+
programAt: (program) => variables.programAt(program) ?? expansionUse(program, variables),
|
|
2841
|
+
referenceAt: (word) => variables.referenceAt(word)
|
|
2842
|
+
};
|
|
2843
|
+
}
|
|
2844
|
+
const VARIABLE_NAME = "[A-Za-z_][A-Za-z0-9_]*";
|
|
2845
|
+
const VARIABLE_WORD_RE = new RegExp(
|
|
2846
|
+
`^"?\\$\\$?(?:${VARIABLE_NAME}|\\{${VARIABLE_NAME}(?:\\[[^\\]]*\\])?\\})"?$`
|
|
2847
|
+
);
|
|
2848
|
+
function withUnreadVariables(variables) {
|
|
2849
|
+
return {
|
|
2850
|
+
programAt: (program) => variables.programAt(program) ?? (VARIABLE_WORD_RE.test(program.raw) ? { written: program.raw, program: "generator-or-other" } : void 0),
|
|
2851
|
+
referenceAt: (word) => variables.referenceAt(word)
|
|
2852
|
+
};
|
|
2853
|
+
}
|
|
2587
2854
|
|
|
2588
2855
|
const QUOTES$1 = /* @__PURE__ */ new Set(["'", '"']);
|
|
2589
2856
|
const PATH_SEPARATOR$7 = "/";
|
|
@@ -2720,7 +2987,7 @@ function shellTextFindings(text, locate) {
|
|
|
2720
2987
|
return commandWordFindings(shellCommands(text), locate);
|
|
2721
2988
|
}
|
|
2722
2989
|
function commandWordFindings(commands, locate, variables = NO_VARIABLES) {
|
|
2723
|
-
const known = withShellAssignments(commands, variables);
|
|
2990
|
+
const known = withUnreadVariables(withWordExpansions(withShellAssignments(commands, variables)));
|
|
2724
2991
|
const findings = commands.flatMap((words) => commandFindings(words, locate, known)).sort((left, right) => left.offset - right.offset);
|
|
2725
2992
|
return {
|
|
2726
2993
|
edits: findings.flatMap((finding) => finding.edit === void 0 ? [] : [finding.edit]),
|
|
@@ -2794,45 +3061,6 @@ function commandStringSteps(text, strings) {
|
|
|
2794
3061
|
});
|
|
2795
3062
|
}
|
|
2796
3063
|
|
|
2797
|
-
const isMap = (node) => node?.kind === "map";
|
|
2798
|
-
const isScalar = (node) => node.kind === "scalar";
|
|
2799
|
-
function textEntries(map) {
|
|
2800
|
-
return map.entries.flatMap(({ key, value }) => isScalar(key) ? [{ key, value }] : []);
|
|
2801
|
-
}
|
|
2802
|
-
function valuesAt(map, key) {
|
|
2803
|
-
return textEntries(map).filter((entry) => entry.key.value === key).map((entry) => entry.value);
|
|
2804
|
-
}
|
|
2805
|
-
function mapsAt(map, key) {
|
|
2806
|
-
return valuesAt(map, key).filter(isMap);
|
|
2807
|
-
}
|
|
2808
|
-
function stringsBelow(node, path) {
|
|
2809
|
-
switch (node.kind) {
|
|
2810
|
-
case "scalar":
|
|
2811
|
-
return [{ ...node, path }];
|
|
2812
|
-
case "list":
|
|
2813
|
-
return node.items.flatMap((item, index) => stringsBelow(item, [...path, index]));
|
|
2814
|
-
case "map":
|
|
2815
|
-
return textEntries(node).flatMap(
|
|
2816
|
-
({ key, value }) => stringsBelow(value, [...path, key.value])
|
|
2817
|
-
);
|
|
2818
|
-
default:
|
|
2819
|
-
return [];
|
|
2820
|
-
}
|
|
2821
|
-
}
|
|
2822
|
-
function documentStrings(documents) {
|
|
2823
|
-
return documents.flatMap((document) => stringsBelow(document, []));
|
|
2824
|
-
}
|
|
2825
|
-
function ownerKey(path) {
|
|
2826
|
-
return path.findLast((part) => typeof part === "string");
|
|
2827
|
-
}
|
|
2828
|
-
function unreadableConfig(text, offset) {
|
|
2829
|
-
if (!namesOriginalPackage(text)) {
|
|
2830
|
-
return unchanged(text);
|
|
2831
|
-
}
|
|
2832
|
-
const position = offset === void 0 ? void 0 : { line: lineAt(text, offset), column: columnAt(text, offset) };
|
|
2833
|
-
return { ...unchanged(text), manualSteps: [{ kind: "config-unreadable", position }] };
|
|
2834
|
-
}
|
|
2835
|
-
|
|
2836
3064
|
const KEPT_PROTOCOLS = ["catalog:", "workspace:"];
|
|
2837
3065
|
const LOCAL_PROTOCOLS = ["workspace:", "link:", "file:", "portal:"];
|
|
2838
3066
|
const RANGE_SEPARATOR = "||";
|
|
@@ -2915,8 +3143,12 @@ function localPackageNames(manifest) {
|
|
|
2915
3143
|
);
|
|
2916
3144
|
}
|
|
2917
3145
|
function localPackagesFor(manifests, filePath) {
|
|
2918
|
-
const
|
|
2919
|
-
|
|
3146
|
+
const nearestFirst = manifests.filter(({ path }) => isAtOrAbove(path, filePath)).sort((left, right) => directoryOf(right.path).length - directoryOf(left.path).length);
|
|
3147
|
+
const candidates = new Set(
|
|
3148
|
+
nearestFirst.flatMap(({ localPackages }) => [...localPackages ?? []])
|
|
3149
|
+
);
|
|
3150
|
+
const isLocal = (name) => nearestFirst.find(({ names }) => names?.has(name) === true)?.localPackages?.has(name) === true;
|
|
3151
|
+
return new Set([...candidates].filter(isLocal));
|
|
2920
3152
|
}
|
|
2921
3153
|
function isDeclaredFor(manifests, filePath, name) {
|
|
2922
3154
|
const original = ORIGINAL_NAMES.get(name);
|
|
@@ -2950,7 +3182,7 @@ const NOT_LINE_BREAK_RE$1 = /[^\n]/g;
|
|
|
2950
3182
|
const ARRAY_END = "]";
|
|
2951
3183
|
const VARIABLE_INSTRUCTIONS = /* @__PURE__ */ new Set(["ARG", "ENV"]);
|
|
2952
3184
|
const LEGACY_ENV_INSTRUCTION = "ENV";
|
|
2953
|
-
const ASSIGNMENT = "=";
|
|
3185
|
+
const ASSIGNMENT$1 = "=";
|
|
2954
3186
|
const QUOTES = /* @__PURE__ */ new Set(['"', "'"]);
|
|
2955
3187
|
function matchAt(pattern, text, index) {
|
|
2956
3188
|
pattern.lastIndex = index;
|
|
@@ -3049,7 +3281,7 @@ function escapedScriptSteps(scripts, lineOf) {
|
|
|
3049
3281
|
});
|
|
3050
3282
|
}
|
|
3051
3283
|
function assignedVariable(word) {
|
|
3052
|
-
const at = word.raw.indexOf(ASSIGNMENT);
|
|
3284
|
+
const at = word.raw.indexOf(ASSIGNMENT$1);
|
|
3053
3285
|
if (at <= 0) {
|
|
3054
3286
|
return void 0;
|
|
3055
3287
|
}
|
|
@@ -3067,7 +3299,7 @@ function dockerVariables(commands) {
|
|
|
3067
3299
|
if (!VARIABLE_INSTRUCTIONS.has(instruction.value)) {
|
|
3068
3300
|
return [];
|
|
3069
3301
|
}
|
|
3070
|
-
if (instruction.value === LEGACY_ENV_INSTRUCTION && !first.raw.includes(ASSIGNMENT)) {
|
|
3302
|
+
if (instruction.value === LEGACY_ENV_INSTRUCTION && !first.raw.includes(ASSIGNMENT$1)) {
|
|
3071
3303
|
return [{ name: first.value, commands: [rest] }];
|
|
3072
3304
|
}
|
|
3073
3305
|
return [first, ...rest].flatMap((word) => assignedVariable(word) ?? []);
|
|
@@ -3378,30 +3610,12 @@ function migrateImportMap(text, read, version) {
|
|
|
3378
3610
|
}
|
|
3379
3611
|
|
|
3380
3612
|
const IMPORT_MAP_FIELD = "importMap";
|
|
3381
|
-
const SEPARATOR = "/";
|
|
3382
|
-
const CURRENT_FOLDER = ".";
|
|
3383
|
-
const PARENT_FOLDER = "..";
|
|
3384
|
-
const URL_SCHEME = /^[a-z][a-z\d+.-]*:/i;
|
|
3385
3613
|
function importMapReferences(roots) {
|
|
3386
3614
|
return roots.flatMap((root) => valuesAt(root, IMPORT_MAP_FIELD)).flatMap((value) => isScalar(value) ? [value.value] : []);
|
|
3387
3615
|
}
|
|
3388
|
-
function resolvedPath(configPath, reference) {
|
|
3389
|
-
const parts = configPath.split(SEPARATOR).slice(0, -1);
|
|
3390
|
-
for (const part of reference.split(SEPARATOR)) {
|
|
3391
|
-
if (part === PARENT_FOLDER) {
|
|
3392
|
-
if (parts.pop() === void 0) {
|
|
3393
|
-
return void 0;
|
|
3394
|
-
}
|
|
3395
|
-
} else if (part !== CURRENT_FOLDER && part !== "") {
|
|
3396
|
-
parts.push(part);
|
|
3397
|
-
}
|
|
3398
|
-
}
|
|
3399
|
-
return parts.join(SEPARATOR);
|
|
3400
|
-
}
|
|
3401
3616
|
function importMapLocation(configPath, reference) {
|
|
3402
|
-
const
|
|
3403
|
-
|
|
3404
|
-
return path === void 0 || path === "" ? { kind: "not-editable", reference } : { kind: "in-project", path };
|
|
3617
|
+
const path = referencedProjectPath(configPath, reference);
|
|
3618
|
+
return path === void 0 ? { kind: "not-editable", reference } : { kind: "in-project", path };
|
|
3405
3619
|
}
|
|
3406
3620
|
const importMapLocations = (configPath, roots) => importMapReferences(roots).map((reference) => importMapLocation(configPath, reference));
|
|
3407
3621
|
function importMapSteps(configPath, read) {
|
|
@@ -3580,58 +3794,234 @@ function migrateJsonCommands(text, strings, patterns) {
|
|
|
3580
3794
|
return { text: applyTextEdits(text, edits), changes, manualSteps };
|
|
3581
3795
|
}
|
|
3582
3796
|
|
|
3583
|
-
const
|
|
3584
|
-
const
|
|
3585
|
-
const
|
|
3586
|
-
const
|
|
3797
|
+
const DELIMITERS = ['"""', "'''", "```", '"', "'", "`"];
|
|
3798
|
+
const BACKTICK = "`";
|
|
3799
|
+
const ESCAPING_DELIMITER = '"';
|
|
3800
|
+
const ESCAPE = "\\";
|
|
3801
|
+
const COMMENT_START$1 = "#";
|
|
3802
|
+
const LINE_BREAK$2 = "\n";
|
|
3803
|
+
function closingOffset(text, delimiter, from) {
|
|
3804
|
+
if (delimiter !== ESCAPING_DELIMITER) {
|
|
3805
|
+
const close = text.indexOf(delimiter, from);
|
|
3806
|
+
return close === -1 ? void 0 : close;
|
|
3807
|
+
}
|
|
3808
|
+
for (let index = from; index < text.length; index += 1) {
|
|
3809
|
+
const char = text[index];
|
|
3810
|
+
if (char === ESCAPE) {
|
|
3811
|
+
index += 1;
|
|
3812
|
+
} else if (char === ESCAPING_DELIMITER || char === LINE_BREAK$2) {
|
|
3813
|
+
return char === ESCAPING_DELIMITER ? index : void 0;
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3816
|
+
return void 0;
|
|
3817
|
+
}
|
|
3818
|
+
function literalAt(text, offset) {
|
|
3819
|
+
const delimiter = DELIMITERS.find((candidate) => text.startsWith(candidate, offset));
|
|
3820
|
+
if (delimiter === void 0) {
|
|
3821
|
+
return void 0;
|
|
3822
|
+
}
|
|
3823
|
+
const contentStart = offset + delimiter.length;
|
|
3824
|
+
const close = closingOffset(text, delimiter, contentStart);
|
|
3825
|
+
if (close === void 0) {
|
|
3826
|
+
return void 0;
|
|
3827
|
+
}
|
|
3828
|
+
const kind = delimiter.startsWith(BACKTICK) ? "backtick" : "string";
|
|
3829
|
+
const content = text.slice(contentStart, close);
|
|
3830
|
+
return { kind, start: offset, end: close + delimiter.length, contentStart, content };
|
|
3831
|
+
}
|
|
3832
|
+
function expressionAt(text, start) {
|
|
3833
|
+
const literals = [];
|
|
3834
|
+
let index = start;
|
|
3835
|
+
while (index < text.length && text[index] !== LINE_BREAK$2 && text[index] !== COMMENT_START$1) {
|
|
3836
|
+
const literal = literalAt(text, index);
|
|
3837
|
+
literals.push(...literal === void 0 ? [] : [literal]);
|
|
3838
|
+
index = literal?.end ?? index + 1;
|
|
3839
|
+
}
|
|
3840
|
+
return { literals, end: index };
|
|
3841
|
+
}
|
|
3842
|
+
function literalsBetween(text, start, end) {
|
|
3843
|
+
const literals = [];
|
|
3844
|
+
for (let index = start; index < end; ) {
|
|
3845
|
+
const literal = literalAt(text, index);
|
|
3846
|
+
literals.push(...literal === void 0 ? [] : [literal]);
|
|
3847
|
+
index = literal?.end ?? index + 1;
|
|
3848
|
+
}
|
|
3849
|
+
return literals;
|
|
3850
|
+
}
|
|
3851
|
+
const INTERPOLATION_OPEN = "{{";
|
|
3852
|
+
const INTERPOLATION_CLOSE = "}}";
|
|
3853
|
+
function interpolationAt(text, start) {
|
|
3854
|
+
const literals = [];
|
|
3855
|
+
for (let index = start + INTERPOLATION_OPEN.length; index < text.length; ) {
|
|
3856
|
+
if (text.startsWith(INTERPOLATION_CLOSE, index)) {
|
|
3857
|
+
return { start, end: index + INTERPOLATION_CLOSE.length, literals };
|
|
3858
|
+
}
|
|
3859
|
+
if (text[index] === LINE_BREAK$2) {
|
|
3860
|
+
return void 0;
|
|
3861
|
+
}
|
|
3862
|
+
const literal = literalAt(text, index);
|
|
3863
|
+
literals.push(...literal === void 0 ? [] : [literal]);
|
|
3864
|
+
index = literal?.end ?? index + 1;
|
|
3865
|
+
}
|
|
3866
|
+
return void 0;
|
|
3867
|
+
}
|
|
3868
|
+
function interpolationsOf(text) {
|
|
3869
|
+
const found = [];
|
|
3870
|
+
for (let open = text.indexOf(INTERPOLATION_OPEN); open !== -1; ) {
|
|
3871
|
+
const interpolation = interpolationAt(text, open);
|
|
3872
|
+
found.push(...interpolation === void 0 ? [] : [interpolation]);
|
|
3873
|
+
const next = interpolation?.end ?? open + INTERPOLATION_OPEN.length;
|
|
3874
|
+
open = text.indexOf(INTERPOLATION_OPEN, next);
|
|
3875
|
+
}
|
|
3876
|
+
return found;
|
|
3877
|
+
}
|
|
3878
|
+
|
|
3879
|
+
const RECIPE_NAME_RE = /^@?[A-Za-z_][A-Za-z0-9_-]*(?=[ \t:])/gm;
|
|
3880
|
+
const PARAMETER_RE = /^[+*$]*([A-Za-z_][A-Za-z0-9_-]*)(?:=([\s\S]*))?$/;
|
|
3881
|
+
const NAME_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/;
|
|
3882
|
+
const COLON = ":";
|
|
3883
|
+
const EQUALS = "=";
|
|
3884
|
+
const OPEN_PAREN = "(";
|
|
3885
|
+
const CLOSE_PAREN = ")";
|
|
3886
|
+
const COMMENT_START = "#";
|
|
3887
|
+
const LINE_BREAK$1 = "\n";
|
|
3888
|
+
const BLANK_RE = /[ \t]/;
|
|
3889
|
+
const depthChange = (char) => char === OPEN_PAREN ? 1 : char === CLOSE_PAREN ? -1 : 0;
|
|
3890
|
+
function headerColon(text, from) {
|
|
3891
|
+
for (let index = from; index < text.length && text[index] !== LINE_BREAK$1; ) {
|
|
3892
|
+
const literal = literalAt(text, index);
|
|
3893
|
+
const char = text[index];
|
|
3894
|
+
if (literal !== void 0) {
|
|
3895
|
+
index = literal.end;
|
|
3896
|
+
continue;
|
|
3897
|
+
}
|
|
3898
|
+
if (char === COMMENT_START || char === COLON && text[index + 1] === EQUALS) {
|
|
3899
|
+
return void 0;
|
|
3900
|
+
}
|
|
3901
|
+
if (char === COLON) {
|
|
3902
|
+
return index;
|
|
3903
|
+
}
|
|
3904
|
+
index += 1;
|
|
3905
|
+
}
|
|
3906
|
+
return void 0;
|
|
3907
|
+
}
|
|
3908
|
+
function parameterWords(text, start, end) {
|
|
3909
|
+
const words = [];
|
|
3910
|
+
let wordStart;
|
|
3911
|
+
let depth = 0;
|
|
3912
|
+
for (let index = start; index < end; ) {
|
|
3913
|
+
const isBreak = depth === 0 && BLANK_RE.test(text[index] ?? "");
|
|
3914
|
+
if (isBreak && wordStart !== void 0) {
|
|
3915
|
+
words.push({ start: wordStart, end: index });
|
|
3916
|
+
}
|
|
3917
|
+
wordStart = isBreak ? void 0 : wordStart ?? index;
|
|
3918
|
+
const literal = isBreak ? void 0 : literalAt(text, index);
|
|
3919
|
+
depth += literal === void 0 ? depthChange(text[index]) : 0;
|
|
3920
|
+
index = literal?.end ?? index + 1;
|
|
3921
|
+
}
|
|
3922
|
+
return wordStart === void 0 ? words : [...words, { start: wordStart, end }];
|
|
3923
|
+
}
|
|
3924
|
+
function parameterDefault(text, word) {
|
|
3925
|
+
const written = text.slice(word.start, word.end);
|
|
3926
|
+
const match = PARAMETER_RE.exec(written);
|
|
3927
|
+
const value = match?.[2];
|
|
3928
|
+
if (match === null || value === void 0) {
|
|
3929
|
+
return [];
|
|
3930
|
+
}
|
|
3931
|
+
const defaultStart = word.end - value.length;
|
|
3932
|
+
const literals = literalsBetween(text, defaultStart, word.end);
|
|
3933
|
+
const target = NAME_RE.test(value) ? value : void 0;
|
|
3934
|
+
return [{ name: match[1], literals, target }];
|
|
3935
|
+
}
|
|
3936
|
+
function recipeHeaders(text) {
|
|
3937
|
+
return [...text.matchAll(RECIPE_NAME_RE)].flatMap((match) => {
|
|
3938
|
+
const nameEnd = match.index + match[0].length;
|
|
3939
|
+
const colon = headerColon(text, nameEnd);
|
|
3940
|
+
if (colon === void 0) {
|
|
3941
|
+
return [];
|
|
3942
|
+
}
|
|
3943
|
+
const words = parameterWords(text, nameEnd, colon);
|
|
3944
|
+
const defaults = words.flatMap((word) => parameterDefault(text, word));
|
|
3945
|
+
return [{ start: match.index, end: colon, defaults }];
|
|
3946
|
+
});
|
|
3947
|
+
}
|
|
3948
|
+
|
|
3949
|
+
const ASSIGNMENT_RE$1 = /^(?:export[ \t]+)?([A-Za-z_][A-Za-z0-9_-]*)[ \t]*:=[ \t]*/gm;
|
|
3950
|
+
const NAME_VALUE_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/;
|
|
3587
3951
|
const VARIABLE_INTERPOLATION_RE = /^[@+-]*\{\{[ \t]*([A-Za-z_][A-Za-z0-9_-]*)[ \t]*\}\}$/;
|
|
3588
3952
|
const MASK$1 = "_";
|
|
3589
3953
|
const BLANK = " ";
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3954
|
+
function assignmentsOf$1(text) {
|
|
3955
|
+
return [...text.matchAll(ASSIGNMENT_RE$1)].map((match) => {
|
|
3956
|
+
const valueStart = match.index + match[0].length;
|
|
3957
|
+
const { literals, end } = expressionAt(text, valueStart);
|
|
3958
|
+
const value = text.slice(valueStart, end).trim();
|
|
3959
|
+
return { name: match[1], value, start: match.index, end, literals };
|
|
3960
|
+
});
|
|
3961
|
+
}
|
|
3962
|
+
function onlyString({ value, literals }) {
|
|
3963
|
+
const [literal] = literals;
|
|
3964
|
+
if (literals.length !== 1 || literal?.kind !== "string") {
|
|
3965
|
+
return void 0;
|
|
3966
|
+
}
|
|
3967
|
+
return value.length === literal.end - literal.start ? literal : void 0;
|
|
3968
|
+
}
|
|
3969
|
+
const stringRunsGenerator = (literal) => literal.kind === "string" && shellCommands(literal.content).some(runsGenerator);
|
|
3970
|
+
function computedDefinitions(name, literals) {
|
|
3971
|
+
const other = { name, kind: "command", runsGenerator: false };
|
|
3972
|
+
const isMaybeGenerator = literals.some(stringRunsGenerator);
|
|
3973
|
+
return isMaybeGenerator ? [{ name, kind: "command", runsGenerator: true }, other] : [other];
|
|
3598
3974
|
}
|
|
3599
|
-
function
|
|
3600
|
-
const
|
|
3601
|
-
if (
|
|
3602
|
-
return { name, kind: "reference", target };
|
|
3975
|
+
function assignmentDefinitions(assignment) {
|
|
3976
|
+
const { name, value } = assignment;
|
|
3977
|
+
if (NAME_VALUE_RE.test(value)) {
|
|
3978
|
+
return [{ name, kind: "reference", target: value }];
|
|
3603
3979
|
}
|
|
3604
|
-
const
|
|
3605
|
-
|
|
3606
|
-
|
|
3980
|
+
const literal = onlyString(assignment);
|
|
3981
|
+
return literal === void 0 ? computedDefinitions(name, assignment.literals) : [{ name, kind: "command", runsGenerator: stringRunsGenerator(literal) }];
|
|
3982
|
+
}
|
|
3983
|
+
function parameterDefinitions({ name, literals, target }) {
|
|
3984
|
+
const fromCommandLine = computedDefinitions(name, literals);
|
|
3985
|
+
return target === void 0 ? fromCommandLine : [{ name, kind: "reference", target }, ...fromCommandLine];
|
|
3607
3986
|
}
|
|
3608
|
-
function shellText$1(text,
|
|
3987
|
+
function shellText$1(text, spans) {
|
|
3609
3988
|
const parts = [];
|
|
3610
3989
|
let copiedUpTo = 0;
|
|
3611
|
-
for (const { start,
|
|
3612
|
-
const end = valueStart + value.length;
|
|
3990
|
+
for (const { start, end } of [...spans].sort((left, right) => left.start - right.start)) {
|
|
3613
3991
|
parts.push(text.slice(copiedUpTo, start), BLANK.repeat(end - start));
|
|
3614
3992
|
copiedUpTo = end;
|
|
3615
3993
|
}
|
|
3616
3994
|
parts.push(text.slice(copiedUpTo));
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3995
|
+
const blanked = parts.join("");
|
|
3996
|
+
const interpolations = interpolationsOf(blanked);
|
|
3997
|
+
const masked = interpolations.reduce(
|
|
3998
|
+
(current, { start, end }) => current.slice(0, start) + MASK$1.repeat(end - start) + current.slice(end),
|
|
3999
|
+
blanked
|
|
4000
|
+
);
|
|
4001
|
+
return { text: masked, interpolations };
|
|
3622
4002
|
}
|
|
3623
|
-
|
|
4003
|
+
const literalCommands = (literals) => literals.flatMap((literal) => shellCommandsAt(literal.content, literal.contentStart));
|
|
4004
|
+
function variableValues$1(assignments) {
|
|
3624
4005
|
const values = /* @__PURE__ */ new Map();
|
|
3625
|
-
for (const
|
|
3626
|
-
|
|
4006
|
+
for (const assignment of assignments) {
|
|
4007
|
+
const value = onlyString(assignment)?.content ?? assignment.value;
|
|
4008
|
+
values.set(assignment.name, [values.get(assignment.name), value].join(" ").trim());
|
|
3627
4009
|
}
|
|
4010
|
+
return values;
|
|
4011
|
+
}
|
|
4012
|
+
function computedProgram(written) {
|
|
4013
|
+
const literals = interpolationsOf(written).flatMap((interpolation) => interpolation.literals);
|
|
4014
|
+
return literals.some(stringRunsGenerator) ? "generator-or-other" : void 0;
|
|
4015
|
+
}
|
|
4016
|
+
function justfileVariables(text, values, programs) {
|
|
3628
4017
|
const writtenAt = (word) => text.slice(word.start, word.end);
|
|
3629
4018
|
const nameAt = (word) => VARIABLE_INTERPOLATION_RE.exec(writtenAt(word))?.[1];
|
|
3630
4019
|
return {
|
|
3631
|
-
programAt: (
|
|
3632
|
-
const name = nameAt(
|
|
3633
|
-
const
|
|
3634
|
-
|
|
4020
|
+
programAt: (word) => {
|
|
4021
|
+
const name = nameAt(word);
|
|
4022
|
+
const written = writtenAt(word);
|
|
4023
|
+
const found = name === void 0 ? computedProgram(written) : programs.get(name);
|
|
4024
|
+
return found === void 0 ? void 0 : { written, program: found };
|
|
3635
4025
|
},
|
|
3636
4026
|
referenceAt: (word) => {
|
|
3637
4027
|
const name = nameAt(word);
|
|
@@ -3643,11 +4033,19 @@ function justfileVariables(text, assignments, programs) {
|
|
|
3643
4033
|
function migrateJustfile(text, file) {
|
|
3644
4034
|
const lineOf = lineLocator(text);
|
|
3645
4035
|
const assignments = assignmentsOf$1(text);
|
|
3646
|
-
const
|
|
3647
|
-
const
|
|
4036
|
+
const headers = recipeHeaders(text);
|
|
4037
|
+
const defaults = headers.flatMap((header) => header.defaults);
|
|
4038
|
+
const programs = variablePrograms([
|
|
4039
|
+
...assignments.flatMap(assignmentDefinitions),
|
|
4040
|
+
...defaults.flatMap(parameterDefinitions)
|
|
4041
|
+
]);
|
|
4042
|
+
const variables = justfileVariables(text, variableValues$1(assignments), programs);
|
|
4043
|
+
const shell = shellText$1(text, [...assignments, ...headers]);
|
|
3648
4044
|
const commands = [
|
|
3649
|
-
...shellCommands(
|
|
3650
|
-
...assignments.flatMap(
|
|
4045
|
+
...shellCommands(shell.text),
|
|
4046
|
+
...literalCommands(assignments.flatMap((assignment) => assignment.literals)),
|
|
4047
|
+
...literalCommands(defaults.flatMap((found) => found.literals)),
|
|
4048
|
+
...literalCommands(shell.interpolations.flatMap((found) => found.literals))
|
|
3651
4049
|
];
|
|
3652
4050
|
const locate = (offset) => `${file}:${lineOf(offset)}`;
|
|
3653
4051
|
const { edits, changes, manualSteps } = commandWordFindings(commands, locate, variables);
|
|
@@ -3765,7 +4163,7 @@ function makefileVariables(text, assignments, programs) {
|
|
|
3765
4163
|
const variables = {
|
|
3766
4164
|
programAt: (program) => {
|
|
3767
4165
|
const name = nameAt(program);
|
|
3768
|
-
const found = name === void 0 ? void 0 : programs.get(name);
|
|
4166
|
+
const found = name === void 0 ? void 0 : programs.get(name) ?? "generator-or-other";
|
|
3769
4167
|
const written = text.slice(program.start, program.end);
|
|
3770
4168
|
return found === void 0 ? void 0 : { written, program: found };
|
|
3771
4169
|
},
|
|
@@ -4130,19 +4528,63 @@ function oldPackagePatchSteps(fileName) {
|
|
|
4130
4528
|
}
|
|
4131
4529
|
|
|
4132
4530
|
const STEP_SHELL_KEY = "shell";
|
|
4531
|
+
const DEFAULT_SHELL_PATH = ["defaults", "run", STEP_SHELL_KEY];
|
|
4133
4532
|
const COMMAND_LINE_SHELLS = /* @__PURE__ */ new Set([
|
|
4134
4533
|
...["sh", "bash", "dash", "ash", "zsh", "ksh"],
|
|
4135
|
-
...["pwsh", "powershell", "cmd"]
|
|
4534
|
+
...["pwsh", "powershell", "cmd"],
|
|
4535
|
+
...["msys2", "wsl-bash"]
|
|
4136
4536
|
]);
|
|
4537
|
+
const ENV_PROGRAM = "env";
|
|
4538
|
+
const ENV_OPTIONS_WITH_VALUE = /* @__PURE__ */ new Set(["-u", "--unset", "-C", "--chdir"]);
|
|
4539
|
+
const OPTION_START = "-";
|
|
4540
|
+
const ASSIGNMENT = "=";
|
|
4137
4541
|
const PATH_SEPARATOR_RE = /[/\\]/;
|
|
4542
|
+
const WINDOWS_EXECUTABLE_RE = /\.exe$/i;
|
|
4138
4543
|
const WHITESPACE_RE = /\s+/;
|
|
4139
|
-
const
|
|
4544
|
+
const programName = (word) => (word.split(PATH_SEPARATOR_RE).at(-1) ?? "").replace(WINDOWS_EXECUTABLE_RE, "");
|
|
4545
|
+
function envPrefixLength(words) {
|
|
4546
|
+
let index = 0;
|
|
4547
|
+
while (index < words.length) {
|
|
4548
|
+
const word = words[index] ?? "";
|
|
4549
|
+
if (ENV_OPTIONS_WITH_VALUE.has(word)) {
|
|
4550
|
+
index += 2;
|
|
4551
|
+
} else if (word.startsWith(OPTION_START) || word.includes(ASSIGNMENT)) {
|
|
4552
|
+
index += 1;
|
|
4553
|
+
} else {
|
|
4554
|
+
break;
|
|
4555
|
+
}
|
|
4556
|
+
}
|
|
4557
|
+
return index;
|
|
4558
|
+
}
|
|
4559
|
+
function shellProgram(shell) {
|
|
4560
|
+
const words = shell.trim().split(WHITESPACE_RE);
|
|
4561
|
+
const first = programName(words[0] ?? "");
|
|
4562
|
+
if (first !== ENV_PROGRAM) {
|
|
4563
|
+
return first;
|
|
4564
|
+
}
|
|
4565
|
+
const rest = words.slice(1);
|
|
4566
|
+
return programName(rest[envPrefixLength(rest)] ?? "");
|
|
4567
|
+
}
|
|
4568
|
+
const endsWith = (path, keys) => keys.every((key, index) => path[path.length - keys.length + index] === key);
|
|
4569
|
+
const isDefaultShell = (value) => endsWith(value.path, DEFAULT_SHELL_PATH);
|
|
4570
|
+
function scopeOf(value) {
|
|
4571
|
+
const keys = isDefaultShell(value) ? DEFAULT_SHELL_PATH.length : 1;
|
|
4572
|
+
return JSON.stringify(value.path.slice(0, -keys));
|
|
4573
|
+
}
|
|
4140
4574
|
function stepShells(strings) {
|
|
4141
|
-
const
|
|
4142
|
-
const
|
|
4143
|
-
|
|
4144
|
-
);
|
|
4145
|
-
return (value) =>
|
|
4575
|
+
const shells = strings.filter((value) => value.path.at(-1) === STEP_SHELL_KEY);
|
|
4576
|
+
const isOwnShell = (value) => !isDefaultShell(value);
|
|
4577
|
+
const ordered = [...shells.filter(isDefaultShell), ...shells.filter(isOwnShell)];
|
|
4578
|
+
const byScope = new Map(ordered.map((value) => [scopeOf(value), value.value]));
|
|
4579
|
+
return (value) => {
|
|
4580
|
+
for (let depth = value.path.length - 1; depth >= 0; depth -= 1) {
|
|
4581
|
+
const shell = byScope.get(JSON.stringify(value.path.slice(0, depth)));
|
|
4582
|
+
if (shell !== void 0) {
|
|
4583
|
+
return COMMAND_LINE_SHELLS.has(shellProgram(shell)) ? void 0 : shell;
|
|
4584
|
+
}
|
|
4585
|
+
}
|
|
4586
|
+
return void 0;
|
|
4587
|
+
};
|
|
4146
4588
|
}
|
|
4147
4589
|
function otherShellFindings(values, shellOf, locate) {
|
|
4148
4590
|
const manualSteps = values.flatMap((value) => {
|
|
@@ -4176,10 +4618,6 @@ const TASKFILE_COMMAND_KEYS = /* @__PURE__ */ new Set([
|
|
|
4176
4618
|
"status"
|
|
4177
4619
|
]);
|
|
4178
4620
|
|
|
4179
|
-
const API_DESCRIPTION_KEYS = /* @__PURE__ */ new Set(["openapi", "swagger", "asyncapi"]);
|
|
4180
|
-
const isApiDescription = (documents) => documents.some(
|
|
4181
|
-
(root) => isMap(root) && textEntries(root).some(({ key }) => API_DESCRIPTION_KEYS.has(key.value))
|
|
4182
|
-
);
|
|
4183
4621
|
const ENVIRONMENT_KEYS = /* @__PURE__ */ new Set(["env"]);
|
|
4184
4622
|
const isEnvironmentValue = (value) => value.path.length >= 2 && ENVIRONMENT_KEYS.has(String(value.path.at(-2)));
|
|
4185
4623
|
function environmentVariables(text, strings) {
|
|
@@ -4589,7 +5027,7 @@ const COMMAND_CONFIG_KINDS = [
|
|
|
4589
5027
|
)
|
|
4590
5028
|
}
|
|
4591
5029
|
];
|
|
4592
|
-
const yamlCommandsStep = (path) => (text, read) => read.kind === "read" && isApiDescription(read.documents) ? unchanged(text) : stringsStep((current, strings) => migrateYamlCommands(current, path, strings))(text, read);
|
|
5030
|
+
const yamlCommandsStep = (path, isPart) => (text, read) => isPart || read.kind === "read" && isApiDescription(read.documents) ? unchanged(text) : stringsStep((current, strings) => migrateYamlCommands(current, path, strings))(text, read);
|
|
4593
5031
|
const manifestTarget = ({ version, catalogs, aliases }, path) => ({
|
|
4594
5032
|
version,
|
|
4595
5033
|
catalogs,
|
|
@@ -4665,7 +5103,11 @@ const FILE_KINDS = [
|
|
|
4665
5103
|
},
|
|
4666
5104
|
{
|
|
4667
5105
|
matches: (path) => YAML_EXTENSIONS.has(extensionOf(path)),
|
|
4668
|
-
migrate: whenNamed(
|
|
5106
|
+
migrate: whenNamed(
|
|
5107
|
+
yamlConfig((context, path) => [
|
|
5108
|
+
yamlCommandsStep(path, context.apiDescriptionParts.has(path))
|
|
5109
|
+
])
|
|
5110
|
+
)
|
|
4669
5111
|
},
|
|
4670
5112
|
{
|
|
4671
5113
|
matches: (path) => DOCKERFILE_NAMES.has(baseName(path)),
|
|
@@ -4694,6 +5136,58 @@ function fileMigrationFor(path, namedImportMaps = NO_NAMED_IMPORT_MAPS) {
|
|
|
4694
5136
|
return FILE_KINDS.find((kind) => kind.matches(path))?.migrate;
|
|
4695
5137
|
}
|
|
4696
5138
|
|
|
5139
|
+
const NO_API_DESCRIPTION_PARTS = /* @__PURE__ */ new Set();
|
|
5140
|
+
const JSON_EXTENSION = ".json";
|
|
5141
|
+
const isYaml = (path) => YAML_EXTENSIONS.has(extensionOf(path));
|
|
5142
|
+
const isDescriptionFormat = (path) => isYaml(path) || extensionOf(path) === JSON_EXTENSION;
|
|
5143
|
+
async function textOf(path, files) {
|
|
5144
|
+
const read = await files.read(path);
|
|
5145
|
+
return read.kind === "read" ? read.text : void 0;
|
|
5146
|
+
}
|
|
5147
|
+
function documentsOf(path, text, readers) {
|
|
5148
|
+
const parsed = (isYaml(path) ? readers.yaml : readers.json).read(text);
|
|
5149
|
+
return parsed.kind === "read" ? [...parsed.documents] : void 0;
|
|
5150
|
+
}
|
|
5151
|
+
async function hasNamingYaml(paths, files) {
|
|
5152
|
+
for (const path of paths.filter(isYaml)) {
|
|
5153
|
+
const text = await textOf(path, files);
|
|
5154
|
+
if (text !== void 0 && namesOriginalPackage(text)) {
|
|
5155
|
+
return true;
|
|
5156
|
+
}
|
|
5157
|
+
}
|
|
5158
|
+
return false;
|
|
5159
|
+
}
|
|
5160
|
+
async function descriptionRoots(paths, { files, readers }) {
|
|
5161
|
+
const roots = /* @__PURE__ */ new Map();
|
|
5162
|
+
for (const path of paths.filter(isDescriptionFormat)) {
|
|
5163
|
+
const text = await textOf(path, files);
|
|
5164
|
+
const documents = text !== void 0 && mayBeApiDescription(text) ? documentsOf(path, text, readers) : void 0;
|
|
5165
|
+
if (documents !== void 0 && isApiDescription(documents)) {
|
|
5166
|
+
roots.set(path, documents);
|
|
5167
|
+
}
|
|
5168
|
+
}
|
|
5169
|
+
return roots;
|
|
5170
|
+
}
|
|
5171
|
+
async function apiDescriptionParts(paths, dependencies) {
|
|
5172
|
+
if (!await hasNamingYaml(paths, dependencies.files)) {
|
|
5173
|
+
return NO_API_DESCRIPTION_PARTS;
|
|
5174
|
+
}
|
|
5175
|
+
const listed = new Set(paths.filter(isDescriptionFormat));
|
|
5176
|
+
const roots = await descriptionRoots(paths, dependencies);
|
|
5177
|
+
const parts = /* @__PURE__ */ new Set();
|
|
5178
|
+
const pending = [...roots].flatMap(([path, documents]) => referencedFiles(path, documents));
|
|
5179
|
+
for (let path = pending.pop(); path !== void 0; path = pending.pop()) {
|
|
5180
|
+
if (!listed.has(path) || roots.has(path) || parts.has(path)) {
|
|
5181
|
+
continue;
|
|
5182
|
+
}
|
|
5183
|
+
parts.add(path);
|
|
5184
|
+
const text = await textOf(path, dependencies.files);
|
|
5185
|
+
const documents = text === void 0 ? void 0 : documentsOf(path, text, dependencies.readers);
|
|
5186
|
+
pending.push(...documents === void 0 ? [] : referencedFiles(path, documents));
|
|
5187
|
+
}
|
|
5188
|
+
return parts;
|
|
5189
|
+
}
|
|
5190
|
+
|
|
4697
5191
|
const readJson = (text, readers) => readers.json.read(text);
|
|
4698
5192
|
const readYaml = (text, readers) => readers.yaml.read(text);
|
|
4699
5193
|
function planSourceOf(path, namedImportMaps) {
|
|
@@ -4774,7 +5268,11 @@ async function planProjectTarget(paths, dependencies, version) {
|
|
|
4774
5268
|
isWorkspaceRoot
|
|
4775
5269
|
});
|
|
4776
5270
|
const declarations = withNamedImportMaps(manifests, importMaps);
|
|
4777
|
-
|
|
5271
|
+
const parts = await apiDescriptionParts(paths, dependencies);
|
|
5272
|
+
return {
|
|
5273
|
+
...{ version, catalogs, manifests: declarations, aliases, importMaps },
|
|
5274
|
+
apiDescriptionParts: parts
|
|
5275
|
+
};
|
|
4778
5276
|
}
|
|
4779
5277
|
|
|
4780
5278
|
async function planFile(path, dependencies, target) {
|
|
@@ -4787,9 +5285,9 @@ async function planFile(path, dependencies, target) {
|
|
|
4787
5285
|
return read;
|
|
4788
5286
|
}
|
|
4789
5287
|
const { rewriter, scanner, readers } = dependencies;
|
|
4790
|
-
const { version, catalogs, manifests, aliases } = target;
|
|
5288
|
+
const { version, catalogs, manifests, aliases, apiDescriptionParts } = target;
|
|
4791
5289
|
const context = {
|
|
4792
|
-
...{ version, catalogs, manifests, aliases },
|
|
5290
|
+
...{ version, catalogs, manifests, aliases, apiDescriptionParts },
|
|
4793
5291
|
...{ rewriter, scanner, readers }
|
|
4794
5292
|
};
|
|
4795
5293
|
const migration = migrate(read.text, path, context);
|
|
@@ -4879,7 +5377,7 @@ function terminalSafeText(text) {
|
|
|
4879
5377
|
const PINNED_NOTE = "change it to openapi-typesafe@<version>";
|
|
4880
5378
|
const OLD_FILE_NOTE$1 = "is a file of openapi-typescript, which is no longer installed: run openapi-typesafe instead";
|
|
4881
5379
|
const FLAGS_IN_VARIABLE_NOTE = "holds old flags of the generator and may serve other commands, so it was kept: rename";
|
|
4882
|
-
const NOT_ONLY_GENERATOR_NOTE = "
|
|
5380
|
+
const NOT_ONLY_GENERATOR_NOTE = "may run openapi-typescript or another program (set elsewhere in the file, in another step or outside it), so the flags after it were kept; where it runs the generator, rename";
|
|
4883
5381
|
const OLD_NAME_IN_COMMAND_NOTE = "names an old package where the tool cannot tell what runs it (a script name, an argument of a program it does not know), so it was kept: migrate it by hand";
|
|
4884
5382
|
const SCRIPT_NOT_SHELL_NOTE = "so the tool does not read it as commands: migrate the old package names in it by hand";
|
|
4885
5383
|
const COMMAND_STRING_NOTE = "a string runs openapi-typescript, so it was kept; change it to";
|