@supalive/codegen 1.7.0 → 1.8.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/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{src-DM44BrYS.js → src-BRGy8CeY.js} +154 -7
- package/package.json +1 -1
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as emit, c as loadSchemaEnums, i as resolveConfig, n as generateToDisk, o as extractClient, r as readEntryConfig, s as SchemaEnumRegistry, t as generate } from "./src-
|
|
1
|
+
import { a as emit, c as loadSchemaEnums, i as resolveConfig, n as generateToDisk, o as extractClient, r as readEntryConfig, s as SchemaEnumRegistry, t as generate } from "./src-BRGy8CeY.js";
|
|
2
2
|
export { SchemaEnumRegistry, emit, extractClient, generate, generateToDisk, loadSchemaEnums, readEntryConfig, resolveConfig };
|
|
@@ -92,12 +92,91 @@ function followToCall(node, depth) {
|
|
|
92
92
|
if (!node || depth > 8) return void 0;
|
|
93
93
|
if (Node.isCallExpression(node)) return node;
|
|
94
94
|
if (Node.isIdentifier(node)) {
|
|
95
|
-
for (const def of node.getDefinitionNodes())
|
|
96
|
-
const
|
|
95
|
+
for (const def of node.getDefinitionNodes()) {
|
|
96
|
+
const init = definitionInitializer(def);
|
|
97
|
+
if (init) {
|
|
98
|
+
const found = followToCall(init, depth + 1);
|
|
99
|
+
if (found) return found;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const imported = followImport(node);
|
|
103
|
+
if (imported) {
|
|
104
|
+
const found = followToCall(imported, depth + 1);
|
|
97
105
|
if (found) return found;
|
|
98
106
|
}
|
|
99
107
|
}
|
|
100
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Given an Identifier that may be an import binding, follow through the import
|
|
111
|
+
* chain to the actual exported declaration's initializer node.
|
|
112
|
+
*
|
|
113
|
+
* Handles: `import { listItems } from "./procs.js"` → the exported VariableDeclaration
|
|
114
|
+
* `import { x } from "./reexport.js"` where that file re-exports → recursive follow
|
|
115
|
+
*/
|
|
116
|
+
function followImport(id) {
|
|
117
|
+
const sourceFile = id.getSourceFile();
|
|
118
|
+
const name = id.getText();
|
|
119
|
+
for (const imp of sourceFile.getImportDeclarations()) {
|
|
120
|
+
const specifiers = imp.getNamedImports();
|
|
121
|
+
for (const spec of specifiers) {
|
|
122
|
+
if (spec.getName() !== name) continue;
|
|
123
|
+
const resolved = imp.getModuleSpecifierSourceFile();
|
|
124
|
+
if (!resolved) continue;
|
|
125
|
+
const exportName = spec.getNameNode().getText();
|
|
126
|
+
const exported = resolved.getExportedDeclarations().get(exportName);
|
|
127
|
+
if (!exported || exported.length === 0) continue;
|
|
128
|
+
const decl = exported[0];
|
|
129
|
+
if (Node.isExportSpecifier(decl)) {
|
|
130
|
+
const targets = decl.getLocalTargetDeclarations();
|
|
131
|
+
if (targets.length > 0) return definitionInitializer(targets[0]);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
return definitionInitializer(decl);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
for (const exp of sourceFile.getExportDeclarations()) {
|
|
138
|
+
const specifiers = exp.getNamedExports();
|
|
139
|
+
for (const spec of specifiers) {
|
|
140
|
+
if (spec.getName() !== name) continue;
|
|
141
|
+
const resolved = exp.getModuleSpecifierSourceFile();
|
|
142
|
+
if (!resolved) continue;
|
|
143
|
+
const exportName = spec.getNameNode().getText();
|
|
144
|
+
const exported = resolved.getExportedDeclarations().get(exportName);
|
|
145
|
+
if (!exported || exported.length === 0) continue;
|
|
146
|
+
const decl = exported[0];
|
|
147
|
+
if (Node.isExportSpecifier(decl)) {
|
|
148
|
+
const targets = decl.getLocalTargetDeclarations();
|
|
149
|
+
if (targets.length > 0) return definitionInitializer(targets[0]);
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
return definitionInitializer(decl);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/** Extract the initializer expression from a definition node, unwrapping any
|
|
157
|
+
* container nodes (VariableStatement, ExportNamedDeclaration, etc.) that
|
|
158
|
+
* ts-morph may return for cross-file imports. */
|
|
159
|
+
function definitionInitializer(def) {
|
|
160
|
+
if (Node.isVariableDeclaration(def)) return def.getInitializer();
|
|
161
|
+
if (Node.isVariableStatement(def)) for (const d of def.getDeclarationList().getDeclarations()) {
|
|
162
|
+
const init = d.getInitializer();
|
|
163
|
+
if (init) return init;
|
|
164
|
+
}
|
|
165
|
+
for (const child of def.getChildren()) {
|
|
166
|
+
const init = definitionInitializer(child);
|
|
167
|
+
if (init) return init;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/** Resolve an Identifier to its initializer, following definitions across files. */
|
|
171
|
+
function resolveIdentifierInit(id) {
|
|
172
|
+
if (!Node.isIdentifier(id)) return void 0;
|
|
173
|
+
for (const def of id.getDefinitionNodes()) {
|
|
174
|
+
const init = definitionInitializer(def);
|
|
175
|
+
if (init) return init;
|
|
176
|
+
}
|
|
177
|
+
const imported = followImport(id);
|
|
178
|
+
if (imported) return imported;
|
|
179
|
+
}
|
|
101
180
|
/** From a `query({ args: z.object({...}), handler })` call, get the schema. */
|
|
102
181
|
function getArgsSchema(call) {
|
|
103
182
|
if (!Node.isCallExpression(call)) return void 0;
|
|
@@ -110,7 +189,12 @@ function getArgsSchema(call) {
|
|
|
110
189
|
/** Scan `z.object({ field: <expr>, ... })` for per-field metadata. */
|
|
111
190
|
function scanObjectSchema(schema) {
|
|
112
191
|
const map = /* @__PURE__ */ new Map();
|
|
113
|
-
|
|
192
|
+
let node = schema;
|
|
193
|
+
if (Node.isIdentifier(node)) {
|
|
194
|
+
const init = resolveIdentifierInit(node);
|
|
195
|
+
if (init) node = init;
|
|
196
|
+
}
|
|
197
|
+
const objectLiteral = findZodObjectLiteral(node);
|
|
114
198
|
if (!objectLiteral || !Node.isObjectLiteralExpression(objectLiteral)) return map;
|
|
115
199
|
for (const prop of objectLiteral.getProperties()) {
|
|
116
200
|
if (!Node.isPropertyAssignment(prop)) continue;
|
|
@@ -428,6 +512,31 @@ var Extractor = class {
|
|
|
428
512
|
return;
|
|
429
513
|
}
|
|
430
514
|
}
|
|
515
|
+
/**
|
|
516
|
+
* Read an `@type` JSDoc tag from a property and parse it into a DartType.
|
|
517
|
+
*
|
|
518
|
+
* Supported formats:
|
|
519
|
+
* - `/** @type StoreCardItem */` → model with that name
|
|
520
|
+
* - `/** @type List<StoreCardItem> */` → list with model element
|
|
521
|
+
* - `/** @type String */`, `/** @type int */`, etc. → primitive
|
|
522
|
+
*/
|
|
523
|
+
readTypeOverride(prop) {
|
|
524
|
+
try {
|
|
525
|
+
const decls = prop.getDeclarations();
|
|
526
|
+
if (!decls || decls.length === 0) return null;
|
|
527
|
+
const node = decls[0];
|
|
528
|
+
if (!Node.isJSDocable(node)) return null;
|
|
529
|
+
const jsDocs = node.getJsDocs();
|
|
530
|
+
if (jsDocs.length === 0) return null;
|
|
531
|
+
const typeTag = jsDocs[jsDocs.length - 1].getTags().find((t) => t.getTagName() === "type");
|
|
532
|
+
if (!typeTag) return null;
|
|
533
|
+
const raw = typeTag.compilerNode.typeExpression?.getText?.()?.trim();
|
|
534
|
+
if (!raw) return null;
|
|
535
|
+
return parseTypeOverride(raw);
|
|
536
|
+
} catch {
|
|
537
|
+
return null;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
431
540
|
models() {
|
|
432
541
|
this.finalizeEnums();
|
|
433
542
|
return [...this.modelRegistry.values()];
|
|
@@ -544,11 +653,15 @@ var Extractor = class {
|
|
|
544
653
|
const { core, hasNull, hasUndefined } = splitNullish(propType);
|
|
545
654
|
const optional = declaredOptional || hasUndefined;
|
|
546
655
|
const nullable = hasNull;
|
|
656
|
+
const typeOverride = this.readTypeOverride(prop);
|
|
547
657
|
let dartType;
|
|
548
|
-
if (
|
|
549
|
-
else if (core.length ===
|
|
550
|
-
else
|
|
551
|
-
|
|
658
|
+
if (typeOverride) dartType = typeOverride;
|
|
659
|
+
else if (core.length === 0) dartType = { kind: "dynamic" };
|
|
660
|
+
else if (core.length === 1) {
|
|
661
|
+
const fieldHint = name.replace(/Result$/, "") + pascal(jsonKey);
|
|
662
|
+
dartType = this.walkSingle(core[0], fieldHint);
|
|
663
|
+
} else dartType = this.walkUnion(core, {
|
|
664
|
+
hint: name.replace(/Result$/, "") + pascal(jsonKey),
|
|
552
665
|
stem: cleanStem(name),
|
|
553
666
|
field: jsonKey
|
|
554
667
|
});
|
|
@@ -832,6 +945,40 @@ function cleanStem(modelName) {
|
|
|
832
945
|
}
|
|
833
946
|
return singularizeWord(s);
|
|
834
947
|
}
|
|
948
|
+
const PRIMITIVE_MAP = {
|
|
949
|
+
string: "string",
|
|
950
|
+
int: "int",
|
|
951
|
+
double: "double",
|
|
952
|
+
bool: "bool",
|
|
953
|
+
bigint: "bigint",
|
|
954
|
+
bytes: "bytes",
|
|
955
|
+
datetime: "datetime",
|
|
956
|
+
dynamic: "dynamic"
|
|
957
|
+
};
|
|
958
|
+
/**
|
|
959
|
+
* Parse an `@type` override value into a DartType.
|
|
960
|
+
*
|
|
961
|
+
* - `"StoreCardItem"` → `{ kind: "model", name: "StoreCardItem" }`
|
|
962
|
+
* - `"List<StoreCardItem>"` → `{ kind: "list", element: { kind: "model", name: "StoreCardItem" } }`
|
|
963
|
+
* - `"String"` → `{ kind: "string" }`
|
|
964
|
+
* - `"int"` → `{ kind: "int" }`
|
|
965
|
+
*/
|
|
966
|
+
function parseTypeOverride(raw) {
|
|
967
|
+
const listMatch = raw.match(/^List<(.+)>$/);
|
|
968
|
+
if (listMatch) {
|
|
969
|
+
const innerType = parseTypeOverride(listMatch[1].trim());
|
|
970
|
+
return innerType ? {
|
|
971
|
+
kind: "list",
|
|
972
|
+
element: innerType
|
|
973
|
+
} : null;
|
|
974
|
+
}
|
|
975
|
+
const prim = PRIMITIVE_MAP[raw.toLowerCase()];
|
|
976
|
+
if (prim) return { kind: prim };
|
|
977
|
+
return {
|
|
978
|
+
kind: "model",
|
|
979
|
+
name: raw
|
|
980
|
+
};
|
|
981
|
+
}
|
|
835
982
|
/** The bare candidate name for a structural (non-schema) enum group. */
|
|
836
983
|
function fallbackBase(g) {
|
|
837
984
|
return pascal(g.field ?? g.hint);
|