assistant-ui 0.0.107 → 0.0.108
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/dist/codemods/v0-15/aui-accessor-calls-to-properties.d.ts +5 -0
- package/dist/codemods/v0-15/aui-accessor-calls-to-properties.d.ts.map +1 -0
- package/dist/codemods/v0-15/aui-accessor-calls-to-properties.js +58 -0
- package/dist/codemods/v0-15/aui-accessor-calls-to-properties.js.map +1 -0
- package/dist/commands/upgrade.js +2 -2
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/lib/upgrade.d.ts.map +1 -1
- package/dist/lib/upgrade.js +2 -1
- package/dist/lib/upgrade.js.map +1 -1
- package/dist/run.d.ts +5 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +9 -0
- package/dist/run.js.map +1 -0
- package/package.json +2 -2
- package/src/codemods/v0-15/__tests__/aui-accessor-calls-to-properties.test.ts +109 -0
- package/src/codemods/v0-15/aui-accessor-calls-to-properties.ts +83 -0
- package/src/commands/upgrade.ts +2 -2
- package/src/index.ts +5 -6
- package/src/lib/upgrade.ts +1 -0
- package/src/run.test.ts +27 -0
- package/src/run.ts +5 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
//#region src/codemods/v0-15/aui-accessor-calls-to-properties.d.ts
|
|
2
|
+
declare const auiAccessorCallsToProperties: (fileInfo: import("jscodeshift/src/core").FileInfo, api: import("jscodeshift/src/core").API, options: any) => string | null;
|
|
3
|
+
//#endregion
|
|
4
|
+
export { auiAccessorCallsToProperties as default };
|
|
5
|
+
//# sourceMappingURL=aui-accessor-calls-to-properties.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aui-accessor-calls-to-properties.d.ts","names":[],"sources":["../../../src/codemods/v0-15/aui-accessor-calls-to-properties.ts"],"mappings":";cA4BM,+BAA4B,yCAAA,UAAA,oCAAA,KAAA"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { createTransformer } from "../utils/createTransformer.js";
|
|
2
|
+
//#region src/codemods/v0-15/aui-accessor-calls-to-properties.ts
|
|
3
|
+
const NULLARY_SCOPES = /* @__PURE__ */ new Set([
|
|
4
|
+
"threads",
|
|
5
|
+
"threadListItem",
|
|
6
|
+
"thread",
|
|
7
|
+
"message",
|
|
8
|
+
"part",
|
|
9
|
+
"composer",
|
|
10
|
+
"attachment",
|
|
11
|
+
"modelContext",
|
|
12
|
+
"suggestions",
|
|
13
|
+
"suggestion",
|
|
14
|
+
"chainOfThought",
|
|
15
|
+
"queueItem",
|
|
16
|
+
"tools",
|
|
17
|
+
"dataRenderers",
|
|
18
|
+
"interactables",
|
|
19
|
+
"unstable_interactables",
|
|
20
|
+
"mcp",
|
|
21
|
+
"mcpServer",
|
|
22
|
+
"span"
|
|
23
|
+
]);
|
|
24
|
+
const AUI_HOOKS = /* @__PURE__ */ new Set(["useAui", "useAssistantApi"]);
|
|
25
|
+
const auiAccessorCallsToProperties = createTransformer(({ j, root, markAsChanged }) => {
|
|
26
|
+
const auiNames = /* @__PURE__ */ new Set(["aui"]);
|
|
27
|
+
root.find(j.VariableDeclarator).forEach((path) => {
|
|
28
|
+
const { id, init } = path.value;
|
|
29
|
+
if (j.Identifier.check(id) && init && j.CallExpression.check(init) && j.Identifier.check(init.callee) && AUI_HOOKS.has(init.callee.name)) auiNames.add(id.name);
|
|
30
|
+
});
|
|
31
|
+
const collectParam = (param) => {
|
|
32
|
+
const annotation = param?.typeAnnotation?.typeAnnotation;
|
|
33
|
+
if (j.Identifier.check(param) && annotation && j.TSTypeReference.check(annotation) && j.Identifier.check(annotation.typeName) && annotation.typeName.name === "AssistantClient") auiNames.add(param.name);
|
|
34
|
+
};
|
|
35
|
+
for (const fnType of [
|
|
36
|
+
j.FunctionDeclaration,
|
|
37
|
+
j.FunctionExpression,
|
|
38
|
+
j.ArrowFunctionExpression
|
|
39
|
+
]) root.find(fnType).forEach((path) => {
|
|
40
|
+
path.value.params.forEach(collectParam);
|
|
41
|
+
});
|
|
42
|
+
root.find(j.CallExpression).forEach((path) => {
|
|
43
|
+
const node = path.value;
|
|
44
|
+
if (node.arguments.length !== 0) return;
|
|
45
|
+
const callee = node.callee;
|
|
46
|
+
if (!j.MemberExpression.check(callee) || callee.computed) return;
|
|
47
|
+
if (!j.Identifier.check(callee.property)) return;
|
|
48
|
+
if (!NULLARY_SCOPES.has(callee.property.name)) return;
|
|
49
|
+
if (!j.Identifier.check(callee.object)) return;
|
|
50
|
+
if (!auiNames.has(callee.object.name)) return;
|
|
51
|
+
j(path).replaceWith(callee);
|
|
52
|
+
markAsChanged();
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
//#endregion
|
|
56
|
+
export { auiAccessorCallsToProperties as default };
|
|
57
|
+
|
|
58
|
+
//# sourceMappingURL=aui-accessor-calls-to-properties.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aui-accessor-calls-to-properties.js","names":[],"sources":["../../../src/codemods/v0-15/aui-accessor-calls-to-properties.ts"],"sourcesContent":["import { createTransformer } from \"../utils/createTransformer\";\n\n// Nullary scope accessors that became properties in v0.15. Parameterized\n// lookups (e.g. `aui.thread.message({ id })`) stay as real calls.\nconst NULLARY_SCOPES = new Set([\n \"threads\",\n \"threadListItem\",\n \"thread\",\n \"message\",\n \"part\",\n \"composer\",\n \"attachment\",\n \"modelContext\",\n \"suggestions\",\n \"suggestion\",\n \"chainOfThought\",\n \"queueItem\",\n \"tools\",\n \"dataRenderers\",\n \"interactables\",\n \"unstable_interactables\",\n \"mcp\",\n \"mcpServer\",\n \"span\",\n]);\n\nconst AUI_HOOKS = new Set([\"useAui\", \"useAssistantApi\"]);\n\nconst auiAccessorCallsToProperties = createTransformer(\n ({ j, root, markAsChanged }) => {\n const auiNames = new Set([\"aui\"]);\n\n root.find(j.VariableDeclarator).forEach((path: any) => {\n const { id, init } = path.value;\n if (\n j.Identifier.check(id) &&\n init &&\n j.CallExpression.check(init) &&\n j.Identifier.check(init.callee) &&\n AUI_HOOKS.has(init.callee.name)\n ) {\n auiNames.add(id.name);\n }\n });\n\n const collectParam = (param: any) => {\n const annotation = param?.typeAnnotation?.typeAnnotation;\n if (\n j.Identifier.check(param) &&\n annotation &&\n j.TSTypeReference.check(annotation) &&\n j.Identifier.check(annotation.typeName) &&\n annotation.typeName.name === \"AssistantClient\"\n ) {\n auiNames.add(param.name);\n }\n };\n for (const fnType of [\n j.FunctionDeclaration,\n j.FunctionExpression,\n j.ArrowFunctionExpression,\n ] as const) {\n root.find(fnType as typeof j.FunctionDeclaration).forEach((path: any) => {\n path.value.params.forEach(collectParam);\n });\n }\n\n root.find(j.CallExpression).forEach((path: any) => {\n const node = path.value;\n if (node.arguments.length !== 0) return;\n const callee = node.callee;\n if (!j.MemberExpression.check(callee) || callee.computed) return;\n if (!j.Identifier.check(callee.property)) return;\n if (!NULLARY_SCOPES.has(callee.property.name)) return;\n if (!j.Identifier.check(callee.object)) return;\n if (!auiNames.has(callee.object.name)) return;\n j(path).replaceWith(callee);\n markAsChanged();\n });\n },\n);\n\nexport default auiAccessorCallsToProperties;\n"],"mappings":";;AAIA,MAAM,iCAAiB,IAAI,IAAI;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,4BAAY,IAAI,IAAI,CAAC,UAAU,iBAAiB,CAAC;AAEvD,MAAM,+BAA+B,mBAClC,EAAE,GAAG,MAAM,oBAAoB;CAC9B,MAAM,2BAAW,IAAI,IAAI,CAAC,KAAK,CAAC;CAEhC,KAAK,KAAK,EAAE,kBAAkB,CAAC,CAAC,SAAS,SAAc;EACrD,MAAM,EAAE,IAAI,SAAS,KAAK;EAC1B,IACE,EAAE,WAAW,MAAM,EAAE,KACrB,QACA,EAAE,eAAe,MAAM,IAAI,KAC3B,EAAE,WAAW,MAAM,KAAK,MAAM,KAC9B,UAAU,IAAI,KAAK,OAAO,IAAI,GAE9B,SAAS,IAAI,GAAG,IAAI;CAExB,CAAC;CAED,MAAM,gBAAgB,UAAe;EACnC,MAAM,aAAa,OAAO,gBAAgB;EAC1C,IACE,EAAE,WAAW,MAAM,KAAK,KACxB,cACA,EAAE,gBAAgB,MAAM,UAAU,KAClC,EAAE,WAAW,MAAM,WAAW,QAAQ,KACtC,WAAW,SAAS,SAAS,mBAE7B,SAAS,IAAI,MAAM,IAAI;CAE3B;CACA,KAAK,MAAM,UAAU;EACnB,EAAE;EACF,EAAE;EACF,EAAE;CACJ,GACE,KAAK,KAAK,MAAsC,CAAC,CAAC,SAAS,SAAc;EACvE,KAAK,MAAM,OAAO,QAAQ,YAAY;CACxC,CAAC;CAGH,KAAK,KAAK,EAAE,cAAc,CAAC,CAAC,SAAS,SAAc;EACjD,MAAM,OAAO,KAAK;EAClB,IAAI,KAAK,UAAU,WAAW,GAAG;EACjC,MAAM,SAAS,KAAK;EACpB,IAAI,CAAC,EAAE,iBAAiB,MAAM,MAAM,KAAK,OAAO,UAAU;EAC1D,IAAI,CAAC,EAAE,WAAW,MAAM,OAAO,QAAQ,GAAG;EAC1C,IAAI,CAAC,eAAe,IAAI,OAAO,SAAS,IAAI,GAAG;EAC/C,IAAI,CAAC,EAAE,WAAW,MAAM,OAAO,MAAM,GAAG;EACxC,IAAI,CAAC,SAAS,IAAI,OAAO,OAAO,IAAI,GAAG;EACvC,EAAE,IAAI,CAAC,CAAC,YAAY,MAAM;EAC1B,cAAc;CAChB,CAAC;AACH,CACF"}
|
package/dist/commands/upgrade.js
CHANGED
|
@@ -19,9 +19,9 @@ const codemodCommand = addTransformOptions(new Command().name("codemod").descrip
|
|
|
19
19
|
process.exit(1);
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
|
-
const upgradeCommand = addTransformOptions(new Command().command("upgrade").description("Upgrade ai package dependencies and apply codemods")).action((options) => {
|
|
22
|
+
const upgradeCommand = addTransformOptions(new Command().command("upgrade").description("Upgrade ai package dependencies and apply codemods")).action(async (options) => {
|
|
23
23
|
try {
|
|
24
|
-
upgrade(options);
|
|
24
|
+
await upgrade(options);
|
|
25
25
|
} catch (err) {
|
|
26
26
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
27
27
|
const errorStack = err instanceof Error ? err.stack : void 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade.js","names":[],"sources":["../../src/commands/upgrade.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { transform } from \"../lib/transform\";\nimport { upgrade } from \"../lib/upgrade\";\nimport debug from \"debug\";\n\nexport interface TransformOptions {\n dry?: boolean;\n print?: boolean;\n verbose?: boolean;\n jscodeshift?: string;\n}\n\nconst error = debug(\"codemod:error\");\ndebug.enable(\"codemod:*\");\n\nconst addTransformOptions = (command: Command): Command => {\n return command\n .option(\"-d, --dry\", \"Dry run (no changes are made to files)\")\n .option(\"-p, --print\", \"Print transformed files to stdout\")\n .option(\"--verbose\", \"Show more information about the transform process\")\n .option(\n \"-j, --jscodeshift <options>\",\n \"Pass options directly to jscodeshift\",\n );\n};\n\nexport const codemodCommand = addTransformOptions(\n new Command()\n .name(\"codemod\")\n .description(\"CLI tool for running codemods\")\n .argument(\"<codemod>\", \"Codemod to run (e.g., rewrite-framework-imports)\")\n .argument(\"<source>\", \"Path to source files or directory to transform\"),\n).action((codemod, source, options: TransformOptions) => {\n try {\n transform(codemod, source, options);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n const errorStack = err instanceof Error ? err.stack : undefined;\n error(`Error transforming: ${errorMessage}`);\n if (errorStack) {\n error(errorStack);\n }\n process.exit(1);\n }\n});\n\nexport const upgradeCommand = addTransformOptions(\n new Command()\n .command(\"upgrade\")\n .description(\"Upgrade ai package dependencies and apply codemods\"),\n).action((options: TransformOptions) => {\n try {\n upgrade(options);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n const errorStack = err instanceof Error ? err.stack : undefined;\n error(`Error upgrading: ${errorMessage}`);\n if (errorStack) {\n error(errorStack);\n }\n process.exit(1);\n }\n});\n"],"mappings":";;;;;AAYA,MAAM,QAAQ,MAAM,eAAe;AACnC,MAAM,OAAO,WAAW;AAExB,MAAM,uBAAuB,YAA8B;CACzD,OAAO,QACJ,OAAO,aAAa,wCAAwC,CAAC,CAC7D,OAAO,eAAe,mCAAmC,CAAC,CAC1D,OAAO,aAAa,mDAAmD,CAAC,CACxE,OACC,+BACA,sCACF;AACJ;AAEA,MAAa,iBAAiB,oBAC5B,IAAI,QAAQ,CAAC,CACV,KAAK,SAAS,CAAC,CACf,YAAY,+BAA+B,CAAC,CAC5C,SAAS,aAAa,kDAAkD,CAAC,CACzE,SAAS,YAAY,gDAAgD,CAC1E,CAAC,CAAC,QAAQ,SAAS,QAAQ,YAA8B;CACvD,IAAI;EACF,UAAU,SAAS,QAAQ,OAAO;CACpC,SAAS,KAAK;EACZ,MAAM,eAAe,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;EACpE,MAAM,aAAa,eAAe,QAAQ,IAAI,QAAQ,KAAA;EACtD,MAAM,uBAAuB,cAAc;EAC3C,IAAI,YACF,MAAM,UAAU;EAElB,QAAQ,KAAK,CAAC;CAChB;AACF,CAAC;AAED,MAAa,iBAAiB,oBAC5B,IAAI,QAAQ,CAAC,CACV,QAAQ,SAAS,CAAC,CAClB,YAAY,oDAAoD,CACrE,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"upgrade.js","names":[],"sources":["../../src/commands/upgrade.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { transform } from \"../lib/transform\";\nimport { upgrade } from \"../lib/upgrade\";\nimport debug from \"debug\";\n\nexport interface TransformOptions {\n dry?: boolean;\n print?: boolean;\n verbose?: boolean;\n jscodeshift?: string;\n}\n\nconst error = debug(\"codemod:error\");\ndebug.enable(\"codemod:*\");\n\nconst addTransformOptions = (command: Command): Command => {\n return command\n .option(\"-d, --dry\", \"Dry run (no changes are made to files)\")\n .option(\"-p, --print\", \"Print transformed files to stdout\")\n .option(\"--verbose\", \"Show more information about the transform process\")\n .option(\n \"-j, --jscodeshift <options>\",\n \"Pass options directly to jscodeshift\",\n );\n};\n\nexport const codemodCommand = addTransformOptions(\n new Command()\n .name(\"codemod\")\n .description(\"CLI tool for running codemods\")\n .argument(\"<codemod>\", \"Codemod to run (e.g., rewrite-framework-imports)\")\n .argument(\"<source>\", \"Path to source files or directory to transform\"),\n).action((codemod, source, options: TransformOptions) => {\n try {\n transform(codemod, source, options);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n const errorStack = err instanceof Error ? err.stack : undefined;\n error(`Error transforming: ${errorMessage}`);\n if (errorStack) {\n error(errorStack);\n }\n process.exit(1);\n }\n});\n\nexport const upgradeCommand = addTransformOptions(\n new Command()\n .command(\"upgrade\")\n .description(\"Upgrade ai package dependencies and apply codemods\"),\n).action(async (options: TransformOptions) => {\n try {\n await upgrade(options);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n const errorStack = err instanceof Error ? err.stack : undefined;\n error(`Error upgrading: ${errorMessage}`);\n if (errorStack) {\n error(errorStack);\n }\n process.exit(1);\n }\n});\n"],"mappings":";;;;;AAYA,MAAM,QAAQ,MAAM,eAAe;AACnC,MAAM,OAAO,WAAW;AAExB,MAAM,uBAAuB,YAA8B;CACzD,OAAO,QACJ,OAAO,aAAa,wCAAwC,CAAC,CAC7D,OAAO,eAAe,mCAAmC,CAAC,CAC1D,OAAO,aAAa,mDAAmD,CAAC,CACxE,OACC,+BACA,sCACF;AACJ;AAEA,MAAa,iBAAiB,oBAC5B,IAAI,QAAQ,CAAC,CACV,KAAK,SAAS,CAAC,CACf,YAAY,+BAA+B,CAAC,CAC5C,SAAS,aAAa,kDAAkD,CAAC,CACzE,SAAS,YAAY,gDAAgD,CAC1E,CAAC,CAAC,QAAQ,SAAS,QAAQ,YAA8B;CACvD,IAAI;EACF,UAAU,SAAS,QAAQ,OAAO;CACpC,SAAS,KAAK;EACZ,MAAM,eAAe,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;EACpE,MAAM,aAAa,eAAe,QAAQ,IAAI,QAAQ,KAAA;EACtD,MAAM,uBAAuB,cAAc;EAC3C,IAAI,YACF,MAAM,UAAU;EAElB,QAAQ,KAAK,CAAC;CAChB;AACF,CAAC;AAED,MAAa,iBAAiB,oBAC5B,IAAI,QAAQ,CAAC,CACV,QAAQ,SAAS,CAAC,CAClB,YAAY,oDAAoD,CACrE,CAAC,CAAC,OAAO,OAAO,YAA8B;CAC5C,IAAI;EACF,MAAM,QAAQ,OAAO;CACvB,SAAS,KAAK;EACZ,MAAM,eAAe,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;EACpE,MAAM,aAAa,eAAe,QAAQ,IAAI,QAAQ,KAAA;EACtD,MAAM,oBAAoB,cAAc;EACxC,IAAI,YACF,MAAM,UAAU;EAElB,QAAQ,KAAK,CAAC;CAChB;AACF,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { runCli } from "./run.js";
|
|
3
3
|
//#region src/index.ts
|
|
4
4
|
process.on("SIGINT", () => process.exit(0));
|
|
5
5
|
process.on("SIGTERM", () => process.exit(0));
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
runCli().catch((error) => {
|
|
7
|
+
console.error(error);
|
|
8
|
+
process.exitCode = 1;
|
|
9
|
+
});
|
|
10
10
|
//#endregion
|
|
11
11
|
|
|
12
12
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport {
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { runCli } from \"./run\";\n\nprocess.on(\"SIGINT\", () => process.exit(0));\nprocess.on(\"SIGTERM\", () => process.exit(0));\n\nvoid runCli().catch((error: unknown) => {\n console.error(error);\n process.exitCode = 1;\n});\n"],"mappings":";;;AAIA,QAAQ,GAAG,gBAAgB,QAAQ,KAAK,CAAC,CAAC;AAC1C,QAAQ,GAAG,iBAAiB,QAAQ,KAAK,CAAC,CAAC;AAEtC,OAAO,CAAC,CAAC,OAAO,UAAmB;CACtC,QAAQ,MAAM,KAAK;CACnB,QAAQ,WAAW;AACrB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade.d.ts","names":[],"sources":["../../src/lib/upgrade.ts"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"upgrade.d.ts","names":[],"sources":["../../src/lib/upgrade.ts"],"mappings":";;;;;;;;iBA4BsB,QAAQ,SAAS,mBAAgB"}
|
package/dist/lib/upgrade.js
CHANGED
|
@@ -12,7 +12,8 @@ const bundle = [
|
|
|
12
12
|
"v0-11/content-part-to-message-part",
|
|
13
13
|
"v0-12/assistant-api-to-aui",
|
|
14
14
|
"v0-12/event-names-to-camelcase",
|
|
15
|
-
"v0-12/primitive-if-to-aui-if"
|
|
15
|
+
"v0-12/primitive-if-to-aui-if",
|
|
16
|
+
"v0-15/aui-accessor-calls-to-properties"
|
|
16
17
|
];
|
|
17
18
|
const log = debug("codemod:upgrade");
|
|
18
19
|
const error = debug("codemod:upgrade:error");
|
package/dist/lib/upgrade.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade.js","names":[],"sources":["../../src/lib/upgrade.ts"],"sourcesContent":["import debug from \"debug\";\nimport { transform, type TransformErrors, getRelevantFiles } from \"./transform\";\nimport type { TransformOptions } from \"./transform-options\";\nimport { SingleBar, Presets } from \"cli-progress\";\nimport installReactUILib from \"./install-ui-lib\";\nimport installEdgeLib from \"./install-edge-lib\";\nimport installAiSdkLib from \"./install-ai-sdk-lib\";\nimport { logger } from \"./utils/logger\";\n\nconst bundle = [\n \"v0-8/ui-package-split\",\n \"v0-9/edge-package-split\",\n \"v0-11/content-part-to-message-part\",\n \"v0-12/assistant-api-to-aui\",\n \"v0-12/event-names-to-camelcase\",\n \"v0-12/primitive-if-to-aui-if\",\n];\n\nconst log = debug(\"codemod:upgrade\");\nconst error = debug(\"codemod:upgrade:error\");\n\n/**\n * Runs the upgrade cycle:\n * - Runs each codemod in the bundle.\n * - Displays progress using cli-progress.\n * - After codemods run, checks if any file now imports from the new packages and prompts for install.\n */\nexport async function upgrade(options: TransformOptions) {\n const cwd = process.cwd();\n log(\"Starting upgrade...\");\n\n // Find relevant files once to avoid duplicate work\n logger.info(\"Analyzing codebase...\");\n const relevantFiles = getRelevantFiles(cwd);\n const fileCount = relevantFiles.length;\n logger.info(`Found ${fileCount} files to process.`);\n\n // Calculate total work units (files × codemods)\n const totalWork = fileCount * bundle.length;\n let completedWork = 0;\n\n const bar = new SingleBar(\n {\n format: \"Progress |{bar}| {percentage}% | ETA: {eta}s || {status}\",\n hideCursor: true,\n },\n Presets.shades_classic,\n );\n\n bar.start(totalWork, 0, { status: \"Starting...\" });\n const allErrors: TransformErrors = [];\n\n for (const codemod of bundle) {\n bar.update(completedWork, { status: `Running ${codemod}...` });\n\n // Use a custom progress callback to update the progress bar\n const errors = transform(codemod, cwd, options, {\n logStatus: false,\n onProgress: (processedFiles: number) => {\n completedWork = bundle.indexOf(codemod) * fileCount + processedFiles;\n bar.update(Math.min(completedWork, totalWork), {\n status: `Running ${codemod} (${processedFiles}/${fileCount} files)`,\n });\n },\n relevantFiles, // Pass the pre-computed relevant files\n });\n\n allErrors.push(...errors);\n completedWork = (bundle.indexOf(codemod) + 1) * fileCount;\n bar.update(completedWork, { status: `Completed ${codemod}` });\n }\n\n bar.update(totalWork, { status: \"Checking dependencies...\" });\n bar.stop();\n\n if (allErrors.length > 0) {\n log(\"Some codemods did not apply successfully to all files. Details:\");\n allErrors.forEach(({ transform, filename, summary }) => {\n error(`codemod=${transform}, path=${filename}, summary=${summary}`);\n });\n }\n\n // After codemods run, check if files import from the new packages and prompt for install.\n logger.info(\"Checking for package dependencies...\");\n await installReactUILib();\n await installEdgeLib();\n await installAiSdkLib();\n\n log(\"Upgrade complete.\");\n logger.success(\"Upgrade complete!\");\n}\n"],"mappings":";;;;;;;;AASA,MAAM,SAAS;CACb;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,MAAM,MAAM,iBAAiB;AACnC,MAAM,QAAQ,MAAM,uBAAuB;;;;;;;AAQ3C,eAAsB,QAAQ,SAA2B;CACvD,MAAM,MAAM,QAAQ,IAAI;CACxB,IAAI,qBAAqB;CAGzB,OAAO,KAAK,uBAAuB;CACnC,MAAM,gBAAgB,iBAAiB,GAAG;CAC1C,MAAM,YAAY,cAAc;CAChC,OAAO,KAAK,SAAS,UAAU,mBAAmB;CAGlD,MAAM,YAAY,YAAY,OAAO;CACrC,IAAI,gBAAgB;CAEpB,MAAM,MAAM,IAAI,UACd;EACE,QAAQ;EACR,YAAY;CACd,GACA,QAAQ,cACV;CAEA,IAAI,MAAM,WAAW,GAAG,EAAE,QAAQ,cAAc,CAAC;CACjD,MAAM,YAA6B,CAAC;CAEpC,KAAK,MAAM,WAAW,QAAQ;EAC5B,IAAI,OAAO,eAAe,EAAE,QAAQ,WAAW,QAAQ,KAAK,CAAC;EAG7D,MAAM,SAAS,UAAU,SAAS,KAAK,SAAS;GAC9C,WAAW;GACX,aAAa,mBAA2B;IACtC,gBAAgB,OAAO,QAAQ,OAAO,IAAI,YAAY;IACtD,IAAI,OAAO,KAAK,IAAI,eAAe,SAAS,GAAG,EAC7C,QAAQ,WAAW,QAAQ,IAAI,eAAe,GAAG,UAAU,SAC7D,CAAC;GACH;GACA;EACF,CAAC;EAED,UAAU,KAAK,GAAG,MAAM;EACxB,iBAAiB,OAAO,QAAQ,OAAO,IAAI,KAAK;EAChD,IAAI,OAAO,eAAe,EAAE,QAAQ,aAAa,UAAU,CAAC;CAC9D;CAEA,IAAI,OAAO,WAAW,EAAE,QAAQ,2BAA2B,CAAC;CAC5D,IAAI,KAAK;CAET,IAAI,UAAU,SAAS,GAAG;EACxB,IAAI,iEAAiE;EACrE,UAAU,SAAS,EAAE,WAAW,UAAU,cAAc;GACtD,MAAM,WAAW,UAAU,SAAS,SAAS,YAAY,SAAS;EACpE,CAAC;CACH;CAGA,OAAO,KAAK,sCAAsC;CAClD,MAAM,kBAAkB;CACxB,MAAM,eAAe;CACrB,MAAM,gBAAgB;CAEtB,IAAI,mBAAmB;CACvB,OAAO,QAAQ,mBAAmB;AACpC"}
|
|
1
|
+
{"version":3,"file":"upgrade.js","names":[],"sources":["../../src/lib/upgrade.ts"],"sourcesContent":["import debug from \"debug\";\nimport { transform, type TransformErrors, getRelevantFiles } from \"./transform\";\nimport type { TransformOptions } from \"./transform-options\";\nimport { SingleBar, Presets } from \"cli-progress\";\nimport installReactUILib from \"./install-ui-lib\";\nimport installEdgeLib from \"./install-edge-lib\";\nimport installAiSdkLib from \"./install-ai-sdk-lib\";\nimport { logger } from \"./utils/logger\";\n\nconst bundle = [\n \"v0-8/ui-package-split\",\n \"v0-9/edge-package-split\",\n \"v0-11/content-part-to-message-part\",\n \"v0-12/assistant-api-to-aui\",\n \"v0-12/event-names-to-camelcase\",\n \"v0-12/primitive-if-to-aui-if\",\n \"v0-15/aui-accessor-calls-to-properties\",\n];\n\nconst log = debug(\"codemod:upgrade\");\nconst error = debug(\"codemod:upgrade:error\");\n\n/**\n * Runs the upgrade cycle:\n * - Runs each codemod in the bundle.\n * - Displays progress using cli-progress.\n * - After codemods run, checks if any file now imports from the new packages and prompts for install.\n */\nexport async function upgrade(options: TransformOptions) {\n const cwd = process.cwd();\n log(\"Starting upgrade...\");\n\n // Find relevant files once to avoid duplicate work\n logger.info(\"Analyzing codebase...\");\n const relevantFiles = getRelevantFiles(cwd);\n const fileCount = relevantFiles.length;\n logger.info(`Found ${fileCount} files to process.`);\n\n // Calculate total work units (files × codemods)\n const totalWork = fileCount * bundle.length;\n let completedWork = 0;\n\n const bar = new SingleBar(\n {\n format: \"Progress |{bar}| {percentage}% | ETA: {eta}s || {status}\",\n hideCursor: true,\n },\n Presets.shades_classic,\n );\n\n bar.start(totalWork, 0, { status: \"Starting...\" });\n const allErrors: TransformErrors = [];\n\n for (const codemod of bundle) {\n bar.update(completedWork, { status: `Running ${codemod}...` });\n\n // Use a custom progress callback to update the progress bar\n const errors = transform(codemod, cwd, options, {\n logStatus: false,\n onProgress: (processedFiles: number) => {\n completedWork = bundle.indexOf(codemod) * fileCount + processedFiles;\n bar.update(Math.min(completedWork, totalWork), {\n status: `Running ${codemod} (${processedFiles}/${fileCount} files)`,\n });\n },\n relevantFiles, // Pass the pre-computed relevant files\n });\n\n allErrors.push(...errors);\n completedWork = (bundle.indexOf(codemod) + 1) * fileCount;\n bar.update(completedWork, { status: `Completed ${codemod}` });\n }\n\n bar.update(totalWork, { status: \"Checking dependencies...\" });\n bar.stop();\n\n if (allErrors.length > 0) {\n log(\"Some codemods did not apply successfully to all files. Details:\");\n allErrors.forEach(({ transform, filename, summary }) => {\n error(`codemod=${transform}, path=${filename}, summary=${summary}`);\n });\n }\n\n // After codemods run, check if files import from the new packages and prompt for install.\n logger.info(\"Checking for package dependencies...\");\n await installReactUILib();\n await installEdgeLib();\n await installAiSdkLib();\n\n log(\"Upgrade complete.\");\n logger.success(\"Upgrade complete!\");\n}\n"],"mappings":";;;;;;;;AASA,MAAM,SAAS;CACb;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,MAAM,MAAM,iBAAiB;AACnC,MAAM,QAAQ,MAAM,uBAAuB;;;;;;;AAQ3C,eAAsB,QAAQ,SAA2B;CACvD,MAAM,MAAM,QAAQ,IAAI;CACxB,IAAI,qBAAqB;CAGzB,OAAO,KAAK,uBAAuB;CACnC,MAAM,gBAAgB,iBAAiB,GAAG;CAC1C,MAAM,YAAY,cAAc;CAChC,OAAO,KAAK,SAAS,UAAU,mBAAmB;CAGlD,MAAM,YAAY,YAAY,OAAO;CACrC,IAAI,gBAAgB;CAEpB,MAAM,MAAM,IAAI,UACd;EACE,QAAQ;EACR,YAAY;CACd,GACA,QAAQ,cACV;CAEA,IAAI,MAAM,WAAW,GAAG,EAAE,QAAQ,cAAc,CAAC;CACjD,MAAM,YAA6B,CAAC;CAEpC,KAAK,MAAM,WAAW,QAAQ;EAC5B,IAAI,OAAO,eAAe,EAAE,QAAQ,WAAW,QAAQ,KAAK,CAAC;EAG7D,MAAM,SAAS,UAAU,SAAS,KAAK,SAAS;GAC9C,WAAW;GACX,aAAa,mBAA2B;IACtC,gBAAgB,OAAO,QAAQ,OAAO,IAAI,YAAY;IACtD,IAAI,OAAO,KAAK,IAAI,eAAe,SAAS,GAAG,EAC7C,QAAQ,WAAW,QAAQ,IAAI,eAAe,GAAG,UAAU,SAC7D,CAAC;GACH;GACA;EACF,CAAC;EAED,UAAU,KAAK,GAAG,MAAM;EACxB,iBAAiB,OAAO,QAAQ,OAAO,IAAI,KAAK;EAChD,IAAI,OAAO,eAAe,EAAE,QAAQ,aAAa,UAAU,CAAC;CAC9D;CAEA,IAAI,OAAO,WAAW,EAAE,QAAQ,2BAA2B,CAAC;CAC5D,IAAI,KAAK;CAET,IAAI,UAAU,SAAS,GAAG;EACxB,IAAI,iEAAiE;EACrE,UAAU,SAAS,EAAE,WAAW,UAAU,cAAc;GACtD,MAAM,WAAW,UAAU,SAAS,SAAS,YAAY,SAAS;EACpE,CAAC;CACH;CAGA,OAAO,KAAK,sCAAsC;CAClD,MAAM,kBAAkB;CACxB,MAAM,eAAe;CACrB,MAAM,gBAAgB;CAEtB,IAAI,mBAAmB;CACvB,OAAO,QAAQ,mBAAmB;AACpC"}
|
package/dist/run.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","names":[],"sources":["../src/run.ts"],"mappings":";iBAEsB,UAAU"}
|
package/dist/run.js
ADDED
package/dist/run.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","names":[],"sources":["../src/run.ts"],"sourcesContent":["import { buildProgram } from \"./program\";\n\nexport async function runCli(): Promise<void> {\n await buildProgram().parseAsync();\n}\n"],"mappings":";;AAEA,eAAsB,SAAwB;CAC5C,MAAM,aAAa,CAAC,CAAC,WAAW;AAClC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "assistant-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.108",
|
|
4
4
|
"description": "CLI for assistant-ui",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"@types/semver": "^7.7.1",
|
|
50
50
|
"@vitest/coverage-v8": "^4.1.10",
|
|
51
51
|
"vitest": "^4.1.10",
|
|
52
|
-
"@assistant-ui/x-buildutils": "0.0.
|
|
52
|
+
"@assistant-ui/x-buildutils": "0.0.20"
|
|
53
53
|
},
|
|
54
54
|
"publishConfig": {
|
|
55
55
|
"access": "public",
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import jscodeshift, { type API } from "jscodeshift";
|
|
3
|
+
import transform from "../aui-accessor-calls-to-properties";
|
|
4
|
+
|
|
5
|
+
const j = jscodeshift.withParser("tsx");
|
|
6
|
+
|
|
7
|
+
function applyTransform(source: string): string | null {
|
|
8
|
+
const fileInfo = {
|
|
9
|
+
path: "test.tsx",
|
|
10
|
+
source,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const api: API = {
|
|
14
|
+
jscodeshift: j,
|
|
15
|
+
j,
|
|
16
|
+
stats: () => {},
|
|
17
|
+
report: () => {},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
return transform(fileInfo, api, {});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
describe("aui-accessor-calls-to-properties", () => {
|
|
24
|
+
it("rewrites nullary accessor calls on a useAui variable", () => {
|
|
25
|
+
const input = `
|
|
26
|
+
const client = useAui();
|
|
27
|
+
client.thread().cancelRun();
|
|
28
|
+
const state = client.composer().getState();
|
|
29
|
+
`;
|
|
30
|
+
const expected = `
|
|
31
|
+
const client = useAui();
|
|
32
|
+
client.thread.cancelRun();
|
|
33
|
+
const state = client.composer.getState();
|
|
34
|
+
`;
|
|
35
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("rewrites only the accessor call in chained expressions", () => {
|
|
39
|
+
const input = `
|
|
40
|
+
const aui = useAui();
|
|
41
|
+
const part = aui.message().part({ index: 0 });
|
|
42
|
+
aui.message().composer().send();
|
|
43
|
+
`;
|
|
44
|
+
const expected = `
|
|
45
|
+
const aui = useAui();
|
|
46
|
+
const part = aui.message.part({ index: 0 });
|
|
47
|
+
aui.message.composer().send();
|
|
48
|
+
`;
|
|
49
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("rewrites identifiers named aui without a declaration", () => {
|
|
53
|
+
const input = `
|
|
54
|
+
const Derived = {
|
|
55
|
+
get: (aui) => aui.thread().message({ index: 0 }),
|
|
56
|
+
};
|
|
57
|
+
`;
|
|
58
|
+
const expected = `
|
|
59
|
+
const Derived = {
|
|
60
|
+
get: (aui) => aui.thread.message({ index: 0 }),
|
|
61
|
+
};
|
|
62
|
+
`;
|
|
63
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("rewrites parameters typed AssistantClient", () => {
|
|
67
|
+
const input = `
|
|
68
|
+
const getItem = (client: AssistantClient) => client.threadListItem().getState();
|
|
69
|
+
`;
|
|
70
|
+
const expected = `
|
|
71
|
+
const getItem = (client: AssistantClient) => client.threadListItem.getState();
|
|
72
|
+
`;
|
|
73
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("leaves calls with arguments untouched", () => {
|
|
77
|
+
const input = `
|
|
78
|
+
const aui = useAui();
|
|
79
|
+
const t = aui.threads().thread({ id: "t1" });
|
|
80
|
+
`;
|
|
81
|
+
const expected = `
|
|
82
|
+
const aui = useAui();
|
|
83
|
+
const t = aui.threads.thread({ id: "t1" });
|
|
84
|
+
`;
|
|
85
|
+
expect(applyTransform(input)?.trim()).toBe(expected.trim());
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("does not rewrite unknown receivers", () => {
|
|
89
|
+
const input = `
|
|
90
|
+
toolkit.tools();
|
|
91
|
+
message.composer().send();
|
|
92
|
+
ref.current.thread().getState();
|
|
93
|
+
`;
|
|
94
|
+
expect(applyTransform(input)).toBeNull();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("does not rewrite non-scope member calls on aui", () => {
|
|
98
|
+
const input = `
|
|
99
|
+
const aui = useAui();
|
|
100
|
+
aui.subscribe(() => {});
|
|
101
|
+
aui.on("thread.updated", () => {});
|
|
102
|
+
`;
|
|
103
|
+
expect(applyTransform(input)).toBeNull();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("returns null when nothing changes", () => {
|
|
107
|
+
expect(applyTransform(`const x = 1;`)).toBeNull();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { createTransformer } from "../utils/createTransformer";
|
|
2
|
+
|
|
3
|
+
// Nullary scope accessors that became properties in v0.15. Parameterized
|
|
4
|
+
// lookups (e.g. `aui.thread.message({ id })`) stay as real calls.
|
|
5
|
+
const NULLARY_SCOPES = new Set([
|
|
6
|
+
"threads",
|
|
7
|
+
"threadListItem",
|
|
8
|
+
"thread",
|
|
9
|
+
"message",
|
|
10
|
+
"part",
|
|
11
|
+
"composer",
|
|
12
|
+
"attachment",
|
|
13
|
+
"modelContext",
|
|
14
|
+
"suggestions",
|
|
15
|
+
"suggestion",
|
|
16
|
+
"chainOfThought",
|
|
17
|
+
"queueItem",
|
|
18
|
+
"tools",
|
|
19
|
+
"dataRenderers",
|
|
20
|
+
"interactables",
|
|
21
|
+
"unstable_interactables",
|
|
22
|
+
"mcp",
|
|
23
|
+
"mcpServer",
|
|
24
|
+
"span",
|
|
25
|
+
]);
|
|
26
|
+
|
|
27
|
+
const AUI_HOOKS = new Set(["useAui", "useAssistantApi"]);
|
|
28
|
+
|
|
29
|
+
const auiAccessorCallsToProperties = createTransformer(
|
|
30
|
+
({ j, root, markAsChanged }) => {
|
|
31
|
+
const auiNames = new Set(["aui"]);
|
|
32
|
+
|
|
33
|
+
root.find(j.VariableDeclarator).forEach((path: any) => {
|
|
34
|
+
const { id, init } = path.value;
|
|
35
|
+
if (
|
|
36
|
+
j.Identifier.check(id) &&
|
|
37
|
+
init &&
|
|
38
|
+
j.CallExpression.check(init) &&
|
|
39
|
+
j.Identifier.check(init.callee) &&
|
|
40
|
+
AUI_HOOKS.has(init.callee.name)
|
|
41
|
+
) {
|
|
42
|
+
auiNames.add(id.name);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const collectParam = (param: any) => {
|
|
47
|
+
const annotation = param?.typeAnnotation?.typeAnnotation;
|
|
48
|
+
if (
|
|
49
|
+
j.Identifier.check(param) &&
|
|
50
|
+
annotation &&
|
|
51
|
+
j.TSTypeReference.check(annotation) &&
|
|
52
|
+
j.Identifier.check(annotation.typeName) &&
|
|
53
|
+
annotation.typeName.name === "AssistantClient"
|
|
54
|
+
) {
|
|
55
|
+
auiNames.add(param.name);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
for (const fnType of [
|
|
59
|
+
j.FunctionDeclaration,
|
|
60
|
+
j.FunctionExpression,
|
|
61
|
+
j.ArrowFunctionExpression,
|
|
62
|
+
] as const) {
|
|
63
|
+
root.find(fnType as typeof j.FunctionDeclaration).forEach((path: any) => {
|
|
64
|
+
path.value.params.forEach(collectParam);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
root.find(j.CallExpression).forEach((path: any) => {
|
|
69
|
+
const node = path.value;
|
|
70
|
+
if (node.arguments.length !== 0) return;
|
|
71
|
+
const callee = node.callee;
|
|
72
|
+
if (!j.MemberExpression.check(callee) || callee.computed) return;
|
|
73
|
+
if (!j.Identifier.check(callee.property)) return;
|
|
74
|
+
if (!NULLARY_SCOPES.has(callee.property.name)) return;
|
|
75
|
+
if (!j.Identifier.check(callee.object)) return;
|
|
76
|
+
if (!auiNames.has(callee.object.name)) return;
|
|
77
|
+
j(path).replaceWith(callee);
|
|
78
|
+
markAsChanged();
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
export default auiAccessorCallsToProperties;
|
package/src/commands/upgrade.ts
CHANGED
|
@@ -48,9 +48,9 @@ export const upgradeCommand = addTransformOptions(
|
|
|
48
48
|
new Command()
|
|
49
49
|
.command("upgrade")
|
|
50
50
|
.description("Upgrade ai package dependencies and apply codemods"),
|
|
51
|
-
).action((options: TransformOptions) => {
|
|
51
|
+
).action(async (options: TransformOptions) => {
|
|
52
52
|
try {
|
|
53
|
-
upgrade(options);
|
|
53
|
+
await upgrade(options);
|
|
54
54
|
} catch (err) {
|
|
55
55
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
56
56
|
const errorStack = err instanceof Error ? err.stack : undefined;
|
package/src/index.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { runCli } from "./run";
|
|
4
4
|
|
|
5
5
|
process.on("SIGINT", () => process.exit(0));
|
|
6
6
|
process.on("SIGTERM", () => process.exit(0));
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
main();
|
|
8
|
+
void runCli().catch((error: unknown) => {
|
|
9
|
+
console.error(error);
|
|
10
|
+
process.exitCode = 1;
|
|
11
|
+
});
|
package/src/lib/upgrade.ts
CHANGED
package/src/run.test.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
|
|
3
|
+
const mocks = vi.hoisted(() => ({
|
|
4
|
+
parseAsync: vi.fn(),
|
|
5
|
+
}));
|
|
6
|
+
|
|
7
|
+
vi.mock("./program", () => ({
|
|
8
|
+
buildProgram: () => ({
|
|
9
|
+
parseAsync: mocks.parseAsync,
|
|
10
|
+
}),
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
import { runCli } from "./run";
|
|
14
|
+
|
|
15
|
+
describe("runCli", () => {
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
vi.clearAllMocks();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("awaits and propagates asynchronous command failures", async () => {
|
|
21
|
+
const error = new Error("command failed");
|
|
22
|
+
mocks.parseAsync.mockRejectedValue(error);
|
|
23
|
+
|
|
24
|
+
await expect(runCli()).rejects.toBe(error);
|
|
25
|
+
expect(mocks.parseAsync).toHaveBeenCalledOnce();
|
|
26
|
+
});
|
|
27
|
+
});
|