@danielhritcu/zenstack-custom 1.1.0 → 1.2.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.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { Z as ZenConfig } from './config-1Cdfs72F.cjs';
2
+ import { Z as ZenConfig } from './config-CRQer7hw.cjs';
3
3
  import 'drizzle-orm/pg-core';
4
4
 
5
5
  declare function runCodegen(config: ZenConfig): Promise<void>;
package/dist/cli.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { Z as ZenConfig } from './config-1Cdfs72F.js';
2
+ import { Z as ZenConfig } from './config-CRQer7hw.js';
3
3
  import 'drizzle-orm/pg-core';
4
4
 
5
5
  declare function runCodegen(config: ZenConfig): Promise<void>;
package/dist/cli.js CHANGED
@@ -908,6 +908,32 @@ __name(sortTypedJsonFields, "sortTypedJsonFields");
908
908
 
909
909
  // src/codegen/emit.ts
910
910
  var DB_ATTR_RE = /@db\.(\w+)(?:\((\d+)\))?/;
911
+ function isUuidField(t, fieldName) {
912
+ const col = t.table[fieldName];
913
+ if (!col) return false;
914
+ return col.columnType === "PgUUID";
915
+ }
916
+ __name(isUuidField, "isUuidField");
917
+ function isPkField(t, fieldName) {
918
+ const col = t.table[fieldName];
919
+ if (!col) return false;
920
+ if (col.primary) return true;
921
+ const sqlName = col.name;
922
+ return t.cfg.primaryKeys.some((pk) => pk.columns.some((c) => c.name === sqlName));
923
+ }
924
+ __name(isPkField, "isPkField");
925
+ function findFkTarget(t, fieldName, fkRelations) {
926
+ const modelFks = fkRelations[t.modelName];
927
+ if (!modelFks) return null;
928
+ for (const fkInfo of Object.values(modelFks)) {
929
+ const idx = fkInfo.fields.indexOf(fieldName);
930
+ if (idx >= 0) {
931
+ return fkInfo.targetExportName;
932
+ }
933
+ }
934
+ return null;
935
+ }
936
+ __name(findFkTarget, "findFkTarget");
911
937
  function buildDerivedEnumName(modelName, fieldName) {
912
938
  return `${toPascalCase(modelName)}${toPascalCase(fieldName)}`;
913
939
  }
@@ -1403,8 +1429,9 @@ function emitSchemaTs({ tables, enumMap, modelRelations, inverseRelations, searc
1403
1429
  return out.join("\n");
1404
1430
  }
1405
1431
  __name(emitSchemaTs, "emitSchemaTs");
1406
- function emitModelsTs(tables, typedJsonFields = []) {
1432
+ function emitModelsTs(tables, typedJsonFields = [], branding) {
1407
1433
  const jsonFieldAliases = createJsonFieldAliasMap(typedJsonFields);
1434
+ const hasBranding = branding && (Object.keys(branding.brandedFields).length > 0 || tables.some((t) => getEntityFieldNames(t).some((f) => isUuidField(t, f) && isPkField(t, f))));
1408
1435
  const out = [
1409
1436
  ...emitGeneratedFileBanner()
1410
1437
  ];
@@ -1412,6 +1439,10 @@ function emitModelsTs(tables, typedJsonFields = []) {
1412
1439
  out.push('import type * as $ from "@zenstackhq/orm";');
1413
1440
  out.push('import type * as Json from "./json";');
1414
1441
  out.push('import { type SchemaType as Schema } from "./schema";');
1442
+ if (hasBranding) {
1443
+ out.push("");
1444
+ out.push("declare const __brand: unique symbol;");
1445
+ }
1415
1446
  out.push("");
1416
1447
  for (const t of tables) {
1417
1448
  out.push(`export interface ${t.typeName} extends $.ModelResult<Schema, ${esc(t.modelName)}> {}`);
@@ -1422,7 +1453,12 @@ function emitModelsTs(tables, typedJsonFields = []) {
1422
1453
  if (jsonAlias) {
1423
1454
  out.push(` export interface ${exportName} extends Json.${jsonAlias} {}`);
1424
1455
  } else {
1425
- out.push(` export type ${exportName} = ${t.typeName}[${esc(fieldName)}];`);
1456
+ const brandedLine = branding ? emitBrandedFieldLine(t, fieldName, exportName, branding, " ") : null;
1457
+ if (brandedLine) {
1458
+ out.push(...brandedLine);
1459
+ } else {
1460
+ out.push(` export type ${exportName} = ${t.typeName}[${esc(fieldName)}];`);
1461
+ }
1426
1462
  }
1427
1463
  }
1428
1464
  out.push("}");
@@ -1431,6 +1467,33 @@ function emitModelsTs(tables, typedJsonFields = []) {
1431
1467
  return out.join("\n");
1432
1468
  }
1433
1469
  __name(emitModelsTs, "emitModelsTs");
1470
+ function emitBrandedFieldLine(t, fieldName, exportName, branding, indent) {
1471
+ const customBranded = branding.brandedFields[t.modelName]?.[fieldName];
1472
+ if (isUuidField(t, fieldName) && isPkField(t, fieldName)) {
1473
+ const brand = `${t.modelName}.${fieldName}`;
1474
+ return [
1475
+ `${indent}export type ${exportName} = string & { [__brand]: '${brand}' };`,
1476
+ `${indent}export const ${exportName} = (id: string): ${exportName} => id as ${exportName};`
1477
+ ];
1478
+ }
1479
+ if (isUuidField(t, fieldName)) {
1480
+ const targetExportName = findFkTarget(t, fieldName, branding.fkRelations);
1481
+ if (targetExportName) {
1482
+ return [
1483
+ `${indent}export type ${exportName} = ${targetExportName}.Id;`
1484
+ ];
1485
+ }
1486
+ }
1487
+ if (customBranded) {
1488
+ const brand = `${t.modelName}.${fieldName}`;
1489
+ return [
1490
+ `${indent}export type ${exportName} = string & { [__brand]: '${brand}' };`,
1491
+ `${indent}export const ${exportName} = (id: string): ${exportName} => id as ${exportName};`
1492
+ ];
1493
+ }
1494
+ return null;
1495
+ }
1496
+ __name(emitBrandedFieldLine, "emitBrandedFieldLine");
1434
1497
  function emitViewsTs(views, typedJsonFields = []) {
1435
1498
  const jsonFieldAliases = createJsonFieldAliasMap(typedJsonFields);
1436
1499
  const out = [
@@ -1496,12 +1559,13 @@ function emitInputTs(tables) {
1496
1559
  return out.join("\n");
1497
1560
  }
1498
1561
  __name(emitInputTs, "emitInputTs");
1499
- function emitIndexTs({ tables, views, enumMap, typeDefs, typedJsonFields }) {
1562
+ function emitIndexTs({ tables, views, enumMap, typeDefs, typedJsonFields, branding }) {
1500
1563
  const allEnums = new Map([
1501
1564
  ...enumMap,
1502
1565
  ...collectDerivedEnums(tables, enumMap)
1503
1566
  ]);
1504
1567
  const jsonFieldAliases = createJsonFieldAliasMap(typedJsonFields);
1568
+ const hasBranding = branding && (Object.keys(branding.brandedFields).length > 0 || tables.some((t) => getEntityFieldNames(t).some((f) => isUuidField(t, f) && isPkField(t, f))));
1505
1569
  const out = [
1506
1570
  ...emitGeneratedFileBanner()
1507
1571
  ];
@@ -1509,6 +1573,10 @@ function emitIndexTs({ tables, views, enumMap, typeDefs, typedJsonFields }) {
1509
1573
  out.push('import type * as $ from "@zenstackhq/orm";');
1510
1574
  out.push('import type * as RawJson from "../../supabase/schema/types";');
1511
1575
  out.push('import { type SchemaType as Schema } from "./schema";');
1576
+ if (hasBranding) {
1577
+ out.push("");
1578
+ out.push("declare const __brand: unique symbol;");
1579
+ }
1512
1580
  out.push("");
1513
1581
  out.push("export namespace Json {");
1514
1582
  out.push(...emitJsonNamespaceBlock(typeDefs, typedJsonFields, " "));
@@ -1523,7 +1591,7 @@ function emitIndexTs({ tables, views, enumMap, typeDefs, typedJsonFields }) {
1523
1591
  out.push("");
1524
1592
  out.push("export namespace Table {");
1525
1593
  for (const table of tables) {
1526
- out.push(...emitEntityNamespaceBlock(table, table.modelName, jsonFieldAliases, " "));
1594
+ out.push(...emitEntityNamespaceBlock(table, table.modelName, jsonFieldAliases, " ", branding));
1527
1595
  out.push("");
1528
1596
  }
1529
1597
  out.push("}");
@@ -1682,7 +1750,7 @@ function createJsonFieldAliasMap(typedJsonFields) {
1682
1750
  ]));
1683
1751
  }
1684
1752
  __name(createJsonFieldAliasMap, "createJsonFieldAliasMap");
1685
- function emitEntityNamespaceBlock(entity, modelName, jsonFieldAliases, indent = "") {
1753
+ function emitEntityNamespaceBlock(entity, modelName, jsonFieldAliases, indent = "", branding) {
1686
1754
  const out = [];
1687
1755
  out.push(`${indent}export interface ${entity.typeName} extends $.ModelResult<Schema, ${esc(modelName)}> {}`);
1688
1756
  out.push(`${indent}export namespace ${entity.typeName} {`);
@@ -1692,7 +1760,13 @@ function emitEntityNamespaceBlock(entity, modelName, jsonFieldAliases, indent =
1692
1760
  if (jsonAlias) {
1693
1761
  out.push(`${indent} export interface ${exportName} extends Json.${jsonAlias} {}`);
1694
1762
  } else {
1695
- out.push(`${indent} export type ${exportName} = ${entity.typeName}[${esc(fieldName)}];`);
1763
+ const isTable = "table" in entity;
1764
+ const brandedLine = isTable && branding ? emitBrandedFieldLine(entity, fieldName, exportName, branding, `${indent} `) : null;
1765
+ if (brandedLine) {
1766
+ out.push(...brandedLine);
1767
+ } else {
1768
+ out.push(`${indent} export type ${exportName} = ${entity.typeName}[${esc(fieldName)}];`);
1769
+ }
1696
1770
  }
1697
1771
  }
1698
1772
  out.push(`${indent}}`);
@@ -2241,6 +2315,7 @@ function resolveConfig(config) {
2241
2315
  const derivedFieldsMap = {};
2242
2316
  const validationSchemas = {};
2243
2317
  const fkRelations = {};
2318
+ const brandedFields = {};
2244
2319
  for (const [derivedName, desc] of Object.entries(derived)) {
2245
2320
  const baseExportName = sqlNameToExportName(tables, desc.baseName);
2246
2321
  if (!derivedModels[baseExportName]) {
@@ -2373,6 +2448,9 @@ function resolveConfig(config) {
2373
2448
  if (modelConfig.validate) {
2374
2449
  validationSchemas[modelName] = modelConfig.validate;
2375
2450
  }
2451
+ if (modelConfig.branded) {
2452
+ brandedFields[modelName] = modelConfig.branded;
2453
+ }
2376
2454
  if (modelConfig.search) {
2377
2455
  const modelSearchDefaults = {};
2378
2456
  for (const [profileName, profile] of Object.entries(modelConfig.search)) {
@@ -2392,7 +2470,8 @@ function resolveConfig(config) {
2392
2470
  modelScopes,
2393
2471
  derivedFields: derivedFieldsMap,
2394
2472
  validationSchemas,
2395
- fkRelations
2473
+ fkRelations,
2474
+ brandedFields
2396
2475
  };
2397
2476
  }
2398
2477
  __name(resolveConfig, "resolveConfig");
@@ -2426,12 +2505,17 @@ async function runCodegen(config) {
2426
2505
  fieldToTypeDef,
2427
2506
  views
2428
2507
  });
2508
+ const branding = {
2509
+ fkRelations: resolved.fkRelations,
2510
+ brandedFields: resolved.brandedFields
2511
+ };
2429
2512
  const indexContent = emitIndexTs({
2430
2513
  tables,
2431
2514
  views,
2432
2515
  enumMap,
2433
2516
  typeDefs,
2434
- typedJsonFields
2517
+ typedJsonFields,
2518
+ branding
2435
2519
  });
2436
2520
  const compatContent = emitCompatTs({
2437
2521
  tables,
@@ -2440,7 +2524,7 @@ async function runCodegen(config) {
2440
2524
  typedJsonFields
2441
2525
  });
2442
2526
  const ormTypesContent = emitOrmTypesTs(tables);
2443
- const modelsContent = emitModelsTs(tables, typedJsonFields);
2527
+ const modelsContent = emitModelsTs(tables, typedJsonFields, branding);
2444
2528
  const inputContent = emitInputTs(tables);
2445
2529
  const enumsContent = emitEnumsTs(enumMap);
2446
2530
  const jsonContent = emitJsonTs(typeDefs, typedJsonFields);