@supalive/codegen 1.22.1 → 1.23.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-Ckf5xah9.js → src-Cmwpfczg.js} +58 -2
- 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-Cmwpfczg.js";
|
|
2
2
|
export { SchemaEnumRegistry, emit, extractClient, generate, generateToDisk, loadSchemaEnums, readEntryConfig, resolveConfig };
|
|
@@ -358,7 +358,7 @@ function scanObjectSchema(schema) {
|
|
|
358
358
|
}
|
|
359
359
|
return map;
|
|
360
360
|
}
|
|
361
|
-
function topLevelZodMethods(node) {
|
|
361
|
+
function topLevelZodMethods(node, depth = 0) {
|
|
362
362
|
const methods = /* @__PURE__ */ new Set();
|
|
363
363
|
let cur = node;
|
|
364
364
|
while (cur && Node.isCallExpression(cur)) {
|
|
@@ -368,8 +368,14 @@ function topLevelZodMethods(node) {
|
|
|
368
368
|
cur = expr.getExpression();
|
|
369
369
|
} else break;
|
|
370
370
|
}
|
|
371
|
+
if (cur && Node.isIdentifier(cur) && depth < MAX_ALIAS_DEPTH) {
|
|
372
|
+
const init = resolveIdentifierInit(cur);
|
|
373
|
+
if (init) for (const m of topLevelZodMethods(init, depth + 1)) methods.add(m);
|
|
374
|
+
}
|
|
371
375
|
return methods;
|
|
372
376
|
}
|
|
377
|
+
/** Guards against a cyclic alias (`const A = B; const B = A;`) looping forever. */
|
|
378
|
+
const MAX_ALIAS_DEPTH = 8;
|
|
373
379
|
function topLevelZodDescription(node) {
|
|
374
380
|
let cur = node;
|
|
375
381
|
while (cur && Node.isCallExpression(cur)) {
|
|
@@ -711,10 +717,47 @@ function extractClient(config, schemaEnums = SchemaEnumRegistry.empty()) {
|
|
|
711
717
|
return {
|
|
712
718
|
clientClassName: config.clientClassName,
|
|
713
719
|
procedures,
|
|
714
|
-
models: extractor.models(),
|
|
720
|
+
models: pruneUnreachableModels(procedures, extractor.models()),
|
|
715
721
|
enums: extractor.enums()
|
|
716
722
|
};
|
|
717
723
|
}
|
|
724
|
+
/**
|
|
725
|
+
* Drop models nothing refers to.
|
|
726
|
+
*
|
|
727
|
+
* A result model is first registered under a name derived from the handler's TS
|
|
728
|
+
* return type, then RENAMED when the procedure's `returns` schema declares
|
|
729
|
+
* `.modelName("X")`. When a second procedure shares that same schema, the name
|
|
730
|
+
* is already taken: the reference correctly points at the registered `X`, but
|
|
731
|
+
* the structural model allocated for this procedure is left behind — emitting a
|
|
732
|
+
* near-identical `MyTimetableItem` beside the `TimetableSlotRow` everything
|
|
733
|
+
* actually uses.
|
|
734
|
+
*
|
|
735
|
+
* Pruning by reachability fixes that without having to decide, at rename time,
|
|
736
|
+
* whether a model is safe to delete — which is not knowable then, because a
|
|
737
|
+
* later procedure may still refer to it.
|
|
738
|
+
*/
|
|
739
|
+
function pruneUnreachableModels(procedures, models) {
|
|
740
|
+
const byName = new Map(models.map((m) => [m.name, m]));
|
|
741
|
+
const reachable = /* @__PURE__ */ new Set();
|
|
742
|
+
const visitType = (t) => {
|
|
743
|
+
if (!t) return;
|
|
744
|
+
switch (t.kind) {
|
|
745
|
+
case "model":
|
|
746
|
+
if (reachable.has(t.name)) return;
|
|
747
|
+
reachable.add(t.name);
|
|
748
|
+
for (const f of byName.get(t.name)?.fields ?? []) visitType(f.type);
|
|
749
|
+
return;
|
|
750
|
+
case "list": return visitType(t.element);
|
|
751
|
+
case "map": return visitType(t.value);
|
|
752
|
+
default: return;
|
|
753
|
+
}
|
|
754
|
+
};
|
|
755
|
+
for (const p of procedures) {
|
|
756
|
+
visitType(p.args);
|
|
757
|
+
visitType(p.result);
|
|
758
|
+
}
|
|
759
|
+
return models.filter((m) => reachable.has(m.name));
|
|
760
|
+
}
|
|
718
761
|
var Extractor = class {
|
|
719
762
|
locationNode;
|
|
720
763
|
config;
|
|
@@ -1392,6 +1435,7 @@ function stripNull(expr) {
|
|
|
1392
1435
|
function emitModels(ir) {
|
|
1393
1436
|
const out = [HEADER];
|
|
1394
1437
|
if (modelsUseBytes(ir)) out.push("import 'dart:typed_data';\n");
|
|
1438
|
+
if (ir.enums.length > 0) out.push("import 'package:intl/intl.dart';");
|
|
1395
1439
|
out.push("import 'package:supalive_client/supalive_client.dart';\n");
|
|
1396
1440
|
for (const e of ir.enums) out.push(emitEnum(e));
|
|
1397
1441
|
for (const m of ir.models) out.push(emitModel(m));
|
|
@@ -1423,6 +1467,18 @@ ${values};
|
|
|
1423
1467
|
);
|
|
1424
1468
|
|
|
1425
1469
|
String toJson() => wire;
|
|
1470
|
+
|
|
1471
|
+
/// This value in the reader's language, from the ARB key
|
|
1472
|
+
/// \`${e.name}_<constant>\` — e.g. \`"${e.name}_${e.values[0]?.dartName ?? "value"}": "…"\`.
|
|
1473
|
+
///
|
|
1474
|
+
/// Lives on the enum so no app has to write a \`switch\` over it. Add the keys
|
|
1475
|
+
/// to your ARB files and every screen showing this enum is translated at once;
|
|
1476
|
+
/// an enum the server adds later shows up as a missing key rather than as a
|
|
1477
|
+
/// non-exhaustive switch nobody notices.
|
|
1478
|
+
///
|
|
1479
|
+
/// Falls back to the constant name when the key is absent, so an untranslated
|
|
1480
|
+
/// value reads \`${e.values[0]?.dartName ?? "value"}\` rather than rendering blank.
|
|
1481
|
+
String get localizedName => Intl.message(name, name: '${e.name}_\$name');
|
|
1426
1482
|
}
|
|
1427
1483
|
`;
|
|
1428
1484
|
}
|