assistant-ui 0.0.123 → 0.0.124
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-11/content-part-to-message-part.d.ts.map +1 -1
- package/dist/codemods/v0-11/content-part-to-message-part.js +126 -40
- package/dist/codemods/v0-11/content-part-to-message-part.js.map +1 -1
- package/dist/codemods/v0-12/event-names-to-camelcase.d.ts.map +1 -1
- package/dist/codemods/v0-12/event-names-to-camelcase.js +2 -2
- package/dist/codemods/v0-12/event-names-to-camelcase.js.map +1 -1
- package/dist/codemods/v0-12/primitive-if-to-aui-if.d.ts.map +1 -1
- package/dist/codemods/v0-12/primitive-if-to-aui-if.js +53 -37
- package/dist/codemods/v0-12/primitive-if-to-aui-if.js.map +1 -1
- package/dist/codemods/v0-8/ui-package-split.d.ts.map +1 -1
- package/dist/codemods/v0-8/ui-package-split.js +11 -35
- package/dist/codemods/v0-8/ui-package-split.js.map +1 -1
- package/dist/codemods/v0-9/edge-package-split.d.ts.map +1 -1
- package/dist/codemods/v0-9/edge-package-split.js +15 -69
- package/dist/codemods/v0-9/edge-package-split.js.map +1 -1
- package/dist/lib/utils/package-installer.d.ts.map +1 -1
- package/dist/lib/utils/package-installer.js +3 -2
- package/dist/lib/utils/package-installer.js.map +1 -1
- package/package.json +1 -1
- package/src/codemods/v0-11/__tests__/content-part-to-message-part.test.ts +268 -2
- package/src/codemods/v0-11/content-part-to-message-part.ts +211 -80
- package/src/codemods/v0-12/__tests__/event-names-to-camelcase.test.ts +23 -0
- package/src/codemods/v0-12/__tests__/primitive-if-to-aui-if.test.ts +115 -0
- package/src/codemods/v0-12/event-names-to-camelcase.ts +2 -8
- package/src/codemods/v0-12/primitive-if-to-aui-if.ts +87 -57
- package/src/codemods/v0-8/__tests__/ui-package-split.test.ts +83 -0
- package/src/codemods/v0-8/ui-package-split.ts +21 -59
- package/src/codemods/v0-9/edge-package-split.test.ts +100 -0
- package/src/codemods/v0-9/edge-package-split.ts +30 -139
- package/src/lib/utils/package-installer.test.ts +39 -0
- package/src/lib/utils/package-installer.ts +3 -1
- package/templates/cloud-harness/components/assistant-ui/elements/tool-fallback.aui.tsx +17 -8
- package/templates/cloud-harness/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui-package-split.js","names":[],"sources":["../../../src/codemods/v0-8/ui-package-split.ts"],"sourcesContent":["import { createTransformer } from \"../utils/createTransformer\";\n\nconst reactUIExports: string[] = [\n \"ThreadConfigProvider\",\n \"useThreadConfig\",\n \"ThreadConfig\",\n \"ThreadWelcomeConfig\",\n \"UserMessageConfig\",\n \"AssistantMessageConfig\",\n \"StringsConfig\",\n \"SuggestionConfig\",\n \"ThreadConfigProviderProps\",\n \"AssistantActionBar\",\n \"AssistantMessage\",\n \"AssistantModal\",\n \"BranchPicker\",\n \"Composer\",\n \"MessagePart\",\n \"AttachmentUI\",\n \"EditComposer\",\n \"Thread\",\n \"ThreadList\",\n \"ThreadListItem\",\n \"ThreadWelcome\",\n \"UserMessage\",\n \"makeMarkdownText\",\n \"MakeMarkdownTextProps\",\n \"CodeHeader\",\n];\n\nconst migrateAssistantUI = createTransformer(({ j, root, markAsChanged }) => {\n const sourcesToMigrate: string[] = [\n \"@assistant-ui/react\",\n \"@assistant-ui/react-markdown\",\n ];\n
|
|
1
|
+
{"version":3,"file":"ui-package-split.js","names":[],"sources":["../../../src/codemods/v0-8/ui-package-split.ts"],"sourcesContent":["import { createTransformer } from \"../utils/createTransformer\";\n\nconst reactUIExports: string[] = [\n \"ThreadConfigProvider\",\n \"useThreadConfig\",\n \"ThreadConfig\",\n \"ThreadWelcomeConfig\",\n \"UserMessageConfig\",\n \"AssistantMessageConfig\",\n \"StringsConfig\",\n \"SuggestionConfig\",\n \"ThreadConfigProviderProps\",\n \"AssistantActionBar\",\n \"AssistantMessage\",\n \"AssistantModal\",\n \"BranchPicker\",\n \"Composer\",\n \"MessagePart\",\n \"AttachmentUI\",\n \"EditComposer\",\n \"Thread\",\n \"ThreadList\",\n \"ThreadListItem\",\n \"ThreadWelcome\",\n \"UserMessage\",\n \"makeMarkdownText\",\n \"MakeMarkdownTextProps\",\n \"CodeHeader\",\n];\n\nconst migrateAssistantUI = createTransformer(({ j, root, markAsChanged }) => {\n const sourcesToMigrate: string[] = [\n \"@assistant-ui/react\",\n \"@assistant-ui/react-markdown\",\n ];\n\n root\n .find(j.ImportDeclaration)\n .filter((path) =>\n sourcesToMigrate.includes(path.node.source.value as string),\n )\n .forEach((path) => {\n const specifiers = path.node.specifiers ?? [];\n const moved = specifiers.filter(\n (specifier) =>\n j.ImportSpecifier.check(specifier) &&\n reactUIExports.includes(specifier.imported.name as string),\n );\n if (moved.length === 0) return;\n\n const destination = j.literal(\"@assistant-ui/react-ui\");\n if (moved.length === specifiers.length) {\n path.node.source = destination;\n } else {\n path.node.specifiers = specifiers.filter(\n (specifier) => !moved.includes(specifier),\n );\n const declaration = j.importDeclaration(moved, destination);\n declaration.importKind = path.node.importKind ?? \"value\";\n j(path).insertAfter(declaration);\n }\n markAsChanged();\n });\n\n const cssReplacements: Record<string, string> = {\n \"@assistant-ui/react/styles/index.css\":\n \"@assistant-ui/react-ui/styles/index.css\",\n \"@assistant-ui/react/styles/modal.css\":\n \"@assistant-ui/react-ui/styles/modal.css\",\n \"@assistant-ui/react-markdown/styles/markdown.css\":\n \"@assistant-ui/react-ui/styles/markdown.css\",\n };\n\n root.find(j.ImportDeclaration).forEach((path: any) => {\n const sourceValue: string = path.value.source.value;\n if (cssReplacements[sourceValue]) {\n path.value.source = j.literal(cssReplacements[sourceValue]);\n markAsChanged();\n }\n });\n\n let removedMarkdownPlugin = false;\n root\n .find(j.CallExpression, { callee: { name: \"require\" } })\n .filter((path: any) => {\n const arg = path.value.arguments[0];\n return (\n arg &&\n (arg.type === \"Literal\" || arg.type === \"StringLiteral\") &&\n arg.value === \"@assistant-ui/react-markdown/tailwindcss\"\n );\n })\n .forEach((path: any) => {\n removedMarkdownPlugin = true;\n const parent = path.parentPath;\n if (parent?.value && parent.value.type === \"VariableDeclarator\") {\n const varDecl = parent.parentPath;\n if (\n varDecl?.value.declarations &&\n varDecl.value.declarations.length === 1\n ) {\n j(varDecl).remove();\n } else {\n varDecl.value.declarations = varDecl.value.declarations.filter(\n (decl: any) => decl !== parent.value,\n );\n }\n markAsChanged();\n } else {\n j(path).remove();\n markAsChanged();\n }\n });\n\n root\n .find(j.CallExpression, { callee: { name: \"require\" } })\n .filter((path: any) => {\n const arg = path.value.arguments[0];\n return (\n arg &&\n (arg.type === \"Literal\" || arg.type === \"StringLiteral\") &&\n arg.value === \"@assistant-ui/react/tailwindcss\"\n );\n })\n .forEach((path: any) => {\n path.value.arguments[0].value = \"@assistant-ui/react-ui/tailwindcss\";\n markAsChanged();\n if (removedMarkdownPlugin) {\n if (\n path.parentPath?.value &&\n path.parentPath.value.type === \"CallExpression\" &&\n path.parentPath.value.arguments.length > 0\n ) {\n const configObj = path.parentPath.value.arguments[0];\n if (configObj && configObj.type === \"ObjectExpression\") {\n const componentsProp = configObj.properties.find((prop: any) => {\n return (\n (prop.key.name === \"components\" ||\n prop.key.value === \"components\") &&\n prop.value.type === \"ArrayExpression\"\n );\n });\n if (componentsProp) {\n const componentsArray = componentsProp.value.elements;\n const hasMarkdown = componentsArray.some(\n (el: any) => el.type === \"Literal\" && el.value === \"markdown\",\n );\n if (!hasMarkdown) {\n componentsArray.push(j.literal(\"markdown\"));\n markAsChanged();\n }\n }\n }\n }\n }\n });\n});\n\nexport default migrateAssistantUI;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edge-package-split.d.ts","sourceRoot":"","sources":["../../../src/codemods/v0-9/edge-package-split.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"edge-package-split.d.ts","sourceRoot":"","sources":["../../../src/codemods/v0-9/edge-package-split.ts"],"names":[],"mappings":"AAyBA,QAAA,MAAM,oBAAoB,6HA0CxB,CAAC;AAEH,eAAe,oBAAoB,CAAC"}
|
|
@@ -20,80 +20,26 @@ const reactAiSdkExports = [
|
|
|
20
20
|
"useDangerousInBrowserRuntime"
|
|
21
21
|
];
|
|
22
22
|
const migrateToEdgePackage = createTransformer(({ j, root, markAsChanged }) => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
let hadMigratedSpecifiers = false;
|
|
28
|
-
const remainingSpecifiers = [];
|
|
29
|
-
path.value.specifiers.forEach((specifier) => {
|
|
30
|
-
if (j.ImportSpecifier.check(specifier) && reactAiSdkExports.includes(specifier.imported.name)) {
|
|
31
|
-
movedAiSdkSpecifiers.push(specifier);
|
|
32
|
-
hadMigratedSpecifiers = true;
|
|
33
|
-
} else remainingSpecifiers.push(specifier);
|
|
34
|
-
});
|
|
35
|
-
if (hadMigratedSpecifiers) lastMigratedImportPath = path;
|
|
36
|
-
if (remainingSpecifiers.length === 0) {
|
|
37
|
-
j(path).remove();
|
|
38
|
-
markAsChanged();
|
|
39
|
-
} else if (remainingSpecifiers.length !== path.value.specifiers.length) {
|
|
40
|
-
path.value.specifiers = remainingSpecifiers;
|
|
23
|
+
root.find(j.ImportDeclaration).forEach((path) => {
|
|
24
|
+
const source = path.node.source.value;
|
|
25
|
+
if (typeof source === "string" && source.startsWith("@assistant-ui/react/") && (source.includes("edge/") || source.includes("dangerous-in-browser/"))) {
|
|
26
|
+
path.node.source = j.literal(source.replace("@assistant-ui/react/", "@assistant-ui/react-ai-sdk/"));
|
|
41
27
|
markAsChanged();
|
|
28
|
+
return;
|
|
42
29
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
if (
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
});
|
|
50
|
-
});
|
|
30
|
+
if (source !== "@assistant-ui/react" && source !== "@assistant-ui/react-edge") return;
|
|
31
|
+
const specifiers = path.node.specifiers ?? [];
|
|
32
|
+
const moved = specifiers.filter((specifier) => j.ImportSpecifier.check(specifier) && reactAiSdkExports.includes(specifier.imported.name));
|
|
33
|
+
if (moved.length === 0) return;
|
|
34
|
+
const destination = j.literal("@assistant-ui/react-ai-sdk");
|
|
35
|
+
if (moved.length === specifiers.length) path.node.source = destination;
|
|
51
36
|
else {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (firstImport.size() > 0) firstImport.insertBefore(newImport);
|
|
57
|
-
else root.get().node.program.body.unshift(newImport);
|
|
58
|
-
}
|
|
37
|
+
path.node.specifiers = specifiers.filter((specifier) => !moved.includes(specifier));
|
|
38
|
+
const declaration = j.importDeclaration(moved, destination);
|
|
39
|
+
declaration.importKind = path.node.importKind ?? "value";
|
|
40
|
+
j(path).insertAfter(declaration);
|
|
59
41
|
}
|
|
60
42
|
markAsChanged();
|
|
61
|
-
}
|
|
62
|
-
root.find(j.ImportDeclaration).forEach((path) => {
|
|
63
|
-
const sourceValue = path.value.source.value;
|
|
64
|
-
if (sourceValue.startsWith("@assistant-ui/react/") && (sourceValue.includes("edge/") || sourceValue.includes("dangerous-in-browser/"))) {
|
|
65
|
-
path.value.source = j.literal(sourceValue.replace("@assistant-ui/react/", "@assistant-ui/react-ai-sdk/"));
|
|
66
|
-
markAsChanged();
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
root.find(j.ImportDeclaration).forEach((path) => {
|
|
70
|
-
const sourceValue = path.value.source.value;
|
|
71
|
-
if (sourceValue === "@assistant-ui/react-edge" || sourceValue === "@assistant-ui/react") {
|
|
72
|
-
let hasLanguageModelConverters = false;
|
|
73
|
-
const remainingSpecifiers = [];
|
|
74
|
-
const aiSdkSpecifiers = [];
|
|
75
|
-
path.value.specifiers.forEach((specifier) => {
|
|
76
|
-
if (j.ImportSpecifier.check(specifier) && reactAiSdkExports.includes(specifier.imported.name)) {
|
|
77
|
-
aiSdkSpecifiers.push(specifier);
|
|
78
|
-
hasLanguageModelConverters = true;
|
|
79
|
-
} else remainingSpecifiers.push(specifier);
|
|
80
|
-
});
|
|
81
|
-
if (hasLanguageModelConverters) {
|
|
82
|
-
if (remainingSpecifiers.length === 0) j(path).remove();
|
|
83
|
-
else path.value.specifiers = remainingSpecifiers;
|
|
84
|
-
const existingAiSdkImport = root.find(j.ImportDeclaration, { source: { value: "@assistant-ui/react-ai-sdk" } });
|
|
85
|
-
if (existingAiSdkImport.size() > 0) existingAiSdkImport.forEach((importPath) => {
|
|
86
|
-
aiSdkSpecifiers.forEach((specifier) => {
|
|
87
|
-
if (!importPath.value.specifiers.some((s) => s.imported.name === specifier.imported.name)) importPath.value.specifiers.push(specifier);
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
else {
|
|
91
|
-
const newImport = j.importDeclaration(aiSdkSpecifiers, j.literal("@assistant-ui/react-ai-sdk"));
|
|
92
|
-
j(path).insertAfter(newImport);
|
|
93
|
-
}
|
|
94
|
-
markAsChanged();
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
43
|
});
|
|
98
44
|
});
|
|
99
45
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edge-package-split.js","names":[],"sources":["../../../src/codemods/v0-9/edge-package-split.ts"],"sourcesContent":["import { createTransformer } from \"../utils/createTransformer\";\n\
|
|
1
|
+
{"version":3,"file":"edge-package-split.js","names":[],"sources":["../../../src/codemods/v0-9/edge-package-split.ts"],"sourcesContent":["import { createTransformer } from \"../utils/createTransformer\";\n\nconst reactAiSdkExports: string[] = [\n \"useChatRuntime\",\n\n \"CoreMessage\",\n \"CoreUserMessage\",\n \"CoreAssistantMessage\",\n \"CoreSystemMessage\",\n \"CoreUserMessagePart\",\n \"CoreAssistantMessagePart\",\n \"CoreToolCallMessagePart\",\n\n \"fromCoreMessages\",\n \"fromCoreMessage\",\n \"toCoreMessages\",\n \"toCoreMessage\",\n\n \"toLanguageModelMessages\",\n \"toLanguageModelTools\",\n \"fromLanguageModelMessages\",\n \"fromLanguageModelTools\",\n \"useDangerousInBrowserRuntime\",\n];\n\nconst migrateToEdgePackage = createTransformer(({ j, root, markAsChanged }) => {\n root.find(j.ImportDeclaration).forEach((path) => {\n const source = path.node.source.value;\n if (\n typeof source === \"string\" &&\n source.startsWith(\"@assistant-ui/react/\") &&\n (source.includes(\"edge/\") || source.includes(\"dangerous-in-browser/\"))\n ) {\n path.node.source = j.literal(\n source.replace(\"@assistant-ui/react/\", \"@assistant-ui/react-ai-sdk/\"),\n );\n markAsChanged();\n return;\n }\n\n if (\n source !== \"@assistant-ui/react\" &&\n source !== \"@assistant-ui/react-edge\"\n )\n return;\n\n const specifiers = path.node.specifiers ?? [];\n const moved = specifiers.filter(\n (specifier) =>\n j.ImportSpecifier.check(specifier) &&\n reactAiSdkExports.includes(specifier.imported.name as string),\n );\n if (moved.length === 0) return;\n\n const destination = j.literal(\"@assistant-ui/react-ai-sdk\");\n if (moved.length === specifiers.length) {\n path.node.source = destination;\n } else {\n path.node.specifiers = specifiers.filter(\n (specifier) => !moved.includes(specifier),\n );\n const declaration = j.importDeclaration(moved, destination);\n declaration.importKind = path.node.importKind ?? \"value\";\n j(path).insertAfter(declaration);\n }\n markAsChanged();\n });\n});\n\nexport default migrateToEdgePackage;\n"],"mappings":";;AAEA,MAAM,oBAA8B;CAClC;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,uBAAuB,mBAAmB,EAAE,GAAG,MAAM,oBAAoB;CAC7E,KAAK,KAAK,EAAE,iBAAiB,CAAC,CAAC,SAAS,SAAS;EAC/C,MAAM,SAAS,KAAK,KAAK,OAAO;EAChC,IACE,OAAO,WAAW,YAClB,OAAO,WAAW,sBAAsB,MACvC,OAAO,SAAS,OAAO,KAAK,OAAO,SAAS,uBAAuB,IACpE;GACA,KAAK,KAAK,SAAS,EAAE,QACnB,OAAO,QAAQ,wBAAwB,6BAA6B,CACtE;GACA,cAAc;GACd;EACF;EAEA,IACE,WAAW,yBACX,WAAW,4BAEX;EAEF,MAAM,aAAa,KAAK,KAAK,cAAc,CAAC;EAC5C,MAAM,QAAQ,WAAW,QACtB,cACC,EAAE,gBAAgB,MAAM,SAAS,KACjC,kBAAkB,SAAS,UAAU,SAAS,IAAc,CAChE;EACA,IAAI,MAAM,WAAW,GAAG;EAExB,MAAM,cAAc,EAAE,QAAQ,4BAA4B;EAC1D,IAAI,MAAM,WAAW,WAAW,QAC9B,KAAK,KAAK,SAAS;OACd;GACL,KAAK,KAAK,aAAa,WAAW,QAC/B,cAAc,CAAC,MAAM,SAAS,SAAS,CAC1C;GACA,MAAM,cAAc,EAAE,kBAAkB,OAAO,WAAW;GAC1D,YAAY,aAAa,KAAK,KAAK,cAAc;GACjD,EAAE,IAAI,CAAC,CAAC,YAAY,WAAW;EACjC;EACA,cAAc;CAChB,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-installer.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/package-installer.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"package-installer.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/package-installer.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAqBf"}
|
|
@@ -12,8 +12,9 @@ async function installPackageIfNeeded(config) {
|
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
14
|
const answer = await askQuestion(config.promptMessage);
|
|
15
|
-
if (answer === "" || answer.toLowerCase().startsWith("y"))
|
|
16
|
-
|
|
15
|
+
if (answer === "" || answer.toLowerCase().startsWith("y")) {
|
|
16
|
+
if (!await installPackage(config.packageName)) throw new Error(`Failed to install ${config.packageName}`);
|
|
17
|
+
} else logger.info("Skipping installation.");
|
|
17
18
|
}
|
|
18
19
|
//#endregion
|
|
19
20
|
export { installPackageIfNeeded };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-installer.js","names":[],"sources":["../../../src/lib/utils/package-installer.ts"],"sourcesContent":["import { scanForImport } from \"./file-scanner\";\nimport {\n isPackageInstalled,\n askQuestion,\n installPackage,\n} from \"./package-manager\";\nimport { logger } from \"./logger\";\n\nexport interface PackageInstallConfig {\n packageName: string;\n importPatterns: string[];\n promptMessage: string;\n skipMessage: string;\n notFoundMessage: string;\n}\n\nexport async function installPackageIfNeeded(\n config: PackageInstallConfig,\n): Promise<void> {\n const found = scanForImport(config.importPatterns);\n\n if (!found) {\n logger.info(config.notFoundMessage);\n return;\n }\n\n if (isPackageInstalled(config.packageName)) {\n logger.info(config.skipMessage);\n return;\n }\n\n const answer = await askQuestion(config.promptMessage);\n if (answer === \"\" || answer.toLowerCase().startsWith(\"y\")) {\n await installPackage(config.packageName);\n } else {\n logger.info(\"Skipping installation.\");\n }\n}\n"],"mappings":";;;;AAgBA,eAAsB,uBACpB,QACe;CAGf,IAAI,CAFU,cAAc,OAAO,cAE1B,GAAG;EACV,OAAO,KAAK,OAAO,eAAe;EAClC;CACF;CAEA,IAAI,mBAAmB,OAAO,WAAW,GAAG;EAC1C,OAAO,KAAK,OAAO,WAAW;EAC9B;CACF;CAEA,MAAM,SAAS,MAAM,YAAY,OAAO,aAAa;CACrD,IAAI,WAAW,MAAM,OAAO,YAAY,CAAC,CAAC,WAAW,GAAG,
|
|
1
|
+
{"version":3,"file":"package-installer.js","names":[],"sources":["../../../src/lib/utils/package-installer.ts"],"sourcesContent":["import { scanForImport } from \"./file-scanner\";\nimport {\n isPackageInstalled,\n askQuestion,\n installPackage,\n} from \"./package-manager\";\nimport { logger } from \"./logger\";\n\nexport interface PackageInstallConfig {\n packageName: string;\n importPatterns: string[];\n promptMessage: string;\n skipMessage: string;\n notFoundMessage: string;\n}\n\nexport async function installPackageIfNeeded(\n config: PackageInstallConfig,\n): Promise<void> {\n const found = scanForImport(config.importPatterns);\n\n if (!found) {\n logger.info(config.notFoundMessage);\n return;\n }\n\n if (isPackageInstalled(config.packageName)) {\n logger.info(config.skipMessage);\n return;\n }\n\n const answer = await askQuestion(config.promptMessage);\n if (answer === \"\" || answer.toLowerCase().startsWith(\"y\")) {\n if (!(await installPackage(config.packageName))) {\n throw new Error(`Failed to install ${config.packageName}`);\n }\n } else {\n logger.info(\"Skipping installation.\");\n }\n}\n"],"mappings":";;;;AAgBA,eAAsB,uBACpB,QACe;CAGf,IAAI,CAFU,cAAc,OAAO,cAE1B,GAAG;EACV,OAAO,KAAK,OAAO,eAAe;EAClC;CACF;CAEA,IAAI,mBAAmB,OAAO,WAAW,GAAG;EAC1C,OAAO,KAAK,OAAO,WAAW;EAC9B;CACF;CAEA,MAAM,SAAS,MAAM,YAAY,OAAO,aAAa;CACrD,IAAI,WAAW,MAAM,OAAO,YAAY,CAAC,CAAC,WAAW,GAAG,GAClD;MAAA,CAAE,MAAM,eAAe,OAAO,WAAW,GAC3C,MAAM,IAAI,MAAM,qBAAqB,OAAO,aAAa;CAAA,OAG3D,OAAO,KAAK,wBAAwB;AAExC"}
|
package/package.json
CHANGED
|
@@ -158,14 +158,14 @@ function MyComponent() {
|
|
|
158
158
|
|
|
159
159
|
it("should handle complex type unions and generics", () => {
|
|
160
160
|
const input = `
|
|
161
|
-
import { ThreadAssistantContentPart, ToolCallContentPart } from "@assistant-ui/react";
|
|
161
|
+
import { ThreadAssistantContentPart, ToolCallContentPart, TextContentPart } from "@assistant-ui/react";
|
|
162
162
|
|
|
163
163
|
type MyUnion = ThreadAssistantContentPart | TextContentPart;
|
|
164
164
|
type MyGeneric = Array<ToolCallContentPart<{ query: string }, string>>;
|
|
165
165
|
`;
|
|
166
166
|
|
|
167
167
|
const expected = `
|
|
168
|
-
import { ThreadAssistantMessagePart, ToolCallMessagePart } from "@assistant-ui/react";
|
|
168
|
+
import { ThreadAssistantMessagePart, ToolCallMessagePart, TextMessagePart } from "@assistant-ui/react";
|
|
169
169
|
|
|
170
170
|
type MyUnion = ThreadAssistantMessagePart | TextMessagePart;
|
|
171
171
|
type MyGeneric = Array<ToolCallMessagePart<{ query: string }, string>>;
|
|
@@ -228,3 +228,269 @@ function MyComponent() {
|
|
|
228
228
|
expect(applyTransform(input).trim()).toBe(expected.trim());
|
|
229
229
|
});
|
|
230
230
|
});
|
|
231
|
+
|
|
232
|
+
describe("content-part import bindings", () => {
|
|
233
|
+
it.each([
|
|
234
|
+
[
|
|
235
|
+
"type references",
|
|
236
|
+
`import * as AUI from "@assistant-ui/react";
|
|
237
|
+
import * as X from "./local";
|
|
238
|
+
type Part = AUI.TextContentPart;
|
|
239
|
+
type LocalPart = X.TextContentPart;
|
|
240
|
+
function shadow(AUI: typeof X) { return null as AUI.TextContentPart | null; }`,
|
|
241
|
+
`import * as AUI from "@assistant-ui/react";
|
|
242
|
+
import * as X from "./local";
|
|
243
|
+
type Part = AUI.TextMessagePart;
|
|
244
|
+
type LocalPart = X.TextContentPart;
|
|
245
|
+
function shadow(AUI: typeof X) { return null as AUI.TextMessagePart | null; }`,
|
|
246
|
+
],
|
|
247
|
+
[
|
|
248
|
+
"JSX members",
|
|
249
|
+
`import * as AUI from "@assistant-ui/react";
|
|
250
|
+
import * as X from "./local";
|
|
251
|
+
const View = () => <AUI.ContentPartPrimitive.Text />;
|
|
252
|
+
const LocalView = () => <X.ContentPartPrimitive.Text />;
|
|
253
|
+
function shadow(AUI: typeof X) { return <AUI.ContentPartPrimitive.Text />; }`,
|
|
254
|
+
`import * as AUI from "@assistant-ui/react";
|
|
255
|
+
import * as X from "./local";
|
|
256
|
+
const View = () => <AUI.MessagePartPrimitive.Text />;
|
|
257
|
+
const LocalView = () => <X.ContentPartPrimitive.Text />;
|
|
258
|
+
function shadow(AUI: typeof X) { return <AUI.ContentPartPrimitive.Text />; }`,
|
|
259
|
+
],
|
|
260
|
+
[
|
|
261
|
+
"calls",
|
|
262
|
+
`import * as AUI from "@assistant-ui/react";
|
|
263
|
+
import * as X from "./local";
|
|
264
|
+
const part = AUI.useContentPart();
|
|
265
|
+
const localPart = X.useContentPart();
|
|
266
|
+
function shadow(AUI: typeof X) { return AUI.useContentPart(); }`,
|
|
267
|
+
`import * as AUI from "@assistant-ui/react";
|
|
268
|
+
import * as X from "./local";
|
|
269
|
+
const part = AUI.useMessagePart();
|
|
270
|
+
const localPart = X.useContentPart();
|
|
271
|
+
function shadow(AUI: typeof X) { return AUI.useContentPart(); }`,
|
|
272
|
+
],
|
|
273
|
+
])(
|
|
274
|
+
"renames assistant-ui namespace %s without changing other bindings",
|
|
275
|
+
(_, input, expected) => {
|
|
276
|
+
expect(applyTransform(input)).toBe(expected);
|
|
277
|
+
},
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
it("renames qualified types from a type-only namespace import", () => {
|
|
281
|
+
const input = `import type * as AUI from "@assistant-ui/react";
|
|
282
|
+
type Part = AUI.TextContentPart;`;
|
|
283
|
+
const expected = `import type * as AUI from "@assistant-ui/react";
|
|
284
|
+
type Part = AUI.TextMessagePart;`;
|
|
285
|
+
expect(applyTransform(input)).toBe(expected);
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it("preserves qualified types shadowed by a type-space declaration", () => {
|
|
289
|
+
const input = `import * as AUI from "@assistant-ui/react";
|
|
290
|
+
type Part = AUI.TextContentPart;
|
|
291
|
+
namespace Local {
|
|
292
|
+
namespace AUI { export type TextContentPart = string; }
|
|
293
|
+
type Part = AUI.TextContentPart;
|
|
294
|
+
}`;
|
|
295
|
+
const expected = `import * as AUI from "@assistant-ui/react";
|
|
296
|
+
type Part = AUI.TextMessagePart;
|
|
297
|
+
namespace Local {
|
|
298
|
+
namespace AUI { export type TextContentPart = string; }
|
|
299
|
+
type Part = AUI.TextContentPart;
|
|
300
|
+
}`;
|
|
301
|
+
expect(applyTransform(input)).toBe(expected);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it("resolves typeof qualified names as values", () => {
|
|
305
|
+
const input = `import * as AUI from "@assistant-ui/react";
|
|
306
|
+
import * as X from "./local";
|
|
307
|
+
type Part = typeof AUI.TextContentPart;
|
|
308
|
+
function shadow(AUI: typeof X) { return null as typeof AUI.TextContentPart | null; }`;
|
|
309
|
+
const expected = `import * as AUI from "@assistant-ui/react";
|
|
310
|
+
import * as X from "./local";
|
|
311
|
+
type Part = typeof AUI.TextMessagePart;
|
|
312
|
+
function shadow(AUI: typeof X) { return null as typeof AUI.TextContentPart | null; }`;
|
|
313
|
+
expect(applyTransform(input)).toBe(expected);
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
it.each([
|
|
317
|
+
'import { useContentPart } from "./custom-hooks";\nexport const read = () => useContentPart();',
|
|
318
|
+
'import type { TextContentPart } from "./custom-types";\nexport const read = (part: TextContentPart) => part.text;',
|
|
319
|
+
'import { ContentPartPrimitive } from "./custom-ui";\nexport const Text = () => <ContentPartPrimitive.Text />;',
|
|
320
|
+
'import { MessagePrimitive } from "./custom-ui";\nexport const Content = () => <MessagePrimitive.Content />;',
|
|
321
|
+
])("preserves foreign imports and references: %s", (custom) => {
|
|
322
|
+
const input = `import { ThreadPrimitive } from "@assistant-ui/react";\n${custom}`;
|
|
323
|
+
expect(applyTransform(input)).toBe(input);
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
it("preserves unbound names", () => {
|
|
327
|
+
const input = `import { ThreadPrimitive } from "@assistant-ui/react";
|
|
328
|
+
export const read = () => useContentPart();
|
|
329
|
+
export type Part = TextContentPart;`;
|
|
330
|
+
expect(applyTransform(input)).toBe(input);
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
it("preserves an import alias while leaving another module's canonical name alone", () => {
|
|
334
|
+
const output =
|
|
335
|
+
applyTransform(`import { useContentPart as usePart, TextContentPart as Part } from "@assistant-ui/react";
|
|
336
|
+
import { useContentPart } from "./custom-hooks";
|
|
337
|
+
export const read = (part: Part) => [usePart(), useContentPart(), part];`);
|
|
338
|
+
expect(output).toContain("useMessagePart as usePart");
|
|
339
|
+
expect(output).toContain("TextMessagePart as Part");
|
|
340
|
+
expect(output).toContain("[usePart(), useContentPart(), part]");
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it("preserves shadowed parameters and uses an import alias to keep their references intact", () => {
|
|
344
|
+
const output =
|
|
345
|
+
applyTransform(`import { useContentPart } from "@assistant-ui/react";
|
|
346
|
+
export const read = () => useContentPart();
|
|
347
|
+
export const custom = (useContentPart) => useContentPart();`);
|
|
348
|
+
expect(output).toContain("useMessagePart as useContentPart");
|
|
349
|
+
expect(output).toContain("export const read = () => useContentPart();");
|
|
350
|
+
expect(output).toContain(
|
|
351
|
+
"export const custom = (useContentPart) => useContentPart();",
|
|
352
|
+
);
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
it.each([
|
|
356
|
+
"export type Identity<TextContentPart> = TextContentPart;",
|
|
357
|
+
"export function custom() { type TextContentPart = { custom: string }; return null as TextContentPart | null; }",
|
|
358
|
+
'export type Keys = { [TextContentPart in "a" | "b"]: TextContentPart };',
|
|
359
|
+
])("preserves type declarations and parameters: %s", (body) => {
|
|
360
|
+
const output =
|
|
361
|
+
applyTransform(`import type { TextContentPart } from "@assistant-ui/react";
|
|
362
|
+
export type Part = TextContentPart;
|
|
363
|
+
${body}`);
|
|
364
|
+
expect(output).toContain("TextMessagePart as TextContentPart");
|
|
365
|
+
expect(output).toContain("export type Part = TextContentPart;");
|
|
366
|
+
expect(output).toContain(body);
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
it("preserves ambient declarations with the same name", () => {
|
|
370
|
+
const output =
|
|
371
|
+
applyTransform(`import { useContentPart } from "@assistant-ui/react";
|
|
372
|
+
export const read = () => useContentPart();
|
|
373
|
+
namespace Custom {
|
|
374
|
+
export declare function useContentPart(): string;
|
|
375
|
+
export const read = () => useContentPart();
|
|
376
|
+
}`);
|
|
377
|
+
expect(output).toContain("useMessagePart as useContentPart");
|
|
378
|
+
expect(output).toContain(
|
|
379
|
+
"export declare function useContentPart(): string;",
|
|
380
|
+
);
|
|
381
|
+
expect(output.match(/read = \(\) => useContentPart\(\)/g)).toHaveLength(2);
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
it.each([
|
|
385
|
+
'import type { TextContentPart } from "@assistant-ui/react";',
|
|
386
|
+
'import { type TextContentPart } from "@assistant-ui/react";',
|
|
387
|
+
])("renames unshadowed type-only references: %s", (declaration) => {
|
|
388
|
+
const output = applyTransform(
|
|
389
|
+
`${declaration}\nexport type Part = Array<TextContentPart>;`,
|
|
390
|
+
);
|
|
391
|
+
expect(output).toContain(
|
|
392
|
+
declaration.replace("TextContentPart", "TextMessagePart"),
|
|
393
|
+
);
|
|
394
|
+
expect(output).toContain("Array<TextMessagePart>");
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
it.each([
|
|
398
|
+
'const useMessagePart = () => "custom";\nexport const read = () => [useContentPart(), useMessagePart()];',
|
|
399
|
+
"export const read = (useMessagePart) => [useContentPart(), useMessagePart()];",
|
|
400
|
+
])("preserves names when the replacement would collide: %s", (body) => {
|
|
401
|
+
const output = applyTransform(
|
|
402
|
+
`import { useContentPart } from "@assistant-ui/react";\n${body}`,
|
|
403
|
+
);
|
|
404
|
+
expect(output).toContain("useMessagePart as useContentPart");
|
|
405
|
+
expect(output).toContain(body);
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
it("avoids capturing a type reference with a generic parameter", () => {
|
|
409
|
+
const output =
|
|
410
|
+
applyTransform(`import type { TextContentPart } from "@assistant-ui/react";
|
|
411
|
+
export type Pair<TextMessagePart> = [TextContentPart, TextMessagePart];`);
|
|
412
|
+
expect(output).toContain("TextMessagePart as TextContentPart");
|
|
413
|
+
expect(output).toContain("[TextContentPart, TextMessagePart]");
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
it("keeps object keys, member names, JSX attributes, and public export names", () => {
|
|
417
|
+
const output =
|
|
418
|
+
applyTransform(`import { useContentPart, ContentPartPrimitive } from "@assistant-ui/react";
|
|
419
|
+
export const hooks = { useContentPart };
|
|
420
|
+
export const read = (other) => other.useContentPart();
|
|
421
|
+
export const View = () => <ContentPartPrimitive.Text useContentPart={useContentPart} />;
|
|
422
|
+
export { useContentPart };
|
|
423
|
+
export { useContentPart as custom } from "./custom-hooks";`);
|
|
424
|
+
expect(output).toMatch(/useContentPart: useMessagePart/);
|
|
425
|
+
expect(output).toContain("other.useContentPart()");
|
|
426
|
+
expect(output).toContain(
|
|
427
|
+
"<MessagePartPrimitive.Text useContentPart={useMessagePart}",
|
|
428
|
+
);
|
|
429
|
+
expect(output).toContain("export { useMessagePart as useContentPart }");
|
|
430
|
+
expect(output).toContain(
|
|
431
|
+
'export { useContentPart as custom } from "./custom-hooks"',
|
|
432
|
+
);
|
|
433
|
+
expect(applyTransform(output)).toBe(output);
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
it("preserves type-only exports while renaming their local references", () => {
|
|
437
|
+
const output =
|
|
438
|
+
applyTransform(`import type { TextContentPart } from "@assistant-ui/react";
|
|
439
|
+
export type { TextContentPart };
|
|
440
|
+
export { type TextContentPart as PublicPart };`);
|
|
441
|
+
expect(output).toContain(
|
|
442
|
+
"export type { TextMessagePart as TextContentPart }",
|
|
443
|
+
);
|
|
444
|
+
expect(output).toContain("export { type TextMessagePart as PublicPart }");
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
it("resolves the MessagePrimitive import before renaming Content", () => {
|
|
448
|
+
const output =
|
|
449
|
+
applyTransform(`import { MessagePrimitive as Message } from "@assistant-ui/react";
|
|
450
|
+
export const View = () => <Message.Content />;
|
|
451
|
+
export const content = Message.Content;
|
|
452
|
+
export const dynamic = (Content) => Message[Content];
|
|
453
|
+
export const custom = (Message) => <Message.Content />;`);
|
|
454
|
+
expect(output).toContain("<Message.Parts />");
|
|
455
|
+
expect(output).toContain("export const content = Message.Parts;");
|
|
456
|
+
expect(output).toContain("Message[Content]");
|
|
457
|
+
expect(output).toContain(
|
|
458
|
+
"export const custom = (Message) => <Message.Content />;",
|
|
459
|
+
);
|
|
460
|
+
});
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
describe("content-part re-exports", () => {
|
|
464
|
+
it.each([
|
|
465
|
+
[
|
|
466
|
+
'export { useContentPart } from "@assistant-ui/react";',
|
|
467
|
+
'export { useMessagePart as useContentPart } from "@assistant-ui/react";',
|
|
468
|
+
],
|
|
469
|
+
[
|
|
470
|
+
'export type { TextContentPart } from "@assistant-ui/react";',
|
|
471
|
+
'export type { TextMessagePart as TextContentPart } from "@assistant-ui/react";',
|
|
472
|
+
],
|
|
473
|
+
[
|
|
474
|
+
'export { type TextContentPart as Part } from "@assistant-ui/react";',
|
|
475
|
+
'export { type TextMessagePart as Part } from "@assistant-ui/react";',
|
|
476
|
+
],
|
|
477
|
+
[
|
|
478
|
+
'export { useContentPart as usePart } from "@assistant-ui/react";',
|
|
479
|
+
'export { useMessagePart as usePart } from "@assistant-ui/react";',
|
|
480
|
+
],
|
|
481
|
+
])(
|
|
482
|
+
"migrates the source symbol while preserving its public name: %s",
|
|
483
|
+
(input, expected) => {
|
|
484
|
+
const output = applyTransform(input);
|
|
485
|
+
expect(output).toBe(expected);
|
|
486
|
+
expect(applyTransform(output)).toBe(output);
|
|
487
|
+
},
|
|
488
|
+
);
|
|
489
|
+
|
|
490
|
+
it("preserves unrelated re-exports and export namespaces", () => {
|
|
491
|
+
const input = `export { useContentPart } from "./custom-hooks";
|
|
492
|
+
export type { TextContentPart } from "./custom-types";
|
|
493
|
+
export * as ContentPartPrimitive from "@assistant-ui/react";`;
|
|
494
|
+
expect(applyTransform(input)).toBe(input);
|
|
495
|
+
});
|
|
496
|
+
});
|