@vibeorm/schema 2.4.0 → 2.5.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/index.js CHANGED
@@ -1,85 +1,4 @@
1
1
  // @bun
2
- // packages/schema/src/ir.ts
3
- var DIALECTS = ["postgres", "sqlite", "mysql"];
4
- function providerToDialect(params) {
5
- const { provider } = params;
6
- switch (provider) {
7
- case "postgresql":
8
- case "pglite":
9
- return "postgres";
10
- case "sqlite":
11
- return "sqlite";
12
- case "mysql":
13
- return "mysql";
14
- }
15
- }
16
- function isEnumType(fieldType) {
17
- return typeof fieldType === "object" && "enum" in fieldType;
18
- }
19
- function fieldTypeIdentity(params) {
20
- const { type } = params;
21
- return isEnumType(type) ? `enum:${type.enum}` : type;
22
- }
23
- var ENUM_STORAGES = ["database", "string"];
24
- function enumStorageOf(params) {
25
- return params.enumDef.storage ?? "database";
26
- }
27
- // packages/schema/src/predicate.ts
28
- var PREDICATE_COMPARISON_OPS = [
29
- "eq",
30
- "ne",
31
- "gt",
32
- "gte",
33
- "lt",
34
- "lte"
35
- ];
36
- function isPredicateFieldRef(operand) {
37
- return operand.kind === "field";
38
- }
39
- function predicateFieldNames(params) {
40
- const seen = new Set;
41
- const walk = (node) => {
42
- switch (node.kind) {
43
- case "compare":
44
- seen.add(node.left.name);
45
- if (isPredicateFieldRef(node.right))
46
- seen.add(node.right.name);
47
- return;
48
- case "inList":
49
- case "isNull":
50
- seen.add(node.field.name);
51
- return;
52
- case "and":
53
- case "or":
54
- for (const operand of node.operands)
55
- walk(operand);
56
- return;
57
- case "not":
58
- walk(node.operand);
59
- return;
60
- }
61
- };
62
- walk(params.predicate);
63
- return [...seen];
64
- }
65
- function predicateKey(params) {
66
- const encode = (node) => {
67
- switch (node.kind) {
68
- case "compare":
69
- return `cmp(${node.op},${node.left.name},${isPredicateFieldRef(node.right) ? `f:${node.right.name}` : `v:${typeof node.right.value}:${String(node.right.value)}`})`;
70
- case "inList":
71
- return `in${node.negate === true ? "!" : ""}(${node.field.name},[${node.values.map((entry) => `${typeof entry.value}:${String(entry.value)}`).join("|")}])`;
72
- case "isNull":
73
- return `null${node.negate === true ? "!" : ""}(${node.field.name})`;
74
- case "and":
75
- case "or":
76
- return `${node.kind}(${node.operands.map(encode).join(",")})`;
77
- case "not":
78
- return `not(${encode(node.operand)})`;
79
- }
80
- };
81
- return encode(params.predicate);
82
- }
83
2
  // packages/schema/src/errors.ts
84
3
  var VIBE_ERROR_CODES = [
85
4
  "VIBE_NOT_FOUND",
@@ -223,10 +142,203 @@ class ReadOnlyClientError extends VibeError {
223
142
  }
224
143
  }
225
144
 
145
+ // packages/schema/src/physical-names.ts
146
+ var IDENTIFIER_LIMITS = Object.freeze({
147
+ postgres: { max: 63, unit: "bytes" },
148
+ mysql: { max: 64, unit: "characters" },
149
+ sqlite: undefined
150
+ });
151
+ var ENCODER = new TextEncoder;
152
+ function identifierLength(params) {
153
+ const limit = IDENTIFIER_LIMITS[params.dialect];
154
+ return limit?.unit === "bytes" ? ENCODER.encode(params.name).length : [...params.name].length;
155
+ }
156
+ function cutIdentifier(params) {
157
+ let out = "";
158
+ let used = 0;
159
+ for (const char of params.name) {
160
+ const size = params.unit === "bytes" ? ENCODER.encode(char).length : 1;
161
+ if (used + size > params.length)
162
+ break;
163
+ out += char;
164
+ used += size;
165
+ }
166
+ return out;
167
+ }
168
+ function fitDefaultName(params) {
169
+ const limit = IDENTIFIER_LIMITS[params.dialect];
170
+ if (limit === undefined)
171
+ return `${params.prefix}${params.suffix}`;
172
+ const room = limit.max - identifierLength({ name: params.suffix, dialect: params.dialect });
173
+ if (identifierLength({ name: params.prefix, dialect: params.dialect }) <= room)
174
+ return `${params.prefix}${params.suffix}`;
175
+ return `${cutIdentifier({ name: params.prefix, length: room, unit: limit.unit })}${params.suffix}`;
176
+ }
177
+ function assertIdentifierFits(params) {
178
+ const limit = IDENTIFIER_LIMITS[params.dialect];
179
+ if (limit === undefined)
180
+ return;
181
+ const length = identifierLength({ name: params.name, dialect: params.dialect });
182
+ if (length <= limit.max)
183
+ return;
184
+ throw new VibeError({
185
+ code: "VIBE_SCHEMA_INVALID",
186
+ message: `${params.what} "${params.name}" is ${length} ${limit.unit} \u2014 ${params.dialect} keeps at most ${limit.max}; the created object would never carry this name and migrations could not converge. ${params.remedy}`,
187
+ meta: { name: params.name, dialect: params.dialect, length, max: limit.max }
188
+ });
189
+ }
190
+ function defaultIndexName(params) {
191
+ return fitDefaultName({
192
+ prefix: `${params.table}_${params.columns.join("_")}`,
193
+ suffix: params.unique ? "_key" : "_idx",
194
+ dialect: params.dialect
195
+ });
196
+ }
197
+ function defaultForeignKeyName(params) {
198
+ return fitDefaultName({ prefix: `${params.table}_${params.columns.join("_")}`, suffix: "_fkey", dialect: params.dialect });
199
+ }
200
+ function defaultPrimaryKeyName(params) {
201
+ return fitDefaultName({ prefix: params.table, suffix: "_pkey", dialect: params.dialect });
202
+ }
203
+ function implicitJoinTableObjectNames(params) {
204
+ return {
205
+ uniqueIndex: `${params.table}_AB_unique`,
206
+ indexB: `${params.table}_B_index`,
207
+ foreignKeyA: `${params.table}_A_fkey`,
208
+ foreignKeyB: `${params.table}_B_fkey`
209
+ };
210
+ }
211
+ function postgresGeneratedObjectName(params) {
212
+ const limit = IDENTIFIER_LIMITS.postgres;
213
+ const overhead = params.label.length + 2;
214
+ let chars1 = [...params.name1];
215
+ let chars2 = [...params.name2];
216
+ const bytes = (chars) => ENCODER.encode(chars.join("")).length;
217
+ while (bytes(chars1) + bytes(chars2) + overhead > limit.max) {
218
+ if (bytes(chars1) > bytes(chars2))
219
+ chars1 = chars1.slice(0, -1);
220
+ else
221
+ chars2 = chars2.slice(0, -1);
222
+ }
223
+ return `${chars1.join("")}_${chars2.join("")}_${params.label}`;
224
+ }
225
+
226
+ // packages/schema/src/namespaces.ts
227
+ var SQL_NAMESPACES = Object.freeze({
228
+ postgres: "public",
229
+ sqlite: "main",
230
+ private: Object.freeze(["_vibeorm_shadow", "_vibe_shadow"])
231
+ });
232
+ function sqlNamespaceIssue(params) {
233
+ const { namespace } = params;
234
+ if (typeof namespace !== "string" || namespace.trim().length === 0 || namespace.includes("\x00"))
235
+ return "Namespace must be a non-empty identifier without NUL bytes";
236
+ if (identifierLength({ name: namespace, dialect: "postgres" }) > IDENTIFIER_LIMITS.postgres.max)
237
+ return "PostgreSQL namespace exceeds its identifier byte limit";
238
+ if (namespace === "information_schema" || namespace.startsWith("pg_") || SQL_NAMESPACES.private.includes(namespace))
239
+ return "System and private VibeORM namespaces cannot be declared";
240
+ if (params.allowPublic === false && namespace === SQL_NAMESPACES.postgres)
241
+ return "A fixed package namespace must be non-public; omit namespace for a legacy public artifact";
242
+ return;
243
+ }
244
+ function assertSqlNamespace(params) {
245
+ if (params.dialect !== "postgres")
246
+ throw unsupportedCapability({ dialect: params.dialect, feature: "fixedNamespaces" });
247
+ const issue = sqlNamespaceIssue(params);
248
+ if (issue !== undefined)
249
+ throw new VibeError({ code: "VIBE_SCHEMA_INVALID", message: issue, meta: { rule: "namespace", namespace: params.namespace } });
250
+ }
251
+ function qualifiedSqlName(params) {
252
+ return { namespace: params.namespace ?? params.defaultNamespace ?? SQL_NAMESPACES.postgres, name: params.name };
253
+ }
254
+ // packages/schema/src/capabilities.ts
255
+ var POSTGRES_CAPABILITIES = Object.freeze({
256
+ fixedNamespaces: true,
257
+ externalObjects: true,
258
+ indexOperatorClasses: true,
259
+ exclusionConstraints: true,
260
+ exclusionExtensions: Object.freeze(["btree_gist"]),
261
+ checkNormalization: "rollback",
262
+ nativeRowLevelSecurity: true,
263
+ returning: true,
264
+ scalarArrays: true,
265
+ nativeEnums: true,
266
+ ilike: true,
267
+ lateralJoin: true,
268
+ distinctOn: true,
269
+ partialIndexes: true,
270
+ conflictTargetConstraint: true,
271
+ transactionalDdl: true,
272
+ createManyAndReturn: true,
273
+ jsonColumnType: true,
274
+ orderByNulls: true,
275
+ fullTextEngines: Object.freeze(["bm25", "tsvector"]),
276
+ rowLockStrengths: Object.freeze(["update", "noKeyUpdate", "share", "keyShare"]),
277
+ rowLockWaitPolicies: Object.freeze(["wait", "nowait", "skipLocked"]),
278
+ advisoryLocks: true
279
+ });
280
+ var SQLITE_CAPABILITIES = Object.freeze({
281
+ fixedNamespaces: false,
282
+ externalObjects: false,
283
+ indexOperatorClasses: false,
284
+ exclusionConstraints: false,
285
+ exclusionExtensions: Object.freeze([]),
286
+ checkNormalization: "sourceText",
287
+ nativeRowLevelSecurity: false,
288
+ returning: true,
289
+ scalarArrays: false,
290
+ nativeEnums: false,
291
+ ilike: false,
292
+ lateralJoin: false,
293
+ distinctOn: false,
294
+ partialIndexes: true,
295
+ conflictTargetConstraint: false,
296
+ transactionalDdl: true,
297
+ createManyAndReturn: true,
298
+ jsonColumnType: false,
299
+ orderByNulls: true,
300
+ fullTextEngines: Object.freeze(["fts5"]),
301
+ rowLockStrengths: Object.freeze([]),
302
+ rowLockWaitPolicies: Object.freeze([]),
303
+ advisoryLocks: false
304
+ });
305
+ var MYSQL_CAPABILITIES = Object.freeze({
306
+ fixedNamespaces: false,
307
+ externalObjects: false,
308
+ indexOperatorClasses: false,
309
+ exclusionConstraints: false,
310
+ exclusionExtensions: Object.freeze([]),
311
+ checkNormalization: "temporary",
312
+ nativeRowLevelSecurity: false,
313
+ returning: false,
314
+ scalarArrays: false,
315
+ nativeEnums: true,
316
+ ilike: false,
317
+ lateralJoin: false,
318
+ distinctOn: false,
319
+ partialIndexes: false,
320
+ conflictTargetConstraint: false,
321
+ transactionalDdl: false,
322
+ createManyAndReturn: false,
323
+ jsonColumnType: true,
324
+ orderByNulls: false,
325
+ fullTextEngines: Object.freeze(["fulltext"]),
326
+ rowLockStrengths: Object.freeze(["update", "share"]),
327
+ rowLockWaitPolicies: Object.freeze(["wait", "nowait", "skipLocked"]),
328
+ advisoryLocks: false
329
+ });
330
+ var DIALECT_CAPABILITIES = Object.freeze({
331
+ postgres: POSTGRES_CAPABILITIES,
332
+ sqlite: SQLITE_CAPABILITIES,
333
+ mysql: MYSQL_CAPABILITIES
334
+ });
335
+
226
336
  // packages/schema/src/migration-objects.ts
227
337
  function sqlObjectKey(params) {
228
338
  const object = params.identity;
229
339
  switch (object.kind) {
340
+ case "namespace":
341
+ return JSON.stringify([object.kind, object.name]);
230
342
  case "table":
231
343
  case "view":
232
344
  case "sequence":
@@ -246,6 +358,12 @@ function sqlObjectKey(params) {
246
358
  return JSON.stringify([object.kind, object.table.namespace, object.table.name, object.column]);
247
359
  }
248
360
  }
361
+ function sqlObjectNamespace(params) {
362
+ const identity = params.identity;
363
+ if (identity.kind === "namespace")
364
+ return identity.name;
365
+ return "table" in identity ? identity.table.namespace : identity.name.namespace;
366
+ }
249
367
  function record(value) {
250
368
  return value !== null && typeof value === "object" && !Array.isArray(value);
251
369
  }
@@ -256,6 +374,8 @@ function isSqlObjectIdentity(value) {
256
374
  if (!record(value))
257
375
  return false;
258
376
  switch (value.kind) {
377
+ case "namespace":
378
+ return typeof value.name === "string" && value.name.length > 0;
259
379
  case "table":
260
380
  case "view":
261
381
  case "sequence":
@@ -277,24 +397,257 @@ function isSqlObjectIdentity(value) {
277
397
  return false;
278
398
  }
279
399
  }
280
- function isSqlObjectDefinition(value) {
281
- return record(value) && (value.format === "catalog-v1" || value.format === "catalog-v2") && isSqlObjectIdentity(value.identity) && record(value.facts) && Object.keys(value.facts).length > 0 && Object.values(value.facts).every((fact) => fact === null || typeof fact === "string" || typeof fact === "boolean" || typeof fact === "number" && Number.isFinite(fact) || Array.isArray(fact) && fact.every((entry) => typeof entry === "string")) && Array.isArray(value.dependencies) && value.dependencies.every(isSqlObjectIdentity);
400
+ function isSqlObjectDefinition(value) {
401
+ return record(value) && (value.format === "catalog-v1" || value.format === "catalog-v2") && isSqlObjectIdentity(value.identity) && record(value.facts) && Object.keys(value.facts).length > 0 && Object.values(value.facts).every((fact) => fact === null || typeof fact === "string" || typeof fact === "boolean" || typeof fact === "number" && Number.isFinite(fact) || Array.isArray(fact) && fact.every((entry) => typeof entry === "string")) && Array.isArray(value.dependencies) && value.dependencies.every(isSqlObjectIdentity);
402
+ }
403
+ function qualifiedNameIssue(params) {
404
+ if (!record(params.value))
405
+ return { path: params.path, expected: "qualified SQL name { namespace, name }" };
406
+ const member = typeof params.value.namespace !== "string" || params.value.namespace.length === 0 ? "namespace" : "name";
407
+ return { path: `${params.path}.${member}`, expected: "non-empty string" };
408
+ }
409
+ function identityIssue(params) {
410
+ const { value, path } = params;
411
+ if (!record(value))
412
+ return { path, expected: "SQL object identity" };
413
+ switch (value.kind) {
414
+ case "namespace":
415
+ return { path: `${path}.name`, expected: "non-empty namespace string" };
416
+ case "table":
417
+ case "view":
418
+ case "sequence":
419
+ case "postgresExtension":
420
+ case "enum":
421
+ return qualifiedNameIssue({ value: value.name, path: `${path}.name` });
422
+ case "function": {
423
+ if (!name(value.name))
424
+ return qualifiedNameIssue({ value: value.name, path: `${path}.name` });
425
+ if (!Array.isArray(value.argumentTypes))
426
+ return { path: `${path}.argumentTypes`, expected: "array of qualified SQL type names" };
427
+ const index = value.argumentTypes.findIndex((entry) => !name(entry));
428
+ return qualifiedNameIssue({ value: value.argumentTypes[index], path: `${path}.argumentTypes[${index}]` });
429
+ }
430
+ case "index":
431
+ case "trigger":
432
+ case "constraint":
433
+ case "column":
434
+ case "columnDefault":
435
+ case "generatedColumn": {
436
+ if (!name(value.table))
437
+ return qualifiedNameIssue({ value: value.table, path: `${path}.table` });
438
+ if (value.kind === "column" || value.kind === "columnDefault" || value.kind === "generatedColumn")
439
+ return { path: `${path}.column`, expected: "non-empty column name" };
440
+ if (typeof value.name !== "string" || value.name.length === 0)
441
+ return { path: `${path}.name`, expected: "non-empty object name" };
442
+ return { path: `${path}.constraintType`, expected: ["check", "foreignKey", "exclusion", "unique", "primaryKey"] };
443
+ }
444
+ default:
445
+ return { path: `${path}.kind`, expected: ["namespace", "table", "view", "sequence", "postgresExtension", "enum", "function", "index", "trigger", "constraint", "column", "columnDefault", "generatedColumn"] };
446
+ }
447
+ }
448
+ function definitionIssue(params) {
449
+ const { value, path } = params;
450
+ if (!record(value))
451
+ return { path, expected: "independent SQL object definition" };
452
+ if (value.format !== "catalog-v1" && value.format !== "catalog-v2")
453
+ return { path: `${path}.format`, expected: ["catalog-v1", "catalog-v2"] };
454
+ if (!isSqlObjectIdentity(value.identity))
455
+ return identityIssue({ value: value.identity, path: `${path}.identity` });
456
+ if (!record(value.facts) || Object.keys(value.facts).length === 0)
457
+ return { path: `${path}.facts`, expected: "non-empty serializable catalog facts" };
458
+ for (const [key, fact] of Object.entries(value.facts)) {
459
+ if (!(fact === null || typeof fact === "string" || typeof fact === "boolean" || typeof fact === "number" && Number.isFinite(fact) || Array.isArray(fact) && fact.every((entry) => typeof entry === "string")))
460
+ return { path: `${path}.facts.${key}`, expected: "string, finite number, boolean, null or string array" };
461
+ }
462
+ if (!Array.isArray(value.dependencies))
463
+ return { path: `${path}.dependencies`, expected: "array of SQL object identities" };
464
+ const index = value.dependencies.findIndex((entry) => !isSqlObjectIdentity(entry));
465
+ return identityIssue({ value: value.dependencies[index], path: `${path}.dependencies[${index}]` });
466
+ }
467
+ function invalidDeclaration(params) {
468
+ const expected = typeof params.expected === "string" ? params.expected : params.expected.join(", ");
469
+ throw new VibeError({
470
+ code: "VIBE_SCHEMA_INVALID",
471
+ message: `Invalid migration-only object declaration at ${params.path}; expected ${expected}`,
472
+ meta: { path: params.path, expected: params.expected, ...params.id === undefined ? {} : { id: params.id } }
473
+ });
474
+ }
475
+ function assertMigrationObjects(params) {
476
+ if (!Array.isArray(params.objects))
477
+ invalidDeclaration({ path: "migrationObjects", expected: "array" });
478
+ const ids = new Set;
479
+ const owners = new Set;
480
+ for (const [index, value] of params.objects.entries()) {
481
+ const object = value;
482
+ const path = `migrationObjects[${index}]`;
483
+ if (!record(object))
484
+ invalidDeclaration({ path, expected: "object" });
485
+ if (typeof object.id !== "string" || object.id.length === 0)
486
+ invalidDeclaration({ path: `${path}.id`, expected: "non-empty string" });
487
+ const id = object.id;
488
+ if (!["postgres", "sqlite", "mysql"].includes(String(object.dialect)))
489
+ invalidDeclaration({ path: `${path}.dialect`, expected: ["postgres", "sqlite", "mysql"], id });
490
+ const identity = object.identity;
491
+ if (!isSqlObjectIdentity(identity))
492
+ invalidDeclaration({ ...identityIssue({ value: identity, path: `${path}.identity` }), id });
493
+ for (const member of ["create", "drop"]) {
494
+ const statements = object[member];
495
+ if (!Array.isArray(statements))
496
+ invalidDeclaration({ path: `${path}.${member}`, expected: "array of SQL strings", id });
497
+ const invalid = statements.findIndex((entry) => typeof entry !== "string");
498
+ if (invalid !== -1)
499
+ invalidDeclaration({ path: `${path}.${member}[${invalid}]`, expected: "SQL string", id });
500
+ }
501
+ if (!Array.isArray(object.dependsOn))
502
+ invalidDeclaration({ path: `${path}.dependsOn`, expected: "array of SQL object identities", id });
503
+ for (const [dependencyIndex, dependency] of object.dependsOn.entries())
504
+ if (!isSqlObjectIdentity(dependency))
505
+ invalidDeclaration({ ...identityIssue({ value: dependency, path: `${path}.dependsOn[${dependencyIndex}]` }), id });
506
+ if (object.expected !== undefined) {
507
+ if (!isSqlObjectDefinition(object.expected))
508
+ invalidDeclaration({ ...definitionIssue({ value: object.expected, path: `${path}.expected` }), id });
509
+ if (sqlObjectKey({ identity: object.expected.identity }) !== sqlObjectKey({ identity }))
510
+ invalidDeclaration({ path: `${path}.expected.identity`, expected: "the declaration's SQL object identity", id });
511
+ }
512
+ const key = sqlObjectKey({ identity });
513
+ if (ids.has(id) || owners.has(key))
514
+ throw new VibeError({ code: "VIBE_SCHEMA_INVALID", message: "Duplicate migration object identity or id", meta: { id, key, path: `${path}.${ids.has(id) ? "id" : "identity"}` } });
515
+ ids.add(id);
516
+ owners.add(key);
517
+ }
518
+ }
519
+
520
+ // packages/schema/src/index-operator-classes.ts
521
+ function assertIndexOperatorClasses(params) {
522
+ for (const model of params.schema.models)
523
+ for (const index of model.indexes)
524
+ for (const field of index.fields) {
525
+ if (field.operatorClass === undefined)
526
+ continue;
527
+ if (!DIALECT_CAPABILITIES[params.dialect].indexOperatorClasses)
528
+ throw unsupportedCapability({ dialect: params.dialect, feature: "indexOperatorClasses" });
529
+ if (index.kind === "unique" && params.physical !== true)
530
+ throw unsupportedCapability({ dialect: params.dialect, feature: "uniqueIndexOperatorClasses", hint: "custom unique operator classes can change client selector equality" });
531
+ if (!isSqlObjectIdentity({ kind: "table", name: field.operatorClass }))
532
+ throw new VibeError({ code: "VIBE_SCHEMA_INVALID", message: "Index operator class must be a qualified SQL name { namespace, name }", meta: { rule: "index-operator-class-identity", model: model.name, field: field.name } });
533
+ }
534
+ }
535
+ // packages/schema/src/ir.ts
536
+ var DIALECTS = ["postgres", "sqlite", "mysql"];
537
+ function providerToDialect(params) {
538
+ const { provider } = params;
539
+ switch (provider) {
540
+ case "postgresql":
541
+ case "pglite":
542
+ return "postgres";
543
+ case "sqlite":
544
+ return "sqlite";
545
+ case "mysql":
546
+ return "mysql";
547
+ }
548
+ }
549
+ function isEnumType(fieldType) {
550
+ return typeof fieldType === "object" && "enum" in fieldType;
282
551
  }
283
- function assertMigrationObjects(params) {
284
- if (!Array.isArray(params.objects))
285
- throw new VibeError({ code: "VIBE_SCHEMA_INVALID", message: "migrationObjects must be an array" });
286
- const ids = new Set;
287
- const owners = new Set;
288
- for (const object of params.objects) {
289
- if (!record(object) || typeof object.id !== "string" || object.id.length === 0 || !["postgres", "sqlite", "mysql"].includes(String(object.dialect)) || !isSqlObjectIdentity(object.identity) || !Array.isArray(object.create) || !object.create.every((sql) => typeof sql === "string") || !Array.isArray(object.drop) || !object.drop.every((sql) => typeof sql === "string") || !Array.isArray(object.dependsOn) || !object.dependsOn.every(isSqlObjectIdentity) || object.expected !== undefined && (!isSqlObjectDefinition(object.expected) || sqlObjectKey({ identity: object.expected.identity }) !== sqlObjectKey({ identity: object.identity }))) {
290
- throw new VibeError({ code: "VIBE_SCHEMA_INVALID", message: "Invalid migration-only object declaration" });
291
- }
292
- const key = sqlObjectKey({ identity: object.identity });
293
- if (ids.has(object.id) || owners.has(key))
294
- throw new VibeError({ code: "VIBE_SCHEMA_INVALID", message: "Duplicate migration object identity or id", meta: { id: object.id, key } });
295
- ids.add(object.id);
296
- owners.add(key);
552
+ function fieldTypeIdentity(params) {
553
+ const { type } = params;
554
+ return isEnumType(type) ? type.namespace === undefined || type.namespace === "public" ? `enum:${type.enum}` : JSON.stringify(["enum", type.namespace, type.enum]) : type;
555
+ }
556
+ var ENUM_STORAGES = ["database", "string"];
557
+ function enumStorageOf(params) {
558
+ return params.enumDef.storage ?? "database";
559
+ }
560
+
561
+ // packages/schema/src/module-schema.ts
562
+ function prepareDatabaseModuleSchema(params) {
563
+ const { schema, module } = params;
564
+ const namespace = module.namespace;
565
+ const dialect = providerToDialect({ provider: schema.datasource.provider });
566
+ if (namespace !== undefined)
567
+ assertSqlNamespace({ namespace, dialect, allowPublic: false });
568
+ const expected = namespace ?? SQL_NAMESPACES.postgres;
569
+ for (const entry of [...schema.models, ...schema.enums]) {
570
+ if (entry.namespace === undefined)
571
+ continue;
572
+ assertSqlNamespace({ namespace: entry.namespace, dialect });
573
+ if (qualifiedSqlName({ name: entry.dbName ?? entry.name, namespace: entry.namespace }).namespace !== expected)
574
+ throw new VibeError({ code: "VIBE_CONFIG", message: "Module schema placement differs from its immutable namespace; host configuration cannot remap it", meta: { reason: "module-placement-mismatch", moduleId: module.id, name: entry.name } });
297
575
  }
576
+ for (const model of schema.models)
577
+ for (const field of model.fields) {
578
+ if (!isEnumType(field.type) || field.type.namespace === undefined)
579
+ continue;
580
+ assertSqlNamespace({ namespace: field.type.namespace, dialect });
581
+ if (field.type.namespace !== expected)
582
+ throw new VibeError({ code: "VIBE_CONFIG", message: "Module enum reference placement differs from its immutable namespace", meta: { reason: "module-placement-mismatch", moduleId: module.id, model: model.name, field: field.name } });
583
+ }
584
+ if (namespace === undefined)
585
+ return schema;
586
+ const nativeEnums = new Set(schema.enums.filter((entry) => enumStorageOf({ enumDef: entry }) === "database").map((entry) => entry.name));
587
+ return {
588
+ ...schema,
589
+ models: schema.models.map((model) => ({ ...model, namespace, fields: model.fields.map((field) => {
590
+ const type = field.type;
591
+ return isEnumType(type) && nativeEnums.has(type.enum) ? { ...field, type: { ...type, namespace } } : field;
592
+ }) })),
593
+ enums: schema.enums.map((entry) => enumStorageOf({ enumDef: entry }) === "database" ? { ...entry, namespace } : entry)
594
+ };
595
+ }
596
+ // packages/schema/src/predicate.ts
597
+ var PREDICATE_COMPARISON_OPS = [
598
+ "eq",
599
+ "ne",
600
+ "gt",
601
+ "gte",
602
+ "lt",
603
+ "lte"
604
+ ];
605
+ function isPredicateFieldRef(operand) {
606
+ return operand.kind === "field";
607
+ }
608
+ function predicateFieldNames(params) {
609
+ const seen = new Set;
610
+ const walk = (node) => {
611
+ switch (node.kind) {
612
+ case "compare":
613
+ seen.add(node.left.name);
614
+ if (isPredicateFieldRef(node.right))
615
+ seen.add(node.right.name);
616
+ return;
617
+ case "inList":
618
+ case "isNull":
619
+ seen.add(node.field.name);
620
+ return;
621
+ case "and":
622
+ case "or":
623
+ for (const operand of node.operands)
624
+ walk(operand);
625
+ return;
626
+ case "not":
627
+ walk(node.operand);
628
+ return;
629
+ }
630
+ };
631
+ walk(params.predicate);
632
+ return [...seen];
633
+ }
634
+ function predicateKey(params) {
635
+ const encode = (node) => {
636
+ switch (node.kind) {
637
+ case "compare":
638
+ return `cmp(${node.op},${node.left.name},${isPredicateFieldRef(node.right) ? `f:${node.right.name}` : `v:${typeof node.right.value}:${String(node.right.value)}`})`;
639
+ case "inList":
640
+ return `in${node.negate === true ? "!" : ""}(${node.field.name},[${node.values.map((entry) => `${typeof entry.value}:${String(entry.value)}`).join("|")}])`;
641
+ case "isNull":
642
+ return `null${node.negate === true ? "!" : ""}(${node.field.name})`;
643
+ case "and":
644
+ case "or":
645
+ return `${node.kind}(${node.operands.map(encode).join(",")})`;
646
+ case "not":
647
+ return `not(${encode(node.operand)})`;
648
+ }
649
+ };
650
+ return encode(params.predicate);
298
651
  }
299
652
  // packages/schema/src/prisma-literal.ts
300
653
  var STRING_ESCAPES = {
@@ -407,6 +760,7 @@ function exactDecimalLiteral(params) {
407
760
  // packages/schema/src/reserved.ts
408
761
  var RESERVED_DELEGATE_NAMES = [
409
762
  "findMany",
763
+ "findPage",
410
764
  "findFirst",
411
765
  "findUnique",
412
766
  "findFirstOrThrow",
@@ -740,160 +1094,6 @@ function implicitJoinTable(params) {
740
1094
  };
741
1095
  }
742
1096
 
743
- // packages/schema/src/physical-names.ts
744
- var IDENTIFIER_LIMITS = Object.freeze({
745
- postgres: { max: 63, unit: "bytes" },
746
- mysql: { max: 64, unit: "characters" },
747
- sqlite: undefined
748
- });
749
- var ENCODER = new TextEncoder;
750
- function identifierLength(params) {
751
- const limit = IDENTIFIER_LIMITS[params.dialect];
752
- return limit?.unit === "bytes" ? ENCODER.encode(params.name).length : [...params.name].length;
753
- }
754
- function cutIdentifier(params) {
755
- let out = "";
756
- let used = 0;
757
- for (const char of params.name) {
758
- const size = params.unit === "bytes" ? ENCODER.encode(char).length : 1;
759
- if (used + size > params.length)
760
- break;
761
- out += char;
762
- used += size;
763
- }
764
- return out;
765
- }
766
- function fitDefaultName(params) {
767
- const limit = IDENTIFIER_LIMITS[params.dialect];
768
- if (limit === undefined)
769
- return `${params.prefix}${params.suffix}`;
770
- const room = limit.max - identifierLength({ name: params.suffix, dialect: params.dialect });
771
- if (identifierLength({ name: params.prefix, dialect: params.dialect }) <= room)
772
- return `${params.prefix}${params.suffix}`;
773
- return `${cutIdentifier({ name: params.prefix, length: room, unit: limit.unit })}${params.suffix}`;
774
- }
775
- function assertIdentifierFits(params) {
776
- const limit = IDENTIFIER_LIMITS[params.dialect];
777
- if (limit === undefined)
778
- return;
779
- const length = identifierLength({ name: params.name, dialect: params.dialect });
780
- if (length <= limit.max)
781
- return;
782
- throw new VibeError({
783
- code: "VIBE_SCHEMA_INVALID",
784
- message: `${params.what} "${params.name}" is ${length} ${limit.unit} \u2014 ${params.dialect} keeps at most ${limit.max}; the created object would never carry this name and migrations could not converge. ${params.remedy}`,
785
- meta: { name: params.name, dialect: params.dialect, length, max: limit.max }
786
- });
787
- }
788
- function defaultIndexName(params) {
789
- return fitDefaultName({
790
- prefix: `${params.table}_${params.columns.join("_")}`,
791
- suffix: params.unique ? "_key" : "_idx",
792
- dialect: params.dialect
793
- });
794
- }
795
- function defaultForeignKeyName(params) {
796
- return fitDefaultName({ prefix: `${params.table}_${params.columns.join("_")}`, suffix: "_fkey", dialect: params.dialect });
797
- }
798
- function defaultPrimaryKeyName(params) {
799
- return fitDefaultName({ prefix: params.table, suffix: "_pkey", dialect: params.dialect });
800
- }
801
- function implicitJoinTableObjectNames(params) {
802
- return {
803
- uniqueIndex: `${params.table}_AB_unique`,
804
- indexB: `${params.table}_B_index`,
805
- foreignKeyA: `${params.table}_A_fkey`,
806
- foreignKeyB: `${params.table}_B_fkey`
807
- };
808
- }
809
- function postgresGeneratedObjectName(params) {
810
- const limit = IDENTIFIER_LIMITS.postgres;
811
- const overhead = params.label.length + 2;
812
- let chars1 = [...params.name1];
813
- let chars2 = [...params.name2];
814
- const bytes = (chars) => ENCODER.encode(chars.join("")).length;
815
- while (bytes(chars1) + bytes(chars2) + overhead > limit.max) {
816
- if (bytes(chars1) > bytes(chars2))
817
- chars1 = chars1.slice(0, -1);
818
- else
819
- chars2 = chars2.slice(0, -1);
820
- }
821
- return `${chars1.join("")}_${chars2.join("")}_${params.label}`;
822
- }
823
-
824
- // packages/schema/src/capabilities.ts
825
- var POSTGRES_CAPABILITIES = Object.freeze({
826
- exclusionConstraints: true,
827
- exclusionExtensions: Object.freeze(["btree_gist"]),
828
- checkNormalization: "rollback",
829
- nativeRowLevelSecurity: true,
830
- returning: true,
831
- scalarArrays: true,
832
- nativeEnums: true,
833
- ilike: true,
834
- lateralJoin: true,
835
- distinctOn: true,
836
- partialIndexes: true,
837
- conflictTargetConstraint: true,
838
- transactionalDdl: true,
839
- createManyAndReturn: true,
840
- jsonColumnType: true,
841
- orderByNulls: true,
842
- fullTextEngines: Object.freeze(["bm25", "tsvector"]),
843
- rowLockStrengths: Object.freeze(["update", "noKeyUpdate", "share", "keyShare"]),
844
- rowLockWaitPolicies: Object.freeze(["wait", "nowait", "skipLocked"]),
845
- advisoryLocks: true
846
- });
847
- var SQLITE_CAPABILITIES = Object.freeze({
848
- exclusionConstraints: false,
849
- exclusionExtensions: Object.freeze([]),
850
- checkNormalization: "sourceText",
851
- nativeRowLevelSecurity: false,
852
- returning: true,
853
- scalarArrays: false,
854
- nativeEnums: false,
855
- ilike: false,
856
- lateralJoin: false,
857
- distinctOn: false,
858
- partialIndexes: true,
859
- conflictTargetConstraint: false,
860
- transactionalDdl: true,
861
- createManyAndReturn: true,
862
- jsonColumnType: false,
863
- orderByNulls: true,
864
- fullTextEngines: Object.freeze(["fts5"]),
865
- rowLockStrengths: Object.freeze([]),
866
- rowLockWaitPolicies: Object.freeze([]),
867
- advisoryLocks: false
868
- });
869
- var MYSQL_CAPABILITIES = Object.freeze({
870
- exclusionConstraints: false,
871
- exclusionExtensions: Object.freeze([]),
872
- checkNormalization: "temporary",
873
- nativeRowLevelSecurity: false,
874
- returning: false,
875
- scalarArrays: false,
876
- nativeEnums: true,
877
- ilike: false,
878
- lateralJoin: false,
879
- distinctOn: false,
880
- partialIndexes: false,
881
- conflictTargetConstraint: false,
882
- transactionalDdl: false,
883
- createManyAndReturn: false,
884
- jsonColumnType: true,
885
- orderByNulls: false,
886
- fullTextEngines: Object.freeze(["fulltext"]),
887
- rowLockStrengths: Object.freeze(["update", "share"]),
888
- rowLockWaitPolicies: Object.freeze(["wait", "nowait", "skipLocked"]),
889
- advisoryLocks: false
890
- });
891
- var DIALECT_CAPABILITIES = Object.freeze({
892
- postgres: POSTGRES_CAPABILITIES,
893
- sqlite: SQLITE_CAPABILITIES,
894
- mysql: MYSQL_CAPABILITIES
895
- });
896
-
897
1097
  // packages/schema/src/validate.ts
898
1098
  var RESERVED_ENUM_NAMES = [
899
1099
  "sql",
@@ -948,6 +1148,7 @@ var RESERVED_ENUM_NAMES = [
948
1148
  "SortOrder",
949
1149
  "SortOrderWithNulls",
950
1150
  "KeysetToken",
1151
+ "KeysetPage",
951
1152
  "KeysetOptions",
952
1153
  "RowLockRequest",
953
1154
  "JsonValue",
@@ -1026,6 +1227,7 @@ var GENERATED_TYPE_NAMES = {
1026
1227
  "MinAggregateInput",
1027
1228
  "MaxAggregateInput",
1028
1229
  "FindManyArgs",
1230
+ "FindPageArgs",
1029
1231
  "FindFirstArgs",
1030
1232
  "FindUniqueArgs",
1031
1233
  "CreateArgs",
@@ -1196,6 +1398,15 @@ function validateGeneratedNames(params) {
1196
1398
  function validateSchemaIR(params) {
1197
1399
  const { schema } = params;
1198
1400
  const issues = [];
1401
+ for (const entry of [...schema.models, ...schema.enums]) {
1402
+ if (entry.namespace === undefined)
1403
+ continue;
1404
+ const issue = sqlNamespaceIssue({ namespace: entry.namespace });
1405
+ if (issue !== undefined)
1406
+ issues.push({ rule: "namespace", message: issue });
1407
+ if (providerToDialect({ provider: schema.datasource.provider }) !== "postgres")
1408
+ issues.push({ rule: "namespace-dialect", message: "Explicit fixed namespaces require PostgreSQL or PGlite" });
1409
+ }
1199
1410
  const modelByName = new Map;
1200
1411
  for (const model of schema.models) {
1201
1412
  if (modelByName.has(model.name)) {
@@ -1378,7 +1589,7 @@ function validatePhysicalNameUniqueness(params) {
1378
1589
  const dialect = providerToDialect({ provider: schema.datasource.provider });
1379
1590
  const owners = new Map;
1380
1591
  const claim = (entry) => {
1381
- const key = `${entry.namespace}\x00${entry.name}`;
1592
+ const key = JSON.stringify([entry.physicalNamespace ?? "public", entry.namespace, entry.name]);
1382
1593
  const previous = owners.get(key);
1383
1594
  if (previous === undefined) {
1384
1595
  owners.set(key, `${entry.what} of ${entry.owner}`);
@@ -1396,10 +1607,11 @@ function validatePhysicalNameUniqueness(params) {
1396
1607
  const constraintNamespace = (table) => dialect === "mysql" ? "constraint" : `constraint:${table}`;
1397
1608
  for (const model of schema.models) {
1398
1609
  const table = model.dbName ?? model.name;
1399
- if (!claim({ namespace: "relation", name: table, what: model.isView ? "view" : "table", owner: `model "${model.name}"`, model: model.name }))
1610
+ const physicalNamespace = qualifiedSqlName({ name: table, namespace: model.namespace }).namespace;
1611
+ if (!claim({ namespace: "relation", physicalNamespace, name: table, what: model.isView ? "view" : "table", owner: `model "${model.name}"`, model: model.name }))
1400
1612
  continue;
1401
1613
  for (const fieldIR of model.fields) {
1402
- claim({ namespace: `column:${table}`, name: fieldIR.dbName ?? fieldIR.name, what: "column", owner: `field "${model.name}.${fieldIR.name}"`, model: model.name, field: fieldIR.name });
1614
+ claim({ namespace: `column:${table}`, physicalNamespace, name: fieldIR.dbName ?? fieldIR.name, what: "column", owner: `field "${model.name}.${fieldIR.name}"`, model: model.name, field: fieldIR.name });
1403
1615
  }
1404
1616
  if (model.isView)
1405
1617
  continue;
@@ -1417,15 +1629,15 @@ function validatePhysicalNameUniqueness(params) {
1417
1629
  continue;
1418
1630
  seenIndexKeys.add(key);
1419
1631
  const name = index.name ?? defaultIndexName({ table, columns: index.fields.map((entry) => columnOf(entry.name)), unique, dialect });
1420
- claim({ namespace: indexNamespace(table), name, what: unique ? "unique index" : "index", owner: `${site} on "${model.name}"`, model: model.name });
1632
+ claim({ namespace: indexNamespace(table), physicalNamespace, name, what: unique ? "unique index" : "index", owner: `${site} on "${model.name}"`, model: model.name });
1421
1633
  if (index.constraintName !== undefined) {
1422
- claim({ namespace: constraintNamespace(table), name: index.constraintName, what: "unique constraint", owner: `${site} on "${model.name}"`, model: model.name });
1634
+ claim({ namespace: constraintNamespace(table), physicalNamespace, name: index.constraintName, what: "unique constraint", owner: `${site} on "${model.name}"`, model: model.name });
1423
1635
  }
1424
1636
  }
1425
1637
  if (dialect === "postgres" && (model.primaryKey !== undefined || model.fields.some((fieldIR) => fieldIR.isId))) {
1426
1638
  const name = model.primaryKeyConstraintName ?? defaultPrimaryKeyName({ table, dialect });
1427
- claim({ namespace: "relation", name, what: "primary key", owner: `model "${model.name}"`, model: model.name });
1428
- claim({ namespace: constraintNamespace(table), name, what: "primary key", owner: `model "${model.name}"`, model: model.name });
1639
+ claim({ namespace: "relation", physicalNamespace, name, what: "primary key", owner: `model "${model.name}"`, model: model.name });
1640
+ claim({ namespace: constraintNamespace(table), physicalNamespace, name, what: "primary key", owner: `model "${model.name}"`, model: model.name });
1429
1641
  }
1430
1642
  for (const relation of model.relations) {
1431
1643
  if (relation.fields === undefined || relation.fields.length === 0)
@@ -1434,22 +1646,22 @@ function validatePhysicalNameUniqueness(params) {
1434
1646
  if (target !== undefined && target.isView)
1435
1647
  continue;
1436
1648
  const name = relation.constraintName ?? defaultForeignKeyName({ table, columns: relation.fields.map((entry) => columnOf(entry)), dialect });
1437
- claim({ namespace: constraintNamespace(table), name, what: "foreign key", owner: `relation "${model.name}.${relation.name}"`, model: model.name });
1649
+ claim({ namespace: constraintNamespace(table), physicalNamespace, name, what: "foreign key", owner: `relation "${model.name}.${relation.name}"`, model: model.name });
1438
1650
  }
1439
1651
  for (const checkIR of model.checks ?? []) {
1440
- claim({ namespace: constraintNamespace(table), name: checkIR.name, what: "CHECK constraint", owner: `model "${model.name}"`, model: model.name });
1652
+ claim({ namespace: constraintNamespace(table), physicalNamespace, name: checkIR.name, what: "CHECK constraint", owner: `model "${model.name}"`, model: model.name });
1441
1653
  }
1442
1654
  for (const exclusion of model.exclusions ?? []) {
1443
- claim({ namespace: constraintNamespace(table), name: exclusion.name, what: "exclusion constraint", owner: `model "${model.name}"`, model: model.name });
1655
+ claim({ namespace: constraintNamespace(table), physicalNamespace, name: exclusion.name, what: "exclusion constraint", owner: `model "${model.name}"`, model: model.name });
1444
1656
  if (dialect === "postgres")
1445
- claim({ namespace: "relation", name: exclusion.name, what: "exclusion constraint", owner: `model "${model.name}"`, model: model.name });
1657
+ claim({ namespace: "relation", physicalNamespace, name: exclusion.name, what: "exclusion constraint", owner: `model "${model.name}"`, model: model.name });
1446
1658
  }
1447
1659
  }
1448
1660
  if (dialect === "postgres") {
1449
1661
  for (const enumDef of schema.enums) {
1450
1662
  if (enumStorageOf({ enumDef }) !== "database")
1451
1663
  continue;
1452
- claim({ namespace: "relation", name: enumDef.dbName ?? enumDef.name, what: "enum type", owner: `enum "${enumDef.name}"` });
1664
+ claim({ namespace: "relation", physicalNamespace: qualifiedSqlName({ name: enumDef.dbName ?? enumDef.name, namespace: enumDef.namespace }).namespace, name: enumDef.dbName ?? enumDef.name, what: "enum type", owner: `enum "${enumDef.name}"` });
1453
1665
  }
1454
1666
  }
1455
1667
  const seenJoinTables = new Set;
@@ -1459,17 +1671,24 @@ function validatePhysicalNameUniqueness(params) {
1459
1671
  continue;
1460
1672
  if (!isImplicitManyToManyRelation({ model, relation, models: schema.models }))
1461
1673
  continue;
1674
+ const target = schema.models.find((candidate) => candidate.name === relation.targetModel);
1675
+ const physicalNamespace = model.namespace ?? "public";
1676
+ if ((target?.namespace ?? "public") !== physicalNamespace) {
1677
+ issues.push({ rule: "implicit-join-namespace", message: "Implicit many-to-many endpoints must share one fixed namespace", model: model.name, field: relation.name });
1678
+ continue;
1679
+ }
1462
1680
  const join = implicitJoinTable({ modelA: model.name, modelB: relation.targetModel, ...relation.relationName === undefined ? {} : { relationName: relation.relationName } });
1463
- if (seenJoinTables.has(join.tableName))
1681
+ const joinKey = JSON.stringify([physicalNamespace, join.tableName]);
1682
+ if (seenJoinTables.has(joinKey))
1464
1683
  continue;
1465
- seenJoinTables.add(join.tableName);
1684
+ seenJoinTables.add(joinKey);
1466
1685
  const owner = `implicit relation "${model.name}.${relation.name}"`;
1467
- claim({ namespace: "relation", name: join.tableName, what: "join table", owner, model: model.name });
1686
+ claim({ namespace: "relation", physicalNamespace, name: join.tableName, what: "join table", owner, model: model.name });
1468
1687
  const derived = implicitJoinTableObjectNames({ table: join.tableName });
1469
- claim({ namespace: indexNamespace(join.tableName), name: derived.uniqueIndex, what: "unique index", owner, model: model.name });
1470
- claim({ namespace: indexNamespace(join.tableName), name: derived.indexB, what: "index", owner, model: model.name });
1471
- claim({ namespace: constraintNamespace(join.tableName), name: derived.foreignKeyA, what: "foreign key", owner, model: model.name });
1472
- claim({ namespace: constraintNamespace(join.tableName), name: derived.foreignKeyB, what: "foreign key", owner, model: model.name });
1688
+ claim({ namespace: indexNamespace(join.tableName), physicalNamespace, name: derived.uniqueIndex, what: "unique index", owner, model: model.name });
1689
+ claim({ namespace: indexNamespace(join.tableName), physicalNamespace, name: derived.indexB, what: "index", owner, model: model.name });
1690
+ claim({ namespace: constraintNamespace(join.tableName), physicalNamespace, name: derived.foreignKeyA, what: "foreign key", owner, model: model.name });
1691
+ claim({ namespace: constraintNamespace(join.tableName), physicalNamespace, name: derived.foreignKeyB, what: "foreign key", owner, model: model.name });
1473
1692
  }
1474
1693
  }
1475
1694
  }
@@ -1835,6 +2054,20 @@ function validatePredicateFields(params) {
1835
2054
  }
1836
2055
  function assertValidSchemaIR(params) {
1837
2056
  const dialect = providerToDialect({ provider: params.schema.datasource.provider });
2057
+ assertIndexOperatorClasses({ schema: params.schema, dialect });
2058
+ for (const entry of [...params.schema.models, ...params.schema.enums])
2059
+ if (entry.namespace !== undefined)
2060
+ assertSqlNamespace({ namespace: entry.namespace, dialect });
2061
+ for (const model of params.schema.models)
2062
+ for (const field of model.fields) {
2063
+ if (!isEnumType(field.type) || field.type.namespace === undefined)
2064
+ continue;
2065
+ assertSqlNamespace({ namespace: field.type.namespace, dialect });
2066
+ const enumType = field.type;
2067
+ const declared = params.schema.enums.find((entry) => entry.name === enumType.enum || entry.dbName === enumType.enum);
2068
+ if (declared !== undefined && (declared.namespace ?? "public") !== enumType.namespace)
2069
+ throw new VibeError({ code: "VIBE_SCHEMA_INVALID", message: "Enum reference namespace differs from its declared native type", meta: { rule: "enum-namespace", model: model.name, field: field.name } });
2070
+ }
1838
2071
  for (const model of params.schema.models) {
1839
2072
  if (model.exclusions !== undefined && !Array.isArray(model.exclusions))
1840
2073
  throw new VibeError({ code: "VIBE_SCHEMA_INVALID", message: "Exclusions must be an array", meta: { rule: "exclusion-definition" } });
@@ -2094,11 +2327,14 @@ export {
2094
2327
  RlsContextError,
2095
2328
  SCOPED_REFUSAL_REASONS,
2096
2329
  SQLITE_CAPABILITIES,
2330
+ SQL_NAMESPACES,
2097
2331
  ScopedQueryError,
2098
2332
  VIBE_ERROR_CODES,
2099
2333
  VibeError,
2100
2334
  assertIdentifierFits,
2335
+ assertIndexOperatorClasses,
2101
2336
  assertMigrationObjects,
2337
+ assertSqlNamespace,
2102
2338
  assertValidSchemaIR,
2103
2339
  buildComputedManifest,
2104
2340
  buildExtensionRegistry,
@@ -2132,14 +2368,18 @@ export {
2132
2368
  postgresGeneratedObjectName,
2133
2369
  predicateFieldNames,
2134
2370
  predicateKey,
2371
+ prepareDatabaseModuleSchema,
2135
2372
  providerToDialect,
2373
+ qualifiedSqlName,
2136
2374
  scalarListDefault,
2137
2375
  serializeJsonDefault,
2376
+ sqlNamespaceIssue,
2138
2377
  sqlObjectKey,
2378
+ sqlObjectNamespace,
2139
2379
  unsupportedCapability,
2140
2380
  validateComputedConfig,
2141
2381
  validateRlsContextIR,
2142
2382
  validateSchemaIR
2143
2383
  };
2144
2384
 
2145
- //# debugId=47DE6CAFB1D4DC2864756E2164756E21
2385
+ //# debugId=20984641ACA6D36E64756E2164756E21