aiex-cli 0.0.0
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/LICENSE.md +21 -0
- package/README.md +118 -0
- package/bin/cli.mjs +2 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +9948 -0
- package/dist/core/schema-sqlite/migrate-helper.d.mts +1 -0
- package/dist/core/schema-sqlite/migrate-helper.mjs +190 -0
- package/dist/doctor-Wic10PLt.mjs +711 -0
- package/dist/index.d.mts +281 -0
- package/dist/index.mjs +3 -0
- package/dist/table-schema.json +220 -0
- package/dist/web/assets/abap-Cry0R76c.js +1 -0
- package/dist/web/assets/apex-xqbJ58nJ.js +1 -0
- package/dist/web/assets/azcli-D7JTNGKs.js +1 -0
- package/dist/web/assets/bat-Cuq6hn0K.js +1 -0
- package/dist/web/assets/bicep-eTuQjz9F.js +2 -0
- package/dist/web/assets/cameligo-DKgCRl36.js +1 -0
- package/dist/web/assets/chunk-BEqpzyXh.js +1 -0
- package/dist/web/assets/clojure-B_aTBtVh.js +1 -0
- package/dist/web/assets/codicon-DCmgc-ay.ttf +0 -0
- package/dist/web/assets/coffee-BWAYpIPu.js +1 -0
- package/dist/web/assets/cpp-BduBQE8d.js +1 -0
- package/dist/web/assets/csharp-CMqOVYKK.js +1 -0
- package/dist/web/assets/csp-6cGliXw2.js +1 -0
- package/dist/web/assets/css-CHnKqS9Q.js +3 -0
- package/dist/web/assets/cssMode-BloHqzZF.js +4 -0
- package/dist/web/assets/cypher-DMzZBj2L.js +1 -0
- package/dist/web/assets/dart-7hYfJ1Dv.js +1 -0
- package/dist/web/assets/dockerfile-BflvjnJW.js +1 -0
- package/dist/web/assets/ecl-BEt6xb2p.js +1 -0
- package/dist/web/assets/editor-BR-TvLsg.css +1 -0
- package/dist/web/assets/editor-DPKWm9GW.css +1 -0
- package/dist/web/assets/editor.api-BG499EJF.js +642 -0
- package/dist/web/assets/editor.main-BhEWG0_P.js +53 -0
- package/dist/web/assets/editor.worker-DwXe4U6w.js +12 -0
- package/dist/web/assets/elixir-CnrQCt6o.js +1 -0
- package/dist/web/assets/flow9-CfLCoUuB.js +1 -0
- package/dist/web/assets/freemarker2-DOHaFATh.js +3 -0
- package/dist/web/assets/fsharp-BQqR9uQ6.js +1 -0
- package/dist/web/assets/go-C3AlMVwy.js +1 -0
- package/dist/web/assets/graphql-O_-hDldf.js +1 -0
- package/dist/web/assets/handlebars-BIFWety9.js +1 -0
- package/dist/web/assets/hcl-BQQD6Mtj.js +1 -0
- package/dist/web/assets/html-YGaqGZNd.js +1 -0
- package/dist/web/assets/htmlMode-Bu3PyHjq.js +4 -0
- package/dist/web/assets/index-Bi376XVf.css +2 -0
- package/dist/web/assets/index-c6KB-9C-.js +3262 -0
- package/dist/web/assets/ini-Bf0RDfP_.js +1 -0
- package/dist/web/assets/java-nqX2KEDD.js +1 -0
- package/dist/web/assets/javascript-N0gZqDK0.js +1 -0
- package/dist/web/assets/json.worker-DhD1Scrm.js +51 -0
- package/dist/web/assets/jsonMode-z5YscjcG.js +10 -0
- package/dist/web/assets/julia-B6P9U5er.js +1 -0
- package/dist/web/assets/kotlin-B-LRk09-.js +1 -0
- package/dist/web/assets/less-CEaIdW1f.js +2 -0
- package/dist/web/assets/lexon-Qv4pvFSW.js +1 -0
- package/dist/web/assets/liquid-BHfNNVLs.js +1 -0
- package/dist/web/assets/lua-CFpyR7YN.js +1 -0
- package/dist/web/assets/m3-CvKhVPQn.js +1 -0
- package/dist/web/assets/markdown-qldG3Vc4.js +1 -0
- package/dist/web/assets/mdx-Dqu2t0et.js +1 -0
- package/dist/web/assets/mips-0D8PRyHq.js +1 -0
- package/dist/web/assets/monaco.contribution-ByQ3yI-W.js +2 -0
- package/dist/web/assets/msdax-DwZXSC5M.js +1 -0
- package/dist/web/assets/mysql-BWq85KY4.js +1 -0
- package/dist/web/assets/objective-c-D653JUMG.js +1 -0
- package/dist/web/assets/pascal-rWjRDdnR.js +1 -0
- package/dist/web/assets/pascaligo-Db8EehaF.js +1 -0
- package/dist/web/assets/perl-C68oq8-D.js +1 -0
- package/dist/web/assets/pgsql-BXeHe33s.js +1 -0
- package/dist/web/assets/php-CDVsAbfl.js +1 -0
- package/dist/web/assets/pla-DnryFT0q.js +1 -0
- package/dist/web/assets/postiats-CDg_4Ev-.js +1 -0
- package/dist/web/assets/powerquery-CWPi8ROz.js +1 -0
- package/dist/web/assets/powershell-C5A0QX3-.js +1 -0
- package/dist/web/assets/preload-helper-DSXbuxSR.js +1 -0
- package/dist/web/assets/primeicons-C6QP2o4f.woff2 +0 -0
- package/dist/web/assets/primeicons-DMOk5skT.eot +0 -0
- package/dist/web/assets/primeicons-Dr5RGzOO.svg +345 -0
- package/dist/web/assets/primeicons-MpK4pl85.ttf +0 -0
- package/dist/web/assets/primeicons-WjwUDZjB.woff +0 -0
- package/dist/web/assets/protobuf-Cgt-BQbL.js +2 -0
- package/dist/web/assets/pug-RPYJC9QB.js +1 -0
- package/dist/web/assets/python-icfse9Ji.js +1 -0
- package/dist/web/assets/qsharp-BZ3S7fu_.js +1 -0
- package/dist/web/assets/r-CN875f1X.js +1 -0
- package/dist/web/assets/razor-DwVkryG9.js +1 -0
- package/dist/web/assets/redis-BLesvTwR.js +1 -0
- package/dist/web/assets/redshift-Byf_0XqD.js +1 -0
- package/dist/web/assets/restructuredtext-DYg_6BiZ.js +1 -0
- package/dist/web/assets/ruby-C4OkxbC-.js +1 -0
- package/dist/web/assets/rust-xAoaEFMh.js +1 -0
- package/dist/web/assets/sb-C8dHOW_y.js +1 -0
- package/dist/web/assets/scala-Spx0wP1o.js +1 -0
- package/dist/web/assets/scheme-D2mZlAUz.js +1 -0
- package/dist/web/assets/scss-DDCn3Ylu.js +3 -0
- package/dist/web/assets/shell-M6px0EWn.js +1 -0
- package/dist/web/assets/solidity-DUWMJi-f.js +1 -0
- package/dist/web/assets/sophia-DwJbUG-2.js +1 -0
- package/dist/web/assets/sparql-ClQxbRPI.js +1 -0
- package/dist/web/assets/sql-BQdjW7Vy.js +1 -0
- package/dist/web/assets/st-BpISyZ_v.js +1 -0
- package/dist/web/assets/swift-CMbl5gM4.js +1 -0
- package/dist/web/assets/systemverilog-jx2Xs7uO.js +1 -0
- package/dist/web/assets/tcl-GIGnfs89.js +1 -0
- package/dist/web/assets/tsMode-CLrI3bdf.js +11 -0
- package/dist/web/assets/twig-Bc0mxc_m.js +1 -0
- package/dist/web/assets/typescript-BzuZVF7m.js +1 -0
- package/dist/web/assets/typespec-CEioAsEm.js +1 -0
- package/dist/web/assets/vb-BPk67J-d.js +1 -0
- package/dist/web/assets/wgsl-DOnyt8_J.js +298 -0
- package/dist/web/assets/xml-Cr85kdqA.js +1 -0
- package/dist/web/assets/yaml-D3RbJnnO.js +1 -0
- package/dist/web/index.html +25 -0
- package/package.json +86 -0
- package/src/core/schema-sqlite/migrate-helper.ts +246 -0
|
@@ -0,0 +1,711 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import fs from "node:fs/promises";
|
|
5
|
+
import os from "node:os";
|
|
6
|
+
import Conf from "conf";
|
|
7
|
+
|
|
8
|
+
//#region src/core/doctor.ts
|
|
9
|
+
function buildDoctorDiagnostics(input) {
|
|
10
|
+
return {
|
|
11
|
+
cli: {
|
|
12
|
+
name: input.pkg.name,
|
|
13
|
+
version: input.pkg.version,
|
|
14
|
+
executable: input.executable
|
|
15
|
+
},
|
|
16
|
+
runtime: {
|
|
17
|
+
node: input.node,
|
|
18
|
+
platform: input.platform,
|
|
19
|
+
arch: input.arch,
|
|
20
|
+
shell: input.shell,
|
|
21
|
+
packageManager: input.packageManager
|
|
22
|
+
},
|
|
23
|
+
system: {
|
|
24
|
+
os: `${input.osType} ${input.osRelease}`,
|
|
25
|
+
cwd: input.cwd
|
|
26
|
+
},
|
|
27
|
+
config: {
|
|
28
|
+
path: input.configPath,
|
|
29
|
+
keys: [...input.configStoreKeys].sort()
|
|
30
|
+
},
|
|
31
|
+
project: { ...input.project }
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function formatDoctorDiagnosticsJson(d) {
|
|
35
|
+
return `${JSON.stringify(d, null, 2)}\n`;
|
|
36
|
+
}
|
|
37
|
+
function doctorDiagnosticsTableRows(d) {
|
|
38
|
+
const rows = [
|
|
39
|
+
["node", d.runtime.node],
|
|
40
|
+
["platform", d.runtime.platform],
|
|
41
|
+
["arch", d.runtime.arch],
|
|
42
|
+
["shell", d.runtime.shell],
|
|
43
|
+
["packageManager", d.runtime.packageManager],
|
|
44
|
+
["os", d.system.os],
|
|
45
|
+
["cwd", d.system.cwd],
|
|
46
|
+
["config", d.config.path],
|
|
47
|
+
["configKeys", d.config.keys.join(", ")]
|
|
48
|
+
];
|
|
49
|
+
const p = d.project;
|
|
50
|
+
rows.push(["aiexDir", p.aiexDir]);
|
|
51
|
+
rows.push(["dirExists", String(p.dirExists)]);
|
|
52
|
+
rows.push(["schemaFiles", `${p.schemaCount} (${p.schemaFiles.join(", ") || "none"})`]);
|
|
53
|
+
rows.push(["aiConfig", String(p.aiConfig)]);
|
|
54
|
+
rows.push(["aiApiKeySet", String(p.aiApiKeySet)]);
|
|
55
|
+
rows.push(["aiModels", p.aiModelCount ? p.aiModels.join(", ") : "none"]);
|
|
56
|
+
rows.push(["aiProvider", p.aiProvider ?? "none"]);
|
|
57
|
+
rows.push(["aiConnectionOk", p.aiConnectionOk === null ? "not tested" : String(p.aiConnectionOk)]);
|
|
58
|
+
rows.push(["hasDatabase", String(p.hasDatabase)]);
|
|
59
|
+
rows.push(["migrations", String(p.migrationCount)]);
|
|
60
|
+
for (const err of p.errors) rows.push(["error", err]);
|
|
61
|
+
return rows;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/core/schema-sqlite/generator.ts
|
|
66
|
+
function generateColumnDefinition(column) {
|
|
67
|
+
if (column.isPrimary && column.isAutoIncrement) return ` ${column.name}: integer().primaryKey({ autoIncrement: true })`;
|
|
68
|
+
let def = ` ${column.name}: ${column.drizzleType}`;
|
|
69
|
+
if (column.isPrimary) def += ".primaryKey()";
|
|
70
|
+
if (!column.isNullable && !column.isPrimary) def += ".notNull()";
|
|
71
|
+
if (column.isUnique && !column.isPrimary) def += ".unique()";
|
|
72
|
+
if (column.defaultValue !== void 0) def += `.default(${column.defaultValue})`;
|
|
73
|
+
if (column.isForeignKey && column.foreignKeyRef) def += `.references(() => ${column.foreignKeyRef.table}.${column.foreignKeyRef.column})`;
|
|
74
|
+
return def;
|
|
75
|
+
}
|
|
76
|
+
function generateTableDefinition(table) {
|
|
77
|
+
const columns = table.columns.map(generateColumnDefinition);
|
|
78
|
+
return `export const ${table.name} = sqliteTable('${table.name}', {\n${columns.join(",\n")}\n})`;
|
|
79
|
+
}
|
|
80
|
+
function generateRelationDefinitions(relations, reverseRelations) {
|
|
81
|
+
if (relations.length === 0 && reverseRelations.length === 0) return "";
|
|
82
|
+
const definitions = [];
|
|
83
|
+
const childByTable = /* @__PURE__ */ new Map();
|
|
84
|
+
for (const rel of relations) {
|
|
85
|
+
const list = childByTable.get(rel.fromTable) ?? [];
|
|
86
|
+
list.push(rel);
|
|
87
|
+
childByTable.set(rel.fromTable, list);
|
|
88
|
+
}
|
|
89
|
+
const parentByTable = /* @__PURE__ */ new Map();
|
|
90
|
+
for (const rel of reverseRelations) {
|
|
91
|
+
const list = parentByTable.get(rel.fromTable) ?? [];
|
|
92
|
+
list.push(rel);
|
|
93
|
+
parentByTable.set(rel.fromTable, list);
|
|
94
|
+
}
|
|
95
|
+
const allTableNames = new Set([...childByTable.keys(), ...parentByTable.keys()]);
|
|
96
|
+
for (const tableName of allTableNames) {
|
|
97
|
+
const childRels = childByTable.get(tableName) ?? [];
|
|
98
|
+
const parentRels = parentByTable.get(tableName) ?? [];
|
|
99
|
+
const needsOne = childRels.length > 0 || parentRels.some((r) => r.type === "has-one");
|
|
100
|
+
const needsMany = parentRels.some((r) => r.type === "has-many");
|
|
101
|
+
const imports = [];
|
|
102
|
+
if (needsOne) imports.push("one");
|
|
103
|
+
if (needsMany) imports.push("many");
|
|
104
|
+
const importStr = imports.join(", ");
|
|
105
|
+
const relDefs = [];
|
|
106
|
+
for (const rel of childRels) relDefs.push(` ${rel.name}: one(${rel.toTable}, {\n fields: [${rel.fromColumn}],\n references: [id],\n })`);
|
|
107
|
+
for (const rel of parentRels) if (rel.type === "has-many") relDefs.push(` ${rel.name}: many(${rel.toTable})`);
|
|
108
|
+
else relDefs.push(` ${rel.name}: one(${rel.toTable})`);
|
|
109
|
+
definitions.push(`export const ${tableName}Relations = relations(${tableName}, ({ ${importStr} }) => ({\n${relDefs.join(",\n")}\n}))`);
|
|
110
|
+
}
|
|
111
|
+
return definitions.join("\n\n");
|
|
112
|
+
}
|
|
113
|
+
function generateDrizzleSchema(result) {
|
|
114
|
+
const imports = `import { sqliteTable, text, integer, real } from 'drizzle-orm/sqlite-core'\nimport { relations } from 'drizzle-orm'`;
|
|
115
|
+
const tableDefs = result.tables.map(generateTableDefinition).join("\n\n");
|
|
116
|
+
const relationDefs = generateRelationDefinitions(result.relations, result.reverseRelations);
|
|
117
|
+
const parts = [
|
|
118
|
+
imports,
|
|
119
|
+
"",
|
|
120
|
+
tableDefs
|
|
121
|
+
];
|
|
122
|
+
if (relationDefs) parts.push("", relationDefs);
|
|
123
|
+
parts.push("");
|
|
124
|
+
return parts.join("\n");
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region src/core/schema-sqlite/parser.ts
|
|
129
|
+
function toSnakeCase(str) {
|
|
130
|
+
return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
131
|
+
}
|
|
132
|
+
function mapPropertyToColumn(name$1, property, isRequired) {
|
|
133
|
+
const snakeName = toSnakeCase(name$1);
|
|
134
|
+
let drizzleType;
|
|
135
|
+
const isPrimary = property.primary ?? false;
|
|
136
|
+
const isAutoIncrement = property.autoIncrement ?? false;
|
|
137
|
+
switch (property.type) {
|
|
138
|
+
case "string": {
|
|
139
|
+
const format = property.format;
|
|
140
|
+
if (format === "date-time" || property.drizzle?.mode === "timestamp") drizzleType = `integer({ mode: 'timestamp' })`;
|
|
141
|
+
else if (format === "json" || property.drizzle?.mode === "json") drizzleType = `text({ mode: 'json' })`;
|
|
142
|
+
else drizzleType = "text()";
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
case "integer": {
|
|
146
|
+
const mode = property.drizzle?.mode;
|
|
147
|
+
if (mode === "boolean") drizzleType = `integer({ mode: 'boolean' })`;
|
|
148
|
+
else if (mode === "timestamp" || mode === "timestamp_ms") drizzleType = `integer({ mode: '${mode}' })`;
|
|
149
|
+
else if (mode === "bigint") drizzleType = `integer({ mode: 'bigint' })`;
|
|
150
|
+
else drizzleType = "integer()";
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
case "number":
|
|
154
|
+
drizzleType = "real()";
|
|
155
|
+
break;
|
|
156
|
+
case "boolean":
|
|
157
|
+
drizzleType = `integer({ mode: 'boolean' })`;
|
|
158
|
+
break;
|
|
159
|
+
case "object":
|
|
160
|
+
case "array":
|
|
161
|
+
drizzleType = `text({ mode: 'json' })`;
|
|
162
|
+
break;
|
|
163
|
+
case "null":
|
|
164
|
+
drizzleType = "text()";
|
|
165
|
+
break;
|
|
166
|
+
default: drizzleType = "text()";
|
|
167
|
+
}
|
|
168
|
+
return {
|
|
169
|
+
name: snakeName,
|
|
170
|
+
drizzleType,
|
|
171
|
+
isPrimary,
|
|
172
|
+
isAutoIncrement,
|
|
173
|
+
isNullable: !isRequired && !isPrimary,
|
|
174
|
+
isUnique: property.unique ?? false,
|
|
175
|
+
defaultValue: property.default !== void 0 ? JSON.stringify(property.default) : void 0,
|
|
176
|
+
isForeignKey: property.foreignKey !== void 0,
|
|
177
|
+
foreignKeyRef: property.foreignKey ?? void 0
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function parseObjectToTable(schema, _warnings) {
|
|
181
|
+
const tableName = schema.table.name;
|
|
182
|
+
const columns = [];
|
|
183
|
+
const requiredFields = new Set(schema.required ?? []);
|
|
184
|
+
const autoColumns = /* @__PURE__ */ new Set();
|
|
185
|
+
if (schema.table.timestamps) {
|
|
186
|
+
autoColumns.add("created_at");
|
|
187
|
+
autoColumns.add("updated_at");
|
|
188
|
+
}
|
|
189
|
+
if (schema.table.softDelete) autoColumns.add("deleted_at");
|
|
190
|
+
for (const [propName, prop] of Object.entries(schema.properties)) {
|
|
191
|
+
if (prop.nested?.enabled && (prop.type === "object" || prop.type === "array")) continue;
|
|
192
|
+
if (prop.type === "array" && prop.items?.nested?.enabled) continue;
|
|
193
|
+
const snakeName = toSnakeCase(propName);
|
|
194
|
+
if (autoColumns.has(snakeName)) continue;
|
|
195
|
+
const column = mapPropertyToColumn(propName, prop, requiredFields.has(propName));
|
|
196
|
+
columns.push(column);
|
|
197
|
+
}
|
|
198
|
+
if (schema.table.timestamps) {
|
|
199
|
+
columns.push({
|
|
200
|
+
name: "created_at",
|
|
201
|
+
drizzleType: `integer({ mode: 'timestamp' })`,
|
|
202
|
+
isPrimary: false,
|
|
203
|
+
isAutoIncrement: false,
|
|
204
|
+
isNullable: false,
|
|
205
|
+
isUnique: false,
|
|
206
|
+
defaultValue: void 0
|
|
207
|
+
});
|
|
208
|
+
columns.push({
|
|
209
|
+
name: "updated_at",
|
|
210
|
+
drizzleType: `integer({ mode: 'timestamp' })`,
|
|
211
|
+
isPrimary: false,
|
|
212
|
+
isAutoIncrement: false,
|
|
213
|
+
isNullable: false,
|
|
214
|
+
isUnique: false,
|
|
215
|
+
defaultValue: void 0
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
if (schema.table.softDelete) columns.push({
|
|
219
|
+
name: "deleted_at",
|
|
220
|
+
drizzleType: `integer({ mode: 'timestamp' })`,
|
|
221
|
+
isPrimary: false,
|
|
222
|
+
isAutoIncrement: false,
|
|
223
|
+
isNullable: true,
|
|
224
|
+
isUnique: false,
|
|
225
|
+
defaultValue: void 0
|
|
226
|
+
});
|
|
227
|
+
return {
|
|
228
|
+
name: tableName,
|
|
229
|
+
columns
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
function parseNestedObject(propName, property, parentTableName, warnings) {
|
|
233
|
+
const nestedTableName = `${parentTableName}_${toSnakeCase(propName)}`;
|
|
234
|
+
const columns = [];
|
|
235
|
+
const relationType = property.nested?.relation === "has-many" ? "has-many" : "has-one";
|
|
236
|
+
columns.push({
|
|
237
|
+
name: "id",
|
|
238
|
+
drizzleType: "integer()",
|
|
239
|
+
isPrimary: true,
|
|
240
|
+
isAutoIncrement: true,
|
|
241
|
+
isNullable: false,
|
|
242
|
+
isUnique: false,
|
|
243
|
+
defaultValue: void 0
|
|
244
|
+
});
|
|
245
|
+
columns.push({
|
|
246
|
+
name: `${parentTableName}_id`,
|
|
247
|
+
drizzleType: "integer()",
|
|
248
|
+
isPrimary: false,
|
|
249
|
+
isAutoIncrement: false,
|
|
250
|
+
isNullable: false,
|
|
251
|
+
isUnique: false,
|
|
252
|
+
defaultValue: void 0,
|
|
253
|
+
isForeignKey: true,
|
|
254
|
+
foreignKeyRef: {
|
|
255
|
+
table: parentTableName,
|
|
256
|
+
column: "id"
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
if (property.type === "object" && property.properties) for (const [childName, childProp] of Object.entries(property.properties)) {
|
|
260
|
+
if (childProp.nested?.enabled) {
|
|
261
|
+
warnings.push(`Nested property "${childName}" inside "${nestedTableName}" is skipped — only one level of nesting is supported. Remove nested.enabled or use drizzle.mode: 'json' instead.`);
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
const column = mapPropertyToColumn(childName, childProp, false);
|
|
265
|
+
columns.push(column);
|
|
266
|
+
}
|
|
267
|
+
const relation = {
|
|
268
|
+
fromTable: nestedTableName,
|
|
269
|
+
fromColumn: `${parentTableName}_id`,
|
|
270
|
+
toTable: parentTableName,
|
|
271
|
+
toColumn: "id",
|
|
272
|
+
name: parentTableName
|
|
273
|
+
};
|
|
274
|
+
const reverseRelation = {
|
|
275
|
+
type: relationType,
|
|
276
|
+
fromTable: parentTableName,
|
|
277
|
+
toTable: nestedTableName,
|
|
278
|
+
name: toSnakeCase(propName)
|
|
279
|
+
};
|
|
280
|
+
return {
|
|
281
|
+
table: {
|
|
282
|
+
name: nestedTableName,
|
|
283
|
+
columns
|
|
284
|
+
},
|
|
285
|
+
relation,
|
|
286
|
+
reverseRelation
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
function parseJsonSchema(schema) {
|
|
290
|
+
const tables = [];
|
|
291
|
+
const relations = [];
|
|
292
|
+
const reverseRelations = [];
|
|
293
|
+
const warnings = [];
|
|
294
|
+
const mainTable = parseObjectToTable(schema, warnings);
|
|
295
|
+
tables.push(mainTable);
|
|
296
|
+
for (const [propName, prop] of Object.entries(schema.properties)) if (prop.type === "object" && prop.nested?.enabled) {
|
|
297
|
+
const nested = parseNestedObject(propName, prop, mainTable.name, warnings);
|
|
298
|
+
tables.push(nested.table);
|
|
299
|
+
relations.push(nested.relation);
|
|
300
|
+
reverseRelations.push(nested.reverseRelation);
|
|
301
|
+
} else if (prop.type === "array" && prop.items?.nested?.enabled && prop.items?.type === "object" && prop.items.properties) {
|
|
302
|
+
const nested = parseNestedObject(propName, prop.items, mainTable.name, warnings);
|
|
303
|
+
tables.push(nested.table);
|
|
304
|
+
relations.push(nested.relation);
|
|
305
|
+
reverseRelations.push(nested.reverseRelation);
|
|
306
|
+
}
|
|
307
|
+
return {
|
|
308
|
+
tables,
|
|
309
|
+
relations,
|
|
310
|
+
reverseRelations,
|
|
311
|
+
warnings
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
//#endregion
|
|
316
|
+
//#region src/core/schema-sqlite/schemas.ts
|
|
317
|
+
const DrizzleModeSchema = z.enum([
|
|
318
|
+
"json",
|
|
319
|
+
"timestamp",
|
|
320
|
+
"timestamp_ms",
|
|
321
|
+
"boolean",
|
|
322
|
+
"bigint"
|
|
323
|
+
]);
|
|
324
|
+
const DrizzleExtensionSchema = z.object({
|
|
325
|
+
mode: DrizzleModeSchema.optional(),
|
|
326
|
+
customType: z.string().optional()
|
|
327
|
+
}).optional();
|
|
328
|
+
const NestedConfigSchema = z.object({
|
|
329
|
+
enabled: z.literal(true),
|
|
330
|
+
relation: z.enum(["has-one", "has-many"])
|
|
331
|
+
});
|
|
332
|
+
const ForeignKeyRefSchema = z.object({
|
|
333
|
+
table: z.string().min(1),
|
|
334
|
+
column: z.string().min(1)
|
|
335
|
+
});
|
|
336
|
+
const JsonSchemaPropertySchema = z.lazy(() => z.object({
|
|
337
|
+
type: z.enum([
|
|
338
|
+
"string",
|
|
339
|
+
"integer",
|
|
340
|
+
"number",
|
|
341
|
+
"boolean",
|
|
342
|
+
"object",
|
|
343
|
+
"array",
|
|
344
|
+
"null"
|
|
345
|
+
]),
|
|
346
|
+
format: z.string().optional(),
|
|
347
|
+
primary: z.boolean().optional(),
|
|
348
|
+
autoIncrement: z.boolean().optional(),
|
|
349
|
+
unique: z.boolean().optional(),
|
|
350
|
+
default: z.unknown().optional(),
|
|
351
|
+
maxLength: z.number().int().positive().optional(),
|
|
352
|
+
minLength: z.number().int().nonnegative().optional(),
|
|
353
|
+
minimum: z.number().optional(),
|
|
354
|
+
maximum: z.number().optional(),
|
|
355
|
+
drizzle: DrizzleExtensionSchema,
|
|
356
|
+
nested: NestedConfigSchema.optional(),
|
|
357
|
+
foreignKey: ForeignKeyRefSchema.optional(),
|
|
358
|
+
properties: z.record(z.string(), JsonSchemaPropertySchema).optional(),
|
|
359
|
+
items: JsonSchemaPropertySchema.optional(),
|
|
360
|
+
required: z.array(z.string()).optional()
|
|
361
|
+
}));
|
|
362
|
+
const TableConfigSchema = z.object({
|
|
363
|
+
name: z.string().min(1).regex(/^[a-z][a-z0-9_]*$/, "Table name must be snake_case (lowercase letters, digits, underscores)"),
|
|
364
|
+
timestamps: z.boolean().optional(),
|
|
365
|
+
softDelete: z.boolean().optional()
|
|
366
|
+
});
|
|
367
|
+
const JsonSchemaDefinitionSchema = z.object({
|
|
368
|
+
$schema: z.string().optional(),
|
|
369
|
+
title: z.string().min(1),
|
|
370
|
+
description: z.string().optional(),
|
|
371
|
+
type: z.literal("object"),
|
|
372
|
+
table: TableConfigSchema,
|
|
373
|
+
properties: z.record(z.string(), JsonSchemaPropertySchema),
|
|
374
|
+
required: z.array(z.string()).optional()
|
|
375
|
+
}).refine((schema) => Object.keys(schema.properties).length >= 1, {
|
|
376
|
+
message: "At least one property is required",
|
|
377
|
+
path: ["properties"]
|
|
378
|
+
}).refine((schema) => !schema.required || schema.required.every((r) => r in schema.properties), {
|
|
379
|
+
message: "All required fields must be defined in properties",
|
|
380
|
+
path: ["required"]
|
|
381
|
+
}).refine((schema) => {
|
|
382
|
+
return !Object.values(schema.properties).some((p) => p.primary) || Object.values(schema.properties).filter((p) => p.primary).length === 1;
|
|
383
|
+
}, {
|
|
384
|
+
message: "Only one primary key is allowed per table",
|
|
385
|
+
path: ["properties"]
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
//#endregion
|
|
389
|
+
//#region src/core/schema-sqlite/migrator.ts
|
|
390
|
+
function createMigrationConfig(cwd) {
|
|
391
|
+
return {
|
|
392
|
+
schemaPath: `${cwd}/.aiex/schema`,
|
|
393
|
+
drizzleSchemaPath: `${cwd}/.aiex/drizzle/schema.ts`,
|
|
394
|
+
migrationsPath: `${cwd}/.aiex/migrations`,
|
|
395
|
+
databasePath: `${cwd}/.aiex/database.db`,
|
|
396
|
+
drizzleConfigPath: `${cwd}/.aiex/drizzle.config.ts`
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
function generateDrizzleConfig() {
|
|
400
|
+
return `export default {
|
|
401
|
+
dialect: 'sqlite',
|
|
402
|
+
schema: './.aiex/drizzle/schema.ts',
|
|
403
|
+
out: './.aiex/migrations',
|
|
404
|
+
dbCredentials: {
|
|
405
|
+
url: './.aiex/database.db',
|
|
406
|
+
},
|
|
407
|
+
}
|
|
408
|
+
`;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
//#endregion
|
|
412
|
+
//#region package.json
|
|
413
|
+
var name = "aiex-cli";
|
|
414
|
+
var version = "0.0.0";
|
|
415
|
+
var description = "JSON Schema → SQLite with AI-powered data extraction";
|
|
416
|
+
var package_default = {
|
|
417
|
+
name,
|
|
418
|
+
type: "module",
|
|
419
|
+
version,
|
|
420
|
+
description,
|
|
421
|
+
author: "OSpoon <zxin088@gmail.com>",
|
|
422
|
+
license: "MIT",
|
|
423
|
+
homepage: "https://github.com/OSpoon/aiex-cli#readme",
|
|
424
|
+
repository: {
|
|
425
|
+
"type": "git",
|
|
426
|
+
"url": "git+https://github.com/OSpoon/aiex-cli.git"
|
|
427
|
+
},
|
|
428
|
+
bugs: "https://github.com/OSpoon/aiex-cli/issues",
|
|
429
|
+
keywords: [
|
|
430
|
+
"json-schema",
|
|
431
|
+
"sqlite",
|
|
432
|
+
"drizzle",
|
|
433
|
+
"orm",
|
|
434
|
+
"ai-extraction",
|
|
435
|
+
"cli",
|
|
436
|
+
"database-migration",
|
|
437
|
+
"schema-editor",
|
|
438
|
+
"code-generation",
|
|
439
|
+
"structured-output"
|
|
440
|
+
],
|
|
441
|
+
sideEffects: false,
|
|
442
|
+
exports: {
|
|
443
|
+
".": "./dist/index.mjs",
|
|
444
|
+
"./cli": "./dist/cli.mjs",
|
|
445
|
+
"./core/schema-sqlite/migrate-helper": "./dist/core/schema-sqlite/migrate-helper.mjs",
|
|
446
|
+
"./package.json": "./package.json"
|
|
447
|
+
},
|
|
448
|
+
main: "./dist/index.mjs",
|
|
449
|
+
module: "./dist/index.mjs",
|
|
450
|
+
types: "./dist/index.d.mts",
|
|
451
|
+
bin: { "aiex": "./bin/cli.mjs" },
|
|
452
|
+
files: [
|
|
453
|
+
"bin",
|
|
454
|
+
"dist",
|
|
455
|
+
"src/core/schema-sqlite/migrate-helper.ts"
|
|
456
|
+
],
|
|
457
|
+
scripts: {
|
|
458
|
+
"build": "tsdown && pnpm --filter aiex-web build",
|
|
459
|
+
"dev": "tsdown --watch",
|
|
460
|
+
"start": "tsx src/index.ts",
|
|
461
|
+
"test": "vitest",
|
|
462
|
+
"typecheck": "tsc",
|
|
463
|
+
"lint": "eslint .",
|
|
464
|
+
"prepublishOnly": "cp ../../README.md . && pnpm run build",
|
|
465
|
+
"postpublish": "rm -f README.md"
|
|
466
|
+
},
|
|
467
|
+
dependencies: {
|
|
468
|
+
"@ai-sdk/openai-compatible": "catalog:",
|
|
469
|
+
"@clack/prompts": "catalog:",
|
|
470
|
+
"@hono/node-server": "catalog:",
|
|
471
|
+
"ai": "catalog:",
|
|
472
|
+
"better-sqlite3": "catalog:",
|
|
473
|
+
"citty": "catalog:",
|
|
474
|
+
"cli-table3": "catalog:",
|
|
475
|
+
"conf": "catalog:",
|
|
476
|
+
"consola": "catalog:",
|
|
477
|
+
"date-fns": "catalog:",
|
|
478
|
+
"drizzle-kit": "catalog:cli",
|
|
479
|
+
"drizzle-orm": "catalog:",
|
|
480
|
+
"es-toolkit": "catalog:",
|
|
481
|
+
"esbuild": "catalog:",
|
|
482
|
+
"hono": "catalog:",
|
|
483
|
+
"picocolors": "catalog:",
|
|
484
|
+
"tsx": "catalog:cli",
|
|
485
|
+
"update-notifier": "catalog:",
|
|
486
|
+
"zod": "catalog:"
|
|
487
|
+
},
|
|
488
|
+
devDependencies: {
|
|
489
|
+
"@antfu/eslint-config": "catalog:cli",
|
|
490
|
+
"@antfu/ni": "catalog:cli",
|
|
491
|
+
"@types/better-sqlite3": "catalog:types",
|
|
492
|
+
"@types/node": "catalog:types",
|
|
493
|
+
"@types/update-notifier": "catalog:",
|
|
494
|
+
"eslint": "catalog:cli",
|
|
495
|
+
"publint": "catalog:cli",
|
|
496
|
+
"tsdown": "catalog:cli",
|
|
497
|
+
"tsnapi": "catalog:testing",
|
|
498
|
+
"typescript": "catalog:cli",
|
|
499
|
+
"vitest": "catalog:testing"
|
|
500
|
+
}
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
//#endregion
|
|
504
|
+
//#region src/config.ts
|
|
505
|
+
function createConfig() {
|
|
506
|
+
return new Conf({
|
|
507
|
+
cwd: process.env.CLI_CONFIG_DIR,
|
|
508
|
+
projectName: process.env.CLI_CONFIG_PROJECT_NAME || name
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
function seedConfig(config = createConfig()) {
|
|
512
|
+
if (!config.has("name")) config.set("name", name);
|
|
513
|
+
if (!config.has("version")) config.set("version", version);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
//#endregion
|
|
517
|
+
//#region src/core/ai-extraction/schemas.ts
|
|
518
|
+
const ModelCapabilitiesSchema = z.object({
|
|
519
|
+
vision: z.boolean(),
|
|
520
|
+
structuredOutput: z.boolean()
|
|
521
|
+
});
|
|
522
|
+
const AIModelConfigSchema = z.object({
|
|
523
|
+
name: z.string().min(1),
|
|
524
|
+
capabilities: ModelCapabilitiesSchema
|
|
525
|
+
});
|
|
526
|
+
const AIProviderConfigSchema = z.object({
|
|
527
|
+
baseURL: z.string().min(1),
|
|
528
|
+
apiKey: z.string(),
|
|
529
|
+
models: z.array(AIModelConfigSchema).min(1)
|
|
530
|
+
});
|
|
531
|
+
const PromptConfigSchema = z.object({
|
|
532
|
+
systemTemplate: z.string().min(1),
|
|
533
|
+
userTemplate: z.string().min(1)
|
|
534
|
+
});
|
|
535
|
+
const ExtractionConfigSchema = z.object({ outputDir: z.string().min(1) });
|
|
536
|
+
const AIConfigSchema = z.object({
|
|
537
|
+
provider: AIProviderConfigSchema,
|
|
538
|
+
prompt: PromptConfigSchema,
|
|
539
|
+
extraction: ExtractionConfigSchema
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
//#endregion
|
|
543
|
+
//#region src/core/ai-extraction/types.ts
|
|
544
|
+
const PLACEHOLDER_SCHEMA = "{schema}";
|
|
545
|
+
const PLACEHOLDER_TEXT = "{text}";
|
|
546
|
+
const DEFAULT_MODELS = [{
|
|
547
|
+
name: "qwen-plus",
|
|
548
|
+
capabilities: {
|
|
549
|
+
vision: false,
|
|
550
|
+
structuredOutput: true
|
|
551
|
+
}
|
|
552
|
+
}, {
|
|
553
|
+
name: "qwen-vl-plus",
|
|
554
|
+
capabilities: {
|
|
555
|
+
vision: true,
|
|
556
|
+
structuredOutput: true
|
|
557
|
+
}
|
|
558
|
+
}];
|
|
559
|
+
const DEFAULT_PROVIDER_CONFIG = {
|
|
560
|
+
baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
561
|
+
apiKey: "",
|
|
562
|
+
models: [...DEFAULT_MODELS]
|
|
563
|
+
};
|
|
564
|
+
const DEFAULT_PROMPT_CONFIG = {
|
|
565
|
+
systemTemplate: `You are a professional data extraction assistant. Your task is to extract structured data from text based on the data structure definition provided below.
|
|
566
|
+
|
|
567
|
+
{schema}
|
|
568
|
+
|
|
569
|
+
Extraction requirements:
|
|
570
|
+
1. Extract strictly according to the field names and types defined in the structure
|
|
571
|
+
2. If the text lacks information for a field, set that field to null
|
|
572
|
+
3. Do not add fields that do not exist in the structure definition
|
|
573
|
+
4. Maintain data accuracy and completeness`,
|
|
574
|
+
userTemplate: `Please extract data from the following text:
|
|
575
|
+
{text}`
|
|
576
|
+
};
|
|
577
|
+
const DEFAULT_EXTRACTION_CONFIG = { outputDir: ".aiex/extracted" };
|
|
578
|
+
const DEFAULT_AI_CONFIG = {
|
|
579
|
+
provider: DEFAULT_PROVIDER_CONFIG,
|
|
580
|
+
prompt: DEFAULT_PROMPT_CONFIG,
|
|
581
|
+
extraction: DEFAULT_EXTRACTION_CONFIG
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
//#endregion
|
|
585
|
+
//#region src/core/ai-extraction/config.ts
|
|
586
|
+
const CONFIG_FILE_NAME = "ai-config.json";
|
|
587
|
+
const GITIGNORE_FILE = ".gitignore";
|
|
588
|
+
async function readAIConfig(aiexDir) {
|
|
589
|
+
const configPath = path.join(aiexDir, CONFIG_FILE_NAME);
|
|
590
|
+
try {
|
|
591
|
+
const content = await fs.readFile(configPath, "utf-8");
|
|
592
|
+
const parsed = JSON.parse(content);
|
|
593
|
+
return AIConfigSchema.parse(parsed);
|
|
594
|
+
} catch {
|
|
595
|
+
return null;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
async function writeAIConfig(aiexDir, config) {
|
|
599
|
+
const configPath = path.join(aiexDir, CONFIG_FILE_NAME);
|
|
600
|
+
await fs.mkdir(aiexDir, { recursive: true });
|
|
601
|
+
await fs.writeFile(configPath, `${JSON.stringify(config, null, 2)}\n`);
|
|
602
|
+
await addToGitignore(aiexDir, CONFIG_FILE_NAME);
|
|
603
|
+
}
|
|
604
|
+
function getDefaultAIConfig() {
|
|
605
|
+
return { ...DEFAULT_AI_CONFIG };
|
|
606
|
+
}
|
|
607
|
+
function maskApiKey(apiKey) {
|
|
608
|
+
if (apiKey.length <= 4) return "****";
|
|
609
|
+
return `sk-***${apiKey.slice(-4)}`;
|
|
610
|
+
}
|
|
611
|
+
async function addToGitignore(aiexDir, fileName) {
|
|
612
|
+
const projectRoot = path.dirname(aiexDir);
|
|
613
|
+
const gitignorePath = path.join(projectRoot, GITIGNORE_FILE);
|
|
614
|
+
try {
|
|
615
|
+
const content = await fs.readFile(gitignorePath, "utf-8");
|
|
616
|
+
if (content.split("\n").some((line) => line.trim() === fileName || line.includes(".aiex/"))) return;
|
|
617
|
+
const newContent = content.endsWith("\n") ? `${content}${fileName}\n` : `${content}\n${fileName}\n`;
|
|
618
|
+
await fs.writeFile(gitignorePath, newContent);
|
|
619
|
+
} catch {
|
|
620
|
+
await fs.writeFile(gitignorePath, `${fileName}\n`);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
//#endregion
|
|
625
|
+
//#region src/doctor.ts
|
|
626
|
+
const V1_SUFFIX_RE = /\/v1\/?$/;
|
|
627
|
+
async function checkConnection(baseURL) {
|
|
628
|
+
try {
|
|
629
|
+
const base = baseURL.replace(V1_SUFFIX_RE, "");
|
|
630
|
+
return (await fetch(`${base}/v1/models`, { signal: AbortSignal.timeout(5e3) })).ok;
|
|
631
|
+
} catch {
|
|
632
|
+
return false;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
async function collectDoctorDiagnostics(options = {}) {
|
|
636
|
+
const config = options.config ?? createConfig();
|
|
637
|
+
const cwd = process.cwd();
|
|
638
|
+
const errors = [];
|
|
639
|
+
const migConfig = createMigrationConfig(cwd);
|
|
640
|
+
const aiexDir = path.dirname(migConfig.schemaPath);
|
|
641
|
+
const dirExists = await fs.stat(aiexDir).then((s) => s.isDirectory()).catch(() => false);
|
|
642
|
+
let schemaFiles = [];
|
|
643
|
+
if (dirExists) try {
|
|
644
|
+
const schemaDir = migConfig.schemaPath;
|
|
645
|
+
schemaFiles = (await fs.readdir(schemaDir).catch(() => [])).filter((f) => f.endsWith(".json")).sort();
|
|
646
|
+
} catch {
|
|
647
|
+
errors.push("Could not read schema directory");
|
|
648
|
+
}
|
|
649
|
+
let aiConfig = false;
|
|
650
|
+
let aiApiKeySet = false;
|
|
651
|
+
let aiModelCount = 0;
|
|
652
|
+
let aiModels = [];
|
|
653
|
+
let aiProvider = null;
|
|
654
|
+
let aiConnectionOk = null;
|
|
655
|
+
if (dirExists) {
|
|
656
|
+
const cfg = await readAIConfig(aiexDir);
|
|
657
|
+
if (cfg) {
|
|
658
|
+
aiConfig = true;
|
|
659
|
+
aiApiKeySet = Boolean(cfg.provider.apiKey);
|
|
660
|
+
aiModelCount = cfg.provider.models?.length ?? 0;
|
|
661
|
+
aiModels = cfg.provider.models?.map((m) => m.name) ?? [];
|
|
662
|
+
aiProvider = cfg.provider.baseURL;
|
|
663
|
+
aiConnectionOk = await checkConnection(cfg.provider.baseURL);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
let dbExists = false;
|
|
667
|
+
if (dirExists) try {
|
|
668
|
+
dbExists = (await fs.stat(migConfig.databasePath)).isFile();
|
|
669
|
+
} catch {
|
|
670
|
+
dbExists = false;
|
|
671
|
+
}
|
|
672
|
+
let migrationCount = 0;
|
|
673
|
+
if (dirExists) try {
|
|
674
|
+
migrationCount = (await fs.readdir(migConfig.migrationsPath).catch(() => [])).filter((f) => f.endsWith(".sql")).length;
|
|
675
|
+
} catch {}
|
|
676
|
+
return buildDoctorDiagnostics({
|
|
677
|
+
pkg: {
|
|
678
|
+
name,
|
|
679
|
+
version
|
|
680
|
+
},
|
|
681
|
+
executable: process.argv[1] ?? "unknown",
|
|
682
|
+
node: process.version,
|
|
683
|
+
platform: process.platform,
|
|
684
|
+
arch: process.arch,
|
|
685
|
+
shell: process.env.SHELL ?? process.env.ComSpec ?? "unknown",
|
|
686
|
+
packageManager: process.env.npm_config_user_agent?.split(" ")[0] || "unknown",
|
|
687
|
+
osType: os.type(),
|
|
688
|
+
osRelease: os.release(),
|
|
689
|
+
cwd,
|
|
690
|
+
configPath: config.path,
|
|
691
|
+
configStoreKeys: Object.keys(config.store),
|
|
692
|
+
project: {
|
|
693
|
+
aiexDir,
|
|
694
|
+
dirExists,
|
|
695
|
+
schemaCount: schemaFiles.length,
|
|
696
|
+
schemaFiles,
|
|
697
|
+
aiConfig,
|
|
698
|
+
aiApiKeySet,
|
|
699
|
+
aiModelCount,
|
|
700
|
+
aiModels,
|
|
701
|
+
aiProvider,
|
|
702
|
+
aiConnectionOk,
|
|
703
|
+
hasDatabase: dbExists,
|
|
704
|
+
migrationCount,
|
|
705
|
+
errors
|
|
706
|
+
}
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
//#endregion
|
|
711
|
+
export { formatDoctorDiagnosticsJson as C, doctorDiagnosticsTableRows as S, generateDrizzleConfig as _, writeAIConfig as a, generateDrizzleSchema as b, PLACEHOLDER_TEXT as c, seedConfig as d, description as f, createMigrationConfig as g, version as h, readAIConfig as i, AIConfigSchema as l, package_default as m, getDefaultAIConfig as n, DEFAULT_PROMPT_CONFIG as o, name as p, maskApiKey as r, PLACEHOLDER_SCHEMA as s, collectDoctorDiagnostics as t, createConfig as u, JsonSchemaDefinitionSchema as v, buildDoctorDiagnostics as x, parseJsonSchema as y };
|