@prisma-next/family-sql 0.13.0-dev.3 → 0.13.0-dev.30

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.
Files changed (53) hide show
  1. package/dist/authoring-type-constructors-CjFfO6LM.mjs +342 -0
  2. package/dist/authoring-type-constructors-CjFfO6LM.mjs.map +1 -0
  3. package/dist/{control-adapter-CgIL9Vtx.d.mts → control-adapter-Cmw9LvEP.d.mts} +16 -33
  4. package/dist/control-adapter-Cmw9LvEP.d.mts.map +1 -0
  5. package/dist/control-adapter.d.mts +2 -2
  6. package/dist/control.d.mts +36 -34
  7. package/dist/control.d.mts.map +1 -1
  8. package/dist/control.mjs +24 -77
  9. package/dist/control.mjs.map +1 -1
  10. package/dist/ir.d.mts +3 -2
  11. package/dist/ir.d.mts.map +1 -1
  12. package/dist/ir.mjs +1 -1
  13. package/dist/migration.d.mts +1 -1
  14. package/dist/migration.d.mts.map +1 -1
  15. package/dist/migration.mjs +2 -1
  16. package/dist/migration.mjs.map +1 -1
  17. package/dist/pack.d.mts +16 -3
  18. package/dist/pack.d.mts.map +1 -1
  19. package/dist/pack.mjs +4 -2
  20. package/dist/pack.mjs.map +1 -1
  21. package/dist/schema-verify.d.mts +1 -1
  22. package/dist/schema-verify.mjs +1 -1
  23. package/dist/{sql-contract-serializer-CY7qnms7.mjs → sql-contract-serializer-D6-28zKd.mjs} +26 -15
  24. package/dist/sql-contract-serializer-D6-28zKd.mjs.map +1 -0
  25. package/dist/{types-CbwQCzXY.d.mts → types-kgstZ_Zd.d.mts} +5 -5
  26. package/dist/types-kgstZ_Zd.d.mts.map +1 -0
  27. package/dist/{verify-sql-schema-DcMaT5Zj.d.mts → verify-sql-schema-thU-jKpf.d.mts} +2 -14
  28. package/dist/verify-sql-schema-thU-jKpf.d.mts.map +1 -0
  29. package/dist/{verify-sql-schema-DlAgBiT_.mjs → verify-sql-schema-xT4udQLQ.mjs} +25 -118
  30. package/dist/verify-sql-schema-xT4udQLQ.mjs.map +1 -0
  31. package/package.json +21 -21
  32. package/src/core/authoring-entity-types.ts +178 -0
  33. package/src/core/authoring-field-presets.ts +8 -3
  34. package/src/core/control-adapter.ts +18 -49
  35. package/src/core/control-descriptor.ts +3 -0
  36. package/src/core/control-instance.ts +13 -11
  37. package/src/core/ir/sql-contract-serializer-base.ts +76 -60
  38. package/src/core/migrations/contract-to-schema-ir.ts +47 -112
  39. package/src/core/migrations/types.ts +4 -1
  40. package/src/core/psl-contract-infer/postgres-type-map.ts +5 -13
  41. package/src/core/psl-contract-infer/sql-schema-ir-to-psl-ast.ts +17 -70
  42. package/src/core/schema-verify/verify-sql-schema.ts +10 -146
  43. package/src/core/sql-migration.ts +5 -1
  44. package/src/exports/control-adapter.ts +1 -0
  45. package/src/exports/control.ts +1 -1
  46. package/src/exports/pack.ts +3 -0
  47. package/dist/authoring-type-constructors-D4lQ-qpj.mjs +0 -192
  48. package/dist/authoring-type-constructors-D4lQ-qpj.mjs.map +0 -1
  49. package/dist/control-adapter-CgIL9Vtx.d.mts.map +0 -1
  50. package/dist/sql-contract-serializer-CY7qnms7.mjs.map +0 -1
  51. package/dist/types-CbwQCzXY.d.mts.map +0 -1
  52. package/dist/verify-sql-schema-DcMaT5Zj.d.mts.map +0 -1
  53. package/dist/verify-sql-schema-DlAgBiT_.mjs.map +0 -1
@@ -1,18 +1,14 @@
1
- import type { ColumnDefault, Contract } from '@prisma-next/contract/types';
1
+ import type { ColumnDefault, Contract, JsonValue } from '@prisma-next/contract/types';
2
2
  import type { MigrationPlannerConflict } from '@prisma-next/framework-components/control';
3
- import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
4
3
  import {
5
4
  type CheckConstraint,
6
5
  type ForeignKey,
7
6
  type Index,
8
- isPostgresEnumStorageEntry,
9
7
  isStorageTypeInstance,
10
- type PostgresEnumStorageEntry,
11
8
  type SqlStorage,
12
9
  type StorageColumn,
13
10
  StorageTable,
14
11
  type StorageTypeInstance,
15
- toStorageTypeInstance,
16
12
  type UniqueConstraint,
17
13
  } from '@prisma-next/sql-contract/types';
18
14
  import { defaultIndexName } from '@prisma-next/sql-schema-ir/naming';
@@ -26,7 +22,6 @@ import type {
26
22
  SqlTableIR,
27
23
  SqlUniqueIR,
28
24
  } from '@prisma-next/sql-schema-ir/types';
29
- import { blindCast } from '@prisma-next/utils/casts';
30
25
  import { ifDefined } from '@prisma-next/utils/defined';
31
26
 
32
27
  /**
@@ -57,24 +52,19 @@ export type NativeTypeExpander = (input: {
57
52
  export type DefaultRenderer = (def: ColumnDefault, column: StorageColumn) => string;
58
53
 
59
54
  /**
60
- * Target-supplied callback that computes the schema-qualified annotation-map
61
- * key for a namespace-scoped enum storage type.
55
+ * Target-supplied callback that resolves a contract namespace to the live
56
+ * database schema its enums are stored under.
62
57
  *
63
- * Enum lookups (`readExistingEnumValues`) are namespace/schema-qualified so two
64
- * namespaces holding an enum with the same TypeScript name (and even the same
65
- * native type) resolve to distinct live-database types. The *format* of that
66
- * key and the namespace DDL-schema resolution it depends on — is a
67
- * target-specific concern (Postgres schemas; SQLite/MySQL differ), so the
68
- * target injects it here as data rather than the family layer importing a
69
- * concrete `ddlSchemaName`/key implementation. This keeps the family layer
70
- * target-agnostic (no `@prisma-next/target-*` dependency) while the projection
71
- * still emits keys that match the target's read side exactly.
58
+ * The projected enum annotations are nested by schema
59
+ * (`storageTypes[schema][nativeType]`) so two namespaces holding an enum with
60
+ * the same native type resolve to distinct live-database types. Mapping a
61
+ * namespace to its DDL schema is target-specific (Postgres schemas;
62
+ * SQLite/MySQL differ), so the target injects it here rather than the family
63
+ * importing a concrete `ddlSchemaName`. This keeps the family layer
64
+ * target-agnostic while the projection nests under the same schema the
65
+ * target's read side (`readExistingEnumValues`) looks up.
72
66
  */
73
- export type EnumStorageKeyResolver = (
74
- storage: SqlStorage,
75
- namespaceId: string,
76
- nativeType: string,
77
- ) => string;
67
+ export type EnumNamespaceSchemaResolver = (storage: SqlStorage, namespaceId: string) => string;
78
68
 
79
69
  function convertColumn(
80
70
  name: string,
@@ -110,17 +100,7 @@ function convertColumn(
110
100
  };
111
101
  }
112
102
 
113
- /**
114
- * `storageTypes` is polymorphic per Decision 18 (Option B) — codec-typed
115
- * entries match `StorageTypeInstance`; enum entries match the structural
116
- * `PostgresEnumStorageEntry` shape (Postgres-only; cross-domain layering
117
- * keeps target IR classes out of the family layer). Both shapes resolve
118
- * into the same `(codecId, nativeType, typeParams)` triplet at the
119
- * column-resolution boundary so downstream walks stay uniform.
120
- */
121
- type ResolvedStorageTypes = Readonly<
122
- Record<string, StorageTypeInstance | PostgresEnumStorageEntry>
123
- >;
103
+ type ResolvedStorageTypes = Readonly<Record<string, StorageTypeInstance>>;
124
104
 
125
105
  function resolveColumnTypeMetadata(
126
106
  column: StorageColumn,
@@ -135,13 +115,6 @@ function resolveColumnTypeMetadata(
135
115
  `Column references storage type "${column.typeRef}" but it is not defined in storage.types.`,
136
116
  );
137
117
  }
138
- if (isPostgresEnumStorageEntry(referenced)) {
139
- return {
140
- codecId: referenced.codecId,
141
- nativeType: referenced.nativeType,
142
- typeParams: { values: referenced.values } as Record<string, unknown>,
143
- };
144
- }
145
118
  if (isStorageTypeInstance(referenced)) {
146
119
  return {
147
120
  codecId: referenced.codecId,
@@ -150,7 +123,7 @@ function resolveColumnTypeMetadata(
150
123
  };
151
124
  }
152
125
  throw new Error(
153
- `Storage type "${column.typeRef}" has an unknown polymorphic kind; expected codec-instance or postgres-enum.`,
126
+ `Storage type "${column.typeRef}" has an unknown polymorphic kind; expected a codec-typed StorageTypeInstance.`,
154
127
  );
155
128
  }
156
129
 
@@ -164,8 +137,12 @@ function resolveColumnTypeMetadata(
164
137
  * `checkConstraintPlanCallStrategy` (migration planning) so all three agree on
165
138
  * the resolved values and the error behavior on a missing reference.
166
139
  */
140
+ function allStrings(values: readonly JsonValue[]): values is readonly string[] {
141
+ return values.every((value) => typeof value === 'string');
142
+ }
143
+
167
144
  export function resolveValueSetValues(
168
- ref: { readonly namespaceId: string; readonly name: string },
145
+ ref: { readonly namespaceId: string; readonly entityName: string },
169
146
  storage: SqlStorage,
170
147
  contextLabel: string,
171
148
  ): readonly string[] {
@@ -175,13 +152,22 @@ export function resolveValueSetValues(
175
152
  `resolveValueSetValues: namespace "${ref.namespaceId}" not found in storage (${contextLabel})`,
176
153
  );
177
154
  }
178
- const valueSet = ns.entries.valueSet?.[ref.name];
155
+ const valueSet = ns.entries.valueSet?.[ref.entityName];
179
156
  if (!valueSet) {
180
157
  throw new Error(
181
- `resolveValueSetValues: value-set "${ref.name}" not found in namespace "${ref.namespaceId}" (${contextLabel})`,
158
+ `resolveValueSetValues: value-set "${ref.entityName}" not found in namespace "${ref.namespaceId}" (${contextLabel})`,
159
+ );
160
+ }
161
+ // Only TEXT enums ship a CHECK-constraint round-trip in this slice. A
162
+ // non-string value-set is a numeric enum, whose CHECK rendering/verification
163
+ // is future work; fail loudly rather than emit a wrong numeric-as-text check.
164
+ const values = valueSet.values;
165
+ if (!allStrings(values)) {
166
+ throw new Error(
167
+ `resolveValueSetValues: value-set "${ref.entityName}" in namespace "${ref.namespaceId}" has a non-string value; numeric-enum CHECK constraints are not yet supported (${contextLabel})`,
182
168
  );
183
169
  }
184
- return valueSet.values;
170
+ return values;
185
171
  }
186
172
 
187
173
  /**
@@ -316,7 +302,7 @@ export function detectDestructiveChanges(
316
302
  if (!fromTables) continue;
317
303
 
318
304
  for (const tableName of Object.keys(fromTables)) {
319
- const toTableRaw = toNs?.entries.table[tableName];
305
+ const toTableRaw = toNs?.entries.table?.[tableName];
320
306
  if (!(toTableRaw instanceof StorageTable)) {
321
307
  conflicts.push({
322
308
  kind: 'tableRemoved',
@@ -349,13 +335,13 @@ export interface ContractToSchemaIROptions {
349
335
  readonly expandNativeType?: NativeTypeExpander;
350
336
  readonly renderDefault?: DefaultRenderer;
351
337
  /**
352
- * Target-supplied resolver for namespace/schema-qualified enum annotation
353
- * keys. When provided (Postgres), every namespace-scoped enum is keyed by the
354
- * resolver's output so the projected `storageTypes` map matches the target's
355
- * `readExistingEnumValues` lookup. Targets without namespace-qualified enum
356
- * storage (SQLite) omit it; enums are absent there.
338
+ * Target-supplied resolver mapping a namespace to the live database schema
339
+ * its enums are stored under. When provided (Postgres), namespace-scoped
340
+ * enums are nested by that schema in `enumTypes` so the projection matches
341
+ * the target's `readExistingEnumValues` lookup. Targets without
342
+ * schema-scoped enum storage (SQLite) omit it; enums are absent there.
357
343
  */
358
- readonly resolveEnumStorageKey?: EnumStorageKeyResolver;
344
+ readonly resolveEnumNamespaceSchema?: EnumNamespaceSchemaResolver;
359
345
  }
360
346
 
361
347
  /**
@@ -385,24 +371,12 @@ export function contractToSchemaIR(
385
371
  }
386
372
 
387
373
  const storage = contract.storage;
388
- const allTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = {
374
+ const storageTypes: ResolvedStorageTypes = {
389
375
  ...((storage.types ?? {}) as ResolvedStorageTypes),
390
376
  };
391
- for (const ns of Object.values(storage.namespaces)) {
392
- const nsEnums = ns.entries['type'];
393
- if (nsEnums) {
394
- for (const [k, v] of Object.entries(nsEnums)) {
395
- allTypes[k] = blindCast<
396
- PostgresEnumStorageEntry | StorageTypeInstance,
397
- 'entries.type holds postgres-specific enum entries at runtime'
398
- >(v);
399
- }
400
- }
401
- }
402
- const storageTypes = allTypes as ResolvedStorageTypes;
403
377
  const tables: Record<string, SqlTableIR> = {};
404
378
  for (const ns of Object.values(storage.namespaces)) {
405
- for (const [tableName, tableDefRaw] of Object.entries(ns.entries.table)) {
379
+ for (const [tableName, tableDefRaw] of Object.entries(ns.entries.table ?? {})) {
406
380
  if (!(tableDefRaw instanceof StorageTable)) {
407
381
  throw new Error(
408
382
  `contractToSchemaIR: expected StorageTable at namespaces.${ns.id}.entries.table.${tableName}`,
@@ -428,7 +402,7 @@ export function contractToSchemaIR(
428
402
  const annotations = deriveAnnotations(
429
403
  storage,
430
404
  options.annotationNamespace,
431
- options.resolveEnumStorageKey,
405
+ options.resolveEnumNamespaceSchema,
432
406
  );
433
407
 
434
408
  return {
@@ -437,61 +411,22 @@ export function contractToSchemaIR(
437
411
  };
438
412
  }
439
413
 
440
- /**
441
- * Normalises a native enum storage entry to the codec-typed annotation shape
442
- * `{codecId, nativeType, typeParams}` the introspector writes and
443
- * `readExistingEnumValues` reads (`existing.codecId` + `existing.typeParams.values`).
444
- * Without this the projector would emit the raw `PostgresEnumStorageEntry`
445
- * shape (top-level `values`, no `typeParams`) and the enum would read as new.
446
- */
447
- function normalizeEnumAnnotation(entry: PostgresEnumStorageEntry): StorageTypeInstance {
448
- return toStorageTypeInstance({
449
- codecId: entry.codecId,
450
- nativeType: entry.nativeType,
451
- typeParams: { values: entry.values },
452
- });
453
- }
454
-
455
414
  function deriveAnnotations(
456
415
  storage: SqlStorage,
457
416
  annotationNamespace: string,
458
- resolveEnumStorageKey: EnumStorageKeyResolver | undefined,
417
+ _resolveEnumNamespaceSchema: EnumNamespaceSchemaResolver | undefined,
459
418
  ): SqlAnnotations | undefined {
460
419
  const storageTypes: Record<string, StorageTypeInstance> = {};
461
420
 
462
- // Top-level `storage.types`: codec-typed entries (vector, decimal, …) keyed
463
- // by bare `nativeType` (unchanged). Post-S1.B enums live in
464
- // `namespaces[*].entries.type`, not here; a defensive top-level enum is still
465
- // namespace/schema-qualified via the resolver under the unbound coordinate
466
- // so it never collides on a bare name.
467
421
  for (const typeInstance of Object.values((storage.types ?? {}) as ResolvedStorageTypes)) {
468
- if (isPostgresEnumStorageEntry(typeInstance)) {
469
- const key = resolveEnumStorageKey
470
- ? resolveEnumStorageKey(storage, UNBOUND_NAMESPACE_ID, typeInstance.nativeType)
471
- : typeInstance.nativeType;
472
- storageTypes[key] = normalizeEnumAnnotation(typeInstance);
473
- continue;
474
- }
475
422
  if (isStorageTypeInstance(typeInstance)) {
476
423
  storageTypes[typeInstance.nativeType] = typeInstance;
477
424
  }
478
425
  }
479
426
 
480
- // Namespace-scoped enums: schema-qualified compound key matching the target's
481
- // `readExistingEnumValues` read side, so two namespaces sharing an enum name
482
- // (or native type) resolve to distinct live-database types.
483
- for (const [namespaceId, ns] of Object.entries(storage.namespaces)) {
484
- const nsEnums = ns.entries['type'];
485
- if (!nsEnums) continue;
486
- for (const entry of Object.values(nsEnums)) {
487
- if (!isPostgresEnumStorageEntry(entry)) continue;
488
- const key = resolveEnumStorageKey
489
- ? resolveEnumStorageKey(storage, namespaceId, entry.nativeType)
490
- : entry.nativeType;
491
- storageTypes[key] = normalizeEnumAnnotation(entry);
492
- }
493
- }
494
-
495
- if (Object.keys(storageTypes).length === 0) return undefined;
496
- return { [annotationNamespace]: { storageTypes } };
427
+ const envelope = {
428
+ ...(Object.keys(storageTypes).length > 0 ? { storageTypes } : {}),
429
+ };
430
+ if (Object.keys(envelope).length === 0) return undefined;
431
+ return { [annotationNamespace]: envelope };
497
432
  }
@@ -251,7 +251,10 @@ export interface SqlMigrationPlan<TTargetDetails> extends MigrationPlan {
251
251
  * Destination contract identity that the plan intends to reach.
252
252
  */
253
253
  readonly destination: SqlMigrationPlanContractInfo;
254
- readonly operations: readonly SqlMigrationPlanOperation<TTargetDetails>[];
254
+ readonly operations: readonly (
255
+ | SqlMigrationPlanOperation<TTargetDetails>
256
+ | Promise<SqlMigrationPlanOperation<TTargetDetails>>
257
+ )[];
255
258
  /**
256
259
  * Sorted, deduplicated invariant ids declared by this plan's data-transform
257
260
  * ops. Required at the SQL-family layer (the SQL runners consume this as
@@ -63,8 +63,6 @@ const PARAMETERIZED_NATIVE_TYPES: Record<
63
63
 
64
64
  const PARAMETERIZED_TYPE_PATTERN = /^(.+?)\((.+)\)$/;
65
65
 
66
- const ENUM_CODEC_ID = 'pg/enum@1';
67
-
68
66
  function getOwnMappingValue(map: Record<string, string>, key: string): string | undefined {
69
67
  return Object.hasOwn(map, key) ? map[key] : undefined;
70
68
  }
@@ -132,21 +130,15 @@ export function createPostgresTypeMap(enumTypeNames?: ReadonlySet<string>): PslT
132
130
 
133
131
  export function extractEnumInfo(annotations?: Record<string, unknown>): EnumInfo {
134
132
  const pgAnnotations = annotations?.['pg'] as Record<string, unknown> | undefined;
135
- const storageTypes = pgAnnotations?.['storageTypes'] as
136
- | Record<string, { codecId: string; nativeType: string; typeParams?: Record<string, unknown> }>
137
- | undefined;
133
+ const nativeEnumTypeNames = pgAnnotations?.['nativeEnumTypeNames'];
138
134
 
139
135
  const typeNames = new Set<string>();
140
136
  const definitions = new Map<string, readonly string[]>();
141
137
 
142
- if (storageTypes) {
143
- for (const [key, typeInstance] of Object.entries(storageTypes)) {
144
- if (typeInstance.codecId === ENUM_CODEC_ID) {
145
- typeNames.add(key);
146
- const values = typeInstance.typeParams?.['values'];
147
- if (Array.isArray(values)) {
148
- definitions.set(key, values as string[]);
149
- }
138
+ if (Array.isArray(nativeEnumTypeNames)) {
139
+ for (const name of nativeEnumTypeNames) {
140
+ if (typeof name === 'string') {
141
+ typeNames.add(name);
150
142
  }
151
143
  }
152
144
  }
@@ -3,7 +3,6 @@ import type {
3
3
  PslAttribute,
4
4
  PslAttributeArgument,
5
5
  PslDocumentAst,
6
- PslEnum,
7
6
  PslField,
8
7
  PslFieldAttribute,
9
8
  PslModel,
@@ -20,11 +19,10 @@ import {
20
19
  import type { SqlColumnIR, SqlSchemaIR, SqlTableIR } from '@prisma-next/sql-schema-ir/types';
21
20
  import type { DefaultMappingOptions } from './default-mapping';
22
21
  import { mapDefault } from './default-mapping';
23
- import { toEnumName, toFieldName, toModelName, toNamedTypeName } from './name-transforms';
22
+ import { toFieldName, toModelName, toNamedTypeName } from './name-transforms';
24
23
  import { createPostgresDefaultMapping } from './postgres-default-mapping';
25
24
  import { createPostgresTypeMap, extractEnumInfo } from './postgres-type-map';
26
25
  import type {
27
- EnumInfo,
28
26
  PslNativeTypeAttribute,
29
27
  PslPrinterOptions,
30
28
  PslTypeMap,
@@ -82,10 +80,19 @@ type TopLevelNameResult = {
82
80
  */
83
81
  export function sqlSchemaIrToPslAst(schemaIR: SqlSchemaIR): PslDocumentAst {
84
82
  const enumInfo = extractEnumInfo(schemaIR.annotations);
83
+ if (enumInfo.typeNames.size > 0) {
84
+ const names = [...enumInfo.typeNames].join(', ');
85
+ throw new Error(
86
+ `contract infer: the database contains native Postgres enum type(s): ${names}. ` +
87
+ 'Native Postgres enums (CREATE TYPE … AS ENUM) are not adoptable by contract infer. ' +
88
+ 'Drop the native type and replace each column with a text column carrying a CHECK constraint, ' +
89
+ `then re-run contract infer. The domain enum (enum Name { @@type("pg/text@1") … }) authoring ` +
90
+ 'surface generates the required check automatically.',
91
+ );
92
+ }
85
93
  const options: PslPrinterOptions = {
86
- typeMap: createPostgresTypeMap(enumInfo.typeNames),
94
+ typeMap: createPostgresTypeMap(new Set()),
87
95
  defaultMapping: createPostgresDefaultMapping(),
88
- enumInfo,
89
96
  parseRawDefault,
90
97
  };
91
98
 
@@ -93,12 +100,7 @@ export function sqlSchemaIrToPslAst(schemaIR: SqlSchemaIR): PslDocumentAst {
93
100
  }
94
101
 
95
102
  function buildPslDocumentAst(schemaIR: SqlSchemaIR, options: PslPrinterOptions): PslDocumentAst {
96
- const { typeMap, defaultMapping, enumInfo, parseRawDefault: rawDefaultParser } = options;
97
- const emptyEnumInfo: EnumInfo = {
98
- typeNames: new Set<string>(),
99
- definitions: new Map<string, readonly string[]>(),
100
- };
101
- const { typeNames: enumTypeNames, definitions: enumDefinitions } = enumInfo ?? emptyEnumInfo;
103
+ const { typeMap, defaultMapping, parseRawDefault: rawDefaultParser } = options;
102
104
 
103
105
  const modelNames = buildTopLevelNameMap(
104
106
  Object.keys(schemaIR.tables),
@@ -106,20 +108,15 @@ function buildPslDocumentAst(schemaIR: SqlSchemaIR, options: PslPrinterOptions):
106
108
  'model',
107
109
  'table',
108
110
  );
109
- const enumNames = buildTopLevelNameMap(enumTypeNames, toEnumName, 'enum', 'enum type');
110
- assertNoCrossKindNameCollisions(modelNames, enumNames);
111
111
 
112
112
  const modelNameMap = new Map(
113
113
  [...modelNames].map(([tableName, result]) => [tableName, result.name]),
114
114
  );
115
- const enumNameMap = new Map(
116
- [...enumNames].map(([pgTypeName, result]) => [pgTypeName, result.name]),
117
- );
118
- const reservedNamedTypeNames = createReservedNamedTypeNames(modelNames, enumNames);
115
+ const reservedNamedTypeNames = createReservedNamedTypeNames(modelNames);
119
116
 
120
117
  const fieldNamesByTable = buildFieldNamesByTable(schemaIR.tables);
121
118
  const { relationsByTable } = inferRelations(schemaIR.tables, modelNameMap);
122
- const namedTypes = seedNamedTypeRegistry(schemaIR, typeMap, enumNameMap, reservedNamedTypeNames);
119
+ const namedTypes = seedNamedTypeRegistry(schemaIR, typeMap, new Map(), reservedNamedTypeNames);
123
120
 
124
121
  const models: PslModel[] = [];
125
122
  for (const table of Object.values(schemaIR.tables)) {
@@ -127,7 +124,7 @@ function buildPslDocumentAst(schemaIR: SqlSchemaIR, options: PslPrinterOptions):
127
124
  buildModel(
128
125
  table,
129
126
  typeMap,
130
- enumNameMap,
127
+ new Map(),
131
128
  fieldNamesByTable,
132
129
  namedTypes,
133
130
  defaultMapping,
@@ -139,13 +136,6 @@ function buildPslDocumentAst(schemaIR: SqlSchemaIR, options: PslPrinterOptions):
139
136
 
140
137
  const sortedModels = topologicalSort(models, schemaIR.tables, modelNameMap);
141
138
 
142
- const enums: PslEnum[] = [];
143
- for (const [pgTypeName, values] of enumDefinitions) {
144
- const enumName = enumNames.get(pgTypeName) as TopLevelNameResult;
145
- enums.push(buildEnum(enumName, values));
146
- }
147
- enums.sort((a, b) => a.name.localeCompare(b.name));
148
-
149
139
  const namedTypeEntries = [...namedTypes.entriesByKey.values()].sort((a, b) =>
150
140
  a.name.localeCompare(b.name),
151
141
  );
@@ -171,7 +161,7 @@ function buildPslDocumentAst(schemaIR: SqlSchemaIR, options: PslPrinterOptions):
171
161
  makePslNamespace({
172
162
  kind: 'namespace',
173
163
  name: UNSPECIFIED_PSL_NAMESPACE_ID,
174
- entries: makePslNamespaceEntries(sortedModels, enums, [], []),
164
+ entries: makePslNamespaceEntries(sortedModels, [], []),
175
165
  span: SYNTHETIC_SPAN,
176
166
  }),
177
167
  ],
@@ -485,24 +475,6 @@ function namedArg(name: string, value: string): PslAttributeArgument {
485
475
  return { kind: 'named', name, value, span: SYNTHETIC_SPAN };
486
476
  }
487
477
 
488
- function buildEnum(name: TopLevelNameResult, values: readonly string[]): PslEnum {
489
- const attrs: PslAttribute[] = [];
490
- if (name.map) {
491
- attrs.push(buildMapAttribute('enum', name.map));
492
- }
493
- return {
494
- kind: 'enum',
495
- name: name.name,
496
- values: values.map((value) => ({
497
- kind: 'enumValue',
498
- name: value,
499
- span: SYNTHETIC_SPAN,
500
- })),
501
- attributes: attrs,
502
- span: SYNTHETIC_SPAN,
503
- };
504
- }
505
-
506
478
  function buildNamedTypeDeclaration(entry: NamedTypeRegistryEntry): PslNamedTypeDeclaration {
507
479
  const attribute = buildAttribute(
508
480
  'namedType',
@@ -647,29 +619,8 @@ function buildTopLevelNameMap(
647
619
  return results;
648
620
  }
649
621
 
650
- function assertNoCrossKindNameCollisions(
651
- modelNames: ReadonlyMap<string, TopLevelNameResult>,
652
- enumNames: ReadonlyMap<string, TopLevelNameResult>,
653
- ): void {
654
- const enumSourceByName = new Map([...enumNames].map(([source, result]) => [result.name, source]));
655
-
656
- const collisions = [...modelNames.entries()]
657
- .map(([tableName, result]) => {
658
- const enumSource = enumSourceByName.get(result.name);
659
- return enumSource
660
- ? `- identifier "${result.name}" from table "${tableName}" collides with enum type "${enumSource}"`
661
- : undefined;
662
- })
663
- .filter((detail): detail is string => detail !== undefined);
664
-
665
- if (collisions.length > 0) {
666
- throw new Error(`PSL top-level name collisions detected:\n${collisions.join('\n')}`);
667
- }
668
- }
669
-
670
622
  function createReservedNamedTypeNames(
671
623
  modelNames: ReadonlyMap<string, TopLevelNameResult>,
672
- enumNames: ReadonlyMap<string, TopLevelNameResult>,
673
624
  ): Set<string> {
674
625
  const reservedNames = new Set<string>(PSL_SCALAR_TYPE_NAMES);
675
626
 
@@ -677,10 +628,6 @@ function createReservedNamedTypeNames(
677
628
  reservedNames.add(result.name);
678
629
  }
679
630
 
680
- for (const result of enumNames.values()) {
681
- reservedNames.add(result.name);
682
- }
683
-
684
631
  return reservedNames;
685
632
  }
686
633