openapi-typesafe-migrate 1.0.0-rc.5 → 1.0.0-rc.6
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 +48 -0
- package/README.md +34 -22
- package/dist/cli/main.mjs +1662 -1395
- package/dist/cli/main.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cli/main.mjs
CHANGED
|
@@ -560,6 +560,21 @@ async function inspectProjectRoot(root) {
|
|
|
560
560
|
}
|
|
561
561
|
}
|
|
562
562
|
|
|
563
|
+
const BROKEN_PIPE = "EPIPE";
|
|
564
|
+
function isBrokenPipe(error) {
|
|
565
|
+
return error.code === BROKEN_PIPE;
|
|
566
|
+
}
|
|
567
|
+
function createPipeSafeWriter(stream) {
|
|
568
|
+
stream.on("error", (error) => {
|
|
569
|
+
if (!isBrokenPipe(error)) {
|
|
570
|
+
throw error;
|
|
571
|
+
}
|
|
572
|
+
});
|
|
573
|
+
return (text) => {
|
|
574
|
+
stream.write(text);
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
|
|
563
578
|
function unchanged(text) {
|
|
564
579
|
return { text, changes: [], manualSteps: [] };
|
|
565
580
|
}
|
|
@@ -610,6 +625,7 @@ function applyTextEdits(text, edits) {
|
|
|
610
625
|
return edited + text.slice(copiedUpTo);
|
|
611
626
|
}
|
|
612
627
|
|
|
628
|
+
const hasExportModifier = (declaration) => (ts.getCombinedModifierFlags(declaration) & ts.ModifierFlags.Export) !== 0;
|
|
613
629
|
const GENERATOR_MODULES = /* @__PURE__ */ new Set([
|
|
614
630
|
"openapi-typesafe",
|
|
615
631
|
"openapi-typescript"
|
|
@@ -692,7 +708,13 @@ function createChecker(file) {
|
|
|
692
708
|
}
|
|
693
709
|
function symbolOf(checker, identifier) {
|
|
694
710
|
const parent = identifier.parent;
|
|
695
|
-
|
|
711
|
+
if (ts.isShorthandPropertyAssignment(parent) && parent.name === identifier) {
|
|
712
|
+
return checker.getShorthandAssignmentValueSymbol(parent);
|
|
713
|
+
}
|
|
714
|
+
if (ts.isExportSpecifier(parent)) {
|
|
715
|
+
return checker.getExportSpecifierLocalTargetSymbol(parent);
|
|
716
|
+
}
|
|
717
|
+
return checker.getSymbolAtLocation(identifier);
|
|
696
718
|
}
|
|
697
719
|
function isDeclaredName(identifier, declaration) {
|
|
698
720
|
const declaredName = declaration.name;
|
|
@@ -778,7 +800,6 @@ function unwrapped(expression, types = []) {
|
|
|
778
800
|
}
|
|
779
801
|
return { value: expression, types };
|
|
780
802
|
}
|
|
781
|
-
const isExported$1 = (declaration) => (ts.getCombinedModifierFlags(declaration) & ts.ModifierFlags.Export) !== 0;
|
|
782
803
|
function constantOptions(name, bindings, outerTypes) {
|
|
783
804
|
const binding = bindings.bindingOf(name);
|
|
784
805
|
const declaration = bindings.declarationOf(name);
|
|
@@ -786,7 +807,7 @@ function constantOptions(name, bindings, outerTypes) {
|
|
|
786
807
|
if (found === void 0 || !ts.isObjectLiteralExpression(found.value)) {
|
|
787
808
|
return { kind: "unknown", expression: name };
|
|
788
809
|
}
|
|
789
|
-
const isOwn = bindings.usesOf(declaration).length === 1 && !
|
|
810
|
+
const isOwn = bindings.usesOf(declaration).length === 1 && !hasExportModifier(declaration);
|
|
790
811
|
if (!isOwn) {
|
|
791
812
|
return { kind: "shared", options: found.value };
|
|
792
813
|
}
|
|
@@ -1086,7 +1107,7 @@ function callbackAnnotations(property, names) {
|
|
|
1086
1107
|
function isSharedFunction(property, names) {
|
|
1087
1108
|
const name = namedValue(property);
|
|
1088
1109
|
const declaration = name === void 0 ? void 0 : names.bindings.declarationOf(name);
|
|
1089
|
-
return declaration !== void 0 && names.bindings.usesOf(declaration).length > 1;
|
|
1110
|
+
return declaration !== void 0 && (names.bindings.usesOf(declaration).length > 1 || hasExportModifier(declaration));
|
|
1090
1111
|
}
|
|
1091
1112
|
|
|
1092
1113
|
const KEYWORDS = /* @__PURE__ */ new Map([
|
|
@@ -1305,7 +1326,6 @@ function returnEdits(expression, names) {
|
|
|
1305
1326
|
return typeTextEdit(expression, names);
|
|
1306
1327
|
}
|
|
1307
1328
|
|
|
1308
|
-
const isExported = (node) => (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) !== 0;
|
|
1309
1329
|
function isRemovable(node, binding, names) {
|
|
1310
1330
|
switch (binding.kind) {
|
|
1311
1331
|
case "typescript-module":
|
|
@@ -1313,7 +1333,7 @@ function isRemovable(node, binding, names) {
|
|
|
1313
1333
|
case "helper-import":
|
|
1314
1334
|
return true;
|
|
1315
1335
|
case "constant":
|
|
1316
|
-
return !
|
|
1336
|
+
return !hasExportModifier(node) && typeTextOf(binding.initializer, names) !== void 0;
|
|
1317
1337
|
default:
|
|
1318
1338
|
return false;
|
|
1319
1339
|
}
|
|
@@ -1647,7 +1667,7 @@ function isModuleSpecifier(literal) {
|
|
|
1647
1667
|
}
|
|
1648
1668
|
return ts.isExternalModuleReference(parent);
|
|
1649
1669
|
}
|
|
1650
|
-
function stringValue(node, file) {
|
|
1670
|
+
function stringValue$1(node, file) {
|
|
1651
1671
|
return ts.isTemplateExpression(node) ? file.text.slice(node.getStart(file) + 1, node.getEnd() - 1) : node.text;
|
|
1652
1672
|
}
|
|
1653
1673
|
function collectStrings(root, file, offset, found) {
|
|
@@ -1658,7 +1678,7 @@ function collectStrings(root, file, offset, found) {
|
|
|
1658
1678
|
found.set(start, {
|
|
1659
1679
|
start,
|
|
1660
1680
|
end,
|
|
1661
|
-
value: stringValue(node, file),
|
|
1681
|
+
value: stringValue$1(node, file),
|
|
1662
1682
|
isModuleSpecifier: isModuleSpecifier(node)
|
|
1663
1683
|
});
|
|
1664
1684
|
}
|
|
@@ -1867,60 +1887,341 @@ function createYamlTextReader() {
|
|
|
1867
1887
|
return { read };
|
|
1868
1888
|
}
|
|
1869
1889
|
|
|
1870
|
-
const
|
|
1871
|
-
const
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1890
|
+
const NONE = /* @__PURE__ */ new Set();
|
|
1891
|
+
const PACKAGE_OPTIONS = /* @__PURE__ */ new Set(["-p", "--package"]);
|
|
1892
|
+
const PACKAGE_MANAGER_OPTIONS = /* @__PURE__ */ new Set([
|
|
1893
|
+
"--filter",
|
|
1894
|
+
"-F",
|
|
1895
|
+
"--dir",
|
|
1896
|
+
"-C",
|
|
1897
|
+
"--prefix",
|
|
1898
|
+
"--cwd",
|
|
1899
|
+
"--workspace"
|
|
1900
|
+
]);
|
|
1901
|
+
const launcher = (words, packageOptions = NONE, valueOptions = NONE) => {
|
|
1902
|
+
const allValueOptions = /* @__PURE__ */ new Set([...valueOptions, ...packageOptions]);
|
|
1903
|
+
return { words, packageOptions, valueOptions: allValueOptions, operands: 0 };
|
|
1904
|
+
};
|
|
1905
|
+
const CONTAINER_OPTIONS = /* @__PURE__ */ new Set([
|
|
1906
|
+
"-e",
|
|
1907
|
+
"--env",
|
|
1908
|
+
"--env-file",
|
|
1909
|
+
"-v",
|
|
1910
|
+
"--volume",
|
|
1911
|
+
"--mount",
|
|
1912
|
+
"-p",
|
|
1913
|
+
"--publish",
|
|
1914
|
+
"-w",
|
|
1915
|
+
"--workdir",
|
|
1916
|
+
"-u",
|
|
1917
|
+
"--user",
|
|
1918
|
+
"--name",
|
|
1919
|
+
"--network",
|
|
1920
|
+
"--entrypoint",
|
|
1921
|
+
"--platform",
|
|
1922
|
+
"-l",
|
|
1923
|
+
"--label",
|
|
1924
|
+
"-h",
|
|
1925
|
+
"--hostname",
|
|
1926
|
+
"--add-host"
|
|
1927
|
+
]);
|
|
1928
|
+
const container = (words) => ({
|
|
1929
|
+
...launcher(words, NONE, CONTAINER_OPTIONS),
|
|
1930
|
+
operands: 1
|
|
1931
|
+
});
|
|
1932
|
+
const withOperands = (words, operands, valueOptions = NONE) => ({ ...launcher(words, NONE, valueOptions), operands });
|
|
1933
|
+
const XARGS_OPTIONS = /* @__PURE__ */ new Set([
|
|
1934
|
+
"-I",
|
|
1935
|
+
"-J",
|
|
1936
|
+
"-L",
|
|
1937
|
+
"-n",
|
|
1938
|
+
"-P",
|
|
1939
|
+
"-R",
|
|
1940
|
+
"-S",
|
|
1941
|
+
"-s",
|
|
1942
|
+
"-d",
|
|
1943
|
+
"-E",
|
|
1944
|
+
"-a",
|
|
1945
|
+
"--max-args",
|
|
1946
|
+
"--max-procs",
|
|
1947
|
+
"--max-lines",
|
|
1948
|
+
"--delimiter",
|
|
1949
|
+
"--arg-file"
|
|
1950
|
+
]);
|
|
1951
|
+
const NODE_OPTIONS = /* @__PURE__ */ new Set([
|
|
1952
|
+
"-r",
|
|
1953
|
+
"--require",
|
|
1954
|
+
"--import",
|
|
1955
|
+
"--loader",
|
|
1956
|
+
"--env-file"
|
|
1957
|
+
]);
|
|
1958
|
+
const LAUNCHERS = [
|
|
1959
|
+
launcher(["npm", "exec"], PACKAGE_OPTIONS),
|
|
1960
|
+
launcher(["npm", "x"], PACKAGE_OPTIONS),
|
|
1961
|
+
launcher(["pnpm", "exec"], NONE, PACKAGE_MANAGER_OPTIONS),
|
|
1962
|
+
launcher(["pnpm", "dlx"], /* @__PURE__ */ new Set(["--package"])),
|
|
1963
|
+
launcher(["yarn", "dlx"], PACKAGE_OPTIONS),
|
|
1964
|
+
launcher(["yarn", "exec"]),
|
|
1965
|
+
launcher(["bun", "x"], PACKAGE_OPTIONS),
|
|
1966
|
+
withOperands(["yarn", "workspace"], 1),
|
|
1967
|
+
launcher(["dotenvx", "run"], NONE, /* @__PURE__ */ new Set(["-f", "--env-file", "-e", "--env", "--convention"])),
|
|
1968
|
+
launcher(
|
|
1969
|
+
["doppler", "run"],
|
|
1970
|
+
NONE,
|
|
1971
|
+
/* @__PURE__ */ new Set(["-p", "--project", "-c", "--config", "--token", "--mount", "--scope"])
|
|
1972
|
+
),
|
|
1973
|
+
launcher(["nx", "exec"], NONE, /* @__PURE__ */ new Set(["--projects", "-p", "--exclude"])),
|
|
1974
|
+
launcher(["deno", "run"], NONE, /* @__PURE__ */ new Set(["--config", "-c", "--import-map", "--location"])),
|
|
1975
|
+
launcher(["deno", "x"]),
|
|
1976
|
+
launcher(["npx"], PACKAGE_OPTIONS, /* @__PURE__ */ new Set(["-c", "--call"])),
|
|
1977
|
+
launcher(["pnpx"], PACKAGE_OPTIONS),
|
|
1978
|
+
launcher(["bunx"], PACKAGE_OPTIONS),
|
|
1979
|
+
// Like a bare `pnpm <name>`, a bare `bun <name>` runs the binary when no script has the name.
|
|
1980
|
+
launcher(["bun"], NONE, /* @__PURE__ */ new Set(["--cwd", "--filter", "-F"])),
|
|
1981
|
+
launcher(["corepack"]),
|
|
1982
|
+
launcher(["pnpm"], NONE, PACKAGE_MANAGER_OPTIONS),
|
|
1983
|
+
launcher(["yarn"], NONE, PACKAGE_MANAGER_OPTIONS),
|
|
1984
|
+
launcher(["node"], NONE, NODE_OPTIONS),
|
|
1985
|
+
launcher(["tsx"], NONE, NODE_OPTIONS),
|
|
1986
|
+
launcher(["ts-node"], NONE, /* @__PURE__ */ new Set([...NODE_OPTIONS, "-P", "--project", "-O", "--compiler"])),
|
|
1987
|
+
launcher(["cross-env"]),
|
|
1988
|
+
launcher(["dotenv"], NONE, /* @__PURE__ */ new Set(["-e", "-c", "-v"])),
|
|
1989
|
+
launcher(["env"], NONE, /* @__PURE__ */ new Set(["-u", "--unset", "-C", "--chdir"])),
|
|
1990
|
+
launcher(["exec"], NONE, /* @__PURE__ */ new Set(["-a"])),
|
|
1991
|
+
launcher(["command"]),
|
|
1992
|
+
launcher(["time"]),
|
|
1993
|
+
launcher(["nice"], NONE, /* @__PURE__ */ new Set(["-n", "--adjustment"])),
|
|
1994
|
+
withOperands(["timeout"], 1, /* @__PURE__ */ new Set(["-s", "--signal", "-k", "--kill-after"])),
|
|
1995
|
+
launcher(["xargs"], NONE, XARGS_OPTIONS),
|
|
1996
|
+
launcher(["nohup"]),
|
|
1997
|
+
launcher(["sudo"], NONE, /* @__PURE__ */ new Set(["-u", "-g"])),
|
|
1998
|
+
// The shell form of Dockerfile instructions runs the rest of the line in a shell.
|
|
1999
|
+
launcher(["RUN"], NONE, /* @__PURE__ */ new Set(["--mount", "--network", "--security"])),
|
|
2000
|
+
launcher(["CMD"]),
|
|
2001
|
+
launcher(["ENTRYPOINT"]),
|
|
2002
|
+
container(["docker", "run"]),
|
|
2003
|
+
container(["docker", "exec"]),
|
|
2004
|
+
container(["docker", "compose", "run"]),
|
|
2005
|
+
container(["docker", "compose", "exec"]),
|
|
2006
|
+
container(["podman", "run"]),
|
|
2007
|
+
container(["podman", "exec"])
|
|
2008
|
+
];
|
|
2009
|
+
const installers = (manager, subcommands) => subcommands.map((subcommand) => ({ words: [manager, subcommand] }));
|
|
2010
|
+
const NPM_INSTALL = ["install", "i", "add", "update", "up", "uninstall", "remove", "rm", "un"];
|
|
2011
|
+
const INSTALLERS = [
|
|
2012
|
+
...installers("npm", NPM_INSTALL),
|
|
2013
|
+
...installers("pnpm", ["add", "update", "up", "remove", "rm", "uninstall", "un"]),
|
|
2014
|
+
...installers("yarn", ["add", "upgrade", "up", "remove"]),
|
|
2015
|
+
// Yarn 1 installs global packages with `yarn global add`.
|
|
2016
|
+
{ words: ["yarn", "global", "add"] },
|
|
2017
|
+
{ words: ["yarn", "global", "remove"] },
|
|
2018
|
+
...installers("bun", ["add", "a", "update", "remove", "rm", "install", "i"]),
|
|
2019
|
+
...installers("deno", ["add", "install", "i", "remove", "uninstall"])
|
|
2020
|
+
];
|
|
2021
|
+
const NPM_SPECIFIER_PREFIX = "npm:";
|
|
2022
|
+
|
|
2023
|
+
const COMMAND_SEPARATORS = /* @__PURE__ */ new Set([
|
|
2024
|
+
";",
|
|
2025
|
+
"&",
|
|
2026
|
+
"|",
|
|
2027
|
+
"(",
|
|
2028
|
+
")",
|
|
2029
|
+
"`",
|
|
2030
|
+
"\n"
|
|
2031
|
+
]);
|
|
2032
|
+
const WORD_BREAKS = /* @__PURE__ */ new Set([" ", " ", "\r", "<", ">"]);
|
|
2033
|
+
const BACKSLASH$1 = "\\";
|
|
2034
|
+
const DOUBLE_QUOTE_ESCAPES = /* @__PURE__ */ new Set(["$", "`", '"', BACKSLASH$1, "\n"]);
|
|
2035
|
+
function singleQuoted(text, start) {
|
|
2036
|
+
const close = text.indexOf("'", start + 1);
|
|
2037
|
+
const end = close === -1 ? text.length : close + 1;
|
|
2038
|
+
return { end, value: text.slice(start + 1, close === -1 ? text.length : close) };
|
|
2039
|
+
}
|
|
2040
|
+
function doubleQuoted(text, start) {
|
|
2041
|
+
let value = "";
|
|
2042
|
+
let index = start + 1;
|
|
2043
|
+
while (index < text.length && text[index] !== '"') {
|
|
2044
|
+
const next = text[index + 1] ?? "";
|
|
2045
|
+
const isEscape = text[index] === BACKSLASH$1 && DOUBLE_QUOTE_ESCAPES.has(next);
|
|
2046
|
+
value += isEscape ? next === "\n" ? "" : next : text[index];
|
|
2047
|
+
index += isEscape ? 2 : 1;
|
|
1875
2048
|
}
|
|
1876
|
-
return
|
|
2049
|
+
return { end: Math.min(index + 1, text.length), value };
|
|
1877
2050
|
}
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
2051
|
+
const isLineContinuation = (text, index) => text[index] === BACKSLASH$1 && (text[index + 1] === "\n" || text.startsWith("\r\n", index + 1));
|
|
2052
|
+
const ARITHMETIC_OPEN = "$((";
|
|
2053
|
+
const NESTING_OPEN = "(";
|
|
2054
|
+
const NESTING_CLOSE = ")";
|
|
2055
|
+
const ARITHMETIC_DEPTH = 2;
|
|
2056
|
+
function arithmeticExpansion(text, start) {
|
|
2057
|
+
let depth = ARITHMETIC_DEPTH;
|
|
2058
|
+
for (let index = start + ARITHMETIC_OPEN.length; index < text.length; index++) {
|
|
2059
|
+
depth += text[index] === NESTING_OPEN ? 1 : text[index] === NESTING_CLOSE ? -1 : 0;
|
|
2060
|
+
if (depth === 0) {
|
|
2061
|
+
return { end: index + 1, value: text.slice(start, index + 1) };
|
|
2062
|
+
}
|
|
1882
2063
|
}
|
|
1883
|
-
|
|
1884
|
-
|
|
2064
|
+
return void 0;
|
|
2065
|
+
}
|
|
2066
|
+
function wordPart(text, index) {
|
|
2067
|
+
const char = text[index];
|
|
2068
|
+
const arithmetic = text.startsWith(ARITHMETIC_OPEN, index) ? arithmeticExpansion(text, index) : void 0;
|
|
2069
|
+
if (arithmetic !== void 0) {
|
|
2070
|
+
return arithmetic;
|
|
2071
|
+
}
|
|
2072
|
+
if (char === "'") {
|
|
2073
|
+
return singleQuoted(text, index);
|
|
2074
|
+
}
|
|
2075
|
+
if (char === '"') {
|
|
2076
|
+
return doubleQuoted(text, index);
|
|
2077
|
+
}
|
|
2078
|
+
if (char === BACKSLASH$1 && index + 1 < text.length) {
|
|
2079
|
+
return { end: index + 2, value: text[index + 1] };
|
|
1885
2080
|
}
|
|
2081
|
+
return { end: index + 1, value: char };
|
|
1886
2082
|
}
|
|
1887
|
-
const
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
defined: new CatalogEntries(),
|
|
1891
|
-
isWorkspaceRoot: false
|
|
2083
|
+
const endsWord = (text, index) => {
|
|
2084
|
+
const char = text[index];
|
|
2085
|
+
return WORD_BREAKS.has(char) || COMMAND_SEPARATORS.has(char) || isLineContinuation(text, index);
|
|
1892
2086
|
};
|
|
2087
|
+
function readWord(text, start) {
|
|
2088
|
+
let value = "";
|
|
2089
|
+
let index = start;
|
|
2090
|
+
while (index < text.length && !endsWord(text, index)) {
|
|
2091
|
+
const part = wordPart(text, index);
|
|
2092
|
+
value += part.value;
|
|
2093
|
+
index = part.end;
|
|
2094
|
+
}
|
|
2095
|
+
return { start, end: index, value, raw: text.slice(start, index) };
|
|
2096
|
+
}
|
|
1893
2097
|
|
|
1894
|
-
const
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
2098
|
+
const ASSIGNMENT_RE$2 = /^([A-Za-z_][A-Za-z0-9_]*)=/;
|
|
2099
|
+
const DECLARATION_BUILTINS = /* @__PURE__ */ new Set([
|
|
2100
|
+
"export",
|
|
2101
|
+
"readonly",
|
|
2102
|
+
"local",
|
|
2103
|
+
"declare",
|
|
2104
|
+
"typeset"
|
|
1899
2105
|
]);
|
|
1900
|
-
|
|
1901
|
-
|
|
2106
|
+
const QUOTES$3 = /* @__PURE__ */ new Set(["'", '"']);
|
|
2107
|
+
const UNPLAIN_RE = /['"\\$`]/;
|
|
2108
|
+
function leadingAssignments(command) {
|
|
2109
|
+
const index = command.findIndex((word) => !ASSIGNMENT_RE$2.test(word.raw));
|
|
2110
|
+
return index === -1 ? command.length : index;
|
|
2111
|
+
}
|
|
2112
|
+
function shellAssignments(command) {
|
|
2113
|
+
const count = leadingAssignments(command);
|
|
2114
|
+
const isDeclaration = DECLARATION_BUILTINS.has(command[count]?.value ?? "");
|
|
2115
|
+
const words = [...command.slice(0, count), ...isDeclaration ? command.slice(count + 1) : []];
|
|
2116
|
+
return words.flatMap((word) => {
|
|
2117
|
+
const match = ASSIGNMENT_RE$2.exec(word.raw);
|
|
2118
|
+
const name = match?.[1];
|
|
2119
|
+
return name === void 0 ? [] : [{ name, value: word.value.slice(name.length + 1), word }];
|
|
2120
|
+
});
|
|
1902
2121
|
}
|
|
1903
|
-
|
|
1904
|
-
const
|
|
1905
|
-
const
|
|
1906
|
-
|
|
1907
|
-
[
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
2122
|
+
function assignmentValueText(assignment) {
|
|
2123
|
+
const at = assignment.name.length + 1;
|
|
2124
|
+
const raw = assignment.word.raw.slice(at);
|
|
2125
|
+
const start = assignment.word.start + at;
|
|
2126
|
+
const quote = raw[0] ?? "";
|
|
2127
|
+
if (QUOTES$3.has(quote)) {
|
|
2128
|
+
const isOneString = raw.length > 1 && raw.endsWith(quote) && wordPart(raw, 0).end === raw.length;
|
|
2129
|
+
return isOneString ? { text: raw.slice(1, -1), start: start + 1 } : void 0;
|
|
2130
|
+
}
|
|
2131
|
+
return UNPLAIN_RE.test(raw) ? void 0 : { text: raw, start };
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2134
|
+
const END_OF_OPTIONS = "--";
|
|
2135
|
+
const isOption$1 = (word) => word.value.startsWith("-") && word.value.length > 1;
|
|
2136
|
+
function skipAssignments(words, start) {
|
|
2137
|
+
let index = start;
|
|
2138
|
+
while (index < words.length && ASSIGNMENT_RE$2.test(words[index].raw)) {
|
|
2139
|
+
index++;
|
|
2140
|
+
}
|
|
2141
|
+
return index;
|
|
2142
|
+
}
|
|
2143
|
+
function matchingPrefix(entries, words, index) {
|
|
2144
|
+
return entries.find(
|
|
2145
|
+
(entry) => entry.words.every((name, offset) => words[index + offset]?.value === name)
|
|
2146
|
+
);
|
|
2147
|
+
}
|
|
2148
|
+
function inlineOptionPackage(word, launcher) {
|
|
2149
|
+
const equals = word.value.indexOf("=");
|
|
2150
|
+
const name = word.value.slice(0, equals);
|
|
2151
|
+
return launcher.packageOptions.has(name) ? { word, value: word.value.slice(equals + 1) } : void 0;
|
|
2152
|
+
}
|
|
2153
|
+
function launchedProgram(words, start, launcher, packages) {
|
|
2154
|
+
let index = start;
|
|
2155
|
+
while (index < words.length && isOption$1(words[index])) {
|
|
2156
|
+
const option = words[index++];
|
|
2157
|
+
if (option.value === END_OF_OPTIONS) {
|
|
2158
|
+
break;
|
|
2159
|
+
}
|
|
2160
|
+
const inline = option.value.includes("=") ? inlineOptionPackage(option, launcher) : void 0;
|
|
2161
|
+
if (inline !== void 0) {
|
|
2162
|
+
packages.push(inline);
|
|
2163
|
+
}
|
|
2164
|
+
const value = words[index];
|
|
2165
|
+
if (!option.value.includes("=") && launcher.valueOptions.has(option.value) && value) {
|
|
2166
|
+
if (launcher.packageOptions.has(option.value)) {
|
|
2167
|
+
packages.push({ word: value, value: value.value });
|
|
2168
|
+
}
|
|
2169
|
+
index++;
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
return index;
|
|
2173
|
+
}
|
|
2174
|
+
const installArguments = (words, start) => words.slice(start).filter((word) => !isOption$1(word)).map((word) => ({ word, value: word.value }));
|
|
2175
|
+
function commandRoles(words) {
|
|
2176
|
+
const packages = [];
|
|
2177
|
+
let index = skipAssignments(words, 0);
|
|
2178
|
+
while (index < words.length) {
|
|
2179
|
+
const installer = matchingPrefix(INSTALLERS, words, index);
|
|
2180
|
+
if (installer !== void 0) {
|
|
2181
|
+
packages.push(...installArguments(words, index + installer.words.length));
|
|
2182
|
+
return { program: void 0, packages };
|
|
2183
|
+
}
|
|
2184
|
+
const launcher = matchingPrefix(LAUNCHERS, words, index);
|
|
2185
|
+
if (launcher === void 0) {
|
|
2186
|
+
return { program: index, packages };
|
|
2187
|
+
}
|
|
2188
|
+
const start = index + launcher.words.length;
|
|
2189
|
+
const afterOptions = launchedProgram(words, start, launcher, packages);
|
|
2190
|
+
index = skipAssignments(words, afterOptions + launcher.operands);
|
|
2191
|
+
}
|
|
2192
|
+
return { program: void 0, packages };
|
|
2193
|
+
}
|
|
2194
|
+
|
|
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"];
|
|
1924
2225
|
const PNPM_SETTINGS_FIELD = "pnpm";
|
|
1925
2226
|
const OLD_PEER_DEPENDENTS = /* @__PURE__ */ new Map([
|
|
1926
2227
|
["swr-openapi", { peer: "openapi-fetch", range: ">=0.15" }]
|
|
@@ -1947,1443 +2248,1133 @@ function oldPackageInNodeModules(path) {
|
|
|
1947
2248
|
);
|
|
1948
2249
|
}
|
|
1949
2250
|
|
|
1950
|
-
|
|
1951
|
-
const
|
|
1952
|
-
|
|
1953
|
-
return
|
|
2251
|
+
function packageReference(value) {
|
|
2252
|
+
const bare = value.startsWith(NPM_SPECIFIER_PREFIX) ? value.slice(NPM_SPECIFIER_PREFIX.length) : value;
|
|
2253
|
+
const at = bare.indexOf("@", 1);
|
|
2254
|
+
return { name: at === -1 ? bare : bare.slice(0, at), isPinned: at !== -1 };
|
|
1954
2255
|
}
|
|
1955
|
-
function
|
|
1956
|
-
return
|
|
2256
|
+
function namesOldPackage(value) {
|
|
2257
|
+
return PACKAGE_RENAMES.has(packageReference(value).name) || oldPackageInNodeModules(value) !== void 0 || value.endsWith(`/${GENERATOR_COMMAND}`);
|
|
1957
2258
|
}
|
|
1958
|
-
function
|
|
1959
|
-
return
|
|
2259
|
+
function unmigratedWordFindings(words, handledOffsets, locate) {
|
|
2260
|
+
return words.filter((word) => !handledOffsets.has(word.start) && namesOldPackage(word.value)).map((word) => ({
|
|
2261
|
+
offset: word.start,
|
|
2262
|
+
manualStep: { kind: "old-name-in-command", location: locate(word.start), word: word.value }
|
|
2263
|
+
}));
|
|
1960
2264
|
}
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
case "map":
|
|
1968
|
-
return textEntries(node).flatMap(
|
|
1969
|
-
({ key, value }) => stringsBelow(value, [...path, key.value])
|
|
1970
|
-
);
|
|
1971
|
-
default:
|
|
1972
|
-
return [];
|
|
2265
|
+
|
|
2266
|
+
const RECIPE_PREFIX_RE$1 = /^[@+-]+(?=.)/;
|
|
2267
|
+
function withoutRecipePrefix(words) {
|
|
2268
|
+
const [first, ...rest] = words;
|
|
2269
|
+
if (first === void 0 || !RECIPE_PREFIX_RE$1.test(first.value)) {
|
|
2270
|
+
return words;
|
|
1973
2271
|
}
|
|
2272
|
+
return [{ ...first, value: first.value.replace(RECIPE_PREFIX_RE$1, "") }, ...rest];
|
|
1974
2273
|
}
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
}
|
|
1985
|
-
const position = offset === void 0 ? void 0 : { line: lineAt(text, offset), column: columnAt(text, offset) };
|
|
1986
|
-
return { ...unchanged(text), manualSteps: [{ kind: "config-unreadable", position }] };
|
|
2274
|
+
const NO_VARIABLES = {
|
|
2275
|
+
programAt: () => void 0,
|
|
2276
|
+
referenceAt: () => void 0
|
|
2277
|
+
};
|
|
2278
|
+
function runsGenerator(command) {
|
|
2279
|
+
const words = withoutRecipePrefix(command);
|
|
2280
|
+
const { program } = commandRoles(words);
|
|
2281
|
+
const word = program === void 0 ? void 0 : words[program];
|
|
2282
|
+
return word !== void 0 && packageReference(word.value).name === GENERATOR_COMMAND;
|
|
1987
2283
|
}
|
|
1988
2284
|
|
|
1989
|
-
const
|
|
1990
|
-
const
|
|
1991
|
-
const
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
2285
|
+
const HEREDOC_OPERATOR = "<<";
|
|
2286
|
+
const HERE_STRING_OPERATOR = "<<<";
|
|
2287
|
+
const STRIP_TABS = "-";
|
|
2288
|
+
const LINE_BREAK$2 = "\n";
|
|
2289
|
+
const LEADING_TABS_RE = /^\t+/;
|
|
2290
|
+
const CARRIAGE_RETURN_RE = /\r$/;
|
|
2291
|
+
function heredocAt(text, index, where) {
|
|
2292
|
+
if (text.startsWith(HERE_STRING_OPERATOR, index)) {
|
|
2293
|
+
return { end: index + HERE_STRING_OPERATOR.length };
|
|
2294
|
+
}
|
|
2295
|
+
if (!text.startsWith(HEREDOC_OPERATOR, index)) {
|
|
2296
|
+
return void 0;
|
|
2297
|
+
}
|
|
2298
|
+
let start = index + HEREDOC_OPERATOR.length;
|
|
2299
|
+
const isTabStripped = text[start] === STRIP_TABS;
|
|
2300
|
+
start += isTabStripped ? 1 : 0;
|
|
2301
|
+
while (text[start] === " " || text[start] === " ") {
|
|
2302
|
+
start++;
|
|
2303
|
+
}
|
|
2304
|
+
const word = readWord(text, start);
|
|
2305
|
+
const pending = { delimiter: word.value, isTabStripped, ...where };
|
|
2306
|
+
return word.value === "" ? void 0 : { pending, end: word.end };
|
|
1999
2307
|
}
|
|
2000
|
-
function
|
|
2001
|
-
|
|
2002
|
-
|
|
2308
|
+
function isDelimiterLine(text, lineStart, end, heredoc) {
|
|
2309
|
+
let first = lineStart;
|
|
2310
|
+
while (first < lineStart + heredoc.indent && text[first] === " ") {
|
|
2311
|
+
first++;
|
|
2312
|
+
}
|
|
2313
|
+
const line = text.slice(first, end).replace(CARRIAGE_RETURN_RE, "");
|
|
2314
|
+
const compared = heredoc.isTabStripped ? line.replace(LEADING_TABS_RE, "") : line;
|
|
2315
|
+
return compared === heredoc.delimiter;
|
|
2003
2316
|
}
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
}
|
|
2011
|
-
|
|
2012
|
-
return textEntries(map).flatMap(({ key, value }) => {
|
|
2013
|
-
if (!isEditable(key)) {
|
|
2014
|
-
return [];
|
|
2317
|
+
function readBody(text, start, heredoc) {
|
|
2318
|
+
let lineStart = start;
|
|
2319
|
+
while (lineStart < text.length) {
|
|
2320
|
+
const lineEnd = text.indexOf(LINE_BREAK$2, lineStart);
|
|
2321
|
+
const end = lineEnd === -1 ? text.length : lineEnd;
|
|
2322
|
+
if (isDelimiterLine(text, lineStart, end, heredoc)) {
|
|
2323
|
+
const body = { command: heredoc.command, start, text: text.slice(start, lineStart) };
|
|
2324
|
+
return { body, end: Math.min(end + 1, text.length) };
|
|
2015
2325
|
}
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
}
|
|
2019
|
-
}
|
|
2020
|
-
function keyEntries(map) {
|
|
2021
|
-
return textEntries(map).map(({ key }) => key).filter(isEditable).map((key) => ({ name: key.value, rename: (name) => replaceScalar(key, name) }));
|
|
2022
|
-
}
|
|
2023
|
-
function itemEntries(list) {
|
|
2024
|
-
return list.items.filter(isEditable).map((item) => ({ name: item.value, rename: (name) => replaceScalar(item, name) }));
|
|
2326
|
+
lineStart = end + 1;
|
|
2327
|
+
}
|
|
2328
|
+
return { body: { command: heredoc.command, start, text: text.slice(start) }, end: text.length };
|
|
2025
2329
|
}
|
|
2026
|
-
function
|
|
2027
|
-
|
|
2028
|
-
|
|
2330
|
+
function readBodies(text, start, pending) {
|
|
2331
|
+
const bodies = [];
|
|
2332
|
+
let end = start;
|
|
2333
|
+
for (const heredoc of pending) {
|
|
2334
|
+
const read = readBody(text, end, heredoc);
|
|
2335
|
+
bodies.push(read.body);
|
|
2336
|
+
end = read.end;
|
|
2029
2337
|
}
|
|
2030
|
-
return
|
|
2338
|
+
return { bodies, end };
|
|
2031
2339
|
}
|
|
2032
2340
|
|
|
2033
|
-
const
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
}));
|
|
2040
|
-
for (const catalogs of mapsAt(root, NAMED_CATALOGS_FIELD)) {
|
|
2041
|
-
for (const { key, value } of textEntries(catalogs)) {
|
|
2042
|
-
if (isMap(value)) {
|
|
2043
|
-
const label = [prefix + NAMED_CATALOGS_FIELD, key.value].join(PATH_SEPARATOR$7);
|
|
2044
|
-
maps.push({ name: key.value, label, map: value });
|
|
2045
|
-
}
|
|
2046
|
-
}
|
|
2341
|
+
const COMMENT = "#";
|
|
2342
|
+
const LINE_BREAK$1 = "\n";
|
|
2343
|
+
function skipTrivia(text, index) {
|
|
2344
|
+
const char = text[index];
|
|
2345
|
+
if (WORD_BREAKS.has(char)) {
|
|
2346
|
+
return index + 1;
|
|
2047
2347
|
}
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2348
|
+
if (isLineContinuation(text, index)) {
|
|
2349
|
+
return text.indexOf("\n", index) + 1;
|
|
2350
|
+
}
|
|
2351
|
+
if (char === COMMENT) {
|
|
2352
|
+
const lineEnd = text.indexOf("\n", index);
|
|
2353
|
+
return lineEnd === -1 ? text.length : lineEnd;
|
|
2354
|
+
}
|
|
2355
|
+
return index;
|
|
2356
|
+
}
|
|
2357
|
+
const PIPE = "|";
|
|
2358
|
+
function topLevelCommands(text, indent) {
|
|
2359
|
+
const commands = [[]];
|
|
2360
|
+
const heredocs = [];
|
|
2361
|
+
const pipes = /* @__PURE__ */ new Set();
|
|
2362
|
+
let pending = [];
|
|
2363
|
+
let index = 0;
|
|
2364
|
+
while (index < text.length) {
|
|
2365
|
+
const afterTrivia = skipTrivia(text, index);
|
|
2366
|
+
const heredoc = heredocAt(text, index, { command: commands.length - 1, indent });
|
|
2367
|
+
if (heredoc !== void 0) {
|
|
2368
|
+
pending.push(...heredoc.pending === void 0 ? [] : [heredoc.pending]);
|
|
2369
|
+
index = heredoc.end;
|
|
2370
|
+
} else if (afterTrivia !== index) {
|
|
2371
|
+
index = afterTrivia;
|
|
2372
|
+
} else if (text[index] === LINE_BREAK$1 && pending.length > 0) {
|
|
2373
|
+
const read = readBodies(text, index + 1, pending);
|
|
2374
|
+
heredocs.push(...read.bodies);
|
|
2375
|
+
pending = [];
|
|
2376
|
+
commands.push([]);
|
|
2377
|
+
index = read.end;
|
|
2378
|
+
} else if (COMMAND_SEPARATORS.has(text[index])) {
|
|
2379
|
+
if (text[index] === PIPE) {
|
|
2380
|
+
pipes.add(commands.length - 1);
|
|
2069
2381
|
}
|
|
2382
|
+
commands.push([]);
|
|
2383
|
+
index++;
|
|
2384
|
+
} else {
|
|
2385
|
+
const word = readWord(text, index);
|
|
2386
|
+
commands.at(-1)?.push(word);
|
|
2387
|
+
index = word.end;
|
|
2070
2388
|
}
|
|
2071
2389
|
}
|
|
2072
|
-
return
|
|
2390
|
+
return { commands, heredocs, pipes };
|
|
2073
2391
|
}
|
|
2074
|
-
|
|
2075
|
-
if
|
|
2076
|
-
|
|
2392
|
+
const COMMAND_PREFIX_WORDS = /* @__PURE__ */ new Set([
|
|
2393
|
+
"if",
|
|
2394
|
+
"then",
|
|
2395
|
+
"elif",
|
|
2396
|
+
"else",
|
|
2397
|
+
"fi",
|
|
2398
|
+
"while",
|
|
2399
|
+
"until",
|
|
2400
|
+
"do",
|
|
2401
|
+
"done",
|
|
2402
|
+
"!",
|
|
2403
|
+
"{",
|
|
2404
|
+
"}",
|
|
2405
|
+
"esac"
|
|
2406
|
+
]);
|
|
2407
|
+
const CLAUSE_WORDS = /* @__PURE__ */ new Set(["for", "select", "case", "[["]);
|
|
2408
|
+
const FUNCTION_WORD = "function";
|
|
2409
|
+
const FUNCTION_HEADER_LENGTH = 2;
|
|
2410
|
+
const isReserved = (word, words) => word !== void 0 && word.raw === word.value && words.has(word.value);
|
|
2411
|
+
function prefixLength(words, index) {
|
|
2412
|
+
if (isReserved(words[index], COMMAND_PREFIX_WORDS)) {
|
|
2413
|
+
return 1;
|
|
2077
2414
|
}
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
);
|
|
2415
|
+
const word = words[index];
|
|
2416
|
+
return word?.raw === FUNCTION_WORD ? FUNCTION_HEADER_LENGTH : 0;
|
|
2081
2417
|
}
|
|
2082
|
-
function
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
for (const { key, value } of sections.flatMap(nestedTexts)) {
|
|
2087
|
-
const catalog = catalogOfSpec(value);
|
|
2088
|
-
const name = overrideTarget(key);
|
|
2089
|
-
if (catalog !== void 0 && PACKAGE_RENAMES.has(name)) {
|
|
2090
|
-
inUse.add(catalog, name);
|
|
2091
|
-
}
|
|
2418
|
+
function simpleCommand(words) {
|
|
2419
|
+
let first = 0;
|
|
2420
|
+
for (let length = prefixLength(words, 0); length > 0; length = prefixLength(words, first)) {
|
|
2421
|
+
first += length;
|
|
2092
2422
|
}
|
|
2423
|
+
return isReserved(words[first], CLAUSE_WORDS) ? [] : words.slice(first);
|
|
2093
2424
|
}
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
const to = PACKAGE_RENAMES.get(name);
|
|
2113
|
-
const stays = spec === void 0 || inUse.has(catalog, name);
|
|
2114
|
-
if (to !== void 0 && !names.has(to) && stays) {
|
|
2115
|
-
kept.add(catalog, name);
|
|
2116
|
-
}
|
|
2117
|
-
}
|
|
2425
|
+
const QUOTES$2 = /* @__PURE__ */ new Set(["'", '"']);
|
|
2426
|
+
const NESTED_COMMAND_RE = /[\s;&|()`]/;
|
|
2427
|
+
function nestedCommandText(word) {
|
|
2428
|
+
const quote = word.raw[0];
|
|
2429
|
+
const isOneQuotedString = QUOTES$2.has(quote) && word.raw.length > 1 && word.raw.endsWith(quote) && wordPart(word.raw, 0).end === word.raw.length;
|
|
2430
|
+
return isOneQuotedString && NESTED_COMMAND_RE.test(word.value) ? word.raw.slice(1, -1) : void 0;
|
|
2431
|
+
}
|
|
2432
|
+
const SHELLS$1 = /* @__PURE__ */ new Set(["sh", "bash", "dash", "ash", "zsh", "ksh"]);
|
|
2433
|
+
const DOCKER_RUN = "RUN";
|
|
2434
|
+
const PASS_THROUGH = "cat";
|
|
2435
|
+
const PATH_SEPARATOR$8 = "/";
|
|
2436
|
+
const OPTION_PREFIX$1 = "-";
|
|
2437
|
+
const programName = (command) => command[0]?.value.split(PATH_SEPARATOR$8).at(-1) ?? "";
|
|
2438
|
+
const isOption = (word) => word.value.startsWith(OPTION_PREFIX$1);
|
|
2439
|
+
const isScriptShell = (command) => SHELLS$1.has(programName(command)) && command.slice(1).every(isOption);
|
|
2440
|
+
function readsScript(command) {
|
|
2441
|
+
if (programName(command) !== DOCKER_RUN) {
|
|
2442
|
+
return isScriptShell(command);
|
|
2118
2443
|
}
|
|
2119
|
-
|
|
2444
|
+
const after = command.slice(1);
|
|
2445
|
+
const shell = after.slice(after.findIndex((word) => !isOption(word)));
|
|
2446
|
+
return after.every(isOption) || isScriptShell(shell);
|
|
2120
2447
|
}
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
]);
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
);
|
|
2128
|
-
const PATH_SEPARATOR$6 = "/";
|
|
2129
|
-
function namesUninstalledPackage(text) {
|
|
2130
|
-
return [...NO_LONGER_INSTALLED.keys()].some(
|
|
2131
|
-
(name) => text.includes(name) || text.includes(ORIGINAL_NAMES.get(name) ?? name)
|
|
2448
|
+
const passesThrough = (command) => programName(command) === PASS_THROUGH && command.slice(1).every(isOption);
|
|
2449
|
+
function scriptsRunBy(top, index, command) {
|
|
2450
|
+
const previous = index - 1;
|
|
2451
|
+
const isPipedScript = top.pipes.has(previous) && isScriptShell(command) && passesThrough(simpleCommand(top.commands[previous] ?? []));
|
|
2452
|
+
return top.heredocs.filter(
|
|
2453
|
+
(body) => body.command === index && readsScript(command) || body.command === previous && isPipedScript
|
|
2132
2454
|
);
|
|
2133
2455
|
}
|
|
2134
|
-
const
|
|
2135
|
-
function
|
|
2136
|
-
return
|
|
2137
|
-
}
|
|
2138
|
-
function isDeclaredFor(manifests, filePath, name) {
|
|
2139
|
-
const original = ORIGINAL_NAMES.get(name);
|
|
2140
|
-
const containing = manifests.filter(({ path }) => filePath.startsWith(directoryOf(path)));
|
|
2141
|
-
const declares = ({ names }) => names === void 0 || names.has(name) || original !== void 0 && names.has(original);
|
|
2142
|
-
return containing.length === 0 || containing.some(declares);
|
|
2456
|
+
const shifted = (words, offset) => words.map((word) => ({ ...word, start: word.start + offset, end: word.end + offset }));
|
|
2457
|
+
function shellCommandsAt(text, offset, indent = 0) {
|
|
2458
|
+
return shellCommands(text, indent).map((words) => shifted(words, offset));
|
|
2143
2459
|
}
|
|
2144
|
-
|
|
2145
|
-
const
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
function undeclaredImportSteps(imports, filePath, manifests) {
|
|
2149
|
-
return imports.flatMap(({ specifier, line }) => {
|
|
2150
|
-
const name = packageOfSpecifier(specifier);
|
|
2151
|
-
const installers = NO_LONGER_INSTALLED.get(name);
|
|
2152
|
-
return installers === void 0 || isDeclaredFor(manifests, filePath, name) ? [] : [{ kind: "package-not-declared", line, name, installers }];
|
|
2460
|
+
function innerCommands(command) {
|
|
2461
|
+
const quoted = command.flatMap((word) => {
|
|
2462
|
+
const inner = nestedCommandText(word);
|
|
2463
|
+
return inner === void 0 ? [] : shellCommandsAt(inner, word.start + 1);
|
|
2153
2464
|
});
|
|
2465
|
+
const assigned = shellAssignments(command).flatMap((assignment) => {
|
|
2466
|
+
const value = assignmentValueText(assignment);
|
|
2467
|
+
return value === void 0 ? [] : shellCommandsAt(value.text, value.start);
|
|
2468
|
+
});
|
|
2469
|
+
return [...quoted, ...assigned];
|
|
2470
|
+
}
|
|
2471
|
+
function shellCommands(text, indent = 0) {
|
|
2472
|
+
const top = topLevelCommands(text, indent);
|
|
2473
|
+
const commands = [];
|
|
2474
|
+
for (const [index, words] of top.commands.entries()) {
|
|
2475
|
+
const command = simpleCommand(words);
|
|
2476
|
+
if (command.length > 0) {
|
|
2477
|
+
commands.push(command);
|
|
2478
|
+
}
|
|
2479
|
+
commands.push(...innerCommands(command));
|
|
2480
|
+
const scripts = scriptsRunBy(top, index, command);
|
|
2481
|
+
commands.push(...scripts.flatMap((body) => shellCommandsAt(body.text, body.start, indent)));
|
|
2482
|
+
}
|
|
2483
|
+
return commands;
|
|
2154
2484
|
}
|
|
2155
2485
|
|
|
2156
2486
|
function assertNever(value) {
|
|
2157
2487
|
throw new Error(`Unexpected variant: ${JSON.stringify(value)}`);
|
|
2158
2488
|
}
|
|
2159
2489
|
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
);
|
|
2171
|
-
const NUMBER_RE = /^\d+$/;
|
|
2172
|
-
const OPERATOR_STYLES = {
|
|
2173
|
-
"^": "^",
|
|
2174
|
-
// `>=` means "this or newer"; with a new package line, a caret range says the same safely.
|
|
2175
|
-
">=": "^",
|
|
2176
|
-
">": "^",
|
|
2177
|
-
"~": "~",
|
|
2178
|
-
"~>": "~"
|
|
2179
|
-
};
|
|
2180
|
-
const isNumber = (part) => part !== void 0 && NUMBER_RE.test(part);
|
|
2181
|
-
function versionStyle(major, minor, patch) {
|
|
2182
|
-
if (!isNumber(major)) {
|
|
2183
|
-
return void 0;
|
|
2184
|
-
}
|
|
2185
|
-
if (isNumber(minor) && isNumber(patch)) {
|
|
2186
|
-
return "";
|
|
2490
|
+
function canRunGenerator(definition, generators) {
|
|
2491
|
+
switch (definition.kind) {
|
|
2492
|
+
case "command":
|
|
2493
|
+
return definition.runsGenerator;
|
|
2494
|
+
case "reference":
|
|
2495
|
+
return generators.has(definition.target);
|
|
2496
|
+
case "append":
|
|
2497
|
+
return false;
|
|
2498
|
+
default:
|
|
2499
|
+
return assertNever(definition);
|
|
2187
2500
|
}
|
|
2188
|
-
return isNumber(minor) ? "~" : "^";
|
|
2189
2501
|
}
|
|
2190
|
-
function
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2502
|
+
function canRunOther(definition, others, defined) {
|
|
2503
|
+
switch (definition.kind) {
|
|
2504
|
+
case "command":
|
|
2505
|
+
return !definition.runsGenerator;
|
|
2506
|
+
case "reference":
|
|
2507
|
+
return others.has(definition.target) || !defined.has(definition.target);
|
|
2508
|
+
case "append":
|
|
2509
|
+
return false;
|
|
2510
|
+
default:
|
|
2511
|
+
return assertNever(definition);
|
|
2198
2512
|
}
|
|
2199
|
-
const operator = first[1];
|
|
2200
|
-
const isHyphenRange = tokens[0]?.[1] === HYPHEN;
|
|
2201
|
-
if (operator !== void 0 && operator !== "=") {
|
|
2202
|
-
return OPERATOR_STYLES[operator];
|
|
2203
|
-
}
|
|
2204
|
-
return isHyphenRange ? "^" : versionStyle(first[2], first[3], first[4]);
|
|
2205
2513
|
}
|
|
2206
|
-
function
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2514
|
+
function variablePrograms(definitions) {
|
|
2515
|
+
const defined = new Set(definitions.map((definition) => definition.name));
|
|
2516
|
+
const generators = /* @__PURE__ */ new Set();
|
|
2517
|
+
const others = /* @__PURE__ */ new Set();
|
|
2518
|
+
for (let size = -1; size !== generators.size + others.size; ) {
|
|
2519
|
+
size = generators.size + others.size;
|
|
2520
|
+
for (const definition of definitions) {
|
|
2521
|
+
if (canRunGenerator(definition, generators)) {
|
|
2522
|
+
generators.add(definition.name);
|
|
2523
|
+
}
|
|
2524
|
+
if (canRunOther(definition, others, defined)) {
|
|
2525
|
+
others.add(definition.name);
|
|
2526
|
+
}
|
|
2527
|
+
}
|
|
2213
2528
|
}
|
|
2214
|
-
|
|
2529
|
+
const programOf = (name) => {
|
|
2530
|
+
if (!generators.has(name)) {
|
|
2531
|
+
return "other";
|
|
2532
|
+
}
|
|
2533
|
+
return others.has(name) ? "generator-or-other" : "generator";
|
|
2534
|
+
};
|
|
2535
|
+
return new Map([...defined].map((name) => [name, programOf(name)]));
|
|
2215
2536
|
}
|
|
2216
2537
|
|
|
2217
|
-
const
|
|
2218
|
-
|
|
2219
|
-
const
|
|
2220
|
-
|
|
2221
|
-
function nameEnd(text) {
|
|
2222
|
-
const searchFrom = text.startsWith(SCOPE_PREFIX$1) ? text.indexOf(PATH_SEPARATOR$5) + 1 : 0;
|
|
2223
|
-
const ends = [VERSION_SEPARATOR, PATH_SEPARATOR$5].map((separator) => text.indexOf(separator, Math.max(searchFrom, 1))).filter((index) => index !== -1);
|
|
2224
|
-
return ends.length === 0 ? text.length : Math.min(...ends);
|
|
2538
|
+
const SHELL_VARIABLE_RE = /^"?\$(?:([A-Za-z_][A-Za-z0-9_]*)|\{([A-Za-z_][A-Za-z0-9_]*)\})"?$/;
|
|
2539
|
+
function expandedName(text) {
|
|
2540
|
+
const match = SHELL_VARIABLE_RE.exec(text);
|
|
2541
|
+
return match === null ? void 0 : match[1] ?? match[2];
|
|
2225
2542
|
}
|
|
2226
|
-
function
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
const body = spec.slice(NPM_PROTOCOL.length);
|
|
2231
|
-
const lead = body.startsWith(PATH_SEPARATOR$5) ? PATH_SEPARATOR$5 : "";
|
|
2232
|
-
const text = body.slice(lead.length);
|
|
2233
|
-
const end = nameEnd(text);
|
|
2234
|
-
const name = text.slice(0, end);
|
|
2235
|
-
if (!text.startsWith(VERSION_SEPARATOR, end)) {
|
|
2236
|
-
return { lead, name, range: void 0, rest: text.slice(end) };
|
|
2543
|
+
function programDefinition$1({ name, value }) {
|
|
2544
|
+
const target = expandedName(value.trim());
|
|
2545
|
+
if (target !== void 0) {
|
|
2546
|
+
return { name, kind: "reference", target };
|
|
2237
2547
|
}
|
|
2238
|
-
|
|
2239
|
-
const restStart = rangeEnd === -1 ? text.length : rangeEnd;
|
|
2240
|
-
return { lead, name, range: text.slice(end + 1, restStart), rest: text.slice(restStart) };
|
|
2241
|
-
}
|
|
2242
|
-
function isOldPackageNpmSpec(spec) {
|
|
2243
|
-
const parsed = parseNpmSpec(spec);
|
|
2244
|
-
return parsed !== void 0 && PACKAGE_RENAMES.has(parsed.name);
|
|
2548
|
+
return { name, kind: "command", runsGenerator: shellCommands(value).some(runsGenerator) };
|
|
2245
2549
|
}
|
|
2246
|
-
function
|
|
2247
|
-
const
|
|
2248
|
-
const
|
|
2249
|
-
|
|
2250
|
-
return void 0;
|
|
2251
|
-
}
|
|
2252
|
-
const head = `${NPM_PROTOCOL}${parsed.lead}${renamed}`;
|
|
2253
|
-
const isDeep = parsed.rest !== "" && parsed.rest !== PATH_SEPARATOR$5;
|
|
2254
|
-
if (parsed.range === void 0) {
|
|
2255
|
-
return { spec: `${head}${parsed.rest}`, isReported: false, isDeep };
|
|
2550
|
+
function shellVariables(definitions) {
|
|
2551
|
+
const values = /* @__PURE__ */ new Map();
|
|
2552
|
+
for (const { name, value } of definitions) {
|
|
2553
|
+
values.set(name, [values.get(name), value].filter((part) => part !== void 0).join(" "));
|
|
2256
2554
|
}
|
|
2257
|
-
const
|
|
2258
|
-
const
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
const
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
let end = start;
|
|
2270
|
-
for (; end < text.length && !AUTHORITY_END_RE.test(text.charAt(end)); end++) {
|
|
2271
|
-
if (text.charAt(end) === USERINFO_END) {
|
|
2272
|
-
userinfoEnd = end;
|
|
2555
|
+
const programs = variablePrograms(definitions.map(programDefinition$1));
|
|
2556
|
+
const nameAt = (word) => expandedName(word.raw);
|
|
2557
|
+
return {
|
|
2558
|
+
programAt: (program) => {
|
|
2559
|
+
const name = nameAt(program);
|
|
2560
|
+
const found = name === void 0 ? void 0 : programs.get(name);
|
|
2561
|
+
return found === void 0 ? void 0 : { written: program.raw, program: found };
|
|
2562
|
+
},
|
|
2563
|
+
referenceAt: (word) => {
|
|
2564
|
+
const name = nameAt(word);
|
|
2565
|
+
const value = name === void 0 ? void 0 : values.get(name);
|
|
2566
|
+
return value === void 0 ? void 0 : { written: word.raw, value };
|
|
2273
2567
|
}
|
|
2274
|
-
}
|
|
2275
|
-
return { end, userinfoEnd };
|
|
2568
|
+
};
|
|
2276
2569
|
}
|
|
2277
|
-
function
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
for (let found = text.indexOf(SCHEME_SEPARATOR); found !== -1; ) {
|
|
2281
|
-
const start = found + SCHEME_SEPARATOR.length;
|
|
2282
|
-
const { end, userinfoEnd } = scanAuthority(text, start);
|
|
2283
|
-
if (userinfoEnd !== -1) {
|
|
2284
|
-
hidden += `${text.slice(copiedUpTo, start)}${HIDDEN_USERINFO}`;
|
|
2285
|
-
copiedUpTo = userinfoEnd;
|
|
2286
|
-
}
|
|
2287
|
-
found = text.indexOf(SCHEME_SEPARATOR, end);
|
|
2570
|
+
function combinedUse(left, right) {
|
|
2571
|
+
if (left === void 0 || right === void 0) {
|
|
2572
|
+
return left ?? right;
|
|
2288
2573
|
}
|
|
2289
|
-
return
|
|
2574
|
+
return left.program === right.program ? left : { ...left, program: "generator-or-other" };
|
|
2290
2575
|
}
|
|
2291
|
-
|
|
2292
|
-
const
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
const renamedKey = (name, map) => map.kind === "imports" ? renamedSpecifier(name)?.to : PACKAGE_RENAMES.get(name);
|
|
2296
|
-
function migrateSpec(spec, version) {
|
|
2297
|
-
const npm = migrateNpmSpec(spec, version);
|
|
2298
|
-
if (npm !== void 0) {
|
|
2299
|
-
return { spec: npm.spec, isReported: npm.isReported };
|
|
2576
|
+
function withShellAssignments(commands, file) {
|
|
2577
|
+
const definitions = commands.flatMap(shellAssignments);
|
|
2578
|
+
if (definitions.length === 0) {
|
|
2579
|
+
return file;
|
|
2300
2580
|
}
|
|
2301
|
-
const
|
|
2302
|
-
return {
|
|
2581
|
+
const own = shellVariables(definitions);
|
|
2582
|
+
return {
|
|
2583
|
+
programAt: (program) => combinedUse(own.programAt(program), file.programAt(program)),
|
|
2584
|
+
referenceAt: (word) => own.referenceAt(word) ?? file.referenceAt(word)
|
|
2585
|
+
};
|
|
2303
2586
|
}
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2587
|
+
|
|
2588
|
+
const QUOTES$1 = /* @__PURE__ */ new Set(["'", '"']);
|
|
2589
|
+
const PATH_SEPARATOR$7 = "/";
|
|
2590
|
+
const BIN_FOLDER = "/.bin/";
|
|
2591
|
+
const OLD_PACKAGE_FOLDER = `node_modules/${GENERATOR_COMMAND}/`;
|
|
2592
|
+
function renameAtEnd(word, name, to) {
|
|
2593
|
+
const at = word.raw.lastIndexOf(name);
|
|
2594
|
+
const tail = word.raw.slice(at + name.length);
|
|
2595
|
+
if (at === -1 || tail !== "" && !QUOTES$1.has(tail)) {
|
|
2596
|
+
return void 0;
|
|
2308
2597
|
}
|
|
2309
|
-
return
|
|
2598
|
+
return { start: word.start + at, end: word.start + at + name.length, text: to };
|
|
2310
2599
|
}
|
|
2311
|
-
function
|
|
2312
|
-
const
|
|
2313
|
-
|
|
2314
|
-
|
|
2600
|
+
function packageFindings(found, locate) {
|
|
2601
|
+
const { name, isPinned } = packageReference(found.value);
|
|
2602
|
+
const to = PACKAGE_RENAMES.get(name);
|
|
2603
|
+
const offset = found.word.start;
|
|
2604
|
+
if (to === void 0) {
|
|
2605
|
+
return [];
|
|
2315
2606
|
}
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
if (migrated.isReported) {
|
|
2320
|
-
findings.manualSteps.push({ kind: "spec-kept", name: entry.name, spec });
|
|
2607
|
+
const location = locate(offset);
|
|
2608
|
+
if (isPinned) {
|
|
2609
|
+
return [{ offset, manualStep: { kind: "pinned-package", location, name } }];
|
|
2321
2610
|
}
|
|
2611
|
+
const edit = renameAtEnd(found.word, name, to);
|
|
2612
|
+
const change = { kind: "package-name-renamed", location, from: name, to };
|
|
2613
|
+
return edit === void 0 ? [] : [{ offset, edit, change }];
|
|
2322
2614
|
}
|
|
2323
|
-
function
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
case "catalog":
|
|
2328
|
-
return { kind: "catalog-entry-renamed", catalog: map.catalog, from, to, spec };
|
|
2329
|
-
case "imports":
|
|
2330
|
-
return { kind: "import-renamed", field: map.field, from, to, target: spec };
|
|
2331
|
-
default:
|
|
2332
|
-
return assertNever(map);
|
|
2615
|
+
function programPathFindings(word, location) {
|
|
2616
|
+
const offset = word.start;
|
|
2617
|
+
if (word.value.includes(OLD_PACKAGE_FOLDER)) {
|
|
2618
|
+
return [{ offset, manualStep: { kind: "old-package-file", location, path: word.value } }];
|
|
2333
2619
|
}
|
|
2620
|
+
const isBin = word.value.endsWith(`${BIN_FOLDER}${GENERATOR_COMMAND}`);
|
|
2621
|
+
const edit = isBin ? renameAtEnd(word, GENERATOR_COMMAND, MIGRATED_GENERATOR_COMMAND) : void 0;
|
|
2622
|
+
return edit === void 0 ? [] : [{ offset, edit, change: { kind: "command-renamed", location } }];
|
|
2334
2623
|
}
|
|
2335
|
-
function
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
findings.edits.push(entry.renameKey(to));
|
|
2339
|
-
if (migrated.spec !== old) {
|
|
2340
|
-
findings.edits.push(spec.replace(migrated.spec));
|
|
2624
|
+
function programFindings(word, location) {
|
|
2625
|
+
if (word.value.includes(PATH_SEPARATOR$7)) {
|
|
2626
|
+
return programPathFindings(word, location);
|
|
2341
2627
|
}
|
|
2342
|
-
|
|
2343
|
-
if (
|
|
2344
|
-
|
|
2628
|
+
const { name, isPinned } = packageReference(word.value);
|
|
2629
|
+
if (name !== GENERATOR_COMMAND) {
|
|
2630
|
+
return [];
|
|
2345
2631
|
}
|
|
2346
|
-
if (
|
|
2347
|
-
|
|
2632
|
+
if (isPinned) {
|
|
2633
|
+
return [{ offset: word.start, manualStep: { kind: "versioned-command", location } }];
|
|
2348
2634
|
}
|
|
2635
|
+
const edit = renameAtEnd(word, GENERATOR_COMMAND, MIGRATED_GENERATOR_COMMAND);
|
|
2636
|
+
const change = { kind: "command-renamed", location };
|
|
2637
|
+
return edit === void 0 ? [] : [{ offset: word.start, edit, change }];
|
|
2349
2638
|
}
|
|
2350
|
-
function
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2639
|
+
function flagFindings(word, locate) {
|
|
2640
|
+
const flag = word.raw.split("=", 1)[0];
|
|
2641
|
+
const to = FLAG_RENAMES.get(flag);
|
|
2642
|
+
if (to === void 0) {
|
|
2643
|
+
return [];
|
|
2354
2644
|
}
|
|
2355
|
-
const
|
|
2356
|
-
|
|
2357
|
-
|
|
2645
|
+
const offset = word.start;
|
|
2646
|
+
const edit = { start: offset, end: offset + flag.length, text: to };
|
|
2647
|
+
return [
|
|
2648
|
+
{ offset, edit, change: { kind: "flag-renamed", location: locate(offset), from: flag, to } }
|
|
2649
|
+
];
|
|
2650
|
+
}
|
|
2651
|
+
function renamedFlags(value) {
|
|
2652
|
+
const flags = shellCommands(value).flat().map((word) => word.raw.split("=", 1)[0]);
|
|
2653
|
+
return [...new Set(flags.filter((flag) => FLAG_RENAMES.has(flag)))];
|
|
2654
|
+
}
|
|
2655
|
+
function argumentFindings(word, locate, variables) {
|
|
2656
|
+
const reference = variables.referenceAt(word);
|
|
2657
|
+
if (reference === void 0) {
|
|
2658
|
+
return flagFindings(word, locate);
|
|
2358
2659
|
}
|
|
2359
|
-
const
|
|
2360
|
-
if (
|
|
2361
|
-
|
|
2362
|
-
return { kind, ...reference };
|
|
2660
|
+
const flags = renamedFlags(reference.value);
|
|
2661
|
+
if (flags.length === 0) {
|
|
2662
|
+
return [];
|
|
2363
2663
|
}
|
|
2364
|
-
|
|
2664
|
+
const manualStep = {
|
|
2665
|
+
kind: "flags-in-variable",
|
|
2666
|
+
location: locate(word.start),
|
|
2667
|
+
variable: reference.written,
|
|
2668
|
+
flags
|
|
2669
|
+
};
|
|
2670
|
+
return [{ offset: word.start, manualStep }];
|
|
2365
2671
|
}
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
const to = renamedKey(entry.name, context.map);
|
|
2370
|
-
const field = mapLabel(context.map);
|
|
2371
|
-
if (to === void 0) {
|
|
2372
|
-
migrateAlias(entry, context);
|
|
2373
|
-
continue;
|
|
2374
|
-
}
|
|
2375
|
-
if (!isFree({ from: entry.name, to, field, names }, context.findings)) {
|
|
2376
|
-
continue;
|
|
2377
|
-
}
|
|
2378
|
-
const hold = entry.spec === void 0 ? void 0 : catalogHold(entry, entry.spec, context);
|
|
2379
|
-
if (entry.spec === void 0) {
|
|
2380
|
-
context.findings.manualSteps.push({ kind: "entry-not-edited", field, name: entry.name });
|
|
2381
|
-
} else if (hold !== void 0) {
|
|
2382
|
-
context.findings.manualSteps.push(hold);
|
|
2383
|
-
} else {
|
|
2384
|
-
migrateEntry(entry, entry.spec, to, context);
|
|
2385
|
-
}
|
|
2386
|
-
}
|
|
2387
|
-
}
|
|
2388
|
-
function renameNames(entries, field, findings) {
|
|
2389
|
-
const names = new Set(entries.map((entry) => entry.name));
|
|
2390
|
-
for (const entry of entries) {
|
|
2391
|
-
const to = PACKAGE_RENAMES.get(entry.name);
|
|
2392
|
-
if (to !== void 0 && isFree({ from: entry.name, to, field, names }, findings)) {
|
|
2393
|
-
findings.edits.push(entry.rename(to));
|
|
2394
|
-
findings.changes.push({
|
|
2395
|
-
kind: "package-name-renamed",
|
|
2396
|
-
location: field,
|
|
2397
|
-
from: entry.name,
|
|
2398
|
-
to
|
|
2399
|
-
});
|
|
2400
|
-
}
|
|
2401
|
-
}
|
|
2402
|
-
}
|
|
2403
|
-
|
|
2404
|
-
const IMPORTS_FIELD$1 = "imports";
|
|
2405
|
-
const SCOPES_FIELD = "scopes";
|
|
2406
|
-
const FIELD_SEPARATOR$2 = ".";
|
|
2407
|
-
function migrateImports(config, version, findings) {
|
|
2408
|
-
for (const imports of mapsAt(config, IMPORTS_FIELD$1)) {
|
|
2409
|
-
const map = { kind: "imports", field: IMPORTS_FIELD$1 };
|
|
2410
|
-
migrateSpecMap(specEntries(imports), { map, version, findings, catalogs: NO_CATALOG_PLAN });
|
|
2411
|
-
}
|
|
2412
|
-
for (const scopes of mapsAt(config, SCOPES_FIELD)) {
|
|
2413
|
-
for (const { key, value } of textEntries(scopes)) {
|
|
2414
|
-
if (isMap(value)) {
|
|
2415
|
-
const field = [SCOPES_FIELD, key.value].join(FIELD_SEPARATOR$2);
|
|
2416
|
-
const map = { kind: "imports", field };
|
|
2417
|
-
migrateSpecMap(specEntries(value), { map, version, findings, catalogs: NO_CATALOG_PLAN });
|
|
2418
|
-
}
|
|
2419
|
-
}
|
|
2420
|
-
}
|
|
2421
|
-
}
|
|
2422
|
-
const PATH_SEPARATOR$4 = "/";
|
|
2423
|
-
const SCOPE_PREFIX = "@";
|
|
2424
|
-
function importMapKeys(config) {
|
|
2425
|
-
const scoped = mapsAt(config, SCOPES_FIELD).flatMap(textEntries).flatMap(({ value }) => isMap(value) ? [value] : []);
|
|
2426
|
-
return [...mapsAt(config, IMPORTS_FIELD$1), ...scoped].flatMap(textEntries).map(({ key }) => key.value);
|
|
2427
|
-
}
|
|
2428
|
-
function importMapNames(config) {
|
|
2429
|
-
return importMapKeys(config).map((key) => {
|
|
2430
|
-
const parts = key.split(PATH_SEPARATOR$4);
|
|
2431
|
-
return key.startsWith(SCOPE_PREFIX) ? parts.slice(0, 2).join(PATH_SEPARATOR$4) : parts[0] ?? key;
|
|
2432
|
-
});
|
|
2433
|
-
}
|
|
2434
|
-
function migrateImportMap(text, read, version) {
|
|
2435
|
-
if (read.kind === "unreadable") {
|
|
2436
|
-
return unreadableConfig(text, read.offset);
|
|
2437
|
-
}
|
|
2438
|
-
const findings = newFindings();
|
|
2439
|
-
for (const config of read.documents.filter(isMap)) {
|
|
2440
|
-
migrateImports(config, version, findings);
|
|
2672
|
+
const oldFlagsOf = (findings) => findings.flatMap(({ change, manualStep }) => {
|
|
2673
|
+
if (change?.kind === "flag-renamed") {
|
|
2674
|
+
return [change.from];
|
|
2441
2675
|
}
|
|
2442
|
-
|
|
2443
|
-
return { text: applyTextEdits(text, edits), changes, manualSteps };
|
|
2444
|
-
}
|
|
2445
|
-
|
|
2446
|
-
const NONE = /* @__PURE__ */ new Set();
|
|
2447
|
-
const PACKAGE_OPTIONS = /* @__PURE__ */ new Set(["-p", "--package"]);
|
|
2448
|
-
const PACKAGE_MANAGER_OPTIONS = /* @__PURE__ */ new Set([
|
|
2449
|
-
"--filter",
|
|
2450
|
-
"-F",
|
|
2451
|
-
"--dir",
|
|
2452
|
-
"-C",
|
|
2453
|
-
"--prefix",
|
|
2454
|
-
"--cwd",
|
|
2455
|
-
"--workspace"
|
|
2456
|
-
]);
|
|
2457
|
-
const launcher = (words, packageOptions = NONE, valueOptions = NONE) => {
|
|
2458
|
-
const allValueOptions = /* @__PURE__ */ new Set([...valueOptions, ...packageOptions]);
|
|
2459
|
-
return { words, packageOptions, valueOptions: allValueOptions, operands: 0 };
|
|
2460
|
-
};
|
|
2461
|
-
const CONTAINER_OPTIONS = /* @__PURE__ */ new Set([
|
|
2462
|
-
"-e",
|
|
2463
|
-
"--env",
|
|
2464
|
-
"--env-file",
|
|
2465
|
-
"-v",
|
|
2466
|
-
"--volume",
|
|
2467
|
-
"--mount",
|
|
2468
|
-
"-p",
|
|
2469
|
-
"--publish",
|
|
2470
|
-
"-w",
|
|
2471
|
-
"--workdir",
|
|
2472
|
-
"-u",
|
|
2473
|
-
"--user",
|
|
2474
|
-
"--name",
|
|
2475
|
-
"--network",
|
|
2476
|
-
"--entrypoint",
|
|
2477
|
-
"--platform",
|
|
2478
|
-
"-l",
|
|
2479
|
-
"--label",
|
|
2480
|
-
"-h",
|
|
2481
|
-
"--hostname",
|
|
2482
|
-
"--add-host"
|
|
2483
|
-
]);
|
|
2484
|
-
const container = (words) => ({
|
|
2485
|
-
...launcher(words, NONE, CONTAINER_OPTIONS),
|
|
2486
|
-
operands: 1
|
|
2676
|
+
return manualStep?.kind === "flags-in-variable" ? [...manualStep.flags] : [];
|
|
2487
2677
|
});
|
|
2488
|
-
|
|
2489
|
-
const
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
"-L",
|
|
2493
|
-
"-n",
|
|
2494
|
-
"-P",
|
|
2495
|
-
"-R",
|
|
2496
|
-
"-S",
|
|
2497
|
-
"-s",
|
|
2498
|
-
"-d",
|
|
2499
|
-
"-E",
|
|
2500
|
-
"-a",
|
|
2501
|
-
"--max-args",
|
|
2502
|
-
"--max-procs",
|
|
2503
|
-
"--max-lines",
|
|
2504
|
-
"--delimiter",
|
|
2505
|
-
"--arg-file"
|
|
2506
|
-
]);
|
|
2507
|
-
const NODE_OPTIONS = /* @__PURE__ */ new Set([
|
|
2508
|
-
"-r",
|
|
2509
|
-
"--require",
|
|
2510
|
-
"--import",
|
|
2511
|
-
"--loader",
|
|
2512
|
-
"--env-file"
|
|
2513
|
-
]);
|
|
2514
|
-
const LAUNCHERS = [
|
|
2515
|
-
launcher(["npm", "exec"], PACKAGE_OPTIONS),
|
|
2516
|
-
launcher(["npm", "x"], PACKAGE_OPTIONS),
|
|
2517
|
-
launcher(["pnpm", "exec"], NONE, PACKAGE_MANAGER_OPTIONS),
|
|
2518
|
-
launcher(["pnpm", "dlx"], /* @__PURE__ */ new Set(["--package"])),
|
|
2519
|
-
launcher(["yarn", "dlx"], PACKAGE_OPTIONS),
|
|
2520
|
-
launcher(["yarn", "exec"]),
|
|
2521
|
-
launcher(["bun", "x"], PACKAGE_OPTIONS),
|
|
2522
|
-
withOperands(["yarn", "workspace"], 1),
|
|
2523
|
-
launcher(["dotenvx", "run"], NONE, /* @__PURE__ */ new Set(["-f", "--env-file", "-e", "--env", "--convention"])),
|
|
2524
|
-
launcher(
|
|
2525
|
-
["doppler", "run"],
|
|
2526
|
-
NONE,
|
|
2527
|
-
/* @__PURE__ */ new Set(["-p", "--project", "-c", "--config", "--token", "--mount", "--scope"])
|
|
2528
|
-
),
|
|
2529
|
-
launcher(["nx", "exec"], NONE, /* @__PURE__ */ new Set(["--projects", "-p", "--exclude"])),
|
|
2530
|
-
launcher(["deno", "run"], NONE, /* @__PURE__ */ new Set(["--config", "-c", "--import-map", "--location"])),
|
|
2531
|
-
launcher(["deno", "x"]),
|
|
2532
|
-
launcher(["npx"], PACKAGE_OPTIONS, /* @__PURE__ */ new Set(["-c", "--call"])),
|
|
2533
|
-
launcher(["pnpx"], PACKAGE_OPTIONS),
|
|
2534
|
-
launcher(["bunx"], PACKAGE_OPTIONS),
|
|
2535
|
-
// Like a bare `pnpm <name>`, a bare `bun <name>` runs the binary when no script has the name.
|
|
2536
|
-
launcher(["bun"], NONE, /* @__PURE__ */ new Set(["--cwd", "--filter", "-F"])),
|
|
2537
|
-
launcher(["corepack"]),
|
|
2538
|
-
launcher(["pnpm"], NONE, PACKAGE_MANAGER_OPTIONS),
|
|
2539
|
-
launcher(["yarn"], NONE, PACKAGE_MANAGER_OPTIONS),
|
|
2540
|
-
launcher(["node"], NONE, NODE_OPTIONS),
|
|
2541
|
-
launcher(["tsx"], NONE, NODE_OPTIONS),
|
|
2542
|
-
launcher(["ts-node"], NONE, /* @__PURE__ */ new Set([...NODE_OPTIONS, "-P", "--project", "-O", "--compiler"])),
|
|
2543
|
-
launcher(["cross-env"]),
|
|
2544
|
-
launcher(["dotenv"], NONE, /* @__PURE__ */ new Set(["-e", "-c", "-v"])),
|
|
2545
|
-
launcher(["env"], NONE, /* @__PURE__ */ new Set(["-u", "--unset", "-C", "--chdir"])),
|
|
2546
|
-
launcher(["exec"], NONE, /* @__PURE__ */ new Set(["-a"])),
|
|
2547
|
-
launcher(["command"]),
|
|
2548
|
-
launcher(["time"]),
|
|
2549
|
-
launcher(["nice"], NONE, /* @__PURE__ */ new Set(["-n", "--adjustment"])),
|
|
2550
|
-
withOperands(["timeout"], 1, /* @__PURE__ */ new Set(["-s", "--signal", "-k", "--kill-after"])),
|
|
2551
|
-
launcher(["xargs"], NONE, XARGS_OPTIONS),
|
|
2552
|
-
launcher(["nohup"]),
|
|
2553
|
-
launcher(["sudo"], NONE, /* @__PURE__ */ new Set(["-u", "-g"])),
|
|
2554
|
-
// The shell form of Dockerfile instructions runs the rest of the line in a shell.
|
|
2555
|
-
launcher(["RUN"], NONE, /* @__PURE__ */ new Set(["--mount", "--network", "--security"])),
|
|
2556
|
-
launcher(["CMD"]),
|
|
2557
|
-
launcher(["ENTRYPOINT"]),
|
|
2558
|
-
container(["docker", "run"]),
|
|
2559
|
-
container(["docker", "exec"]),
|
|
2560
|
-
container(["docker", "compose", "run"]),
|
|
2561
|
-
container(["docker", "compose", "exec"]),
|
|
2562
|
-
container(["podman", "run"]),
|
|
2563
|
-
container(["podman", "exec"])
|
|
2564
|
-
];
|
|
2565
|
-
const installers = (manager, subcommands) => subcommands.map((subcommand) => ({ words: [manager, subcommand] }));
|
|
2566
|
-
const NPM_INSTALL = ["install", "i", "add", "update", "up", "uninstall", "remove", "rm", "un"];
|
|
2567
|
-
const INSTALLERS = [
|
|
2568
|
-
...installers("npm", NPM_INSTALL),
|
|
2569
|
-
...installers("pnpm", ["add", "update", "up", "remove", "rm", "uninstall", "un"]),
|
|
2570
|
-
...installers("yarn", ["add", "upgrade", "up", "remove"]),
|
|
2571
|
-
// Yarn 1 installs global packages with `yarn global add`.
|
|
2572
|
-
{ words: ["yarn", "global", "add"] },
|
|
2573
|
-
{ words: ["yarn", "global", "remove"] },
|
|
2574
|
-
...installers("bun", ["add", "a", "update", "remove", "rm", "install", "i"]),
|
|
2575
|
-
...installers("deno", ["add", "install", "i", "remove", "uninstall"])
|
|
2576
|
-
];
|
|
2577
|
-
const NPM_SPECIFIER_PREFIX = "npm:";
|
|
2578
|
-
|
|
2579
|
-
const ASSIGNMENT_RE$1 = /^[A-Za-z_][A-Za-z0-9_]*=/;
|
|
2580
|
-
const END_OF_OPTIONS = "--";
|
|
2581
|
-
const isOption$1 = (word) => word.value.startsWith("-") && word.value.length > 1;
|
|
2582
|
-
function skipAssignments(words, start) {
|
|
2583
|
-
let index = start;
|
|
2584
|
-
while (index < words.length && ASSIGNMENT_RE$1.test(words[index].raw)) {
|
|
2585
|
-
index++;
|
|
2586
|
-
}
|
|
2587
|
-
return index;
|
|
2588
|
-
}
|
|
2589
|
-
function matchingPrefix(entries, words, index) {
|
|
2590
|
-
return entries.find(
|
|
2591
|
-
(entry) => entry.words.every((name, offset) => words[index + offset]?.value === name)
|
|
2592
|
-
);
|
|
2593
|
-
}
|
|
2594
|
-
function inlineOptionPackage(word, launcher) {
|
|
2595
|
-
const equals = word.value.indexOf("=");
|
|
2596
|
-
const name = word.value.slice(0, equals);
|
|
2597
|
-
return launcher.packageOptions.has(name) ? { word, value: word.value.slice(equals + 1) } : void 0;
|
|
2598
|
-
}
|
|
2599
|
-
function launchedProgram(words, start, launcher, packages) {
|
|
2600
|
-
let index = start;
|
|
2601
|
-
while (index < words.length && isOption$1(words[index])) {
|
|
2602
|
-
const option = words[index++];
|
|
2603
|
-
if (option.value === END_OF_OPTIONS) {
|
|
2604
|
-
break;
|
|
2605
|
-
}
|
|
2606
|
-
const inline = option.value.includes("=") ? inlineOptionPackage(option, launcher) : void 0;
|
|
2607
|
-
if (inline !== void 0) {
|
|
2608
|
-
packages.push(inline);
|
|
2609
|
-
}
|
|
2610
|
-
const value = words[index];
|
|
2611
|
-
if (!option.value.includes("=") && launcher.valueOptions.has(option.value) && value) {
|
|
2612
|
-
if (launcher.packageOptions.has(option.value)) {
|
|
2613
|
-
packages.push({ word: value, value: value.value });
|
|
2614
|
-
}
|
|
2615
|
-
index++;
|
|
2616
|
-
}
|
|
2617
|
-
}
|
|
2618
|
-
return index;
|
|
2619
|
-
}
|
|
2620
|
-
const installArguments = (words, start) => words.slice(start).filter((word) => !isOption$1(word)).map((word) => ({ word, value: word.value }));
|
|
2621
|
-
function commandRoles(words) {
|
|
2622
|
-
const packages = [];
|
|
2623
|
-
let index = skipAssignments(words, 0);
|
|
2624
|
-
while (index < words.length) {
|
|
2625
|
-
const installer = matchingPrefix(INSTALLERS, words, index);
|
|
2626
|
-
if (installer !== void 0) {
|
|
2627
|
-
packages.push(...installArguments(words, index + installer.words.length));
|
|
2628
|
-
return { program: void 0, packages };
|
|
2629
|
-
}
|
|
2630
|
-
const launcher = matchingPrefix(LAUNCHERS, words, index);
|
|
2631
|
-
if (launcher === void 0) {
|
|
2632
|
-
return { program: index, packages };
|
|
2633
|
-
}
|
|
2634
|
-
const start = index + launcher.words.length;
|
|
2635
|
-
const afterOptions = launchedProgram(words, start, launcher, packages);
|
|
2636
|
-
index = skipAssignments(words, afterOptions + launcher.operands);
|
|
2637
|
-
}
|
|
2638
|
-
return { program: void 0, packages };
|
|
2639
|
-
}
|
|
2640
|
-
|
|
2641
|
-
function packageReference(value) {
|
|
2642
|
-
const bare = value.startsWith(NPM_SPECIFIER_PREFIX) ? value.slice(NPM_SPECIFIER_PREFIX.length) : value;
|
|
2643
|
-
const at = bare.indexOf("@", 1);
|
|
2644
|
-
return { name: at === -1 ? bare : bare.slice(0, at), isPinned: at !== -1 };
|
|
2645
|
-
}
|
|
2646
|
-
function namesOldPackage(value) {
|
|
2647
|
-
return PACKAGE_RENAMES.has(packageReference(value).name) || oldPackageInNodeModules(value) !== void 0 || value.endsWith(`/${GENERATOR_COMMAND}`);
|
|
2648
|
-
}
|
|
2649
|
-
function unmigratedWordFindings(words, handledOffsets, locate) {
|
|
2650
|
-
return words.filter((word) => !handledOffsets.has(word.start) && namesOldPackage(word.value)).map((word) => ({
|
|
2651
|
-
offset: word.start,
|
|
2652
|
-
manualStep: { kind: "old-name-in-command", location: locate(word.start), word: word.value }
|
|
2653
|
-
}));
|
|
2654
|
-
}
|
|
2655
|
-
|
|
2656
|
-
const COMMAND_SEPARATORS = /* @__PURE__ */ new Set([
|
|
2657
|
-
";",
|
|
2658
|
-
"&",
|
|
2659
|
-
"|",
|
|
2660
|
-
"(",
|
|
2661
|
-
")",
|
|
2662
|
-
"`",
|
|
2663
|
-
"\n"
|
|
2664
|
-
]);
|
|
2665
|
-
const WORD_BREAKS = /* @__PURE__ */ new Set([" ", " ", "\r", "<", ">"]);
|
|
2666
|
-
const BACKSLASH$1 = "\\";
|
|
2667
|
-
const DOUBLE_QUOTE_ESCAPES = /* @__PURE__ */ new Set(["$", "`", '"', BACKSLASH$1, "\n"]);
|
|
2668
|
-
function singleQuoted(text, start) {
|
|
2669
|
-
const close = text.indexOf("'", start + 1);
|
|
2670
|
-
const end = close === -1 ? text.length : close + 1;
|
|
2671
|
-
return { end, value: text.slice(start + 1, close === -1 ? text.length : close) };
|
|
2672
|
-
}
|
|
2673
|
-
function doubleQuoted(text, start) {
|
|
2674
|
-
let value = "";
|
|
2675
|
-
let index = start + 1;
|
|
2676
|
-
while (index < text.length && text[index] !== '"') {
|
|
2677
|
-
const next = text[index + 1] ?? "";
|
|
2678
|
-
const isEscape = text[index] === BACKSLASH$1 && DOUBLE_QUOTE_ESCAPES.has(next);
|
|
2679
|
-
value += isEscape ? next === "\n" ? "" : next : text[index];
|
|
2680
|
-
index += isEscape ? 2 : 1;
|
|
2678
|
+
function uncertainFlagSteps(program, variable, found, locate) {
|
|
2679
|
+
const flags = [...new Set(oldFlagsOf(found))];
|
|
2680
|
+
if (flags.length === 0) {
|
|
2681
|
+
return [];
|
|
2681
2682
|
}
|
|
2682
|
-
|
|
2683
|
+
const manualStep = {
|
|
2684
|
+
kind: "variable-not-only-generator",
|
|
2685
|
+
location: locate(program.start),
|
|
2686
|
+
variable,
|
|
2687
|
+
flags
|
|
2688
|
+
};
|
|
2689
|
+
return [{ offset: program.start, manualStep }];
|
|
2683
2690
|
}
|
|
2684
|
-
|
|
2685
|
-
const
|
|
2686
|
-
const
|
|
2687
|
-
const
|
|
2688
|
-
|
|
2689
|
-
function arithmeticExpansion(text, start) {
|
|
2690
|
-
let depth = ARITHMETIC_DEPTH;
|
|
2691
|
-
for (let index = start + ARITHMETIC_OPEN.length; index < text.length; index++) {
|
|
2692
|
-
depth += text[index] === NESTING_OPEN ? 1 : text[index] === NESTING_CLOSE ? -1 : 0;
|
|
2693
|
-
if (depth === 0) {
|
|
2694
|
-
return { end: index + 1, value: text.slice(start, index + 1) };
|
|
2695
|
-
}
|
|
2696
|
-
}
|
|
2697
|
-
return void 0;
|
|
2691
|
+
function commandFindings(command, locate, variables) {
|
|
2692
|
+
const words = withoutRecipePrefix(command);
|
|
2693
|
+
const found = knownFindings(words, locate, variables);
|
|
2694
|
+
const handled = new Set(found.map((finding) => finding.offset));
|
|
2695
|
+
return [...found, ...unmigratedWordFindings(words, handled, locate)];
|
|
2698
2696
|
}
|
|
2699
|
-
function
|
|
2700
|
-
const
|
|
2701
|
-
const
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
if (char === "'") {
|
|
2706
|
-
return singleQuoted(text, index);
|
|
2707
|
-
}
|
|
2708
|
-
if (char === '"') {
|
|
2709
|
-
return doubleQuoted(text, index);
|
|
2710
|
-
}
|
|
2711
|
-
if (char === BACKSLASH$1 && index + 1 < text.length) {
|
|
2712
|
-
return { end: index + 2, value: text[index + 1] };
|
|
2697
|
+
function knownFindings(words, locate, variables) {
|
|
2698
|
+
const roles = commandRoles(words);
|
|
2699
|
+
const findings = roles.packages.flatMap((found2) => packageFindings(found2, locate));
|
|
2700
|
+
const program = roles.program === void 0 ? void 0 : words[roles.program];
|
|
2701
|
+
if (program === void 0) {
|
|
2702
|
+
return findings;
|
|
2713
2703
|
}
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
const
|
|
2717
|
-
const
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
function readWord(text, start) {
|
|
2721
|
-
let value = "";
|
|
2722
|
-
let index = start;
|
|
2723
|
-
while (index < text.length && !endsWord(text, index)) {
|
|
2724
|
-
const part = wordPart(text, index);
|
|
2725
|
-
value += part.value;
|
|
2726
|
-
index = part.end;
|
|
2704
|
+
const found = programFindings(program, locate(program.start));
|
|
2705
|
+
findings.push(...found);
|
|
2706
|
+
const isRenamed = found.some((finding) => finding.change?.kind === "command-renamed");
|
|
2707
|
+
const variable = variables.programAt(program);
|
|
2708
|
+
if (!isRenamed && (variable === void 0 || variable.program === "other")) {
|
|
2709
|
+
return findings;
|
|
2727
2710
|
}
|
|
2728
|
-
|
|
2711
|
+
const flags = words.slice(roles.program + 1);
|
|
2712
|
+
const flagFound = flags.flatMap((word) => argumentFindings(word, locate, variables));
|
|
2713
|
+
const isUncertain = variable?.program === "generator-or-other";
|
|
2714
|
+
findings.push(
|
|
2715
|
+
...isUncertain ? uncertainFlagSteps(program, variable.written, flagFound, locate) : flagFound
|
|
2716
|
+
);
|
|
2717
|
+
return findings;
|
|
2729
2718
|
}
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
const HERE_STRING_OPERATOR = "<<<";
|
|
2733
|
-
const STRIP_TABS = "-";
|
|
2734
|
-
const LINE_BREAK$2 = "\n";
|
|
2735
|
-
const LEADING_TABS_RE = /^\t+/;
|
|
2736
|
-
const CARRIAGE_RETURN_RE = /\r$/;
|
|
2737
|
-
function heredocAt(text, index, where) {
|
|
2738
|
-
if (text.startsWith(HERE_STRING_OPERATOR, index)) {
|
|
2739
|
-
return { end: index + HERE_STRING_OPERATOR.length };
|
|
2740
|
-
}
|
|
2741
|
-
if (!text.startsWith(HEREDOC_OPERATOR, index)) {
|
|
2742
|
-
return void 0;
|
|
2743
|
-
}
|
|
2744
|
-
let start = index + HEREDOC_OPERATOR.length;
|
|
2745
|
-
const isTabStripped = text[start] === STRIP_TABS;
|
|
2746
|
-
start += isTabStripped ? 1 : 0;
|
|
2747
|
-
while (text[start] === " " || text[start] === " ") {
|
|
2748
|
-
start++;
|
|
2749
|
-
}
|
|
2750
|
-
const word = readWord(text, start);
|
|
2751
|
-
const pending = { delimiter: word.value, isTabStripped, ...where };
|
|
2752
|
-
return word.value === "" ? void 0 : { pending, end: word.end };
|
|
2719
|
+
function shellTextFindings(text, locate) {
|
|
2720
|
+
return commandWordFindings(shellCommands(text), locate);
|
|
2753
2721
|
}
|
|
2754
|
-
function
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2722
|
+
function commandWordFindings(commands, locate, variables = NO_VARIABLES) {
|
|
2723
|
+
const known = withShellAssignments(commands, variables);
|
|
2724
|
+
const findings = commands.flatMap((words) => commandFindings(words, locate, known)).sort((left, right) => left.offset - right.offset);
|
|
2725
|
+
return {
|
|
2726
|
+
edits: findings.flatMap((finding) => finding.edit === void 0 ? [] : [finding.edit]),
|
|
2727
|
+
changes: findings.flatMap((finding) => finding.change === void 0 ? [] : [finding.change]),
|
|
2728
|
+
manualSteps: findings.flatMap(
|
|
2729
|
+
(finding) => finding.manualStep === void 0 ? [] : [finding.manualStep]
|
|
2730
|
+
)
|
|
2731
|
+
};
|
|
2762
2732
|
}
|
|
2763
|
-
function
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
const lineEnd = text.indexOf(LINE_BREAK$2, lineStart);
|
|
2767
|
-
const end = lineEnd === -1 ? text.length : lineEnd;
|
|
2768
|
-
if (isDelimiterLine(text, lineStart, end, heredoc)) {
|
|
2769
|
-
const body = { command: heredoc.command, start, text: text.slice(start, lineStart) };
|
|
2770
|
-
return { body, end: Math.min(end + 1, text.length) };
|
|
2771
|
-
}
|
|
2772
|
-
lineStart = end + 1;
|
|
2773
|
-
}
|
|
2774
|
-
return { body: { command: heredoc.command, start, text: text.slice(start) }, end: text.length };
|
|
2733
|
+
function migrateShellText(text, locate) {
|
|
2734
|
+
const { edits, changes, manualSteps } = shellTextFindings(text, locate);
|
|
2735
|
+
return { text: applyTextEdits(text, edits), changes, manualSteps };
|
|
2775
2736
|
}
|
|
2776
|
-
function
|
|
2777
|
-
|
|
2778
|
-
let end = start;
|
|
2779
|
-
for (const heredoc of pending) {
|
|
2780
|
-
const read = readBody(text, end, heredoc);
|
|
2781
|
-
bodies.push(read.body);
|
|
2782
|
-
end = read.end;
|
|
2783
|
-
}
|
|
2784
|
-
return { bodies, end };
|
|
2737
|
+
function migrateCommand(text, location) {
|
|
2738
|
+
return migrateShellText(text, () => location);
|
|
2785
2739
|
}
|
|
2786
|
-
|
|
2787
|
-
const
|
|
2788
|
-
|
|
2789
|
-
function skipTrivia(text, index) {
|
|
2790
|
-
const char = text[index];
|
|
2791
|
-
if (WORD_BREAKS.has(char)) {
|
|
2792
|
-
return index + 1;
|
|
2793
|
-
}
|
|
2794
|
-
if (isLineContinuation(text, index)) {
|
|
2795
|
-
return text.indexOf("\n", index) + 1;
|
|
2796
|
-
}
|
|
2797
|
-
if (char === COMMENT) {
|
|
2798
|
-
const lineEnd = text.indexOf("\n", index);
|
|
2799
|
-
return lineEnd === -1 ? text.length : lineEnd;
|
|
2800
|
-
}
|
|
2801
|
-
return index;
|
|
2740
|
+
function migrateCommandLines(text, file) {
|
|
2741
|
+
const lineOf = lineLocator(text);
|
|
2742
|
+
return migrateShellText(text, (offset) => `${file}:${lineOf(offset)}`);
|
|
2802
2743
|
}
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2744
|
+
|
|
2745
|
+
const ANY = "*";
|
|
2746
|
+
const nxOptionPaths = (prefix) => [
|
|
2747
|
+
[...prefix, "command"],
|
|
2748
|
+
[...prefix, "commands", ANY],
|
|
2749
|
+
[...prefix, "commands", ANY, "command"]
|
|
2750
|
+
];
|
|
2751
|
+
const nxTargetPaths = (prefix) => [
|
|
2752
|
+
[...prefix, ANY, "command"],
|
|
2753
|
+
...nxOptionPaths([...prefix, ANY, "options"]),
|
|
2754
|
+
...nxOptionPaths([...prefix, ANY, "configurations", ANY])
|
|
2755
|
+
];
|
|
2756
|
+
const lintStagedPaths = (prefix) => [
|
|
2757
|
+
[...prefix, ANY],
|
|
2758
|
+
[...prefix, ANY, ANY]
|
|
2759
|
+
];
|
|
2760
|
+
const simpleGitHooksPaths = (prefix) => [
|
|
2761
|
+
[...prefix, ANY]
|
|
2762
|
+
];
|
|
2763
|
+
const NX_PROJECT_COMMAND_PATHS = nxTargetPaths(["targets"]);
|
|
2764
|
+
const NX_WORKSPACE_COMMAND_PATHS = nxTargetPaths([
|
|
2765
|
+
"targetDefaults"
|
|
2766
|
+
]);
|
|
2767
|
+
const MANIFEST_COMMAND_PATHS = [
|
|
2768
|
+
["scripts", ANY],
|
|
2769
|
+
["wireit", ANY, "command"],
|
|
2770
|
+
...simpleGitHooksPaths(["simple-git-hooks"]),
|
|
2771
|
+
...lintStagedPaths(["lint-staged"]),
|
|
2772
|
+
...nxTargetPaths(["nx", "targets"])
|
|
2773
|
+
];
|
|
2774
|
+
const LINT_STAGED_COMMAND_PATHS = lintStagedPaths([]);
|
|
2775
|
+
const SIMPLE_GIT_HOOKS_COMMAND_PATHS = simpleGitHooksPaths(
|
|
2776
|
+
[]
|
|
2777
|
+
);
|
|
2778
|
+
const DENO_TASK_PATHS = [
|
|
2779
|
+
["tasks", ANY],
|
|
2780
|
+
["tasks", ANY, "command"]
|
|
2781
|
+
];
|
|
2782
|
+
const matches = (path, pattern) => path.length === pattern.length && pattern.every((part, index) => part === ANY || part === String(path[index]));
|
|
2783
|
+
const isCommandPath = (path, patterns) => patterns.some((pattern) => matches(path, pattern));
|
|
2784
|
+
|
|
2785
|
+
const NO_LOCATION = "";
|
|
2786
|
+
function commandStringSteps(text, strings) {
|
|
2787
|
+
const lineOf = lineLocator(text);
|
|
2788
|
+
return strings.flatMap((found) => {
|
|
2789
|
+
if (found.isModuleSpecifier || PACKAGE_RENAMES.has(found.value)) {
|
|
2790
|
+
return [];
|
|
2834
2791
|
}
|
|
2835
|
-
|
|
2836
|
-
|
|
2792
|
+
const migrated = migrateCommand(found.value, NO_LOCATION).text;
|
|
2793
|
+
return migrated === found.value ? [] : [{ kind: "command-string", line: lineOf(found.start), to: migrated }];
|
|
2794
|
+
});
|
|
2837
2795
|
}
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
"fi",
|
|
2844
|
-
"while",
|
|
2845
|
-
"until",
|
|
2846
|
-
"do",
|
|
2847
|
-
"done",
|
|
2848
|
-
"!",
|
|
2849
|
-
"{",
|
|
2850
|
-
"}",
|
|
2851
|
-
"esac"
|
|
2852
|
-
]);
|
|
2853
|
-
const CLAUSE_WORDS = /* @__PURE__ */ new Set(["for", "select", "case", "[["]);
|
|
2854
|
-
const FUNCTION_WORD = "function";
|
|
2855
|
-
const FUNCTION_HEADER_LENGTH = 2;
|
|
2856
|
-
const isReserved = (word, words) => word !== void 0 && word.raw === word.value && words.has(word.value);
|
|
2857
|
-
function prefixLength(words, index) {
|
|
2858
|
-
if (isReserved(words[index], COMMAND_PREFIX_WORDS)) {
|
|
2859
|
-
return 1;
|
|
2860
|
-
}
|
|
2861
|
-
const word = words[index];
|
|
2862
|
-
return word?.raw === FUNCTION_WORD ? FUNCTION_HEADER_LENGTH : 0;
|
|
2796
|
+
|
|
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 }] : []);
|
|
2863
2801
|
}
|
|
2864
|
-
function
|
|
2865
|
-
|
|
2866
|
-
for (let length = prefixLength(words, 0); length > 0; length = prefixLength(words, first)) {
|
|
2867
|
-
first += length;
|
|
2868
|
-
}
|
|
2869
|
-
return isReserved(words[first], CLAUSE_WORDS) ? [] : words.slice(first);
|
|
2802
|
+
function valuesAt(map, key) {
|
|
2803
|
+
return textEntries(map).filter((entry) => entry.key.value === key).map((entry) => entry.value);
|
|
2870
2804
|
}
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
function nestedCommandText(word) {
|
|
2874
|
-
const quote = word.raw[0];
|
|
2875
|
-
const isOneQuotedString = QUOTES$2.has(quote) && word.raw.length > 1 && word.raw.endsWith(quote) && wordPart(word.raw, 0).end === word.raw.length;
|
|
2876
|
-
return isOneQuotedString && NESTED_COMMAND_RE.test(word.value) ? word.raw.slice(1, -1) : void 0;
|
|
2805
|
+
function mapsAt(map, key) {
|
|
2806
|
+
return valuesAt(map, key).filter(isMap);
|
|
2877
2807
|
}
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
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 [];
|
|
2889
2820
|
}
|
|
2890
|
-
const after = command.slice(1);
|
|
2891
|
-
const shell = after.slice(after.findIndex((word) => !isOption(word)));
|
|
2892
|
-
return after.every(isOption) || isScriptShell(shell);
|
|
2893
2821
|
}
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
const previous = index - 1;
|
|
2897
|
-
const isPipedScript = top.pipes.has(previous) && isScriptShell(command) && passesThrough(simpleCommand(top.commands[previous] ?? []));
|
|
2898
|
-
return top.heredocs.filter(
|
|
2899
|
-
(body) => body.command === index && readsScript(command) || body.command === previous && isPipedScript
|
|
2900
|
-
);
|
|
2822
|
+
function documentStrings(documents) {
|
|
2823
|
+
return documents.flatMap((document) => stringsBelow(document, []));
|
|
2901
2824
|
}
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
return shellCommands(text, indent).map((words) => shifted(words, offset));
|
|
2825
|
+
function ownerKey(path) {
|
|
2826
|
+
return path.findLast((part) => typeof part === "string");
|
|
2905
2827
|
}
|
|
2906
|
-
function
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
for (const [index, words] of top.commands.entries()) {
|
|
2910
|
-
const command = simpleCommand(words);
|
|
2911
|
-
if (command.length > 0) {
|
|
2912
|
-
commands.push(command);
|
|
2913
|
-
}
|
|
2914
|
-
for (const word of command) {
|
|
2915
|
-
const inner = nestedCommandText(word);
|
|
2916
|
-
if (inner !== void 0) {
|
|
2917
|
-
const nested = shellCommands(inner).map((found) => shifted(found, word.start + 1));
|
|
2918
|
-
commands.push(...nested);
|
|
2919
|
-
}
|
|
2920
|
-
}
|
|
2921
|
-
const scripts = scriptsRunBy(top, index, command);
|
|
2922
|
-
commands.push(...scripts.flatMap((body) => shellCommandsAt(body.text, body.start, indent)));
|
|
2828
|
+
function unreadableConfig(text, offset) {
|
|
2829
|
+
if (!namesOriginalPackage(text)) {
|
|
2830
|
+
return unchanged(text);
|
|
2923
2831
|
}
|
|
2924
|
-
|
|
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 }] };
|
|
2925
2834
|
}
|
|
2926
2835
|
|
|
2927
|
-
const
|
|
2928
|
-
const
|
|
2929
|
-
const
|
|
2930
|
-
const
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2836
|
+
const KEPT_PROTOCOLS = ["catalog:", "workspace:"];
|
|
2837
|
+
const LOCAL_PROTOCOLS = ["workspace:", "link:", "file:", "portal:"];
|
|
2838
|
+
const RANGE_SEPARATOR = "||";
|
|
2839
|
+
const HYPHEN = "-";
|
|
2840
|
+
const WHITE_SPACE_RE = /\s+/;
|
|
2841
|
+
const SPACED_OPERATOR_RE = /(<=|>=|<|>|=|~>|~|\^)\s+/g;
|
|
2842
|
+
const OPERATOR = String.raw`(<=|>=|<|>|=|~>|~|\^)?`;
|
|
2843
|
+
const VERSION_PART = String.raw`(\d+|[xX*])`;
|
|
2844
|
+
const LABELS = String.raw`(?:-[\w.-]+)?(?:\+[\w.-]+)?`;
|
|
2845
|
+
const COMPARATOR_RE = new RegExp(
|
|
2846
|
+
String.raw`^${OPERATOR}v?${VERSION_PART}(?:\.${VERSION_PART})?(?:\.${VERSION_PART})?${LABELS}$`
|
|
2847
|
+
);
|
|
2848
|
+
const NUMBER_RE = /^\d+$/;
|
|
2849
|
+
const OPERATOR_STYLES = {
|
|
2850
|
+
"^": "^",
|
|
2851
|
+
// `>=` means "this or newer"; with a new package line, a caret range says the same safely.
|
|
2852
|
+
">=": "^",
|
|
2853
|
+
">": "^",
|
|
2854
|
+
"~": "~",
|
|
2855
|
+
"~>": "~"
|
|
2856
|
+
};
|
|
2857
|
+
const isNumber = (part) => part !== void 0 && NUMBER_RE.test(part);
|
|
2858
|
+
function versionStyle(major, minor, patch) {
|
|
2859
|
+
if (!isNumber(major)) {
|
|
2935
2860
|
return void 0;
|
|
2936
2861
|
}
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
function packageFindings(found, locate) {
|
|
2940
|
-
const { name, isPinned } = packageReference(found.value);
|
|
2941
|
-
const to = PACKAGE_RENAMES.get(name);
|
|
2942
|
-
const offset = found.word.start;
|
|
2943
|
-
if (to === void 0) {
|
|
2944
|
-
return [];
|
|
2945
|
-
}
|
|
2946
|
-
const location = locate(offset);
|
|
2947
|
-
if (isPinned) {
|
|
2948
|
-
return [{ offset, manualStep: { kind: "pinned-package", location, name } }];
|
|
2862
|
+
if (isNumber(minor) && isNumber(patch)) {
|
|
2863
|
+
return "";
|
|
2949
2864
|
}
|
|
2950
|
-
|
|
2951
|
-
const change = { kind: "package-name-renamed", location, from: name, to };
|
|
2952
|
-
return edit === void 0 ? [] : [{ offset, edit, change }];
|
|
2865
|
+
return isNumber(minor) ? "~" : "^";
|
|
2953
2866
|
}
|
|
2954
|
-
function
|
|
2955
|
-
const
|
|
2956
|
-
|
|
2957
|
-
|
|
2867
|
+
function rangeStyle(spec) {
|
|
2868
|
+
const sets = spec.replace(SPACED_OPERATOR_RE, "$1").split(RANGE_SEPARATOR);
|
|
2869
|
+
const tokens = sets.map((set) => set.trim().split(WHITE_SPACE_RE));
|
|
2870
|
+
const comparators = tokens.flat().filter((token) => token !== HYPHEN);
|
|
2871
|
+
const matches = comparators.map((comparator) => COMPARATOR_RE.exec(comparator));
|
|
2872
|
+
const first = matches[0];
|
|
2873
|
+
if (first === void 0 || first === null || matches.includes(null)) {
|
|
2874
|
+
return void 0;
|
|
2958
2875
|
}
|
|
2959
|
-
const
|
|
2960
|
-
const
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
function programFindings(word, location) {
|
|
2964
|
-
if (word.value.includes(PATH_SEPARATOR$2)) {
|
|
2965
|
-
return programPathFindings(word, location);
|
|
2876
|
+
const operator = first[1];
|
|
2877
|
+
const isHyphenRange = tokens[0]?.[1] === HYPHEN;
|
|
2878
|
+
if (operator !== void 0 && operator !== "=") {
|
|
2879
|
+
return OPERATOR_STYLES[operator];
|
|
2966
2880
|
}
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2881
|
+
return isHyphenRange ? "^" : versionStyle(first[2], first[3], first[4]);
|
|
2882
|
+
}
|
|
2883
|
+
const isLocalPackageSpec = (spec) => LOCAL_PROTOCOLS.some((protocol) => spec.startsWith(protocol));
|
|
2884
|
+
function migrateVersionSpec(spec, version) {
|
|
2885
|
+
if (KEPT_PROTOCOLS.some((protocol) => spec.startsWith(protocol))) {
|
|
2886
|
+
return { kind: "kept", spec, isReported: false };
|
|
2970
2887
|
}
|
|
2971
|
-
|
|
2972
|
-
|
|
2888
|
+
const style = rangeStyle(spec);
|
|
2889
|
+
if (style === void 0) {
|
|
2890
|
+
return { kind: "kept", spec, isReported: true };
|
|
2973
2891
|
}
|
|
2974
|
-
|
|
2975
|
-
const change = { kind: "command-renamed", location };
|
|
2976
|
-
return edit === void 0 ? [] : [{ offset: word.start, edit, change }];
|
|
2892
|
+
return { kind: "replaced", spec: `${style}${version}` };
|
|
2977
2893
|
}
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2894
|
+
|
|
2895
|
+
const NO_LONGER_INSTALLED = /* @__PURE__ */ new Map([
|
|
2896
|
+
["openapi-typesafe-helpers", ["openapi-fetch", "openapi-react-query"]]
|
|
2897
|
+
]);
|
|
2898
|
+
const ORIGINAL_NAMES = new Map(
|
|
2899
|
+
[...PACKAGE_RENAMES].map(([original, successor]) => [successor, original])
|
|
2900
|
+
);
|
|
2901
|
+
const PATH_SEPARATOR$6 = "/";
|
|
2902
|
+
function namesUninstalledPackage(text) {
|
|
2903
|
+
return [...NO_LONGER_INSTALLED.keys()].some(
|
|
2904
|
+
(name) => text.includes(name) || text.includes(ORIGINAL_NAMES.get(name) ?? name)
|
|
2905
|
+
);
|
|
2989
2906
|
}
|
|
2990
|
-
const
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
return words;
|
|
2995
|
-
}
|
|
2996
|
-
return [{ ...first, value: first.value.replace(RECIPE_PREFIX_RE$1, "") }, ...rest];
|
|
2907
|
+
const directoryOf = (path) => path.slice(0, path.lastIndexOf(PATH_SEPARATOR$6) + 1);
|
|
2908
|
+
const isAtOrAbove = (path, filePath) => filePath.startsWith(directoryOf(path));
|
|
2909
|
+
function declaredNames(manifest) {
|
|
2910
|
+
return DEPENDENCY_FIELDS.flatMap((field) => mapsAt(manifest, field)).flatMap(textEntries).map(({ key }) => key.value);
|
|
2997
2911
|
}
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
2912
|
+
function localPackageNames(manifest) {
|
|
2913
|
+
return DEPENDENCY_FIELDS.flatMap((field) => mapsAt(manifest, field)).flatMap(textEntries).flatMap(
|
|
2914
|
+
({ key, value }) => isScalar(value) && isLocalPackageSpec(value.value) ? [key.value] : []
|
|
2915
|
+
);
|
|
2916
|
+
}
|
|
2917
|
+
function localPackagesFor(manifests, filePath) {
|
|
2918
|
+
const containing = manifests.filter(({ path }) => isAtOrAbove(path, filePath));
|
|
2919
|
+
return new Set(containing.flatMap(({ localPackages }) => [...localPackages ?? []]));
|
|
2920
|
+
}
|
|
2921
|
+
function isDeclaredFor(manifests, filePath, name) {
|
|
2922
|
+
const original = ORIGINAL_NAMES.get(name);
|
|
2923
|
+
const containing = manifests.filter(({ path }) => isAtOrAbove(path, filePath));
|
|
2924
|
+
const declares = ({ names }) => names === void 0 || names.has(name) || original !== void 0 && names.has(original);
|
|
2925
|
+
return containing.length === 0 || containing.some(declares);
|
|
2926
|
+
}
|
|
2927
|
+
const packageOfSpecifier = (specifier) => {
|
|
2928
|
+
const slash = specifier.indexOf(PATH_SEPARATOR$6);
|
|
2929
|
+
return slash === -1 ? specifier : specifier.slice(0, slash);
|
|
3001
2930
|
};
|
|
3002
|
-
function
|
|
3003
|
-
|
|
3004
|
-
|
|
2931
|
+
function undeclaredImportSteps(imports, filePath, manifests) {
|
|
2932
|
+
return imports.flatMap(({ specifier, line }) => {
|
|
2933
|
+
const name = packageOfSpecifier(specifier);
|
|
2934
|
+
const installers = NO_LONGER_INSTALLED.get(name);
|
|
2935
|
+
return installers === void 0 || isDeclaredFor(manifests, filePath, name) ? [] : [{ kind: "package-not-declared", line, name, installers }];
|
|
2936
|
+
});
|
|
3005
2937
|
}
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
2938
|
+
|
|
2939
|
+
const EXEC_FORM_START_RE = /^[ \t]*(?:RUN|CMD|ENTRYPOINT)(?:[ \t]+--\S+)*[ \t]+\[/gm;
|
|
2940
|
+
const SHELLS = /* @__PURE__ */ new Set(["sh", "bash", "dash", "ash", "zsh"]);
|
|
2941
|
+
const OPTION_PREFIX = "-";
|
|
2942
|
+
const LONG_OPTION_PREFIX = "--";
|
|
2943
|
+
const COMMAND_OPTION = "c";
|
|
2944
|
+
const SET_OPTION = "-o";
|
|
2945
|
+
const PATH_SEPARATOR$5 = "/";
|
|
2946
|
+
const ARRAY_BLANK_RE = /(?:[ \t\r\n]|\\\r?\n)*/y;
|
|
2947
|
+
const QUOTED_RE = /"(?:[^"\\\n]|\\.)*"/y;
|
|
2948
|
+
const ITEM_SEPARATOR = ",";
|
|
2949
|
+
const NOT_LINE_BREAK_RE$1 = /[^\n]/g;
|
|
2950
|
+
const ARRAY_END = "]";
|
|
2951
|
+
const VARIABLE_INSTRUCTIONS = /* @__PURE__ */ new Set(["ARG", "ENV"]);
|
|
2952
|
+
const LEGACY_ENV_INSTRUCTION = "ENV";
|
|
2953
|
+
const ASSIGNMENT = "=";
|
|
2954
|
+
const QUOTES = /* @__PURE__ */ new Set(['"', "'"]);
|
|
2955
|
+
function matchAt(pattern, text, index) {
|
|
2956
|
+
pattern.lastIndex = index;
|
|
2957
|
+
return pattern.exec(text)?.[0];
|
|
3022
2958
|
}
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
return
|
|
2959
|
+
function jsonString(raw) {
|
|
2960
|
+
try {
|
|
2961
|
+
return JSON.parse(raw);
|
|
2962
|
+
} catch (error) {
|
|
2963
|
+
if (error instanceof SyntaxError) {
|
|
2964
|
+
return void 0;
|
|
2965
|
+
}
|
|
2966
|
+
throw error;
|
|
3026
2967
|
}
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
2968
|
+
}
|
|
2969
|
+
function execFormAt(text, start) {
|
|
2970
|
+
const words = [];
|
|
2971
|
+
let index = start + 1;
|
|
2972
|
+
for (; ; ) {
|
|
2973
|
+
index += matchAt(ARRAY_BLANK_RE, text, index)?.length ?? 0;
|
|
2974
|
+
const raw = matchAt(QUOTED_RE, text, index);
|
|
2975
|
+
if (raw === void 0) {
|
|
2976
|
+
const isEmpty = text[index] === ARRAY_END && words.length === 0;
|
|
2977
|
+
return isEmpty ? { start, end: index + 1, words } : void 0;
|
|
2978
|
+
}
|
|
2979
|
+
const value = jsonString(raw);
|
|
2980
|
+
if (value === void 0) {
|
|
2981
|
+
return void 0;
|
|
2982
|
+
}
|
|
2983
|
+
words.push({ start: index + 1, end: index + raw.length - 1, value, raw: raw.slice(1, -1) });
|
|
2984
|
+
index += raw.length;
|
|
2985
|
+
index += matchAt(ARRAY_BLANK_RE, text, index)?.length ?? 0;
|
|
2986
|
+
if (text[index] === ARRAY_END) {
|
|
2987
|
+
return { start, end: index + 1, words };
|
|
2988
|
+
}
|
|
2989
|
+
if (text[index] !== ITEM_SEPARATOR) {
|
|
2990
|
+
return void 0;
|
|
2991
|
+
}
|
|
2992
|
+
index++;
|
|
3033
2993
|
}
|
|
3034
|
-
const manualStep = {
|
|
3035
|
-
kind: "variable-not-only-generator",
|
|
3036
|
-
location: locate(program.start),
|
|
3037
|
-
variable,
|
|
3038
|
-
flags
|
|
3039
|
-
};
|
|
3040
|
-
return [{ offset: program.start, manualStep }];
|
|
3041
2994
|
}
|
|
3042
|
-
function
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
2995
|
+
function execForms(text) {
|
|
2996
|
+
return [...text.matchAll(EXEC_FORM_START_RE)].flatMap((match) => {
|
|
2997
|
+
const form = execFormAt(text, match.index + match[0].length - 1);
|
|
2998
|
+
return form === void 0 ? [] : [form];
|
|
2999
|
+
});
|
|
3047
3000
|
}
|
|
3048
|
-
function
|
|
3049
|
-
const
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
if (program === void 0) {
|
|
3053
|
-
return findings;
|
|
3001
|
+
function shellScript(words) {
|
|
3002
|
+
const program = words[0]?.value.split(PATH_SEPARATOR$5).at(-1) ?? "";
|
|
3003
|
+
if (!SHELLS.has(program)) {
|
|
3004
|
+
return void 0;
|
|
3054
3005
|
}
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3006
|
+
let index = 1;
|
|
3007
|
+
for (let option = words[index]?.value; option !== void 0; option = words[index]?.value) {
|
|
3008
|
+
if (!option.startsWith(OPTION_PREFIX)) {
|
|
3009
|
+
return void 0;
|
|
3010
|
+
}
|
|
3011
|
+
if (!option.startsWith(LONG_OPTION_PREFIX) && option.includes(COMMAND_OPTION)) {
|
|
3012
|
+
return words[index + 1];
|
|
3013
|
+
}
|
|
3014
|
+
index += option === SET_OPTION ? 2 : 1;
|
|
3061
3015
|
}
|
|
3062
|
-
|
|
3063
|
-
const flagFound = flags.flatMap((word) => argumentFindings(word, locate, variables));
|
|
3064
|
-
const isUncertain = variable?.program === "generator-or-other";
|
|
3065
|
-
findings.push(
|
|
3066
|
-
...isUncertain ? uncertainFlagSteps(program, variable.written, flagFound, locate) : flagFound
|
|
3067
|
-
);
|
|
3068
|
-
return findings;
|
|
3069
|
-
}
|
|
3070
|
-
function runsGenerator(command) {
|
|
3071
|
-
const words = withoutRecipePrefix(command);
|
|
3072
|
-
const { program } = commandRoles(words);
|
|
3073
|
-
const word = program === void 0 ? void 0 : words[program];
|
|
3074
|
-
return word !== void 0 && packageReference(word.value).name === GENERATOR_COMMAND;
|
|
3075
|
-
}
|
|
3076
|
-
function shellTextFindings(text, locate) {
|
|
3077
|
-
return commandWordFindings(shellCommands(text), locate);
|
|
3016
|
+
return void 0;
|
|
3078
3017
|
}
|
|
3079
|
-
function
|
|
3080
|
-
const
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3018
|
+
function execCommands(forms) {
|
|
3019
|
+
const commands = [];
|
|
3020
|
+
const escaped = [];
|
|
3021
|
+
for (const { words } of forms) {
|
|
3022
|
+
commands.push(words);
|
|
3023
|
+
const script = shellScript(words);
|
|
3024
|
+
if (script !== void 0 && script.raw === script.value) {
|
|
3025
|
+
commands.push(...shellCommandsAt(script.value, script.start));
|
|
3026
|
+
} else if (script !== void 0) {
|
|
3027
|
+
escaped.push(script);
|
|
3028
|
+
}
|
|
3029
|
+
}
|
|
3030
|
+
return { commands, escaped };
|
|
3088
3031
|
}
|
|
3089
|
-
function
|
|
3090
|
-
const
|
|
3091
|
-
|
|
3032
|
+
function withoutExecForms(text, forms) {
|
|
3033
|
+
const parts = [];
|
|
3034
|
+
let copiedUpTo = 0;
|
|
3035
|
+
for (const { start, end } of forms) {
|
|
3036
|
+
parts.push(
|
|
3037
|
+
text.slice(copiedUpTo, start),
|
|
3038
|
+
text.slice(start, end).replace(NOT_LINE_BREAK_RE$1, " ")
|
|
3039
|
+
);
|
|
3040
|
+
copiedUpTo = end;
|
|
3041
|
+
}
|
|
3042
|
+
parts.push(text.slice(copiedUpTo));
|
|
3043
|
+
return parts.join("");
|
|
3092
3044
|
}
|
|
3093
|
-
function
|
|
3094
|
-
return
|
|
3045
|
+
function escapedScriptSteps(scripts, lineOf) {
|
|
3046
|
+
return scripts.flatMap((script) => {
|
|
3047
|
+
const migrated = migrateCommand(script.value, "").text;
|
|
3048
|
+
return migrated === script.value ? [] : [{ kind: "command-string", line: lineOf(script.start), to: migrated }];
|
|
3049
|
+
});
|
|
3095
3050
|
}
|
|
3096
|
-
function
|
|
3097
|
-
const
|
|
3098
|
-
|
|
3051
|
+
function assignedVariable(word) {
|
|
3052
|
+
const at = word.raw.indexOf(ASSIGNMENT);
|
|
3053
|
+
if (at <= 0) {
|
|
3054
|
+
return void 0;
|
|
3055
|
+
}
|
|
3056
|
+
const raw = word.raw.slice(at + 1);
|
|
3057
|
+
const isQuoted = raw.length >= 2 && QUOTES.has(raw[0]) && raw.at(-1) === raw[0];
|
|
3058
|
+
const value = isQuoted ? raw.slice(1, -1) : raw;
|
|
3059
|
+
const start = word.start + at + 1 + (isQuoted ? 1 : 0);
|
|
3060
|
+
return { name: word.raw.slice(0, at), commands: shellCommandsAt(value, start) };
|
|
3099
3061
|
}
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
[...prefix, "command"],
|
|
3104
|
-
[...prefix, "commands", ANY],
|
|
3105
|
-
[...prefix, "commands", ANY, "command"]
|
|
3106
|
-
];
|
|
3107
|
-
const nxTargetPaths = (prefix) => [
|
|
3108
|
-
[...prefix, ANY, "command"],
|
|
3109
|
-
...nxOptionPaths([...prefix, ANY, "options"]),
|
|
3110
|
-
...nxOptionPaths([...prefix, ANY, "configurations", ANY])
|
|
3111
|
-
];
|
|
3112
|
-
const lintStagedPaths = (prefix) => [
|
|
3113
|
-
[...prefix, ANY],
|
|
3114
|
-
[...prefix, ANY, ANY]
|
|
3115
|
-
];
|
|
3116
|
-
const simpleGitHooksPaths = (prefix) => [
|
|
3117
|
-
[...prefix, ANY]
|
|
3118
|
-
];
|
|
3119
|
-
const NX_PROJECT_COMMAND_PATHS = nxTargetPaths(["targets"]);
|
|
3120
|
-
const NX_WORKSPACE_COMMAND_PATHS = nxTargetPaths([
|
|
3121
|
-
"targetDefaults"
|
|
3122
|
-
]);
|
|
3123
|
-
const MANIFEST_COMMAND_PATHS = [
|
|
3124
|
-
["scripts", ANY],
|
|
3125
|
-
...simpleGitHooksPaths(["simple-git-hooks"]),
|
|
3126
|
-
...lintStagedPaths(["lint-staged"]),
|
|
3127
|
-
...nxTargetPaths(["nx", "targets"])
|
|
3128
|
-
];
|
|
3129
|
-
const LINT_STAGED_COMMAND_PATHS = lintStagedPaths([]);
|
|
3130
|
-
const SIMPLE_GIT_HOOKS_COMMAND_PATHS = simpleGitHooksPaths(
|
|
3131
|
-
[]
|
|
3132
|
-
);
|
|
3133
|
-
const DENO_TASK_PATHS = [
|
|
3134
|
-
["tasks", ANY],
|
|
3135
|
-
["tasks", ANY, "command"]
|
|
3136
|
-
];
|
|
3137
|
-
const matches = (path, pattern) => path.length === pattern.length && pattern.every((part, index) => part === ANY || part === String(path[index]));
|
|
3138
|
-
const isCommandPath = (path, patterns) => patterns.some((pattern) => matches(path, pattern));
|
|
3139
|
-
|
|
3140
|
-
const NO_LOCATION = "";
|
|
3141
|
-
function commandStringSteps(text, strings) {
|
|
3142
|
-
const lineOf = lineLocator(text);
|
|
3143
|
-
return strings.flatMap((found) => {
|
|
3144
|
-
if (found.isModuleSpecifier || PACKAGE_RENAMES.has(found.value)) {
|
|
3062
|
+
function dockerVariables(commands) {
|
|
3063
|
+
return commands.flatMap(([instruction, first, ...rest]) => {
|
|
3064
|
+
if (instruction === void 0 || first === void 0) {
|
|
3145
3065
|
return [];
|
|
3146
3066
|
}
|
|
3147
|
-
|
|
3148
|
-
|
|
3067
|
+
if (!VARIABLE_INSTRUCTIONS.has(instruction.value)) {
|
|
3068
|
+
return [];
|
|
3069
|
+
}
|
|
3070
|
+
if (instruction.value === LEGACY_ENV_INSTRUCTION && !first.raw.includes(ASSIGNMENT)) {
|
|
3071
|
+
return [{ name: first.value, commands: [rest] }];
|
|
3072
|
+
}
|
|
3073
|
+
return [first, ...rest].flatMap((word) => assignedVariable(word) ?? []);
|
|
3149
3074
|
});
|
|
3150
3075
|
}
|
|
3076
|
+
const definitionOf = ({ name, commands }) => ({
|
|
3077
|
+
name,
|
|
3078
|
+
value: commands.flatMap((words) => words.map((word) => word.raw)).join(" ")
|
|
3079
|
+
});
|
|
3080
|
+
function migrateDockerfile(text, file) {
|
|
3081
|
+
const lineOf = lineLocator(text);
|
|
3082
|
+
const locate = (offset) => `${file}:${lineOf(offset)}`;
|
|
3083
|
+
const forms = execForms(text);
|
|
3084
|
+
const exec = execCommands(forms);
|
|
3085
|
+
const shellForm = shellCommands(withoutExecForms(text, forms));
|
|
3086
|
+
const definitions = dockerVariables(shellForm);
|
|
3087
|
+
const values = definitions.flatMap((variable) => variable.commands);
|
|
3088
|
+
const commands = [...shellForm, ...values, ...exec.commands];
|
|
3089
|
+
const variables = shellVariables(definitions.map(definitionOf));
|
|
3090
|
+
const { edits, changes, manualSteps } = commandWordFindings(commands, locate, variables);
|
|
3091
|
+
const steps = [...manualSteps, ...escapedScriptSteps(exec.escaped, lineOf)];
|
|
3092
|
+
return { text: applyTextEdits(text, edits), changes, manualSteps: steps };
|
|
3093
|
+
}
|
|
3151
3094
|
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
return generators.has(definition.target);
|
|
3158
|
-
case "append":
|
|
3159
|
-
return false;
|
|
3160
|
-
default:
|
|
3161
|
-
return assertNever(definition);
|
|
3095
|
+
const CATALOG_PROTOCOL = "catalog:";
|
|
3096
|
+
const DEFAULT_CATALOG = "default";
|
|
3097
|
+
function catalogOfSpec(spec) {
|
|
3098
|
+
if (!spec.startsWith(CATALOG_PROTOCOL)) {
|
|
3099
|
+
return void 0;
|
|
3162
3100
|
}
|
|
3101
|
+
return spec.slice(CATALOG_PROTOCOL.length).trim() || DEFAULT_CATALOG;
|
|
3163
3102
|
}
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
case "reference":
|
|
3169
|
-
return others.has(definition.target) || !defined.has(definition.target);
|
|
3170
|
-
case "append":
|
|
3171
|
-
return false;
|
|
3172
|
-
default:
|
|
3173
|
-
return assertNever(definition);
|
|
3103
|
+
class CatalogEntries {
|
|
3104
|
+
#keys = /* @__PURE__ */ new Set();
|
|
3105
|
+
add(catalog, name) {
|
|
3106
|
+
this.#keys.add(JSON.stringify([catalog, name]));
|
|
3174
3107
|
}
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
const defined = new Set(definitions.map((definition) => definition.name));
|
|
3178
|
-
const generators = /* @__PURE__ */ new Set();
|
|
3179
|
-
const others = /* @__PURE__ */ new Set();
|
|
3180
|
-
for (let size = -1; size !== generators.size + others.size; ) {
|
|
3181
|
-
size = generators.size + others.size;
|
|
3182
|
-
for (const definition of definitions) {
|
|
3183
|
-
if (canRunGenerator(definition, generators)) {
|
|
3184
|
-
generators.add(definition.name);
|
|
3185
|
-
}
|
|
3186
|
-
if (canRunOther(definition, others, defined)) {
|
|
3187
|
-
others.add(definition.name);
|
|
3188
|
-
}
|
|
3189
|
-
}
|
|
3108
|
+
has(catalog, name) {
|
|
3109
|
+
return this.#keys.has(JSON.stringify([catalog, name]));
|
|
3190
3110
|
}
|
|
3191
|
-
const programOf = (name) => {
|
|
3192
|
-
if (!generators.has(name)) {
|
|
3193
|
-
return "other";
|
|
3194
|
-
}
|
|
3195
|
-
return others.has(name) ? "generator-or-other" : "generator";
|
|
3196
|
-
};
|
|
3197
|
-
return new Map([...defined].map((name) => [name, programOf(name)]));
|
|
3198
3111
|
}
|
|
3112
|
+
const NO_CATALOG_PLAN = {
|
|
3113
|
+
inUse: new CatalogEntries(),
|
|
3114
|
+
kept: new CatalogEntries(),
|
|
3115
|
+
defined: new CatalogEntries(),
|
|
3116
|
+
isWorkspaceRoot: false
|
|
3117
|
+
};
|
|
3199
3118
|
|
|
3200
|
-
const
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3119
|
+
const NPM_PROTOCOL = "npm:";
|
|
3120
|
+
const SCOPE_PREFIX$2 = "@";
|
|
3121
|
+
const PATH_SEPARATOR$4 = "/";
|
|
3122
|
+
const VERSION_SEPARATOR = "@";
|
|
3123
|
+
function nameEnd(text) {
|
|
3124
|
+
const searchFrom = text.startsWith(SCOPE_PREFIX$2) ? text.indexOf(PATH_SEPARATOR$4) + 1 : 0;
|
|
3125
|
+
const ends = [VERSION_SEPARATOR, PATH_SEPARATOR$4].map((separator) => text.indexOf(separator, Math.max(searchFrom, 1))).filter((index) => index !== -1);
|
|
3126
|
+
return ends.length === 0 ? text.length : Math.min(...ends);
|
|
3204
3127
|
}
|
|
3205
|
-
function
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
return { name, kind: "reference", target };
|
|
3128
|
+
function parseNpmSpec(spec) {
|
|
3129
|
+
if (!spec.startsWith(NPM_PROTOCOL)) {
|
|
3130
|
+
return void 0;
|
|
3209
3131
|
}
|
|
3210
|
-
|
|
3132
|
+
const body = spec.slice(NPM_PROTOCOL.length);
|
|
3133
|
+
const lead = body.startsWith(PATH_SEPARATOR$4) ? PATH_SEPARATOR$4 : "";
|
|
3134
|
+
const text = body.slice(lead.length);
|
|
3135
|
+
const end = nameEnd(text);
|
|
3136
|
+
const name = text.slice(0, end);
|
|
3137
|
+
if (!text.startsWith(VERSION_SEPARATOR, end)) {
|
|
3138
|
+
return { lead, name, range: void 0, rest: text.slice(end) };
|
|
3139
|
+
}
|
|
3140
|
+
const rangeEnd = text.indexOf(PATH_SEPARATOR$4, end);
|
|
3141
|
+
const restStart = rangeEnd === -1 ? text.length : rangeEnd;
|
|
3142
|
+
return { lead, name, range: text.slice(end + 1, restStart), rest: text.slice(restStart) };
|
|
3211
3143
|
}
|
|
3212
|
-
function
|
|
3213
|
-
const
|
|
3214
|
-
|
|
3215
|
-
|
|
3144
|
+
function isOldPackageNpmSpec(spec) {
|
|
3145
|
+
const parsed = parseNpmSpec(spec);
|
|
3146
|
+
return parsed !== void 0 && PACKAGE_RENAMES.has(parsed.name);
|
|
3147
|
+
}
|
|
3148
|
+
function migrateNpmSpec(spec, version) {
|
|
3149
|
+
const parsed = parseNpmSpec(spec);
|
|
3150
|
+
const renamed = parsed === void 0 ? void 0 : PACKAGE_RENAMES.get(parsed.name);
|
|
3151
|
+
if (parsed === void 0 || renamed === void 0) {
|
|
3152
|
+
return void 0;
|
|
3216
3153
|
}
|
|
3217
|
-
const
|
|
3218
|
-
const
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3154
|
+
const head = `${NPM_PROTOCOL}${parsed.lead}${renamed}`;
|
|
3155
|
+
const isDeep = parsed.rest !== "" && parsed.rest !== PATH_SEPARATOR$4;
|
|
3156
|
+
if (parsed.range === void 0) {
|
|
3157
|
+
return { spec: `${head}${parsed.rest}`, isReported: false, isDeep };
|
|
3158
|
+
}
|
|
3159
|
+
const decision = migrateVersionSpec(parsed.range, version);
|
|
3160
|
+
const isReported = decision.kind === "kept" && decision.isReported;
|
|
3161
|
+
const migrated = `${head}${VERSION_SEPARATOR}${decision.spec}${parsed.rest}`;
|
|
3162
|
+
return { spec: migrated, isReported, isDeep };
|
|
3163
|
+
}
|
|
3164
|
+
|
|
3165
|
+
const SCHEME_SEPARATOR = "://";
|
|
3166
|
+
const HIDDEN_USERINFO = "***";
|
|
3167
|
+
const USERINFO_END = "@";
|
|
3168
|
+
const AUTHORITY_END_RE = /[/?#"'`\s]/;
|
|
3169
|
+
function scanAuthority(text, start) {
|
|
3170
|
+
let userinfoEnd = -1;
|
|
3171
|
+
let end = start;
|
|
3172
|
+
for (; end < text.length && !AUTHORITY_END_RE.test(text.charAt(end)); end++) {
|
|
3173
|
+
if (text.charAt(end) === USERINFO_END) {
|
|
3174
|
+
userinfoEnd = end;
|
|
3175
|
+
}
|
|
3176
|
+
}
|
|
3177
|
+
return { end, userinfoEnd };
|
|
3178
|
+
}
|
|
3179
|
+
function hideUrlCredentials(text) {
|
|
3180
|
+
let hidden = "";
|
|
3181
|
+
let copiedUpTo = 0;
|
|
3182
|
+
for (let found = text.indexOf(SCHEME_SEPARATOR); found !== -1; ) {
|
|
3183
|
+
const start = found + SCHEME_SEPARATOR.length;
|
|
3184
|
+
const { end, userinfoEnd } = scanAuthority(text, start);
|
|
3185
|
+
if (userinfoEnd !== -1) {
|
|
3186
|
+
hidden += `${text.slice(copiedUpTo, start)}${HIDDEN_USERINFO}`;
|
|
3187
|
+
copiedUpTo = userinfoEnd;
|
|
3229
3188
|
}
|
|
3230
|
-
|
|
3189
|
+
found = text.indexOf(SCHEME_SEPARATOR, end);
|
|
3190
|
+
}
|
|
3191
|
+
return `${hidden}${text.slice(copiedUpTo)}`;
|
|
3231
3192
|
}
|
|
3232
3193
|
|
|
3233
|
-
const
|
|
3234
|
-
const
|
|
3235
|
-
const
|
|
3236
|
-
const
|
|
3237
|
-
|
|
3238
|
-
const
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
const
|
|
3243
|
-
|
|
3244
|
-
const ARRAY_END = "]";
|
|
3245
|
-
const VARIABLE_INSTRUCTIONS = /* @__PURE__ */ new Set(["ARG", "ENV"]);
|
|
3246
|
-
const LEGACY_ENV_INSTRUCTION = "ENV";
|
|
3247
|
-
const ASSIGNMENT = "=";
|
|
3248
|
-
const QUOTES = /* @__PURE__ */ new Set(['"', "'"]);
|
|
3249
|
-
function matchAt(pattern, text, index) {
|
|
3250
|
-
pattern.lastIndex = index;
|
|
3251
|
-
return pattern.exec(text)?.[0];
|
|
3194
|
+
const newFindings = () => ({ edits: [], changes: [], manualSteps: [] });
|
|
3195
|
+
const PEER_FIELD = "peerDependencies";
|
|
3196
|
+
const mapLabel = (map) => map.kind === "catalog" ? map.catalog : map.field;
|
|
3197
|
+
const renamedKey = (name, map) => map.kind === "imports" ? renamedSpecifier(name)?.to : PACKAGE_RENAMES.get(name);
|
|
3198
|
+
function migrateSpec(spec, version) {
|
|
3199
|
+
const npm = migrateNpmSpec(spec, version);
|
|
3200
|
+
if (npm !== void 0) {
|
|
3201
|
+
return { spec: npm.spec, isReported: npm.isReported };
|
|
3202
|
+
}
|
|
3203
|
+
const decision = migrateVersionSpec(spec, version);
|
|
3204
|
+
return { spec: decision.spec, isReported: decision.kind === "kept" && decision.isReported };
|
|
3252
3205
|
}
|
|
3253
|
-
function
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
if (error instanceof SyntaxError) {
|
|
3258
|
-
return void 0;
|
|
3259
|
-
}
|
|
3260
|
-
throw error;
|
|
3206
|
+
function isFree({ from, to, field, names }, findings) {
|
|
3207
|
+
if (names.has(to)) {
|
|
3208
|
+
findings.manualSteps.push({ kind: "name-collision", field, from, to });
|
|
3209
|
+
return false;
|
|
3261
3210
|
}
|
|
3211
|
+
return true;
|
|
3262
3212
|
}
|
|
3263
|
-
function
|
|
3264
|
-
const
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
}
|
|
3273
|
-
const value = jsonString(raw);
|
|
3274
|
-
if (value === void 0) {
|
|
3275
|
-
return void 0;
|
|
3276
|
-
}
|
|
3277
|
-
words.push({ start: index + 1, end: index + raw.length - 1, value, raw: raw.slice(1, -1) });
|
|
3278
|
-
index += raw.length;
|
|
3279
|
-
index += matchAt(ARRAY_BLANK_RE, text, index)?.length ?? 0;
|
|
3280
|
-
if (text[index] === ARRAY_END) {
|
|
3281
|
-
return { start, end: index + 1, words };
|
|
3282
|
-
}
|
|
3283
|
-
if (text[index] !== ITEM_SEPARATOR) {
|
|
3284
|
-
return void 0;
|
|
3285
|
-
}
|
|
3286
|
-
index++;
|
|
3213
|
+
function migrateAlias(entry, { map, version, findings }) {
|
|
3214
|
+
const migrated = entry.spec === void 0 ? void 0 : migrateNpmSpec(entry.spec.value, version);
|
|
3215
|
+
if (entry.spec === void 0 || migrated === void 0) {
|
|
3216
|
+
return;
|
|
3217
|
+
}
|
|
3218
|
+
findings.edits.push(entry.spec.replace(migrated.spec));
|
|
3219
|
+
const spec = hideUrlCredentials(migrated.spec);
|
|
3220
|
+
findings.changes.push({ kind: "alias-renamed", field: mapLabel(map), name: entry.name, spec });
|
|
3221
|
+
if (migrated.isReported) {
|
|
3222
|
+
findings.manualSteps.push({ kind: "spec-kept", name: entry.name, spec });
|
|
3287
3223
|
}
|
|
3288
3224
|
}
|
|
3289
|
-
function
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3225
|
+
function renamedChange(map, from, to, spec) {
|
|
3226
|
+
switch (map.kind) {
|
|
3227
|
+
case "dependencies":
|
|
3228
|
+
return { kind: "dependency-renamed", field: map.field, from, to, spec };
|
|
3229
|
+
case "catalog":
|
|
3230
|
+
return { kind: "catalog-entry-renamed", catalog: map.catalog, from, to, spec };
|
|
3231
|
+
case "imports":
|
|
3232
|
+
return { kind: "import-renamed", field: map.field, from, to, target: spec };
|
|
3233
|
+
default:
|
|
3234
|
+
return assertNever(map);
|
|
3235
|
+
}
|
|
3294
3236
|
}
|
|
3295
|
-
function
|
|
3296
|
-
const
|
|
3297
|
-
|
|
3237
|
+
function migrateEntry(entry, spec, to, { map, version, findings }) {
|
|
3238
|
+
const old = spec.value;
|
|
3239
|
+
const migrated = migrateSpec(old, version);
|
|
3240
|
+
findings.edits.push(entry.renameKey(to));
|
|
3241
|
+
if (migrated.spec !== old) {
|
|
3242
|
+
findings.edits.push(spec.replace(migrated.spec));
|
|
3243
|
+
}
|
|
3244
|
+
findings.changes.push(renamedChange(map, entry.name, to, hideUrlCredentials(migrated.spec)));
|
|
3245
|
+
if (migrated.isReported) {
|
|
3246
|
+
findings.manualSteps.push({ kind: "spec-kept", name: to, spec: hideUrlCredentials(old) });
|
|
3247
|
+
}
|
|
3248
|
+
if (map.kind === "dependencies" && map.field === PEER_FIELD) {
|
|
3249
|
+
findings.manualSteps.push({ kind: "peer-dependency-renamed", name: to });
|
|
3250
|
+
}
|
|
3251
|
+
}
|
|
3252
|
+
function catalogHold(entry, spec, { map, catalogs }) {
|
|
3253
|
+
if (map.kind === "catalog") {
|
|
3254
|
+
const isInUse = catalogs.inUse.has(map.name, entry.name);
|
|
3255
|
+
return isInUse ? { kind: "catalog-entry-in-use", catalog: map.catalog, name: entry.name } : void 0;
|
|
3256
|
+
}
|
|
3257
|
+
const catalog = map.kind === "dependencies" ? catalogOfSpec(spec.value) : void 0;
|
|
3258
|
+
if (catalog === void 0) {
|
|
3298
3259
|
return void 0;
|
|
3299
3260
|
}
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
}
|
|
3305
|
-
if (!option.startsWith(LONG_OPTION_PREFIX) && option.includes(COMMAND_OPTION)) {
|
|
3306
|
-
return words[index + 1];
|
|
3307
|
-
}
|
|
3308
|
-
index += option === SET_OPTION ? 2 : 1;
|
|
3261
|
+
const reference = { field: mapLabel(map), name: entry.name, catalog };
|
|
3262
|
+
if (!catalogs.defined.has(catalog, entry.name)) {
|
|
3263
|
+
const kind = catalogs.isWorkspaceRoot ? "catalog-entry-missing" : "catalog-entry-outside";
|
|
3264
|
+
return { kind, ...reference };
|
|
3309
3265
|
}
|
|
3310
|
-
return void 0;
|
|
3266
|
+
return catalogs.kept.has(catalog, entry.name) ? { kind: "catalog-reference-kept", ...reference } : void 0;
|
|
3311
3267
|
}
|
|
3312
|
-
function
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3268
|
+
function localPackageHold(entry, spec, { map }) {
|
|
3269
|
+
return map.kind === "dependencies" && isLocalPackageSpec(spec.value) ? { kind: "local-package", field: map.field, name: entry.name, spec: spec.value } : void 0;
|
|
3270
|
+
}
|
|
3271
|
+
const holdOf = (entry, spec, context) => localPackageHold(entry, spec, context) ?? catalogHold(entry, spec, context);
|
|
3272
|
+
function migrateSpecMap(entries, context) {
|
|
3273
|
+
const names = new Set(entries.map((entry) => entry.name));
|
|
3274
|
+
for (const entry of entries) {
|
|
3275
|
+
const to = renamedKey(entry.name, context.map);
|
|
3276
|
+
const field = mapLabel(context.map);
|
|
3277
|
+
if (to === void 0) {
|
|
3278
|
+
migrateAlias(entry, context);
|
|
3279
|
+
continue;
|
|
3280
|
+
}
|
|
3281
|
+
if (!isFree({ from: entry.name, to, field, names }, context.findings)) {
|
|
3282
|
+
continue;
|
|
3283
|
+
}
|
|
3284
|
+
const hold = entry.spec === void 0 ? void 0 : holdOf(entry, entry.spec, context);
|
|
3285
|
+
if (entry.spec === void 0) {
|
|
3286
|
+
context.findings.manualSteps.push({ kind: "entry-not-edited", field, name: entry.name });
|
|
3287
|
+
} else if (hold !== void 0) {
|
|
3288
|
+
context.findings.manualSteps.push(hold);
|
|
3289
|
+
} else {
|
|
3290
|
+
migrateEntry(entry, entry.spec, to, context);
|
|
3322
3291
|
}
|
|
3323
3292
|
}
|
|
3324
|
-
return { commands, escaped };
|
|
3325
3293
|
}
|
|
3326
|
-
function
|
|
3327
|
-
const
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3294
|
+
function renameNames(entries, field, findings) {
|
|
3295
|
+
const names = new Set(entries.map((entry) => entry.name));
|
|
3296
|
+
for (const entry of entries) {
|
|
3297
|
+
const to = PACKAGE_RENAMES.get(entry.name);
|
|
3298
|
+
if (to !== void 0 && isFree({ from: entry.name, to, field, names }, findings)) {
|
|
3299
|
+
findings.edits.push(entry.rename(to));
|
|
3300
|
+
findings.changes.push({
|
|
3301
|
+
kind: "package-name-renamed",
|
|
3302
|
+
location: field,
|
|
3303
|
+
from: entry.name,
|
|
3304
|
+
to
|
|
3305
|
+
});
|
|
3306
|
+
}
|
|
3335
3307
|
}
|
|
3336
|
-
parts.push(text.slice(copiedUpTo));
|
|
3337
|
-
return parts.join("");
|
|
3338
3308
|
}
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3309
|
+
|
|
3310
|
+
const isEditable = (node) => node.kind === "scalar" && node.encode !== void 0;
|
|
3311
|
+
const replaceScalar = (scalar, value) => ({
|
|
3312
|
+
start: scalar.start,
|
|
3313
|
+
end: scalar.end,
|
|
3314
|
+
text: scalar.encode(value)
|
|
3315
|
+
});
|
|
3316
|
+
function specEntries(map) {
|
|
3317
|
+
return textEntries(map).flatMap(({ key, value }) => {
|
|
3318
|
+
if (!isEditable(key)) {
|
|
3319
|
+
return [];
|
|
3320
|
+
}
|
|
3321
|
+
const spec = isEditable(value) ? { value: value.value, replace: (to) => replaceScalar(value, to) } : void 0;
|
|
3322
|
+
return [{ name: key.value, spec, renameKey: (name) => replaceScalar(key, name) }];
|
|
3343
3323
|
});
|
|
3344
3324
|
}
|
|
3345
|
-
function
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3325
|
+
function keyEntries(map) {
|
|
3326
|
+
return textEntries(map).map(({ key }) => key).filter(isEditable).map((key) => ({ name: key.value, rename: (name) => replaceScalar(key, name) }));
|
|
3327
|
+
}
|
|
3328
|
+
function itemEntries(list) {
|
|
3329
|
+
return list.items.filter(isEditable).map((item) => ({ name: item.value, rename: (name) => replaceScalar(item, name) }));
|
|
3330
|
+
}
|
|
3331
|
+
function nestedKeys(node) {
|
|
3332
|
+
if (node.kind !== "map") {
|
|
3333
|
+
return [];
|
|
3349
3334
|
}
|
|
3350
|
-
|
|
3351
|
-
const isQuoted = raw.length >= 2 && QUOTES.has(raw[0]) && raw.at(-1) === raw[0];
|
|
3352
|
-
const value = isQuoted ? raw.slice(1, -1) : raw;
|
|
3353
|
-
const start = word.start + at + 1 + (isQuoted ? 1 : 0);
|
|
3354
|
-
return { name: word.raw.slice(0, at), commands: shellCommandsAt(value, start) };
|
|
3335
|
+
return textEntries(node).flatMap(({ key, value }) => [key.value, ...nestedKeys(value)]);
|
|
3355
3336
|
}
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
}
|
|
3364
|
-
|
|
3365
|
-
|
|
3337
|
+
|
|
3338
|
+
const IMPORTS_FIELD$1 = "imports";
|
|
3339
|
+
const SCOPES_FIELD = "scopes";
|
|
3340
|
+
const FIELD_SEPARATOR$2 = ".";
|
|
3341
|
+
function migrateImports(config, version, findings) {
|
|
3342
|
+
for (const imports of mapsAt(config, IMPORTS_FIELD$1)) {
|
|
3343
|
+
const map = { kind: "imports", field: IMPORTS_FIELD$1 };
|
|
3344
|
+
migrateSpecMap(specEntries(imports), { map, version, findings, catalogs: NO_CATALOG_PLAN });
|
|
3345
|
+
}
|
|
3346
|
+
for (const scopes of mapsAt(config, SCOPES_FIELD)) {
|
|
3347
|
+
for (const { key, value } of textEntries(scopes)) {
|
|
3348
|
+
if (isMap(value)) {
|
|
3349
|
+
const field = [SCOPES_FIELD, key.value].join(FIELD_SEPARATOR$2);
|
|
3350
|
+
const map = { kind: "imports", field };
|
|
3351
|
+
migrateSpecMap(specEntries(value), { map, version, findings, catalogs: NO_CATALOG_PLAN });
|
|
3352
|
+
}
|
|
3366
3353
|
}
|
|
3367
|
-
|
|
3354
|
+
}
|
|
3355
|
+
}
|
|
3356
|
+
const PATH_SEPARATOR$3 = "/";
|
|
3357
|
+
const SCOPE_PREFIX$1 = "@";
|
|
3358
|
+
function importMapKeys(config) {
|
|
3359
|
+
const scoped = mapsAt(config, SCOPES_FIELD).flatMap(textEntries).flatMap(({ value }) => isMap(value) ? [value] : []);
|
|
3360
|
+
return [...mapsAt(config, IMPORTS_FIELD$1), ...scoped].flatMap(textEntries).map(({ key }) => key.value);
|
|
3361
|
+
}
|
|
3362
|
+
function importMapNames(config) {
|
|
3363
|
+
return importMapKeys(config).map((key) => {
|
|
3364
|
+
const parts = key.split(PATH_SEPARATOR$3);
|
|
3365
|
+
return key.startsWith(SCOPE_PREFIX$1) ? parts.slice(0, 2).join(PATH_SEPARATOR$3) : parts[0] ?? key;
|
|
3368
3366
|
});
|
|
3369
3367
|
}
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
}
|
|
3374
|
-
|
|
3375
|
-
const
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
const
|
|
3379
|
-
|
|
3380
|
-
const definitions = dockerVariables(shellForm);
|
|
3381
|
-
const values = definitions.flatMap((variable) => variable.commands);
|
|
3382
|
-
const commands = [...shellForm, ...values, ...exec.commands];
|
|
3383
|
-
const variables = shellVariables(definitions.map(definitionOf));
|
|
3384
|
-
const { edits, changes, manualSteps } = commandWordFindings(commands, locate, variables);
|
|
3385
|
-
const steps = [...manualSteps, ...escapedScriptSteps(exec.escaped, lineOf)];
|
|
3386
|
-
return { text: applyTextEdits(text, edits), changes, manualSteps: steps };
|
|
3368
|
+
function migrateImportMap(text, read, version) {
|
|
3369
|
+
if (read.kind === "unreadable") {
|
|
3370
|
+
return unreadableConfig(text, read.offset);
|
|
3371
|
+
}
|
|
3372
|
+
const findings = newFindings();
|
|
3373
|
+
for (const config of read.documents.filter(isMap)) {
|
|
3374
|
+
migrateImports(config, version, findings);
|
|
3375
|
+
}
|
|
3376
|
+
const { edits, changes, manualSteps } = findings;
|
|
3377
|
+
return { text: applyTextEdits(text, edits), changes, manualSteps };
|
|
3387
3378
|
}
|
|
3388
3379
|
|
|
3389
3380
|
const IMPORT_MAP_FIELD = "importMap";
|
|
@@ -3488,14 +3479,15 @@ function unrenamedSteps(found, line, dynamic) {
|
|
|
3488
3479
|
const to = name === void 0 ? void 0 : PACKAGE_RENAMES.get(name);
|
|
3489
3480
|
return name === void 0 || to === void 0 ? [] : [{ kind: "old-package-import", line, specifier: found.value, name, to }];
|
|
3490
3481
|
}
|
|
3491
|
-
function migrateModuleSpecifiers(text, strings, version) {
|
|
3482
|
+
function migrateModuleSpecifiers(text, strings, version, kept = /* @__PURE__ */ new Set()) {
|
|
3492
3483
|
const changes = [];
|
|
3493
3484
|
const manualSteps = [];
|
|
3494
3485
|
let migrated = "";
|
|
3495
3486
|
let copiedUpTo = 0;
|
|
3496
3487
|
const lineOf = lineLocator(text);
|
|
3497
3488
|
for (const found of distinctStrings(strings)) {
|
|
3498
|
-
const
|
|
3489
|
+
const isKept = kept.has(packageOfSpecifier(found.value));
|
|
3490
|
+
const renamed = isKept ? void 0 : renamedValue(found.value, version);
|
|
3499
3491
|
const line = lineOf(found.start);
|
|
3500
3492
|
const dynamic = found.isModuleSpecifier ? dynamicPackage(found.value) : void 0;
|
|
3501
3493
|
if (renamed === void 0) {
|
|
@@ -3588,6 +3580,80 @@ function migrateJsonCommands(text, strings, patterns) {
|
|
|
3588
3580
|
return { text: applyTextEdits(text, edits), changes, manualSteps };
|
|
3589
3581
|
}
|
|
3590
3582
|
|
|
3583
|
+
const ASSIGNMENT_RE$1 = /^(?:export[ \t]+)?([A-Za-z_][A-Za-z0-9_-]*)[ \t]*:=[ \t]*(.*)$/gm;
|
|
3584
|
+
const STRING_VALUE_RE = /^(?:"((?:[^"\\\n]|\\.)*)"|'([^'\n]*)')(?:[ \t]+#.*)?$/;
|
|
3585
|
+
const NAME_VALUE_RE = /^([A-Za-z_][A-Za-z0-9_-]*)(?:[ \t]+#.*)?$/;
|
|
3586
|
+
const INTERPOLATION_RE = /\{\{[^\n]*?\}\}/g;
|
|
3587
|
+
const VARIABLE_INTERPOLATION_RE = /^[@+-]*\{\{[ \t]*([A-Za-z_][A-Za-z0-9_-]*)[ \t]*\}\}$/;
|
|
3588
|
+
const MASK$1 = "_";
|
|
3589
|
+
const BLANK = " ";
|
|
3590
|
+
const assignmentsOf$1 = (text) => [...text.matchAll(ASSIGNMENT_RE$1)].map((match) => {
|
|
3591
|
+
const written = match[2];
|
|
3592
|
+
const valueStart = match.index + match[0].length - written.length;
|
|
3593
|
+
return { name: match[1], value: written.trim(), start: match.index, valueStart };
|
|
3594
|
+
});
|
|
3595
|
+
function stringValue(value) {
|
|
3596
|
+
const match = STRING_VALUE_RE.exec(value);
|
|
3597
|
+
return match === null ? void 0 : match[1] ?? match[2];
|
|
3598
|
+
}
|
|
3599
|
+
function programDefinition({ name, value }) {
|
|
3600
|
+
const target = NAME_VALUE_RE.exec(value)?.[1];
|
|
3601
|
+
if (target !== void 0) {
|
|
3602
|
+
return { name, kind: "reference", target };
|
|
3603
|
+
}
|
|
3604
|
+
const text = stringValue(value);
|
|
3605
|
+
const runs = text !== void 0 && shellCommands(text).some(runsGenerator);
|
|
3606
|
+
return { name, kind: "command", runsGenerator: runs };
|
|
3607
|
+
}
|
|
3608
|
+
function shellText$1(text, assignments) {
|
|
3609
|
+
const parts = [];
|
|
3610
|
+
let copiedUpTo = 0;
|
|
3611
|
+
for (const { start, valueStart, value } of assignments) {
|
|
3612
|
+
const end = valueStart + value.length;
|
|
3613
|
+
parts.push(text.slice(copiedUpTo, start), BLANK.repeat(end - start));
|
|
3614
|
+
copiedUpTo = end;
|
|
3615
|
+
}
|
|
3616
|
+
parts.push(text.slice(copiedUpTo));
|
|
3617
|
+
return parts.join("").replace(INTERPOLATION_RE, (found) => MASK$1.repeat(found.length));
|
|
3618
|
+
}
|
|
3619
|
+
function valueCommands({ value, valueStart }) {
|
|
3620
|
+
const inner = stringValue(value);
|
|
3621
|
+
return inner === void 0 ? [] : shellCommandsAt(inner, valueStart + 1);
|
|
3622
|
+
}
|
|
3623
|
+
function justfileVariables(text, assignments, programs) {
|
|
3624
|
+
const values = /* @__PURE__ */ new Map();
|
|
3625
|
+
for (const { name, value } of assignments) {
|
|
3626
|
+
values.set(name, [values.get(name), stringValue(value) ?? value].join(" ").trim());
|
|
3627
|
+
}
|
|
3628
|
+
const writtenAt = (word) => text.slice(word.start, word.end);
|
|
3629
|
+
const nameAt = (word) => VARIABLE_INTERPOLATION_RE.exec(writtenAt(word))?.[1];
|
|
3630
|
+
return {
|
|
3631
|
+
programAt: (program) => {
|
|
3632
|
+
const name = nameAt(program);
|
|
3633
|
+
const found = name === void 0 ? void 0 : programs.get(name);
|
|
3634
|
+
return found === void 0 ? void 0 : { written: writtenAt(program), program: found };
|
|
3635
|
+
},
|
|
3636
|
+
referenceAt: (word) => {
|
|
3637
|
+
const name = nameAt(word);
|
|
3638
|
+
const value = name === void 0 ? void 0 : values.get(name);
|
|
3639
|
+
return value === void 0 ? void 0 : { written: writtenAt(word), value };
|
|
3640
|
+
}
|
|
3641
|
+
};
|
|
3642
|
+
}
|
|
3643
|
+
function migrateJustfile(text, file) {
|
|
3644
|
+
const lineOf = lineLocator(text);
|
|
3645
|
+
const assignments = assignmentsOf$1(text);
|
|
3646
|
+
const programs = variablePrograms(assignments.map(programDefinition));
|
|
3647
|
+
const variables = justfileVariables(text, assignments, programs);
|
|
3648
|
+
const commands = [
|
|
3649
|
+
...shellCommands(shellText$1(text, assignments)),
|
|
3650
|
+
...assignments.flatMap(valueCommands)
|
|
3651
|
+
];
|
|
3652
|
+
const locate = (offset) => `${file}:${lineOf(offset)}`;
|
|
3653
|
+
const { edits, changes, manualSteps } = commandWordFindings(commands, locate, variables);
|
|
3654
|
+
return { text: applyTextEdits(text, edits), changes, manualSteps };
|
|
3655
|
+
}
|
|
3656
|
+
|
|
3591
3657
|
const ASSIGNMENT_RE = new RegExp(
|
|
3592
3658
|
[
|
|
3593
3659
|
"^(?:[^\\s:#=][^:#=\\n]*:[ \\t]*)?",
|
|
@@ -3723,6 +3789,140 @@ function migrateMakefile(text, file) {
|
|
|
3723
3789
|
return { text: applyTextEdits(text, edits), changes, manualSteps };
|
|
3724
3790
|
}
|
|
3725
3791
|
|
|
3792
|
+
const PARENT_SEPARATOR = ">";
|
|
3793
|
+
const PATH_SEPARATOR$2 = "/";
|
|
3794
|
+
const SCOPE_PREFIX = "@";
|
|
3795
|
+
function overrideTarget(key) {
|
|
3796
|
+
const child = key.split(PARENT_SEPARATOR).at(-1) ?? key;
|
|
3797
|
+
const segments = child.split(PATH_SEPARATOR$2);
|
|
3798
|
+
const isScoped = segments.length > 1 && segments.at(-2)?.startsWith(SCOPE_PREFIX) === true;
|
|
3799
|
+
const name = isScoped ? segments.slice(-2).join(PATH_SEPARATOR$2) : segments.at(-1) ?? child;
|
|
3800
|
+
const versionAt = name.indexOf(SCOPE_PREFIX, 1);
|
|
3801
|
+
return versionAt === -1 ? name : name.slice(0, versionAt);
|
|
3802
|
+
}
|
|
3803
|
+
function overriddenPackages(keys) {
|
|
3804
|
+
const targets = keys.map(overrideTarget);
|
|
3805
|
+
return [...new Set(targets.filter((target) => PACKAGE_RENAMES.has(target)))];
|
|
3806
|
+
}
|
|
3807
|
+
|
|
3808
|
+
const PATH_SEPARATOR$1 = ".";
|
|
3809
|
+
function catalogMaps(root, prefix = "") {
|
|
3810
|
+
const maps = mapsAt(root, CATALOG_FIELD).map((map) => ({
|
|
3811
|
+
name: DEFAULT_CATALOG,
|
|
3812
|
+
label: `${prefix}${CATALOG_FIELD}`,
|
|
3813
|
+
map
|
|
3814
|
+
}));
|
|
3815
|
+
for (const catalogs of mapsAt(root, NAMED_CATALOGS_FIELD)) {
|
|
3816
|
+
for (const { key, value } of textEntries(catalogs)) {
|
|
3817
|
+
if (isMap(value)) {
|
|
3818
|
+
const label = [prefix + NAMED_CATALOGS_FIELD, key.value].join(PATH_SEPARATOR$1);
|
|
3819
|
+
maps.push({ name: key.value, label, map: value });
|
|
3820
|
+
}
|
|
3821
|
+
}
|
|
3822
|
+
}
|
|
3823
|
+
return maps;
|
|
3824
|
+
}
|
|
3825
|
+
const manifestCatalogMaps = (manifest) => [
|
|
3826
|
+
...catalogMaps(manifest),
|
|
3827
|
+
...mapsAt(manifest, WORKSPACES_FIELD).flatMap(
|
|
3828
|
+
(workspaces) => catalogMaps(workspaces, `${WORKSPACES_FIELD}${PATH_SEPARATOR$1}`)
|
|
3829
|
+
)
|
|
3830
|
+
];
|
|
3831
|
+
function entriesInUse(manifests) {
|
|
3832
|
+
const inUse = new CatalogEntries();
|
|
3833
|
+
const fields = manifests.flatMap(
|
|
3834
|
+
(manifest) => DEPENDENCY_FIELDS.flatMap((field) => mapsAt(manifest, field))
|
|
3835
|
+
);
|
|
3836
|
+
for (const dependencies of fields) {
|
|
3837
|
+
const entries = specEntries(dependencies);
|
|
3838
|
+
const names = new Set(entries.map((entry) => entry.name));
|
|
3839
|
+
for (const { name, spec } of entries) {
|
|
3840
|
+
const catalog = spec === void 0 ? void 0 : catalogOfSpec(spec.value);
|
|
3841
|
+
const to = PACKAGE_RENAMES.get(name);
|
|
3842
|
+
if (catalog !== void 0 && to !== void 0 && names.has(to)) {
|
|
3843
|
+
inUse.add(catalog, name);
|
|
3844
|
+
}
|
|
3845
|
+
}
|
|
3846
|
+
}
|
|
3847
|
+
return inUse;
|
|
3848
|
+
}
|
|
3849
|
+
function nestedTexts(node) {
|
|
3850
|
+
if (node.kind !== "map") {
|
|
3851
|
+
return [];
|
|
3852
|
+
}
|
|
3853
|
+
return textEntries(node).flatMap(
|
|
3854
|
+
({ key, value }) => value.kind === "scalar" ? [{ key: key.value, value: value.value }] : nestedTexts(value)
|
|
3855
|
+
);
|
|
3856
|
+
}
|
|
3857
|
+
function addOverrideUses(documents, inUse) {
|
|
3858
|
+
const sections = documents.flatMap(
|
|
3859
|
+
(document) => [...OVERRIDE_FIELDS, PNPM_SETTINGS_FIELD].flatMap((field) => valuesAt(document, field))
|
|
3860
|
+
);
|
|
3861
|
+
for (const { key, value } of sections.flatMap(nestedTexts)) {
|
|
3862
|
+
const catalog = catalogOfSpec(value);
|
|
3863
|
+
const name = overrideTarget(key);
|
|
3864
|
+
if (catalog !== void 0 && PACKAGE_RENAMES.has(name)) {
|
|
3865
|
+
inUse.add(catalog, name);
|
|
3866
|
+
}
|
|
3867
|
+
}
|
|
3868
|
+
}
|
|
3869
|
+
function planCatalogs({
|
|
3870
|
+
manifests,
|
|
3871
|
+
catalogFiles,
|
|
3872
|
+
isWorkspaceRoot
|
|
3873
|
+
}) {
|
|
3874
|
+
const inUse = entriesInUse(manifests);
|
|
3875
|
+
addOverrideUses([...manifests, ...catalogFiles], inUse);
|
|
3876
|
+
const kept = new CatalogEntries();
|
|
3877
|
+
const defined = new CatalogEntries();
|
|
3878
|
+
const catalogs = [
|
|
3879
|
+
...catalogFiles.flatMap((file) => catalogMaps(file)),
|
|
3880
|
+
...manifests.flatMap(manifestCatalogMaps)
|
|
3881
|
+
];
|
|
3882
|
+
for (const { name: catalog, map } of catalogs) {
|
|
3883
|
+
const entries = specEntries(map);
|
|
3884
|
+
const names = new Set(entries.map((entry) => entry.name));
|
|
3885
|
+
for (const { name, spec } of entries) {
|
|
3886
|
+
defined.add(catalog, name);
|
|
3887
|
+
const to = PACKAGE_RENAMES.get(name);
|
|
3888
|
+
const stays = spec === void 0 || inUse.has(catalog, name);
|
|
3889
|
+
if (to !== void 0 && !names.has(to) && stays) {
|
|
3890
|
+
kept.add(catalog, name);
|
|
3891
|
+
}
|
|
3892
|
+
}
|
|
3893
|
+
}
|
|
3894
|
+
return { inUse, kept, defined, isWorkspaceRoot };
|
|
3895
|
+
}
|
|
3896
|
+
|
|
3897
|
+
const PNPM_OVERRIDES = "overrides";
|
|
3898
|
+
function isSuccessorAlias(key, value) {
|
|
3899
|
+
const successor = PACKAGE_RENAMES.get(overrideTarget(key));
|
|
3900
|
+
return value.kind === "scalar" && value.value.startsWith(NPM_SPECIFIER_PREFIX) && packageReference(value.value).name === successor;
|
|
3901
|
+
}
|
|
3902
|
+
function overriddenOldPackages(node) {
|
|
3903
|
+
const names = node.kind === "map" ? textEntries(node).flatMap(
|
|
3904
|
+
({ key, value }) => isSuccessorAlias(key.value, value) ? [] : [overrideTarget(key.value), ...overriddenOldPackages(value)]
|
|
3905
|
+
) : documentStrings([node]).map((string) => packageReference(string.value).name);
|
|
3906
|
+
return [...new Set(names.filter((name) => PACKAGE_RENAMES.has(name)))];
|
|
3907
|
+
}
|
|
3908
|
+
function aliasedIn(node) {
|
|
3909
|
+
if (node.kind !== "map") {
|
|
3910
|
+
return [];
|
|
3911
|
+
}
|
|
3912
|
+
return textEntries(node).flatMap(
|
|
3913
|
+
({ key, value }) => isSuccessorAlias(key.value, value) ? [overrideTarget(key.value)] : aliasedIn(value)
|
|
3914
|
+
);
|
|
3915
|
+
}
|
|
3916
|
+
function successorAliasedPackages(root) {
|
|
3917
|
+
const fields = [...OVERRIDE_FIELDS].flatMap((field) => mapsAt(root, field));
|
|
3918
|
+
const pnpm = mapsAt(root, PNPM_SETTINGS_FIELD).flatMap((map) => mapsAt(map, PNPM_OVERRIDES));
|
|
3919
|
+
return [...new Set([...fields, ...pnpm].flatMap(aliasedIn))];
|
|
3920
|
+
}
|
|
3921
|
+
function aliasedPackagesFor(aliases, filePath) {
|
|
3922
|
+
const applying = aliases.filter(({ path }) => isAtOrAbove(path, filePath));
|
|
3923
|
+
return new Set(applying.flatMap(({ names }) => [...names]));
|
|
3924
|
+
}
|
|
3925
|
+
|
|
3726
3926
|
function oldPackagesNamedBy(node) {
|
|
3727
3927
|
const values = documentStrings([node]).map((string) => packageReference(string.value).name);
|
|
3728
3928
|
const names = [...nestedKeys(node).map(overrideTarget), ...values];
|
|
@@ -3735,7 +3935,8 @@ function reportSettingSections(settings, file, findings) {
|
|
|
3735
3935
|
}
|
|
3736
3936
|
const field = `${file.prefix}${key.value}`;
|
|
3737
3937
|
const isOverride = file.overrideSections.has(key.value);
|
|
3738
|
-
|
|
3938
|
+
const names = isOverride ? overriddenOldPackages(value) : oldPackagesNamedBy(value);
|
|
3939
|
+
for (const name of names) {
|
|
3739
3940
|
findings.manualSteps.push(
|
|
3740
3941
|
isOverride ? { kind: "override-names-package", field, name } : { kind: "setting-names-package", field, name }
|
|
3741
3942
|
);
|
|
@@ -3806,7 +4007,18 @@ function migrateBrowserField(manifest, findings) {
|
|
|
3806
4007
|
}
|
|
3807
4008
|
}
|
|
3808
4009
|
}
|
|
4010
|
+
function reportOldPackagePaths(node, prefix, findings) {
|
|
4011
|
+
for (const value of documentStrings([node])) {
|
|
4012
|
+
const name = oldPackageInNodeModules(value.value);
|
|
4013
|
+
const to = name === void 0 ? void 0 : PACKAGE_RENAMES.get(name);
|
|
4014
|
+
if (name !== void 0 && to !== void 0) {
|
|
4015
|
+
const location = [...prefix, ...value.path].join(PATH_SEPARATOR);
|
|
4016
|
+
findings.manualSteps.push({ kind: "old-package-path", location, path: value.value, to });
|
|
4017
|
+
}
|
|
4018
|
+
}
|
|
4019
|
+
}
|
|
3809
4020
|
|
|
4021
|
+
const TYPES_VERSIONS_FIELD = "typesVersions";
|
|
3810
4022
|
function migrateDependencyFields(manifest, target, findings) {
|
|
3811
4023
|
for (const field of DEPENDENCY_FIELDS) {
|
|
3812
4024
|
for (const dependencies of mapsAt(manifest, field)) {
|
|
@@ -3852,7 +4064,7 @@ const PNPM_SETTINGS = {
|
|
|
3852
4064
|
};
|
|
3853
4065
|
function reportSettings(manifest, findings) {
|
|
3854
4066
|
for (const field of OVERRIDE_FIELDS) {
|
|
3855
|
-
for (const name of valuesAt(manifest, field).flatMap(
|
|
4067
|
+
for (const name of valuesAt(manifest, field).flatMap(overriddenOldPackages)) {
|
|
3856
4068
|
findings.manualSteps.push({ kind: "override-names-package", field, name });
|
|
3857
4069
|
}
|
|
3858
4070
|
}
|
|
@@ -3860,10 +4072,10 @@ function reportSettings(manifest, findings) {
|
|
|
3860
4072
|
reportSettingSections(settings, PNPM_SETTINGS, findings);
|
|
3861
4073
|
}
|
|
3862
4074
|
}
|
|
3863
|
-
function reportOldPeers(manifest, findings) {
|
|
4075
|
+
function reportOldPeers(manifest, aliased, findings) {
|
|
3864
4076
|
const dependencies = new Set(declaredNames(manifest));
|
|
3865
4077
|
for (const [dependent, { peer, range }] of OLD_PEER_DEPENDENTS) {
|
|
3866
|
-
if (dependencies.has(dependent)) {
|
|
4078
|
+
if (dependencies.has(dependent) && !aliased.has(peer)) {
|
|
3867
4079
|
findings.manualSteps.push({ kind: "old-peer-needed", dependent, peer, range });
|
|
3868
4080
|
}
|
|
3869
4081
|
}
|
|
@@ -3875,11 +4087,14 @@ function migrateManifestMap(manifest, target, findings) {
|
|
|
3875
4087
|
migrateCatalogs$1(manifest, target, findings);
|
|
3876
4088
|
migrateSubpathImports(manifest, findings);
|
|
3877
4089
|
migrateBrowserField(manifest, findings);
|
|
4090
|
+
for (const versions of valuesAt(manifest, TYPES_VERSIONS_FIELD)) {
|
|
4091
|
+
reportOldPackagePaths(versions, [TYPES_VERSIONS_FIELD], findings);
|
|
4092
|
+
}
|
|
3878
4093
|
reportSettings(manifest, findings);
|
|
3879
4094
|
for (const jest of valuesAt(manifest, JEST_FIELD)) {
|
|
3880
4095
|
findings.manualSteps.push(...jestConfigSteps(jest, [JEST_FIELD]));
|
|
3881
4096
|
}
|
|
3882
|
-
reportOldPeers(manifest, findings);
|
|
4097
|
+
reportOldPeers(manifest, target.aliased ?? /* @__PURE__ */ new Set(), findings);
|
|
3883
4098
|
}
|
|
3884
4099
|
function migratePackageManifest(text, read, target) {
|
|
3885
4100
|
if (read.kind === "unreadable") {
|
|
@@ -3914,6 +4129,29 @@ function oldPackagePatchSteps(fileName) {
|
|
|
3914
4129
|
return name === void 0 || to === void 0 ? [] : [{ kind: "old-package-patch", name, to }];
|
|
3915
4130
|
}
|
|
3916
4131
|
|
|
4132
|
+
const STEP_SHELL_KEY = "shell";
|
|
4133
|
+
const COMMAND_LINE_SHELLS = /* @__PURE__ */ new Set([
|
|
4134
|
+
...["sh", "bash", "dash", "ash", "zsh", "ksh"],
|
|
4135
|
+
...["pwsh", "powershell", "cmd"]
|
|
4136
|
+
]);
|
|
4137
|
+
const PATH_SEPARATOR_RE = /[/\\]/;
|
|
4138
|
+
const WHITESPACE_RE = /\s+/;
|
|
4139
|
+
const shellProgram = (shell) => shell.trim().split(WHITESPACE_RE)[0]?.split(PATH_SEPARATOR_RE).at(-1) ?? "";
|
|
4140
|
+
function stepShells(strings) {
|
|
4141
|
+
const stepOf = (path) => JSON.stringify(path.slice(0, -1));
|
|
4142
|
+
const others = new Map(
|
|
4143
|
+
strings.filter((value) => value.path.at(-1) === STEP_SHELL_KEY).filter((value) => !COMMAND_LINE_SHELLS.has(shellProgram(value.value))).map((value) => [stepOf(value.path), value.value])
|
|
4144
|
+
);
|
|
4145
|
+
return (value) => others.get(stepOf(value.path));
|
|
4146
|
+
}
|
|
4147
|
+
function otherShellFindings(values, shellOf, locate) {
|
|
4148
|
+
const manualSteps = values.flatMap((value) => {
|
|
4149
|
+
const shell = shellOf(value);
|
|
4150
|
+
return shell === void 0 || !namesOriginalPackage(value.value) ? [] : [{ kind: "script-not-shell", location: locate(value.start), shell }];
|
|
4151
|
+
});
|
|
4152
|
+
return { edits: [], changes: [], manualSteps };
|
|
4153
|
+
}
|
|
4154
|
+
|
|
3917
4155
|
const YAML_COMMAND_KEYS = /* @__PURE__ */ new Set([
|
|
3918
4156
|
"run",
|
|
3919
4157
|
"script",
|
|
@@ -3938,6 +4176,10 @@ const TASKFILE_COMMAND_KEYS = /* @__PURE__ */ new Set([
|
|
|
3938
4176
|
"status"
|
|
3939
4177
|
]);
|
|
3940
4178
|
|
|
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
|
+
);
|
|
3941
4183
|
const ENVIRONMENT_KEYS = /* @__PURE__ */ new Set(["env"]);
|
|
3942
4184
|
const isEnvironmentValue = (value) => value.path.length >= 2 && ENVIRONMENT_KEYS.has(String(value.path.at(-2)));
|
|
3943
4185
|
function environmentVariables(text, strings) {
|
|
@@ -4017,9 +4259,10 @@ function appliedFindings(text, found) {
|
|
|
4017
4259
|
};
|
|
4018
4260
|
}
|
|
4019
4261
|
function migrateYamlCommands(text, file, strings, keys = YAML_COMMAND_KEYS) {
|
|
4020
|
-
const values = valuesOf(strings, keys);
|
|
4021
4262
|
const lineOf = lineLocator(text);
|
|
4022
4263
|
const locate = (offset) => `${file}:${lineOf(offset)}`;
|
|
4264
|
+
const shellOf = stepShells(strings);
|
|
4265
|
+
const values = valuesOf(strings, keys).filter((value) => shellOf(value) === void 0);
|
|
4023
4266
|
const commandValues = new Set(values.filter((value) => !isExecFormItem(value)));
|
|
4024
4267
|
const shellValues = strings.filter(
|
|
4025
4268
|
(value) => commandValues.has(value) || isEnvironmentValue(value)
|
|
@@ -4027,7 +4270,8 @@ function migrateYamlCommands(text, file, strings, keys = YAML_COMMAND_KEYS) {
|
|
|
4027
4270
|
const variables = environmentVariables(text, strings);
|
|
4028
4271
|
return appliedFindings(text, [
|
|
4029
4272
|
...shellValues.map((value) => valueFindings(text, value, locate, variables)),
|
|
4030
|
-
commandWordFindings(execFormCommands(text, values.filter(isExecFormItem)), locate)
|
|
4273
|
+
commandWordFindings(execFormCommands(text, values.filter(isExecFormItem)), locate),
|
|
4274
|
+
otherShellFindings(valuesOf(strings, keys), shellOf, locate)
|
|
4031
4275
|
]);
|
|
4032
4276
|
}
|
|
4033
4277
|
function migrateYamlPathCommands(text, strings, patterns) {
|
|
@@ -4115,16 +4359,6 @@ const COMPILER_OPTIONS_FIELD = "compilerOptions";
|
|
|
4115
4359
|
const PATHS_FIELD = "paths";
|
|
4116
4360
|
const TYPES_FIELD = "types";
|
|
4117
4361
|
const FIELD_SEPARATOR = ".";
|
|
4118
|
-
function reportOldPackagePaths(config, findings) {
|
|
4119
|
-
for (const value of documentStrings([config])) {
|
|
4120
|
-
const name = oldPackageInNodeModules(value.value);
|
|
4121
|
-
const to = name === void 0 ? void 0 : PACKAGE_RENAMES.get(name);
|
|
4122
|
-
if (name !== void 0 && to !== void 0) {
|
|
4123
|
-
const location = value.path.join(FIELD_SEPARATOR);
|
|
4124
|
-
findings.manualSteps.push({ kind: "old-package-path", location, path: value.value, to });
|
|
4125
|
-
}
|
|
4126
|
-
}
|
|
4127
|
-
}
|
|
4128
4362
|
function migrateCompilerOptions(options, findings) {
|
|
4129
4363
|
for (const paths of mapsAt(options, PATHS_FIELD)) {
|
|
4130
4364
|
const field = [COMPILER_OPTIONS_FIELD, PATHS_FIELD].join(FIELD_SEPARATOR);
|
|
@@ -4146,7 +4380,7 @@ function migrateTsconfig(text, read) {
|
|
|
4146
4380
|
for (const options of mapsAt(config, COMPILER_OPTIONS_FIELD)) {
|
|
4147
4381
|
migrateCompilerOptions(options, findings);
|
|
4148
4382
|
}
|
|
4149
|
-
reportOldPackagePaths(config, findings);
|
|
4383
|
+
reportOldPackagePaths(config, [], findings);
|
|
4150
4384
|
}
|
|
4151
4385
|
const { edits, changes, manualSteps } = findings;
|
|
4152
4386
|
return { text: applyTextEdits(text, edits), changes, manualSteps };
|
|
@@ -4215,7 +4449,7 @@ const SHELL_EXTENSIONS = /* @__PURE__ */ new Set([".sh", ".bash", ".zsh"]);
|
|
|
4215
4449
|
const MAKEFILE_EXTENSION = ".mk";
|
|
4216
4450
|
const YAML_EXTENSIONS = /* @__PURE__ */ new Set([".yml", ".yaml"]);
|
|
4217
4451
|
const MAKEFILE_NAMES = /* @__PURE__ */ new Set(["Makefile", "makefile", "GNUmakefile"]);
|
|
4218
|
-
const
|
|
4452
|
+
const JUSTFILE_NAMES = /* @__PURE__ */ new Set(["justfile", "Justfile", ".justfile"]);
|
|
4219
4453
|
const DOCKERFILE_NAMES = /* @__PURE__ */ new Set(["Dockerfile", "Containerfile"]);
|
|
4220
4454
|
const HUSKY_FOLDER = ".husky/";
|
|
4221
4455
|
const HUSKY_INTERNALS = ".husky/_/";
|
|
@@ -4289,10 +4523,11 @@ function joinedNames(sets) {
|
|
|
4289
4523
|
}
|
|
4290
4524
|
function withNamedImportMaps(declarations, importMaps) {
|
|
4291
4525
|
const mapNames = new Map(declarations.map(({ path, names }) => [path, names]));
|
|
4292
|
-
return declarations.filter(({ path }) => !importMaps.has(path)).map((
|
|
4526
|
+
return declarations.filter(({ path }) => !importMaps.has(path)).map((declaration) => {
|
|
4527
|
+
const { path, names } = declaration;
|
|
4293
4528
|
const maps = [...importMaps].filter(([, configs]) => configs.includes(path));
|
|
4294
4529
|
const named = maps.flatMap(([map]) => mapNames.has(map) ? [mapNames.get(map)] : []);
|
|
4295
|
-
return {
|
|
4530
|
+
return { ...declaration, names: joinedNames([names, ...named]) };
|
|
4296
4531
|
});
|
|
4297
4532
|
}
|
|
4298
4533
|
|
|
@@ -4300,8 +4535,9 @@ const isHuskyHook = (path) => (path.startsWith(HUSKY_FOLDER) || path.includes(`/
|
|
|
4300
4535
|
const isDependabotConfig = (path) => [...DEPENDABOT_FILES].some((file) => path === file || path.endsWith(`/${file}`));
|
|
4301
4536
|
function migrateSource(text, path, context) {
|
|
4302
4537
|
const strings = context.scanner.scan(text, path);
|
|
4538
|
+
const kept = localPackagesFor(context.manifests, path);
|
|
4303
4539
|
const migrated = chain(
|
|
4304
|
-
migrateModuleSpecifiers(text, strings, context.version),
|
|
4540
|
+
migrateModuleSpecifiers(text, strings, context.version, kept),
|
|
4305
4541
|
(renamed) => context.rewriter.rewrite(renamed, path)
|
|
4306
4542
|
);
|
|
4307
4543
|
const imports = importedSpecifiers(text, strings);
|
|
@@ -4353,18 +4589,24 @@ const COMMAND_CONFIG_KINDS = [
|
|
|
4353
4589
|
)
|
|
4354
4590
|
}
|
|
4355
4591
|
];
|
|
4592
|
+
const yamlCommandsStep = (path) => (text, read) => read.kind === "read" && isApiDescription(read.documents) ? unchanged(text) : stringsStep((current, strings) => migrateYamlCommands(current, path, strings))(text, read);
|
|
4593
|
+
const manifestTarget = ({ version, catalogs, aliases }, path) => ({
|
|
4594
|
+
version,
|
|
4595
|
+
catalogs,
|
|
4596
|
+
aliased: aliasedPackagesFor(aliases, path)
|
|
4597
|
+
});
|
|
4356
4598
|
const FILE_KINDS = [
|
|
4357
4599
|
{
|
|
4358
4600
|
matches: (path) => baseName(path) === MANIFEST_FILE,
|
|
4359
|
-
migrate: jsonConfig((
|
|
4360
|
-
(text, read) => migratePackageManifest(text, read,
|
|
4601
|
+
migrate: jsonConfig((context, path) => [
|
|
4602
|
+
(text, read) => migratePackageManifest(text, read, manifestTarget(context, path)),
|
|
4361
4603
|
jsonCommandsStep(MANIFEST_COMMAND_PATHS)
|
|
4362
4604
|
])
|
|
4363
4605
|
},
|
|
4364
4606
|
{
|
|
4365
4607
|
matches: (path) => YAML_MANIFEST_FILES.has(baseName(path)),
|
|
4366
|
-
migrate: yamlConfig((
|
|
4367
|
-
(text, read) => migratePackageManifest(text, read,
|
|
4608
|
+
migrate: yamlConfig((context, path) => [
|
|
4609
|
+
(text, read) => migratePackageManifest(text, read, manifestTarget(context, path)),
|
|
4368
4610
|
yamlPathCommands(MANIFEST_COMMAND_PATHS)
|
|
4369
4611
|
])
|
|
4370
4612
|
},
|
|
@@ -4423,11 +4665,7 @@ const FILE_KINDS = [
|
|
|
4423
4665
|
},
|
|
4424
4666
|
{
|
|
4425
4667
|
matches: (path) => YAML_EXTENSIONS.has(extensionOf(path)),
|
|
4426
|
-
migrate: whenNamed(
|
|
4427
|
-
yamlConfig((_context, path) => [
|
|
4428
|
-
stringsStep((text, strings) => migrateYamlCommands(text, path, strings))
|
|
4429
|
-
])
|
|
4430
|
-
)
|
|
4668
|
+
migrate: whenNamed(yamlConfig((_context, path) => [yamlCommandsStep(path)]))
|
|
4431
4669
|
},
|
|
4432
4670
|
{
|
|
4433
4671
|
matches: (path) => DOCKERFILE_NAMES.has(baseName(path)),
|
|
@@ -4438,7 +4676,11 @@ const FILE_KINDS = [
|
|
|
4438
4676
|
migrate: whenNamed((text, path) => migrateMakefile(text, path))
|
|
4439
4677
|
},
|
|
4440
4678
|
{
|
|
4441
|
-
matches: (path) =>
|
|
4679
|
+
matches: (path) => JUSTFILE_NAMES.has(baseName(path)),
|
|
4680
|
+
migrate: whenNamed((text, path) => migrateJustfile(text, path))
|
|
4681
|
+
},
|
|
4682
|
+
{
|
|
4683
|
+
matches: (path) => SHELL_EXTENSIONS.has(extensionOf(path)) || isHuskyHook(path),
|
|
4442
4684
|
migrate: whenNamed((text, path) => migrateCommandLines(text, path))
|
|
4443
4685
|
}
|
|
4444
4686
|
];
|
|
@@ -4472,27 +4714,6 @@ function planSourceOf(path, namedImportMaps) {
|
|
|
4472
4714
|
return isCatalogFile ? { role: "catalogs", read: readYaml } : void 0;
|
|
4473
4715
|
}
|
|
4474
4716
|
|
|
4475
|
-
async function planFile(path, dependencies, target) {
|
|
4476
|
-
const migrate = fileMigrationFor(path, target.importMaps);
|
|
4477
|
-
if (migrate === void 0) {
|
|
4478
|
-
return { kind: "not-migrated" };
|
|
4479
|
-
}
|
|
4480
|
-
const read = await dependencies.files.read(path);
|
|
4481
|
-
if (read.kind === "skipped") {
|
|
4482
|
-
return read;
|
|
4483
|
-
}
|
|
4484
|
-
const { rewriter, scanner, readers } = dependencies;
|
|
4485
|
-
const { version, catalogs, manifests } = target;
|
|
4486
|
-
const context = { version, catalogs, manifests, rewriter, scanner, readers };
|
|
4487
|
-
const migration = migrate(read.text, path, context);
|
|
4488
|
-
const isChanged = migration.text !== read.text;
|
|
4489
|
-
const { changes, manualSteps } = migration;
|
|
4490
|
-
if (isChanged || manualSteps.length > 0) {
|
|
4491
|
-
dependencies.logger.info("file_migrated", { path, isChanged, changes, manualSteps });
|
|
4492
|
-
}
|
|
4493
|
-
const report = { path, isChanged, changes, manualSteps };
|
|
4494
|
-
return { kind: "planned", file: { report, text: isChanged ? migration.text : void 0 } };
|
|
4495
|
-
}
|
|
4496
4717
|
async function readForPlan(path, source, dependencies) {
|
|
4497
4718
|
const read = await dependencies.files.read(path);
|
|
4498
4719
|
if (read.kind !== "read") {
|
|
@@ -4516,9 +4737,22 @@ function marksWorkspaceRoot(path, roots) {
|
|
|
4516
4737
|
return manifests.some((manifest) => valuesAt(manifest, WORKSPACES_FIELD).length > 0);
|
|
4517
4738
|
}
|
|
4518
4739
|
const DECLARED_NAMES = { manifest: declaredNames, "import-map": importMapNames, catalogs: void 0 };
|
|
4740
|
+
function declarationsOf(path, role, roots) {
|
|
4741
|
+
const names = DECLARED_NAMES[role];
|
|
4742
|
+
if (names === void 0) {
|
|
4743
|
+
return [];
|
|
4744
|
+
}
|
|
4745
|
+
const local = role === "manifest" ? (roots ?? []).flatMap(localPackageNames) : [];
|
|
4746
|
+
return [{ path, names: roots && new Set(roots.flatMap(names)), localPackages: new Set(local) }];
|
|
4747
|
+
}
|
|
4748
|
+
function aliasesOf(path, roots) {
|
|
4749
|
+
const names = (roots ?? []).flatMap(successorAliasedPackages);
|
|
4750
|
+
return names.length === 0 ? [] : [{ path, names: new Set(names) }];
|
|
4751
|
+
}
|
|
4519
4752
|
async function planProjectTarget(paths, dependencies, version) {
|
|
4520
4753
|
const documents = { manifest: [], catalogs: [] };
|
|
4521
4754
|
const manifests = [];
|
|
4755
|
+
const aliases = [];
|
|
4522
4756
|
let isWorkspaceRoot = false;
|
|
4523
4757
|
const importMaps = await namedImportMaps(paths, dependencies.files, dependencies.readers);
|
|
4524
4758
|
for (const path of paths) {
|
|
@@ -4531,17 +4765,41 @@ async function planProjectTarget(paths, dependencies, version) {
|
|
|
4531
4765
|
if (namesOriginal && source.role !== "import-map") {
|
|
4532
4766
|
documents[source.role].push(...roots ?? []);
|
|
4533
4767
|
}
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
manifests.push({ path, names: roots && new Set(roots.flatMap(names)) });
|
|
4537
|
-
}
|
|
4768
|
+
manifests.push(...declarationsOf(path, source.role, roots));
|
|
4769
|
+
aliases.push(...aliasesOf(path, roots));
|
|
4538
4770
|
}
|
|
4539
4771
|
const catalogs = planCatalogs({
|
|
4540
4772
|
manifests: documents.manifest,
|
|
4541
4773
|
catalogFiles: documents.catalogs,
|
|
4542
4774
|
isWorkspaceRoot
|
|
4543
4775
|
});
|
|
4544
|
-
|
|
4776
|
+
const declarations = withNamedImportMaps(manifests, importMaps);
|
|
4777
|
+
return { version, catalogs, manifests: declarations, aliases, importMaps };
|
|
4778
|
+
}
|
|
4779
|
+
|
|
4780
|
+
async function planFile(path, dependencies, target) {
|
|
4781
|
+
const migrate = fileMigrationFor(path, target.importMaps);
|
|
4782
|
+
if (migrate === void 0) {
|
|
4783
|
+
return { kind: "not-migrated" };
|
|
4784
|
+
}
|
|
4785
|
+
const read = await dependencies.files.read(path);
|
|
4786
|
+
if (read.kind === "skipped") {
|
|
4787
|
+
return read;
|
|
4788
|
+
}
|
|
4789
|
+
const { rewriter, scanner, readers } = dependencies;
|
|
4790
|
+
const { version, catalogs, manifests, aliases } = target;
|
|
4791
|
+
const context = {
|
|
4792
|
+
...{ version, catalogs, manifests, aliases },
|
|
4793
|
+
...{ rewriter, scanner, readers }
|
|
4794
|
+
};
|
|
4795
|
+
const migration = migrate(read.text, path, context);
|
|
4796
|
+
const isChanged = migration.text !== read.text;
|
|
4797
|
+
const { changes, manualSteps } = migration;
|
|
4798
|
+
if (isChanged || manualSteps.length > 0) {
|
|
4799
|
+
dependencies.logger.info("file_migrated", { path, isChanged, changes, manualSteps });
|
|
4800
|
+
}
|
|
4801
|
+
const report = { path, isChanged, changes, manualSteps };
|
|
4802
|
+
return { kind: "planned", file: { report, text: isChanged ? migration.text : void 0 } };
|
|
4545
4803
|
}
|
|
4546
4804
|
async function planProject(paths, dependencies, version) {
|
|
4547
4805
|
const files = [];
|
|
@@ -4623,6 +4881,7 @@ const OLD_FILE_NOTE$1 = "is a file of openapi-typescript, which is no longer ins
|
|
|
4623
4881
|
const FLAGS_IN_VARIABLE_NOTE = "holds old flags of the generator and may serve other commands, so it was kept: rename";
|
|
4624
4882
|
const NOT_ONLY_GENERATOR_NOTE = "runs openapi-typescript in some of its definitions in this file and another program in others, so the flags after it were kept; where it runs the generator, rename";
|
|
4625
4883
|
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
|
+
const SCRIPT_NOT_SHELL_NOTE = "so the tool does not read it as commands: migrate the old package names in it by hand";
|
|
4626
4885
|
const COMMAND_STRING_NOTE = "a string runs openapi-typescript, so it was kept; change it to";
|
|
4627
4886
|
function pinnedPackageMessage(step) {
|
|
4628
4887
|
const successor = PACKAGE_RENAMES.get(step.name) ?? step.name;
|
|
@@ -4642,6 +4901,7 @@ const COMMAND_STEP_KINDS = /* @__PURE__ */ new Set([
|
|
|
4642
4901
|
"pinned-package",
|
|
4643
4902
|
"old-package-file",
|
|
4644
4903
|
"old-name-in-command",
|
|
4904
|
+
"script-not-shell",
|
|
4645
4905
|
"command-string"
|
|
4646
4906
|
]);
|
|
4647
4907
|
const isCommandStep = (step) => COMMAND_STEP_KINDS.has(step.kind);
|
|
@@ -4659,6 +4919,8 @@ function commandStepMessage(step) {
|
|
|
4659
4919
|
return `${step.location}: ${step.path} ${OLD_FILE_NOTE$1}`;
|
|
4660
4920
|
case "old-name-in-command":
|
|
4661
4921
|
return `${step.location}: "${step.word}" ${OLD_NAME_IN_COMMAND_NOTE}`;
|
|
4922
|
+
case "script-not-shell":
|
|
4923
|
+
return `${step.location}: the step runs with shell: ${step.shell}, ${SCRIPT_NOT_SHELL_NOTE}`;
|
|
4662
4924
|
case "command-string":
|
|
4663
4925
|
return `line ${step.line}: ${COMMAND_STRING_NOTE} "${step.to}"`;
|
|
4664
4926
|
default:
|
|
@@ -4732,10 +4994,12 @@ const PATCH_NOTE = "check whether the fix is still needed, then make the patch a
|
|
|
4732
4994
|
const PATTERN_NOTE = "is a pattern that names";
|
|
4733
4995
|
const PATTERN_FIX_NOTE = "where it means the package, make it match";
|
|
4734
4996
|
const SETTING_NOTE = "remove the setting if it no longer applies, or make it name";
|
|
4997
|
+
const LOCAL_PACKAGE_NOTE = "points at a local package, not the npm package, so it and the imports of it were kept: if that package is a copy of the original, move it to";
|
|
4735
4998
|
const DEEP_TARGET_NOTE = "points at a file inside the package; check that it exists";
|
|
4736
4999
|
const OLD_PATH_NOTE = "is a path into node_modules of an old package, which is no longer installed:";
|
|
4737
5000
|
const OLD_PATH_FIX_NOTE = "point it at the files of";
|
|
4738
5001
|
const renamed = (name) => PACKAGE_RENAMES.get(name) ?? name;
|
|
5002
|
+
const localPackageMessage = (step) => `${step.field}: ${step.name} "${step.spec}" ${LOCAL_PACKAGE_NOTE} ${renamed(step.name)}`;
|
|
4739
5003
|
function oldPeerMessage(step) {
|
|
4740
5004
|
const { dependent, peer, range } = step;
|
|
4741
5005
|
const successor = PACKAGE_RENAMES.get(peer) ?? peer;
|
|
@@ -4779,6 +5043,8 @@ function packageStepMessage(step) {
|
|
|
4779
5043
|
return `${step.name} is a peer dependency: ${PEER_NOTE}`;
|
|
4780
5044
|
case "spec-kept":
|
|
4781
5045
|
return `${step.name} kept the spec "${step.spec}": point it at an openapi-typesafe version`;
|
|
5046
|
+
case "local-package":
|
|
5047
|
+
return localPackageMessage(step);
|
|
4782
5048
|
case "override-names-package":
|
|
4783
5049
|
return `"${step.field}" names ${step.name}: update or remove that override`;
|
|
4784
5050
|
case "setting-names-package":
|
|
@@ -4817,6 +5083,7 @@ function manualStepMessage(step) {
|
|
|
4817
5083
|
return catalogStepMessage(step);
|
|
4818
5084
|
case "peer-dependency-renamed":
|
|
4819
5085
|
case "spec-kept":
|
|
5086
|
+
case "local-package":
|
|
4820
5087
|
case "override-names-package":
|
|
4821
5088
|
case "setting-names-package":
|
|
4822
5089
|
case "pattern-names-package":
|
|
@@ -5107,8 +5374,8 @@ const createGit = (root) => createGitFileList({
|
|
|
5107
5374
|
const dependencies = {
|
|
5108
5375
|
version: readVersion(),
|
|
5109
5376
|
cwd: process.cwd(),
|
|
5110
|
-
writeStdout: (
|
|
5111
|
-
writeStderr: (
|
|
5377
|
+
writeStdout: createPipeSafeWriter(process.stdout),
|
|
5378
|
+
writeStderr: createPipeSafeWriter(process.stderr),
|
|
5112
5379
|
inspectRoot: inspectProjectRoot,
|
|
5113
5380
|
createFiles: (root, logger) => createNodeProjectFiles(root, { git: createGit(root), logger }),
|
|
5114
5381
|
createLogger,
|