openapi-typesafe-migrate 1.0.0-rc.8 → 1.0.0-rc.9
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 +46 -0
- package/README.md +16 -8
- package/dist/cli/main.mjs +345 -159
- package/dist/cli/main.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cli/main.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { win32, posix, join, dirname, isAbsolute, relative, sep, basename, resol
|
|
|
4
4
|
import { realpath, lstat, stat, access, readFile, writeFile, chmod, rename, rm, readdir } from 'node:fs/promises';
|
|
5
5
|
import { spawn } from 'node:child_process';
|
|
6
6
|
import ts from '@typescript/typescript6';
|
|
7
|
-
import { Scalar, parseAllDocuments, isScalar as isScalar$1, isSeq, isMap as isMap$1, isNode, CST } from 'yaml';
|
|
7
|
+
import { Scalar, parseAllDocuments, isScalar as isScalar$1, isSeq, isMap as isMap$1, isAlias, isNode, CST } from 'yaml';
|
|
8
8
|
import { parseArgs } from 'node:util';
|
|
9
9
|
|
|
10
10
|
const WINDOWS = "win32";
|
|
@@ -1336,10 +1336,14 @@ function joined(elements, operator, names) {
|
|
|
1336
1336
|
if (parts.some((part) => part === void 0)) {
|
|
1337
1337
|
return void 0;
|
|
1338
1338
|
}
|
|
1339
|
-
const
|
|
1340
|
-
(part) => operator === "&" && part.operator === "|" ? `(${part.text})` : part
|
|
1339
|
+
const members = parts.map(
|
|
1340
|
+
(part) => operator === "&" && part.operator === "|" ? plain$1(`(${part.text})`) : part
|
|
1341
1341
|
);
|
|
1342
|
-
|
|
1342
|
+
const [only] = members;
|
|
1343
|
+
if (members.length === 1 && only !== void 0) {
|
|
1344
|
+
return only;
|
|
1345
|
+
}
|
|
1346
|
+
return { text: members.map((member) => member.text).join(` ${operator} `), operator };
|
|
1343
1347
|
}
|
|
1344
1348
|
function factoryCallText(call, method, names) {
|
|
1345
1349
|
const [first, second] = call.arguments;
|
|
@@ -1954,6 +1958,7 @@ function convertScalar(node, isFlow) {
|
|
|
1954
1958
|
const isReplaceable = quotings !== void 0 && node.anchor === void 0 && node.tag === void 0;
|
|
1955
1959
|
return {
|
|
1956
1960
|
kind: "scalar",
|
|
1961
|
+
...anchorOf(node),
|
|
1957
1962
|
value,
|
|
1958
1963
|
content: contentRange(node.srcToken, span),
|
|
1959
1964
|
isFolded: node.type !== Scalar.BLOCK_LITERAL,
|
|
@@ -1962,6 +1967,7 @@ function convertScalar(node, isFlow) {
|
|
|
1962
1967
|
...span
|
|
1963
1968
|
};
|
|
1964
1969
|
}
|
|
1970
|
+
const anchorOf = (node) => node.anchor === void 0 ? {} : { anchor: node.anchor };
|
|
1965
1971
|
const flowOf = (conversion, node) => ({
|
|
1966
1972
|
isFlow: conversion.isFlow || node.flow === true
|
|
1967
1973
|
});
|
|
@@ -1971,7 +1977,8 @@ function convert(node, conversion) {
|
|
|
1971
1977
|
}
|
|
1972
1978
|
if (isSeq(node)) {
|
|
1973
1979
|
const inner = flowOf(conversion, node);
|
|
1974
|
-
|
|
1980
|
+
const items = node.items.map((item) => convert(item, inner));
|
|
1981
|
+
return { kind: "list", items, ...anchorOf(node), ...spanOf(node) };
|
|
1975
1982
|
}
|
|
1976
1983
|
if (isMap$1(node)) {
|
|
1977
1984
|
const inner = flowOf(conversion, node);
|
|
@@ -1979,7 +1986,10 @@ function convert(node, conversion) {
|
|
|
1979
1986
|
key: convert(pair.key, inner),
|
|
1980
1987
|
value: convert(pair.value, inner)
|
|
1981
1988
|
}));
|
|
1982
|
-
return { kind: "map", entries, ...spanOf(node) };
|
|
1989
|
+
return { kind: "map", entries, ...anchorOf(node), ...spanOf(node) };
|
|
1990
|
+
}
|
|
1991
|
+
if (isAlias(node)) {
|
|
1992
|
+
return { kind: "other", alias: node.source, ...spanOf(node) };
|
|
1983
1993
|
}
|
|
1984
1994
|
return { kind: "other", ...spanOf(isNode(node) ? node : {}) };
|
|
1985
1995
|
}
|
|
@@ -2062,10 +2072,10 @@ const PNPM_SETTINGS_FIELD = "pnpm";
|
|
|
2062
2072
|
const OLD_PEER_DEPENDENTS = /* @__PURE__ */ new Map([
|
|
2063
2073
|
["swr-openapi", { peer: "openapi-fetch", range: ">=0.15" }]
|
|
2064
2074
|
]);
|
|
2065
|
-
const PATH_SEPARATOR$
|
|
2075
|
+
const PATH_SEPARATOR$a = "/";
|
|
2066
2076
|
const QUERY_START = "?";
|
|
2067
2077
|
function renamedSpecifier(value) {
|
|
2068
|
-
const ends = [value.indexOf(PATH_SEPARATOR$
|
|
2078
|
+
const ends = [value.indexOf(PATH_SEPARATOR$a), value.indexOf(QUERY_START)].filter(
|
|
2069
2079
|
(at) => at !== -1
|
|
2070
2080
|
);
|
|
2071
2081
|
const name = value.slice(0, ends.length === 0 ? value.length : Math.min(...ends));
|
|
@@ -2075,12 +2085,12 @@ function renamedSpecifier(value) {
|
|
|
2075
2085
|
}
|
|
2076
2086
|
const rest = value.slice(name.length);
|
|
2077
2087
|
const subpath = rest.split(QUERY_START, 1)[0] ?? rest;
|
|
2078
|
-
return { to: `${renamed}${rest}`, isDeep: subpath !== "" && subpath !== PATH_SEPARATOR$
|
|
2088
|
+
return { to: `${renamed}${rest}`, isDeep: subpath !== "" && subpath !== PATH_SEPARATOR$a };
|
|
2079
2089
|
}
|
|
2080
2090
|
const NODE_MODULES_FOLDER = "node_modules/";
|
|
2081
2091
|
function oldPackageInNodeModules(path) {
|
|
2082
2092
|
return [...PACKAGE_RENAMES.keys()].find(
|
|
2083
|
-
(name) => path.includes(`${NODE_MODULES_FOLDER}${name}${PATH_SEPARATOR$
|
|
2093
|
+
(name) => path.includes(`${NODE_MODULES_FOLDER}${name}${PATH_SEPARATOR$a}`) || path.endsWith(`${NODE_MODULES_FOLDER}${name}`)
|
|
2084
2094
|
);
|
|
2085
2095
|
}
|
|
2086
2096
|
|
|
@@ -2095,22 +2105,40 @@ function valuesAt(map, key) {
|
|
|
2095
2105
|
function mapsAt(map, key) {
|
|
2096
2106
|
return valuesAt(map, key).filter(isMap);
|
|
2097
2107
|
}
|
|
2098
|
-
|
|
2108
|
+
const NO_ALIASES = () => void 0;
|
|
2109
|
+
function stringsBelow(node, path, targetOf) {
|
|
2099
2110
|
switch (node.kind) {
|
|
2100
2111
|
case "scalar":
|
|
2101
2112
|
return [{ ...node, path }];
|
|
2102
2113
|
case "list":
|
|
2103
|
-
return node.items.flatMap((item, index) => stringsBelow(item, [...path, index]));
|
|
2114
|
+
return node.items.flatMap((item, index) => stringsBelow(item, [...path, index], targetOf));
|
|
2104
2115
|
case "map":
|
|
2105
2116
|
return textEntries(node).flatMap(
|
|
2106
|
-
({ key, value }) => stringsBelow(value, [...path, key.value])
|
|
2117
|
+
({ key, value }) => stringsBelow(value, [...path, key.value], targetOf)
|
|
2107
2118
|
);
|
|
2108
|
-
default:
|
|
2109
|
-
|
|
2119
|
+
default: {
|
|
2120
|
+
const target = targetOf(node);
|
|
2121
|
+
return target === void 0 ? [] : stringsBelow(target, path, targetOf);
|
|
2122
|
+
}
|
|
2110
2123
|
}
|
|
2111
2124
|
}
|
|
2112
2125
|
function documentStrings(documents) {
|
|
2113
|
-
return documents.flatMap((document) => stringsBelow(document, []));
|
|
2126
|
+
return documents.flatMap((document) => stringsBelow(document, [], NO_ALIASES));
|
|
2127
|
+
}
|
|
2128
|
+
function nodesBelow(node) {
|
|
2129
|
+
const children = node.kind === "list" ? node.items : node.kind === "map" ? node.entries.flatMap(({ key, value }) => [key, value]) : [];
|
|
2130
|
+
return [node, ...children.flatMap(nodesBelow)];
|
|
2131
|
+
}
|
|
2132
|
+
function aliasTargets(document) {
|
|
2133
|
+
const anchored = nodesBelow(document).filter(
|
|
2134
|
+
(node) => node.kind !== "other" && node.anchor !== void 0
|
|
2135
|
+
);
|
|
2136
|
+
return (alias) => anchored.findLast(
|
|
2137
|
+
(node) => node.kind !== "other" && node.anchor === alias.alias && node.end <= alias.start
|
|
2138
|
+
);
|
|
2139
|
+
}
|
|
2140
|
+
function usedDocumentStrings(documents) {
|
|
2141
|
+
return documents.flatMap((document) => stringsBelow(document, [], aliasTargets(document)));
|
|
2114
2142
|
}
|
|
2115
2143
|
function ownerKey(path) {
|
|
2116
2144
|
return path.findLast((part) => typeof part === "string");
|
|
@@ -2308,6 +2336,64 @@ const INSTALLERS = [
|
|
|
2308
2336
|
];
|
|
2309
2337
|
const NPM_SPECIFIER_PREFIX = "npm:";
|
|
2310
2338
|
|
|
2339
|
+
const EXPRESSION_OPEN = "${{";
|
|
2340
|
+
const EXPRESSION_CLOSE = "}}";
|
|
2341
|
+
const LITERAL_QUOTE = "'";
|
|
2342
|
+
const SHELL_SINGLE_QUOTE = "'";
|
|
2343
|
+
const BACKSLASH$3 = "\\";
|
|
2344
|
+
const DOUBLE_QUOTE$1 = '"';
|
|
2345
|
+
function expressionEnd(text, start) {
|
|
2346
|
+
for (let index = start + EXPRESSION_OPEN.length; index < text.length; ) {
|
|
2347
|
+
if (text.startsWith(EXPRESSION_CLOSE, index)) {
|
|
2348
|
+
return index + EXPRESSION_CLOSE.length;
|
|
2349
|
+
}
|
|
2350
|
+
const close = text[index] === LITERAL_QUOTE ? text.indexOf(LITERAL_QUOTE, index + 1) : index;
|
|
2351
|
+
index = close === -1 ? text.length : close + 1;
|
|
2352
|
+
}
|
|
2353
|
+
return void 0;
|
|
2354
|
+
}
|
|
2355
|
+
function literalsIn(raw, start, end) {
|
|
2356
|
+
const found = [];
|
|
2357
|
+
let open = raw.indexOf(LITERAL_QUOTE, start);
|
|
2358
|
+
while (open !== -1 && open < end) {
|
|
2359
|
+
let close = raw.indexOf(LITERAL_QUOTE, open + 1);
|
|
2360
|
+
let isEscaped = false;
|
|
2361
|
+
while (close !== -1 && raw[close + 1] === LITERAL_QUOTE) {
|
|
2362
|
+
isEscaped = true;
|
|
2363
|
+
close = raw.indexOf(LITERAL_QUOTE, close + 2);
|
|
2364
|
+
}
|
|
2365
|
+
if (close === -1) {
|
|
2366
|
+
break;
|
|
2367
|
+
}
|
|
2368
|
+
found.push(...isEscaped ? [] : [{ text: raw.slice(open + 1, close), start: open + 1 }]);
|
|
2369
|
+
open = raw.indexOf(LITERAL_QUOTE, close + 1);
|
|
2370
|
+
}
|
|
2371
|
+
return found;
|
|
2372
|
+
}
|
|
2373
|
+
function expressionLiterals(raw) {
|
|
2374
|
+
const found = [];
|
|
2375
|
+
for (let index = 0; index < raw.length; ) {
|
|
2376
|
+
if (raw[index] === SHELL_SINGLE_QUOTE) {
|
|
2377
|
+
const close = raw.indexOf(SHELL_SINGLE_QUOTE, index + 1);
|
|
2378
|
+
index = close === -1 ? raw.length : close + 1;
|
|
2379
|
+
} else if (raw[index] === BACKSLASH$3) {
|
|
2380
|
+
index += 2;
|
|
2381
|
+
} else if (raw.startsWith(EXPRESSION_OPEN, index)) {
|
|
2382
|
+
const end = expressionEnd(raw, index) ?? raw.length;
|
|
2383
|
+
found.push(...literalsIn(raw, index + EXPRESSION_OPEN.length, end));
|
|
2384
|
+
index = end;
|
|
2385
|
+
} else {
|
|
2386
|
+
index += 1;
|
|
2387
|
+
}
|
|
2388
|
+
}
|
|
2389
|
+
return found;
|
|
2390
|
+
}
|
|
2391
|
+
function isWholeExpression(raw) {
|
|
2392
|
+
const isQuoted = raw.length > 1 && raw.startsWith(DOUBLE_QUOTE$1) && raw.endsWith(DOUBLE_QUOTE$1);
|
|
2393
|
+
const inner = isQuoted ? 1 : 0;
|
|
2394
|
+
return raw.startsWith(EXPRESSION_OPEN, inner) && expressionEnd(raw, inner) === raw.length - inner;
|
|
2395
|
+
}
|
|
2396
|
+
|
|
2311
2397
|
const COMMAND_SEPARATORS = /* @__PURE__ */ new Set([
|
|
2312
2398
|
";",
|
|
2313
2399
|
"&",
|
|
@@ -2318,8 +2404,8 @@ const COMMAND_SEPARATORS = /* @__PURE__ */ new Set([
|
|
|
2318
2404
|
"\n"
|
|
2319
2405
|
]);
|
|
2320
2406
|
const WORD_BREAKS = /* @__PURE__ */ new Set([" ", " ", "\r", "<", ">"]);
|
|
2321
|
-
const BACKSLASH$
|
|
2322
|
-
const DOUBLE_QUOTE_ESCAPES = /* @__PURE__ */ new Set(["$", "`", '"', BACKSLASH$
|
|
2407
|
+
const BACKSLASH$2 = "\\";
|
|
2408
|
+
const DOUBLE_QUOTE_ESCAPES = /* @__PURE__ */ new Set(["$", "`", '"', BACKSLASH$2, "\n"]);
|
|
2323
2409
|
function singleQuoted(text, start) {
|
|
2324
2410
|
const close = text.indexOf("'", start + 1);
|
|
2325
2411
|
const end = close === -1 ? text.length : close + 1;
|
|
@@ -2330,13 +2416,13 @@ function doubleQuoted(text, start) {
|
|
|
2330
2416
|
let index = start + 1;
|
|
2331
2417
|
while (index < text.length && text[index] !== '"') {
|
|
2332
2418
|
const next = text[index + 1] ?? "";
|
|
2333
|
-
const isEscape = text[index] === BACKSLASH$
|
|
2419
|
+
const isEscape = text[index] === BACKSLASH$2 && DOUBLE_QUOTE_ESCAPES.has(next);
|
|
2334
2420
|
value += isEscape ? next === "\n" ? "" : next : text[index];
|
|
2335
2421
|
index += isEscape ? 2 : 1;
|
|
2336
2422
|
}
|
|
2337
2423
|
return { end: Math.min(index + 1, text.length), value };
|
|
2338
2424
|
}
|
|
2339
|
-
const isLineContinuation = (text, index) => text[index] === BACKSLASH$
|
|
2425
|
+
const isLineContinuation = (text, index) => text[index] === BACKSLASH$2 && (text[index + 1] === "\n" || text.startsWith("\r\n", index + 1));
|
|
2340
2426
|
const ARITHMETIC_OPEN = "$((";
|
|
2341
2427
|
const NESTING_OPEN = "(";
|
|
2342
2428
|
const NESTING_CLOSE = ")";
|
|
@@ -2356,7 +2442,9 @@ const PARAMETER_CLOSE = "}";
|
|
|
2356
2442
|
function parameterExpansionEnd(text, start) {
|
|
2357
2443
|
let depth = 1;
|
|
2358
2444
|
for (let index = start + PARAMETER_OPEN.length; index < text.length; ) {
|
|
2359
|
-
if (text.startsWith(
|
|
2445
|
+
if (text.startsWith(EXPRESSION_OPEN, index)) {
|
|
2446
|
+
index = expressionEnd(text, index) ?? text.length;
|
|
2447
|
+
} else if (text.startsWith(PARAMETER_OPEN, index)) {
|
|
2360
2448
|
depth += 1;
|
|
2361
2449
|
index += PARAMETER_OPEN.length;
|
|
2362
2450
|
} else if (text[index] === PARAMETER_CLOSE) {
|
|
@@ -2379,7 +2467,7 @@ function quotedOrEscapedEnd(text, index) {
|
|
|
2379
2467
|
if (char === '"') {
|
|
2380
2468
|
return doubleQuoted(text, index).end;
|
|
2381
2469
|
}
|
|
2382
|
-
return char === BACKSLASH$
|
|
2470
|
+
return char === BACKSLASH$2 ? index + 2 : void 0;
|
|
2383
2471
|
}
|
|
2384
2472
|
function expansionPart(text, index) {
|
|
2385
2473
|
if (text.startsWith(ARITHMETIC_OPEN, index)) {
|
|
@@ -2400,7 +2488,7 @@ function wordPart(text, index) {
|
|
|
2400
2488
|
if (char === '"') {
|
|
2401
2489
|
return doubleQuoted(text, index);
|
|
2402
2490
|
}
|
|
2403
|
-
if (char === BACKSLASH$
|
|
2491
|
+
if (char === BACKSLASH$2 && index + 1 < text.length) {
|
|
2404
2492
|
return { end: index + 2, value: text[index + 1] };
|
|
2405
2493
|
}
|
|
2406
2494
|
return { end: index + 1, value: char };
|
|
@@ -2489,7 +2577,9 @@ function skipAssignments(words, start) {
|
|
|
2489
2577
|
return index;
|
|
2490
2578
|
}
|
|
2491
2579
|
const WINDOWS_PROGRAM_SUFFIX_RE = /\.(?:cmd|exe|ps1)$/i;
|
|
2492
|
-
const
|
|
2580
|
+
const windowsSuffix = (value) => WINDOWS_PROGRAM_SUFFIX_RE.exec(value)?.[0] ?? "";
|
|
2581
|
+
const withoutWindowsSuffix = (value) => value.slice(0, value.length - windowsSuffix(value).length);
|
|
2582
|
+
const entryWord = (word) => word === void 0 ? void 0 : withoutWindowsSuffix(word.value);
|
|
2493
2583
|
function matchingPrefix(entries, words, index) {
|
|
2494
2584
|
return entries.find(
|
|
2495
2585
|
(entry) => entry.words.every((name, offset) => entryWord(words[index + offset]) === name)
|
|
@@ -2573,7 +2663,7 @@ function runsGenerator(command) {
|
|
|
2573
2663
|
const words = withoutRecipePrefix(command);
|
|
2574
2664
|
const { program } = commandRoles(words);
|
|
2575
2665
|
const word = program === void 0 ? void 0 : words[program];
|
|
2576
|
-
return word !== void 0 && packageReference(word.value).name === GENERATOR_COMMAND;
|
|
2666
|
+
return word !== void 0 && packageReference(withoutWindowsSuffix(word.value)).name === GENERATOR_COMMAND;
|
|
2577
2667
|
}
|
|
2578
2668
|
|
|
2579
2669
|
const CODE_OPTIONS = /* @__PURE__ */ new Map([
|
|
@@ -2618,6 +2708,15 @@ function inlineCode(command) {
|
|
|
2618
2708
|
return void 0;
|
|
2619
2709
|
}
|
|
2620
2710
|
|
|
2711
|
+
const PATH_SEPARATOR$9 = "/";
|
|
2712
|
+
const WINDOWS_SEPARATOR_RE = /\\/g;
|
|
2713
|
+
const QUOTE_RE = /["']/g;
|
|
2714
|
+
function programPath(word) {
|
|
2715
|
+
const suffix = windowsSuffix(word.value);
|
|
2716
|
+
const windowsPath = word.raw.replace(QUOTE_RE, "").replace(WINDOWS_SEPARATOR_RE, PATH_SEPARATOR$9);
|
|
2717
|
+
return { path: suffix === "" ? word.value : windowsPath, suffix };
|
|
2718
|
+
}
|
|
2719
|
+
|
|
2621
2720
|
const EXPANSION_HEAD_RE = /^\$\{([A-Za-z_][A-Za-z0-9_]*):?([-=+])/;
|
|
2622
2721
|
const USES = {
|
|
2623
2722
|
"-": "default",
|
|
@@ -2625,7 +2724,7 @@ const USES = {
|
|
|
2625
2724
|
"+": "alternative"
|
|
2626
2725
|
};
|
|
2627
2726
|
const SINGLE_QUOTE = "'";
|
|
2628
|
-
const BACKSLASH$
|
|
2727
|
+
const BACKSLASH$1 = "\\";
|
|
2629
2728
|
function expansionAt(text, start) {
|
|
2630
2729
|
const head = EXPANSION_HEAD_RE.exec(text.slice(start));
|
|
2631
2730
|
const end = head === null ? void 0 : parameterExpansionEnd(text, start);
|
|
@@ -2649,7 +2748,7 @@ function wordExpansions(raw) {
|
|
|
2649
2748
|
if (char === SINGLE_QUOTE) {
|
|
2650
2749
|
const close = raw.indexOf(SINGLE_QUOTE, index + 1);
|
|
2651
2750
|
index = close === -1 ? raw.length : close + 1;
|
|
2652
|
-
} else if (char === BACKSLASH$
|
|
2751
|
+
} else if (char === BACKSLASH$1) {
|
|
2653
2752
|
index += 2;
|
|
2654
2753
|
} else if (raw.startsWith(PARAMETER_OPEN, index)) {
|
|
2655
2754
|
const expansion = expansionAt(raw, index);
|
|
@@ -2661,9 +2760,9 @@ function wordExpansions(raw) {
|
|
|
2661
2760
|
}
|
|
2662
2761
|
return found;
|
|
2663
2762
|
}
|
|
2664
|
-
const DOUBLE_QUOTE
|
|
2763
|
+
const DOUBLE_QUOTE = '"';
|
|
2665
2764
|
function wholeWordExpansion(raw) {
|
|
2666
|
-
const isQuoted = raw.length > 1 && raw.startsWith(DOUBLE_QUOTE
|
|
2765
|
+
const isQuoted = raw.length > 1 && raw.startsWith(DOUBLE_QUOTE) && raw.endsWith(DOUBLE_QUOTE);
|
|
2667
2766
|
const inner = isQuoted ? 1 : 0;
|
|
2668
2767
|
const [expansion] = wordExpansions(raw);
|
|
2669
2768
|
const isWhole = expansion?.expansionStart === inner && expansion.expansionEnd === raw.length - inner;
|
|
@@ -2726,64 +2825,6 @@ function readBodies(text, start, pending) {
|
|
|
2726
2825
|
return { bodies, end };
|
|
2727
2826
|
}
|
|
2728
2827
|
|
|
2729
|
-
const EXPRESSION_OPEN = "${{";
|
|
2730
|
-
const EXPRESSION_CLOSE = "}}";
|
|
2731
|
-
const LITERAL_QUOTE = "'";
|
|
2732
|
-
const SHELL_SINGLE_QUOTE = "'";
|
|
2733
|
-
const BACKSLASH$1 = "\\";
|
|
2734
|
-
const DOUBLE_QUOTE = '"';
|
|
2735
|
-
function expressionEnd(text, start) {
|
|
2736
|
-
for (let index = start + EXPRESSION_OPEN.length; index < text.length; ) {
|
|
2737
|
-
if (text.startsWith(EXPRESSION_CLOSE, index)) {
|
|
2738
|
-
return index + EXPRESSION_CLOSE.length;
|
|
2739
|
-
}
|
|
2740
|
-
const close = text[index] === LITERAL_QUOTE ? text.indexOf(LITERAL_QUOTE, index + 1) : index;
|
|
2741
|
-
index = close === -1 ? text.length : close + 1;
|
|
2742
|
-
}
|
|
2743
|
-
return void 0;
|
|
2744
|
-
}
|
|
2745
|
-
function literalsIn(raw, start, end) {
|
|
2746
|
-
const found = [];
|
|
2747
|
-
let open = raw.indexOf(LITERAL_QUOTE, start);
|
|
2748
|
-
while (open !== -1 && open < end) {
|
|
2749
|
-
let close = raw.indexOf(LITERAL_QUOTE, open + 1);
|
|
2750
|
-
let isEscaped = false;
|
|
2751
|
-
while (close !== -1 && raw[close + 1] === LITERAL_QUOTE) {
|
|
2752
|
-
isEscaped = true;
|
|
2753
|
-
close = raw.indexOf(LITERAL_QUOTE, close + 2);
|
|
2754
|
-
}
|
|
2755
|
-
if (close === -1) {
|
|
2756
|
-
break;
|
|
2757
|
-
}
|
|
2758
|
-
found.push(...isEscaped ? [] : [{ text: raw.slice(open + 1, close), start: open + 1 }]);
|
|
2759
|
-
open = raw.indexOf(LITERAL_QUOTE, close + 1);
|
|
2760
|
-
}
|
|
2761
|
-
return found;
|
|
2762
|
-
}
|
|
2763
|
-
function expressionLiterals(raw) {
|
|
2764
|
-
const found = [];
|
|
2765
|
-
for (let index = 0; index < raw.length; ) {
|
|
2766
|
-
if (raw[index] === SHELL_SINGLE_QUOTE) {
|
|
2767
|
-
const close = raw.indexOf(SHELL_SINGLE_QUOTE, index + 1);
|
|
2768
|
-
index = close === -1 ? raw.length : close + 1;
|
|
2769
|
-
} else if (raw[index] === BACKSLASH$1) {
|
|
2770
|
-
index += 2;
|
|
2771
|
-
} else if (raw.startsWith(EXPRESSION_OPEN, index)) {
|
|
2772
|
-
const end = expressionEnd(raw, index) ?? raw.length;
|
|
2773
|
-
found.push(...literalsIn(raw, index + EXPRESSION_OPEN.length, end));
|
|
2774
|
-
index = end;
|
|
2775
|
-
} else {
|
|
2776
|
-
index += 1;
|
|
2777
|
-
}
|
|
2778
|
-
}
|
|
2779
|
-
return found;
|
|
2780
|
-
}
|
|
2781
|
-
function isWholeExpression(raw) {
|
|
2782
|
-
const isQuoted = raw.length > 1 && raw.startsWith(DOUBLE_QUOTE) && raw.endsWith(DOUBLE_QUOTE);
|
|
2783
|
-
const inner = isQuoted ? 1 : 0;
|
|
2784
|
-
return raw.startsWith(EXPRESSION_OPEN, inner) && expressionEnd(raw, inner) === raw.length - inner;
|
|
2785
|
-
}
|
|
2786
|
-
|
|
2787
2828
|
const COMMENT = "#";
|
|
2788
2829
|
const LINE_BREAK$4 = "\n";
|
|
2789
2830
|
function skipTrivia(text, index) {
|
|
@@ -2903,9 +2944,15 @@ const shifted = (words, offset) => words.map((word) => ({ ...word, start: word.s
|
|
|
2903
2944
|
function shellCommandsAt(text, offset, indent = 0) {
|
|
2904
2945
|
return shellCommands(text, indent).map((words) => shifted(words, offset));
|
|
2905
2946
|
}
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
)
|
|
2947
|
+
function expansionCommands(word) {
|
|
2948
|
+
const expansions = wordExpansions(word.raw);
|
|
2949
|
+
const literals = expressionLiterals(word.raw).filter(
|
|
2950
|
+
({ start }) => expansions.every((expansion) => start < expansion.start || start >= expansion.expansionEnd)
|
|
2951
|
+
);
|
|
2952
|
+
return [...expansions, ...literals].flatMap(
|
|
2953
|
+
(part) => shellCommandsAt(part.text, word.start + part.start)
|
|
2954
|
+
);
|
|
2955
|
+
}
|
|
2909
2956
|
function innerCommands(command) {
|
|
2910
2957
|
const assignments = new Map(shellAssignments(command).map((found) => [found.word, found]));
|
|
2911
2958
|
const code = inlineCode(command)?.code;
|
|
@@ -2946,6 +2993,8 @@ function canRunGenerator(definition, generators) {
|
|
|
2946
2993
|
return generators.has(definition.target);
|
|
2947
2994
|
case "append":
|
|
2948
2995
|
return false;
|
|
2996
|
+
case "run-time":
|
|
2997
|
+
return true;
|
|
2949
2998
|
default:
|
|
2950
2999
|
return assertNever(definition);
|
|
2951
3000
|
}
|
|
@@ -2958,6 +3007,8 @@ function canRunOther(definition, others, defined) {
|
|
|
2958
3007
|
return others.has(definition.target) || !defined.has(definition.target);
|
|
2959
3008
|
case "append":
|
|
2960
3009
|
return false;
|
|
3010
|
+
case "run-time":
|
|
3011
|
+
return true;
|
|
2961
3012
|
default:
|
|
2962
3013
|
return assertNever(definition);
|
|
2963
3014
|
}
|
|
@@ -2986,15 +3037,24 @@ function variablePrograms(definitions) {
|
|
|
2986
3037
|
return new Map([...defined].map((name) => [name, programOf(name)]));
|
|
2987
3038
|
}
|
|
2988
3039
|
|
|
2989
|
-
const SHELL_VARIABLE_RE = /^"?\$(?:([A-Za-z_][A-Za-z0-9_]*)|\{([A-Za-z_][A-Za-z0-9_]*)\})"?$/;
|
|
2990
|
-
function expandedName(text) {
|
|
2991
|
-
const match = SHELL_VARIABLE_RE.exec(text);
|
|
3040
|
+
const SHELL_VARIABLE_RE$1 = /^"?\$(?:([A-Za-z_][A-Za-z0-9_]*)|\{([A-Za-z_][A-Za-z0-9_]*)\})"?$/;
|
|
3041
|
+
function expandedName$1(text) {
|
|
3042
|
+
const match = SHELL_VARIABLE_RE$1.exec(text);
|
|
2992
3043
|
return match === null ? void 0 : match[1] ?? match[2];
|
|
2993
3044
|
}
|
|
2994
3045
|
const textRunsGenerator = (text) => shellCommands(text).some(runsGenerator);
|
|
3046
|
+
function runsExpression(command) {
|
|
3047
|
+
const { program } = commandRoles(command);
|
|
3048
|
+
const word = program === void 0 ? void 0 : command[program];
|
|
3049
|
+
return word !== void 0 && isWholeExpression(word.raw);
|
|
3050
|
+
}
|
|
2995
3051
|
function textDefinition(name, text) {
|
|
2996
|
-
const target = expandedName(text.trim());
|
|
2997
|
-
|
|
3052
|
+
const target = expandedName$1(text.trim());
|
|
3053
|
+
if (target !== void 0) {
|
|
3054
|
+
return { name, kind: "reference", target };
|
|
3055
|
+
}
|
|
3056
|
+
const commands = shellCommands(text);
|
|
3057
|
+
return commands.some(runsExpression) ? { name, kind: "run-time" } : { name, kind: "command", runsGenerator: commands.some(runsGenerator) };
|
|
2998
3058
|
}
|
|
2999
3059
|
function expansionDefinitions(name, expansion) {
|
|
3000
3060
|
const word = textDefinition(name, expansion.text);
|
|
@@ -3012,7 +3072,7 @@ function shellVariables(definitions) {
|
|
|
3012
3072
|
values.set(name, [values.get(name), value].filter((part) => part !== void 0).join(" "));
|
|
3013
3073
|
}
|
|
3014
3074
|
const programs = variablePrograms(definitions.flatMap(programDefinitions$1));
|
|
3015
|
-
const nameAt = (word) => expandedName(word.raw);
|
|
3075
|
+
const nameAt = (word) => expandedName$1(word.raw);
|
|
3016
3076
|
return {
|
|
3017
3077
|
programAt: (program) => {
|
|
3018
3078
|
const name = nameAt(program);
|
|
@@ -3057,7 +3117,7 @@ function expansionUse(word, variables) {
|
|
|
3057
3117
|
return void 0;
|
|
3058
3118
|
}
|
|
3059
3119
|
const programOf = (name) => (name === void 0 ? void 0 : variables.programAt({ ...word, raw: `$${name}` })?.program) ?? "other";
|
|
3060
|
-
const target = expandedName(expansion.text.trim());
|
|
3120
|
+
const target = expandedName$1(expansion.text.trim());
|
|
3061
3121
|
const textProgram = textRunsGenerator(expansion.text) ? "generator" : "other";
|
|
3062
3122
|
const own = target === void 0 ? textProgram : programOf(target);
|
|
3063
3123
|
const variable = programOf(expansion.use === "alternative" ? void 0 : expansion.name);
|
|
@@ -3084,10 +3144,11 @@ const QUOTES$1 = /* @__PURE__ */ new Set(["'", '"']);
|
|
|
3084
3144
|
const PATH_SEPARATOR$7 = "/";
|
|
3085
3145
|
const BIN_FOLDER = "/.bin/";
|
|
3086
3146
|
const OLD_PACKAGE_FOLDER = `node_modules/${GENERATOR_COMMAND}/`;
|
|
3087
|
-
function renameAtEnd(word, name, to) {
|
|
3147
|
+
function renameAtEnd(word, name, to, suffix = "") {
|
|
3088
3148
|
const at = word.raw.lastIndexOf(name);
|
|
3089
3149
|
const tail = word.raw.slice(at + name.length);
|
|
3090
|
-
|
|
3150
|
+
const quote = tail.slice(suffix.length);
|
|
3151
|
+
if (at === -1 || quote !== "" && !QUOTES$1.has(quote)) {
|
|
3091
3152
|
return void 0;
|
|
3092
3153
|
}
|
|
3093
3154
|
return { start: word.start + at, end: word.start + at + name.length, text: to };
|
|
@@ -3107,27 +3168,30 @@ function packageFindings(found, locate) {
|
|
|
3107
3168
|
const change = { kind: "package-name-renamed", location, from: name, to };
|
|
3108
3169
|
return edit === void 0 ? [] : [{ offset, edit, change }];
|
|
3109
3170
|
}
|
|
3110
|
-
function programPathFindings(word, location) {
|
|
3171
|
+
function programPathFindings(word, { path, suffix }, location) {
|
|
3111
3172
|
const offset = word.start;
|
|
3112
|
-
if (
|
|
3113
|
-
return [{ offset, manualStep: { kind: "old-package-file", location, path
|
|
3173
|
+
if (path.includes(OLD_PACKAGE_FOLDER)) {
|
|
3174
|
+
return [{ offset, manualStep: { kind: "old-package-file", location, path } }];
|
|
3114
3175
|
}
|
|
3115
|
-
const isBin =
|
|
3116
|
-
const
|
|
3176
|
+
const isBin = path.endsWith(`${BIN_FOLDER}${GENERATOR_COMMAND}${suffix}`);
|
|
3177
|
+
const to = MIGRATED_GENERATOR_COMMAND;
|
|
3178
|
+
const edit = isBin ? renameAtEnd(word, GENERATOR_COMMAND, to, suffix) : void 0;
|
|
3117
3179
|
return edit === void 0 ? [] : [{ offset, edit, change: { kind: "command-renamed", location } }];
|
|
3118
3180
|
}
|
|
3119
3181
|
function programFindings(word, location) {
|
|
3120
|
-
|
|
3121
|
-
|
|
3182
|
+
const program = programPath(word);
|
|
3183
|
+
if (program.path.includes(PATH_SEPARATOR$7)) {
|
|
3184
|
+
return programPathFindings(word, program, location);
|
|
3122
3185
|
}
|
|
3123
|
-
const {
|
|
3186
|
+
const { path, suffix } = program;
|
|
3187
|
+
const { name, isPinned } = packageReference(path.slice(0, path.length - suffix.length));
|
|
3124
3188
|
if (name !== GENERATOR_COMMAND) {
|
|
3125
3189
|
return [];
|
|
3126
3190
|
}
|
|
3127
3191
|
if (isPinned) {
|
|
3128
3192
|
return [{ offset: word.start, manualStep: { kind: "versioned-command", location } }];
|
|
3129
3193
|
}
|
|
3130
|
-
const edit = renameAtEnd(word, GENERATOR_COMMAND, MIGRATED_GENERATOR_COMMAND);
|
|
3194
|
+
const edit = renameAtEnd(word, GENERATOR_COMMAND, MIGRATED_GENERATOR_COMMAND, suffix);
|
|
3131
3195
|
const change = { kind: "command-renamed", location };
|
|
3132
3196
|
return edit === void 0 ? [] : [{ offset: word.start, edit, change }];
|
|
3133
3197
|
}
|
|
@@ -4133,7 +4197,8 @@ function interpolationsOf(text) {
|
|
|
4133
4197
|
}
|
|
4134
4198
|
|
|
4135
4199
|
const RECIPE_NAME_RE = /^@?[A-Za-z_][A-Za-z0-9_-]*(?=[ \t:])/gm;
|
|
4136
|
-
const PARAMETER_RE = /^[+*$]*([A-Za-z_][A-Za-z0-9_-]*)(?:=([\s\S]*))?$/;
|
|
4200
|
+
const PARAMETER_RE = /^([+*$]*)([A-Za-z_][A-Za-z0-9_-]*)(?:=([\s\S]*))?$/;
|
|
4201
|
+
const EXPORT_PREFIX = "$";
|
|
4137
4202
|
const NAME_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/;
|
|
4138
4203
|
const COLON = ":";
|
|
4139
4204
|
const EQUALS = "=";
|
|
@@ -4180,14 +4245,15 @@ function parameterWords(text, start, end) {
|
|
|
4180
4245
|
function parameterDefault(text, word) {
|
|
4181
4246
|
const written = text.slice(word.start, word.end);
|
|
4182
4247
|
const match = PARAMETER_RE.exec(written);
|
|
4183
|
-
const value = match?.[
|
|
4248
|
+
const value = match?.[3];
|
|
4184
4249
|
if (match === null || value === void 0) {
|
|
4185
4250
|
return [];
|
|
4186
4251
|
}
|
|
4187
4252
|
const defaultStart = word.end - value.length;
|
|
4188
4253
|
const literals = literalsBetween(text, defaultStart, word.end);
|
|
4189
4254
|
const target = NAME_RE.test(value) ? value : void 0;
|
|
4190
|
-
|
|
4255
|
+
const isExported = match[1].includes(EXPORT_PREFIX);
|
|
4256
|
+
return [{ name: match[2], isExported, literals, target }];
|
|
4191
4257
|
}
|
|
4192
4258
|
function recipeHeaders(text) {
|
|
4193
4259
|
return [...text.matchAll(RECIPE_NAME_RE)].flatMap((match) => {
|
|
@@ -4329,7 +4395,9 @@ function shebangRecipe(text, header) {
|
|
|
4329
4395
|
}
|
|
4330
4396
|
const shebangRecipes = (text, headers) => headers.flatMap((header) => shebangRecipe(text, header));
|
|
4331
4397
|
|
|
4332
|
-
const ASSIGNMENT_RE$1 = /^(
|
|
4398
|
+
const ASSIGNMENT_RE$1 = /^(export[ \t]+)?([A-Za-z_][A-Za-z0-9_-]*)[ \t]*:=[ \t]*/gm;
|
|
4399
|
+
const SET_EXPORT_RE = /^set[ \t]+export(?:[ \t]*:=[ \t]*true)?[ \t]*(?:#.*)?$/m;
|
|
4400
|
+
const SHELL_VARIABLE_RE = /^[@+-]*"?\$(?:([A-Za-z_][A-Za-z0-9_]*)|\{([A-Za-z_][A-Za-z0-9_]*)\})"?$/;
|
|
4333
4401
|
const NAME_VALUE_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/;
|
|
4334
4402
|
const VARIABLE_INTERPOLATION_RE = /^[@+-]*\{\{[ \t]*([A-Za-z_][A-Za-z0-9_-]*)[ \t]*\}\}$/;
|
|
4335
4403
|
const MASK$1 = "_";
|
|
@@ -4339,7 +4407,8 @@ function assignmentsOf$1(text) {
|
|
|
4339
4407
|
const valueStart = match.index + match[0].length;
|
|
4340
4408
|
const { literals, end } = expressionAt(text, valueStart);
|
|
4341
4409
|
const value = text.slice(valueStart, end).trim();
|
|
4342
|
-
|
|
4410
|
+
const name = match[2];
|
|
4411
|
+
return { name, isExported: match[1] !== void 0, value, start: match.index, end, literals };
|
|
4343
4412
|
});
|
|
4344
4413
|
}
|
|
4345
4414
|
function onlyString({ value, literals }) {
|
|
@@ -4400,9 +4469,20 @@ function computedProgram(written) {
|
|
|
4400
4469
|
const literals = interpolationsOf(written).flatMap((interpolation) => interpolation.literals);
|
|
4401
4470
|
return literals.some(stringRunsGenerator) ? "generator-or-other" : void 0;
|
|
4402
4471
|
}
|
|
4403
|
-
function
|
|
4472
|
+
function exportedNames(text, assignments, defaults) {
|
|
4473
|
+
const isAll = SET_EXPORT_RE.test(text);
|
|
4474
|
+
const names = [...assignments, ...defaults].filter((found) => isAll || found.isExported);
|
|
4475
|
+
return new Set(names.map((found) => found.name));
|
|
4476
|
+
}
|
|
4477
|
+
function expandedName(written, exported) {
|
|
4478
|
+
const interpolated = VARIABLE_INTERPOLATION_RE.exec(written)?.[1];
|
|
4479
|
+
const match = SHELL_VARIABLE_RE.exec(written);
|
|
4480
|
+
const shellName = match === null ? void 0 : match[1] ?? match[2];
|
|
4481
|
+
return interpolated ?? (shellName !== void 0 && exported.has(shellName) ? shellName : void 0);
|
|
4482
|
+
}
|
|
4483
|
+
function justfileVariables(text, { values, programs, exported }) {
|
|
4404
4484
|
const writtenAt = (word) => text.slice(word.start, word.end);
|
|
4405
|
-
const nameAt = (word) =>
|
|
4485
|
+
const nameAt = (word) => expandedName(writtenAt(word), exported);
|
|
4406
4486
|
return {
|
|
4407
4487
|
programAt: (word) => {
|
|
4408
4488
|
const name = nameAt(word);
|
|
@@ -4427,7 +4507,11 @@ function migrateJustfile(text, file) {
|
|
|
4427
4507
|
...assignments.flatMap(assignmentDefinitions),
|
|
4428
4508
|
...defaults.flatMap(parameterDefinitions)
|
|
4429
4509
|
]);
|
|
4430
|
-
const variables = justfileVariables(text,
|
|
4510
|
+
const variables = justfileVariables(text, {
|
|
4511
|
+
values: variableValues$1(assignments, defaults),
|
|
4512
|
+
programs,
|
|
4513
|
+
exported: exportedNames(text, assignments, defaults)
|
|
4514
|
+
});
|
|
4431
4515
|
const scripts = shebangRecipes(text, headers);
|
|
4432
4516
|
const shell = shellText$1(text, [...assignments, ...headers, ...scripts]);
|
|
4433
4517
|
const commands = [
|
|
@@ -4442,23 +4526,10 @@ function migrateJustfile(text, file) {
|
|
|
4442
4526
|
return { text: applyTextEdits(text, edits), changes, manualSteps: steps };
|
|
4443
4527
|
}
|
|
4444
4528
|
|
|
4445
|
-
const ASSIGNMENT_RE = new RegExp(
|
|
4446
|
-
[
|
|
4447
|
-
"^(?:[^\\s:#=][^:#=\\n]*:[ \\t]*)?",
|
|
4448
|
-
"(?:(?:export|override|private)[ \\t]+)*",
|
|
4449
|
-
"([A-Za-z_][A-Za-z0-9_.-]*)",
|
|
4450
|
-
"[ \\t]*(:::=|::=|:=|\\?=|\\+=|!=|=)"
|
|
4451
|
-
].join(""),
|
|
4452
|
-
"gm"
|
|
4453
|
-
);
|
|
4454
|
-
const VARIABLE_REFERENCE_RE = /^\$(?:\(([A-Za-z_][A-Za-z0-9_.-]*)\)|\{([A-Za-z_][A-Za-z0-9_.-]*)\}|([A-Za-z_]))$/;
|
|
4455
|
-
const RECIPE_PREFIX_RE = /^[@+-]+/;
|
|
4456
4529
|
const DOLLAR = "$";
|
|
4457
4530
|
const CLOSING = { "(": ")", "{": "}" };
|
|
4458
|
-
const NOT_LINE_BREAK_RE = /[^\n]/g;
|
|
4459
4531
|
const MASK = "_";
|
|
4460
|
-
const
|
|
4461
|
-
const BACKSLASH = "\\";
|
|
4532
|
+
const ARGUMENT_SEPARATOR = ",";
|
|
4462
4533
|
function expansionEnd(text, start) {
|
|
4463
4534
|
const open = text[start + 1] ?? "";
|
|
4464
4535
|
const close = CLOSING[open];
|
|
@@ -4475,9 +4546,8 @@ function expansionEnd(text, start) {
|
|
|
4475
4546
|
}
|
|
4476
4547
|
return void 0;
|
|
4477
4548
|
}
|
|
4478
|
-
function
|
|
4479
|
-
const
|
|
4480
|
-
let copiedUpTo = 0;
|
|
4549
|
+
function expansionsOf(text) {
|
|
4550
|
+
const found = [];
|
|
4481
4551
|
for (let index = text.indexOf(DOLLAR); index !== -1; index = text.indexOf(DOLLAR, index + 1)) {
|
|
4482
4552
|
if (text[index + 1] === DOLLAR) {
|
|
4483
4553
|
index++;
|
|
@@ -4485,15 +4555,75 @@ function maskExpansions(text) {
|
|
|
4485
4555
|
}
|
|
4486
4556
|
const end = expansionEnd(text, index);
|
|
4487
4557
|
if (end !== void 0) {
|
|
4488
|
-
|
|
4489
|
-
copiedUpTo = end;
|
|
4558
|
+
found.push({ start: index, end });
|
|
4490
4559
|
index = end - 1;
|
|
4491
4560
|
}
|
|
4492
4561
|
}
|
|
4562
|
+
return found;
|
|
4563
|
+
}
|
|
4564
|
+
function maskExpansions(text) {
|
|
4565
|
+
const parts = [];
|
|
4566
|
+
let copiedUpTo = 0;
|
|
4567
|
+
for (const { start, end } of expansionsOf(text)) {
|
|
4568
|
+
parts.push(text.slice(copiedUpTo, start + 1), MASK.repeat(end - start - 1));
|
|
4569
|
+
copiedUpTo = end;
|
|
4570
|
+
}
|
|
4493
4571
|
parts.push(text.slice(copiedUpTo));
|
|
4494
4572
|
return parts.join("");
|
|
4495
4573
|
}
|
|
4574
|
+
const VALUE_ARGUMENTS = /* @__PURE__ */ new Map([
|
|
4575
|
+
["if", 1],
|
|
4576
|
+
["or", 0],
|
|
4577
|
+
["and", 0]
|
|
4578
|
+
]);
|
|
4579
|
+
const FUNCTION_HEAD_RE = /^\$[({]([a-z]+)[ \t]+/;
|
|
4580
|
+
const OPENING = new Set(Object.keys(CLOSING));
|
|
4581
|
+
const CLOSINGS = new Set(Object.values(CLOSING));
|
|
4582
|
+
function callArguments(text, start, end) {
|
|
4583
|
+
const found = [];
|
|
4584
|
+
let argumentStart = start;
|
|
4585
|
+
let depth = 0;
|
|
4586
|
+
for (let index = start; index < end; index++) {
|
|
4587
|
+
const char = text[index];
|
|
4588
|
+
depth += OPENING.has(char) ? 1 : CLOSINGS.has(char) ? -1 : 0;
|
|
4589
|
+
if (char === ARGUMENT_SEPARATOR && depth === 0) {
|
|
4590
|
+
found.push({ text: text.slice(argumentStart, index), start: argumentStart });
|
|
4591
|
+
argumentStart = index + 1;
|
|
4592
|
+
}
|
|
4593
|
+
}
|
|
4594
|
+
return [...found, { text: text.slice(argumentStart, end), start: argumentStart }];
|
|
4595
|
+
}
|
|
4596
|
+
function valueArguments(text, { start, end }) {
|
|
4597
|
+
const head = FUNCTION_HEAD_RE.exec(text.slice(start, end));
|
|
4598
|
+
const first = head === null ? void 0 : VALUE_ARGUMENTS.get(head[1]);
|
|
4599
|
+
if (head === null || first === void 0) {
|
|
4600
|
+
return [];
|
|
4601
|
+
}
|
|
4602
|
+
return callArguments(text, start + head[0].length, end - 1).slice(first);
|
|
4603
|
+
}
|
|
4604
|
+
function functionCommands(text, offset = 0) {
|
|
4605
|
+
return expansionsOf(text).flatMap((expansion) => valueArguments(text, expansion)).flatMap((argument) => [
|
|
4606
|
+
...shellCommandsAt(maskExpansions(argument.text), offset + argument.start),
|
|
4607
|
+
...functionCommands(argument.text, offset + argument.start)
|
|
4608
|
+
]);
|
|
4609
|
+
}
|
|
4610
|
+
|
|
4611
|
+
const ASSIGNMENT_RE = new RegExp(
|
|
4612
|
+
[
|
|
4613
|
+
"^(?:[^\\s:#=][^:#=\\n]*:[ \\t]*)?",
|
|
4614
|
+
"(?:(?:export|override|private)[ \\t]+)*",
|
|
4615
|
+
"([A-Za-z_][A-Za-z0-9_.-]*)",
|
|
4616
|
+
"[ \\t]*(:::=|::=|:=|\\?=|\\+=|!=|=)"
|
|
4617
|
+
].join(""),
|
|
4618
|
+
"gm"
|
|
4619
|
+
);
|
|
4620
|
+
const VARIABLE_REFERENCE_RE = /^\$(?:\(([A-Za-z_][A-Za-z0-9_.-]*)\)|\{([A-Za-z_][A-Za-z0-9_.-]*)\}|([A-Za-z_]))$/;
|
|
4621
|
+
const RECIPE_PREFIX_RE = /^[@+-]+/;
|
|
4622
|
+
const NOT_LINE_BREAK_RE = /[^\n]/g;
|
|
4623
|
+
const LINE_BREAK = "\n";
|
|
4624
|
+
const BACKSLASH = "\\";
|
|
4496
4625
|
const APPEND_OPERATOR = "+=";
|
|
4626
|
+
const CONDITIONAL_OPERATOR = "?=";
|
|
4497
4627
|
function logicalLineEnd(text, index) {
|
|
4498
4628
|
let end = text.indexOf(LINE_BREAK, index);
|
|
4499
4629
|
while (end !== -1 && text[end - 1] === BACKSLASH) {
|
|
@@ -4505,8 +4635,8 @@ const assignmentsOf = (text) => [...text.matchAll(ASSIGNMENT_RE)].map((match) =>
|
|
|
4505
4635
|
const valueStart = match.index + match[0].length;
|
|
4506
4636
|
const valueEnd = logicalLineEnd(text, valueStart);
|
|
4507
4637
|
const name = match[1];
|
|
4508
|
-
const
|
|
4509
|
-
return { name,
|
|
4638
|
+
const operator = match[2];
|
|
4639
|
+
return { name, operator, start: match.index, valueStart, valueEnd };
|
|
4510
4640
|
});
|
|
4511
4641
|
function withoutAssignmentHeads(text, assignments) {
|
|
4512
4642
|
const parts = [];
|
|
@@ -4527,18 +4657,34 @@ function referencedName(written) {
|
|
|
4527
4657
|
const match = VARIABLE_REFERENCE_RE.exec(written.trim().replace(RECIPE_PREFIX_RE, ""));
|
|
4528
4658
|
return match === null ? void 0 : match[1] ?? match[2] ?? match[3];
|
|
4529
4659
|
}
|
|
4660
|
+
function programWritten(text, command) {
|
|
4661
|
+
const { program } = commandRoles(command);
|
|
4662
|
+
const word = program === void 0 ? void 0 : command[program];
|
|
4663
|
+
return word === void 0 ? "" : text.slice(word.start, word.end);
|
|
4664
|
+
}
|
|
4665
|
+
function valueDefinition(text, { name, valueStart, valueEnd }, commands) {
|
|
4666
|
+
const inValue = commands.filter(
|
|
4667
|
+
([first2]) => first2 !== void 0 && valueStart <= first2.start && first2.start < valueEnd
|
|
4668
|
+
);
|
|
4669
|
+
const [first] = inValue.sort((left, right) => (left[0]?.start ?? 0) - (right[0]?.start ?? 0));
|
|
4670
|
+
const program = first === void 0 ? "" : programWritten(text, first);
|
|
4671
|
+
const target = referencedName(program);
|
|
4672
|
+
if (target !== void 0) {
|
|
4673
|
+
return { name, kind: "reference", target };
|
|
4674
|
+
}
|
|
4675
|
+
if (isComputed(program)) {
|
|
4676
|
+
return { name, kind: "run-time" };
|
|
4677
|
+
}
|
|
4678
|
+
return { name, kind: "command", runsGenerator: inValue.some(runsGenerator) };
|
|
4679
|
+
}
|
|
4530
4680
|
function programDefinitions(text, commands, assignments) {
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
if (
|
|
4534
|
-
return { name, kind: "append" };
|
|
4535
|
-
}
|
|
4536
|
-
const target = referencedName(text.slice(valueStart, valueEnd));
|
|
4537
|
-
if (target !== void 0) {
|
|
4538
|
-
return { name, kind: "reference", target };
|
|
4681
|
+
return assignments.flatMap((assignment) => {
|
|
4682
|
+
const { name, operator } = assignment;
|
|
4683
|
+
if (operator === APPEND_OPERATOR) {
|
|
4684
|
+
return [{ name, kind: "append" }];
|
|
4539
4685
|
}
|
|
4540
|
-
const
|
|
4541
|
-
return { name, kind: "
|
|
4686
|
+
const value = valueDefinition(text, assignment, commands);
|
|
4687
|
+
return operator === CONDITIONAL_OPERATOR ? [value, { name, kind: "run-time" }] : [value];
|
|
4542
4688
|
});
|
|
4543
4689
|
}
|
|
4544
4690
|
function variableValues(text, assignments) {
|
|
@@ -4573,7 +4719,10 @@ function makefileVariables(text, assignments, programs) {
|
|
|
4573
4719
|
function migrateMakefile(text, file) {
|
|
4574
4720
|
const lineOf = lineLocator(text);
|
|
4575
4721
|
const assignments = assignmentsOf(text);
|
|
4576
|
-
const commands =
|
|
4722
|
+
const commands = [
|
|
4723
|
+
...shellCommands(withoutAssignmentHeads(maskExpansions(text), assignments)),
|
|
4724
|
+
...functionCommands(text)
|
|
4725
|
+
];
|
|
4577
4726
|
const programs = variablePrograms(programDefinitions(text, commands, assignments));
|
|
4578
4727
|
const locate = (offset) => `${file}:${lineOf(offset)}`;
|
|
4579
4728
|
const variables = makefileVariables(text, assignments, programs);
|
|
@@ -4921,6 +5070,31 @@ function oldPackagePatchSteps(fileName) {
|
|
|
4921
5070
|
return name === void 0 || to === void 0 ? [] : [{ kind: "old-package-patch", name, to }];
|
|
4922
5071
|
}
|
|
4923
5072
|
|
|
5073
|
+
const INPUTS_KEY = "inputs";
|
|
5074
|
+
const DEFAULT_KEY = "default";
|
|
5075
|
+
const INPUT_DEFAULT_DEPTH = 3;
|
|
5076
|
+
const INPUT_NAME_INDEX = -2;
|
|
5077
|
+
const isInputDefault = (value) => value.path.length >= INPUT_DEFAULT_DEPTH && value.path.at(-1) === DEFAULT_KEY && value.path.at(-INPUT_DEFAULT_DEPTH) === INPUTS_KEY;
|
|
5078
|
+
const INPUT_EXPRESSION_RE = /^"?\$\{\{[ \t]*inputs\.([A-Za-z_][A-Za-z0-9_-]*)[ \t]*\}\}"?$/;
|
|
5079
|
+
function withInputDefaults(variables, strings) {
|
|
5080
|
+
const values = /* @__PURE__ */ new Map();
|
|
5081
|
+
for (const value of strings.filter(isInputDefault)) {
|
|
5082
|
+
const name = String(value.path.at(INPUT_NAME_INDEX));
|
|
5083
|
+
values.set(
|
|
5084
|
+
name,
|
|
5085
|
+
[values.get(name), value.value].filter((part) => part !== void 0).join(" ")
|
|
5086
|
+
);
|
|
5087
|
+
}
|
|
5088
|
+
return {
|
|
5089
|
+
programAt: (program) => variables.programAt(program),
|
|
5090
|
+
referenceAt: (word) => {
|
|
5091
|
+
const name = INPUT_EXPRESSION_RE.exec(word.raw)?.[1];
|
|
5092
|
+
const value = name === void 0 ? void 0 : values.get(name);
|
|
5093
|
+
return variables.referenceAt(word) ?? (value === void 0 ? void 0 : { written: word.raw, value });
|
|
5094
|
+
}
|
|
5095
|
+
};
|
|
5096
|
+
}
|
|
5097
|
+
|
|
4924
5098
|
const YAML_COMMAND_KEYS = /* @__PURE__ */ new Set([
|
|
4925
5099
|
"run",
|
|
4926
5100
|
"script",
|
|
@@ -4947,10 +5121,6 @@ const TASKFILE_COMMAND_KEYS = /* @__PURE__ */ new Set([
|
|
|
4947
5121
|
|
|
4948
5122
|
const ENVIRONMENT_KEYS = /* @__PURE__ */ new Set(["env"]);
|
|
4949
5123
|
const isEnvironmentValue = (value) => value.path.length >= 2 && ENVIRONMENT_KEYS.has(String(value.path.at(-2)));
|
|
4950
|
-
const INPUTS_KEY = "inputs";
|
|
4951
|
-
const DEFAULT_KEY = "default";
|
|
4952
|
-
const INPUT_DEFAULT_DEPTH = 3;
|
|
4953
|
-
const isInputDefault = (value) => value.path.length >= INPUT_DEFAULT_DEPTH && value.path.at(-1) === DEFAULT_KEY && value.path.at(-INPUT_DEFAULT_DEPTH) === INPUTS_KEY;
|
|
4954
5124
|
function environmentVariables(text, strings) {
|
|
4955
5125
|
return shellVariables(
|
|
4956
5126
|
strings.filter(isEnvironmentValue).map((value) => ({
|
|
@@ -4978,7 +5148,15 @@ function blockIndent(shell) {
|
|
|
4978
5148
|
const indents = lines.map((line) => LEADING_SPACES_RE.exec(line)?.[0].length ?? 0);
|
|
4979
5149
|
return indents.length === 0 ? 0 : Math.min(...indents);
|
|
4980
5150
|
}
|
|
4981
|
-
|
|
5151
|
+
function oncePerPlace(strings) {
|
|
5152
|
+
const starts = /* @__PURE__ */ new Set();
|
|
5153
|
+
return strings.filter((string) => {
|
|
5154
|
+
const isFirst = !starts.has(string.start);
|
|
5155
|
+
starts.add(string.start);
|
|
5156
|
+
return isFirst;
|
|
5157
|
+
});
|
|
5158
|
+
}
|
|
5159
|
+
const valuesOf = (strings, keys) => oncePerPlace(strings.filter((string) => keys.has(ownerKey(string.path) ?? "")));
|
|
4982
5160
|
const EXEC_FORM_KEYS = /* @__PURE__ */ new Set(["command", "entrypoint"]);
|
|
4983
5161
|
const isExecFormItem = (value) => typeof value.path.at(-1) === "number" && EXEC_FORM_KEYS.has(String(value.path.at(-2)));
|
|
4984
5162
|
const listOf = (item) => item.path.slice(0, -1).join(".");
|
|
@@ -5033,10 +5211,12 @@ function migrateYamlCommands(text, file, strings, keys = YAML_COMMAND_KEYS) {
|
|
|
5033
5211
|
const shellOf = stepShells(strings);
|
|
5034
5212
|
const values = valuesOf(strings, keys).filter((value) => shellOf(value) === void 0);
|
|
5035
5213
|
const commandValues = new Set(values.filter((value) => !isExecFormItem(value)));
|
|
5036
|
-
const shellValues =
|
|
5037
|
-
|
|
5214
|
+
const shellValues = oncePerPlace(
|
|
5215
|
+
strings.filter(
|
|
5216
|
+
(value) => commandValues.has(value) || isEnvironmentValue(value) || isInputDefault(value)
|
|
5217
|
+
)
|
|
5038
5218
|
);
|
|
5039
|
-
const variables = environmentVariables(text, strings);
|
|
5219
|
+
const variables = withInputDefaults(environmentVariables(text, strings), strings);
|
|
5040
5220
|
return appliedFindings(text, [
|
|
5041
5221
|
...shellValues.map((value) => valueFindings(text, value, locate, variables)),
|
|
5042
5222
|
commandWordFindings(execFormCommands(text, values.filter(isExecFormItem)), locate),
|
|
@@ -5210,6 +5390,7 @@ function migrateConfig(text, read, steps) {
|
|
|
5210
5390
|
);
|
|
5211
5391
|
}
|
|
5212
5392
|
const stringsStep = (migrate) => (text, read) => read.kind === "unreadable" ? unreadableConfig(text, read.offset) : migrate(text, documentStrings(read.documents));
|
|
5393
|
+
const usedStringsStep = (migrate) => (text, read) => read.kind === "unreadable" ? unreadableConfig(text, read.offset) : migrate(text, usedDocumentStrings(read.documents));
|
|
5213
5394
|
const jsonConfig = (steps) => (text, path, context) => migrateConfig(text, (current) => context.readers.json.read(current), steps(context, path));
|
|
5214
5395
|
const yamlConfig = (steps) => (text, path, context) => migrateConfig(text, (current) => context.readers.yaml.read(current), steps(context, path));
|
|
5215
5396
|
const whenNamed = (migrate) => (text, path, context) => namesOriginalPackage(text) ? migrate(text, path, context) : unchanged(text);
|
|
@@ -5365,7 +5546,7 @@ const COMMAND_CONFIG_KINDS = [
|
|
|
5365
5546
|
matches: (path) => TASKFILE_NAMES.has(baseName(path)),
|
|
5366
5547
|
migrate: whenNamed(
|
|
5367
5548
|
yamlConfig((_context, path) => [
|
|
5368
|
-
|
|
5549
|
+
usedStringsStep(
|
|
5369
5550
|
(text, strings) => migrateYamlCommands(text, path, strings, TASKFILE_COMMAND_KEYS)
|
|
5370
5551
|
)
|
|
5371
5552
|
])
|
|
@@ -5380,7 +5561,10 @@ const COMMAND_CONFIG_KINDS = [
|
|
|
5380
5561
|
)
|
|
5381
5562
|
}
|
|
5382
5563
|
];
|
|
5383
|
-
const yamlCommandsStep = (path, isPart) => (text, read) => isPart || !isCiConfigFile(path) && read.kind === "read" && isApiDescription(read.documents) ? unchanged(text) :
|
|
5564
|
+
const yamlCommandsStep = (path, isPart) => (text, read) => isPart || !isCiConfigFile(path) && read.kind === "read" && isApiDescription(read.documents) ? unchanged(text) : usedStringsStep((current, strings) => migrateYamlCommands(current, path, strings))(
|
|
5565
|
+
text,
|
|
5566
|
+
read
|
|
5567
|
+
);
|
|
5384
5568
|
const manifestTarget = ({ version, catalogs, aliases }, path) => ({
|
|
5385
5569
|
version,
|
|
5386
5570
|
catalogs,
|
|
@@ -6031,6 +6215,7 @@ const NEXT_STEPS = [
|
|
|
6031
6215
|
const DRY_RUN_NOTE = "Dry run: nothing was written. Run again with --write to apply.";
|
|
6032
6216
|
const WRITTEN_NOTE = "Files were written.";
|
|
6033
6217
|
const NOTHING_FOUND = "Nothing to migrate: no openapi-typescript, openapi-fetch, openapi-react-query or openapi-typescript-helpers found.";
|
|
6218
|
+
const NOTHING_ELSE_FOUND = "Nothing else to migrate: migrate the skipped files above by hand.";
|
|
6034
6219
|
|
|
6035
6220
|
function changesSection(reports) {
|
|
6036
6221
|
const changed = reports.filter((report) => report.changes.length > 0);
|
|
@@ -6086,7 +6271,8 @@ function renderReport(migration) {
|
|
|
6086
6271
|
const reports = migration.files;
|
|
6087
6272
|
const skipped = skippedSection(migration.skipped);
|
|
6088
6273
|
if (reports.length === 0) {
|
|
6089
|
-
|
|
6274
|
+
const hasBug = migration.skipped.some((file) => file.reason.kind === "migration-bug");
|
|
6275
|
+
return printed([...skipped, hasBug ? NOTHING_ELSE_FOUND : NOTHING_FOUND]);
|
|
6090
6276
|
}
|
|
6091
6277
|
const lines = [
|
|
6092
6278
|
...changesSection(reports),
|