@vibeorm/schema 5.8.0 → 5.10.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/ir.d.ts CHANGED
@@ -164,6 +164,16 @@ export type RelationIR = {
164
164
  readonly fields?: readonly string[];
165
165
  /** Referenced columns on the target model (FK side only). */
166
166
  readonly references?: readonly string[];
167
+ /**
168
+ * Correlation of a to-one without `fields` whose target declares no foreign
169
+ * key back: `fields` on this model pair, member by member, with `references`,
170
+ * a unique key of the target that holds the same values. No constraint backs
171
+ * it, and migrate emits none; only relation loading reads it.
172
+ */
173
+ readonly inverseKey?: {
174
+ readonly fields: readonly string[];
175
+ readonly references: readonly string[];
176
+ };
167
177
  readonly onDelete?: CascadeAction;
168
178
  readonly onUpdate?: CascadeAction;
169
179
  readonly isList: boolean;
@@ -222,6 +232,13 @@ export type IndexIR = {
222
232
  * Unique indexes only; postgres 15+ (pglite included), capability-gated.
223
233
  */
224
234
  readonly nullsNotDistinct?: boolean;
235
+ /**
236
+ * Non-key columns stored in the index (`INCLUDE (…)`, a covering index), by
237
+ * field name, in order. Never a key column of the same index; absent when the
238
+ * index carries none, never empty. PostgreSQL btree, unique, GiST and SP-GiST
239
+ * indexes only (capability `indexIncludeColumns`).
240
+ */
241
+ readonly include?: readonly string[];
225
242
  };
226
243
  /** Identity scalars supported by native RLS; lists, enums, Json and Bytes refuse. */
227
244
  export type RlsContextScalar = "String" | "Boolean" | "Int" | "BigInt" | "Float" | "Decimal" | "DateTime";
@@ -306,9 +323,55 @@ export type ModelIR = {
306
323
  readonly fields: readonly string[];
307
324
  readonly clientName?: string;
308
325
  };
326
+ /**
327
+ * PostgreSQL table storage parameters (`@@storage(…)`), keyed by their
328
+ * PostgreSQL names; absent when the model declares none, never empty.
329
+ * Capability `tableStorageParameters`.
330
+ */
331
+ readonly storage?: TableStorageParameters;
332
+ /**
333
+ * Introspection only: `false` when the live PostgreSQL table has no TOAST
334
+ * table. PostgreSQL accepts and discards `toast.` parameters for such a
335
+ * table, so they cannot be read back or compared.
336
+ */
337
+ readonly catalogToastTable?: false;
309
338
  readonly isView: boolean;
310
339
  readonly documentation?: string;
311
340
  };
341
+ /** A table storage parameter value: a number, a boolean, or an enum word (`vacuum_index_cleanup`). */
342
+ export type TableStorageValue = number | boolean | string;
343
+ /** Parameters PostgreSQL accepts for a table and, with a `toast.` prefix, for its TOAST table. */
344
+ export type VacuumStorageParameters = {
345
+ readonly autovacuum_enabled?: boolean;
346
+ readonly vacuum_index_cleanup?: "auto" | "on" | "off";
347
+ readonly vacuum_truncate?: boolean;
348
+ readonly autovacuum_vacuum_threshold?: number;
349
+ readonly autovacuum_vacuum_scale_factor?: number;
350
+ readonly autovacuum_vacuum_insert_threshold?: number;
351
+ readonly autovacuum_vacuum_insert_scale_factor?: number;
352
+ readonly autovacuum_vacuum_cost_delay?: number;
353
+ readonly autovacuum_vacuum_cost_limit?: number;
354
+ readonly autovacuum_freeze_min_age?: number;
355
+ readonly autovacuum_freeze_max_age?: number;
356
+ readonly autovacuum_freeze_table_age?: number;
357
+ readonly autovacuum_multixact_freeze_min_age?: number;
358
+ readonly autovacuum_multixact_freeze_max_age?: number;
359
+ readonly autovacuum_multixact_freeze_table_age?: number;
360
+ readonly log_autovacuum_min_duration?: number;
361
+ };
362
+ /**
363
+ * PostgreSQL table storage parameters (CREATE TABLE "Storage Parameters"), by
364
+ * their PostgreSQL names. `toast.`-prefixed keys set the TOAST table's value.
365
+ */
366
+ export type TableStorageParameters = VacuumStorageParameters & {
367
+ readonly fillfactor?: number;
368
+ readonly toast_tuple_target?: number;
369
+ readonly parallel_workers?: number;
370
+ readonly autovacuum_analyze_threshold?: number;
371
+ readonly autovacuum_analyze_scale_factor?: number;
372
+ } & {
373
+ readonly [K in keyof VacuumStorageParameters as `toast.${K}`]?: VacuumStorageParameters[K];
374
+ };
312
375
  /**
313
376
  * How an enum is physically stored.
314
377
  *
@@ -1,5 +1,5 @@
1
1
  import type { Dialect, SchemaIR } from "./ir.ts";
2
- /** Admit only the public-table native RLS contract shared by every consumer. */
2
+ /** Admit only the public-table native RLS contract shared by every consumer (once per dialect for a sealed schema). */
3
3
  export declare function assertNativeRlsAdmission(params: {
4
4
  schema: SchemaIR;
5
5
  dialect?: Dialect;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The comparison key of a partial index's predicate (`where:`): two spellings
3
+ * of one predicate are one database object. Migrate compares indexes by it and
4
+ * the unique-key enumeration dedupes by it, so both agree on which partial
5
+ * uniques are the same key.
6
+ */
7
+ /**
8
+ * Comparison key for a partial-index predicate.
9
+ *
10
+ * Literal bytes, quoted identifier case and casts are semantic. Only the
11
+ * supported boolean structure is reparenthesized. Quoted and unquoted names
12
+ * may conservatively compare unequal; equivalence requires catalog evidence.
13
+ * Complex lexical forms remain opaque rather than claiming false convergence.
14
+ */
15
+ export declare function normalizeWhere(params: {
16
+ where: string | undefined;
17
+ }): string;
18
+ //# sourceMappingURL=partial-predicate.d.ts.map
@@ -8,16 +8,6 @@
8
8
  */
9
9
  export declare const RESERVED_DELEGATE_NAMES: readonly string[];
10
10
  export declare const RESERVED_CLIENT_NAMES: readonly string[];
11
- /**
12
- * Column-name prefix reserved for VibeORM's own result projections — the M2M
13
- * join loader's `__vibe_parent` stitch key today, hidden order/stitch fields
14
- * generally. A user column with this prefix would collide with a projection
15
- * alias and be silently misgrouped or stripped, so schema validation refuses
16
- * it (`reserved-column-prefix`). Unreachable from `.prisma` field-name
17
- * grammar, reachable via `@map` or hand-built IR. Wave-C sqlite review,
18
- * finding 3.
19
- */
20
- export declare const RESERVED_COLUMN_PREFIX: string;
21
11
  export declare function isReservedDelegateName(params: {
22
12
  name: string;
23
13
  }): boolean;
@@ -1,5 +1,5 @@
1
1
  import type { Dialect, FieldIR, ModelIR, SchemaIR } from "./ir.ts";
2
- import type { MigrationObjectIR, SqlObjectIdentity } from "./migration-objects.ts";
2
+ import type { SqlObjectIdentity } from "./migration-objects.ts";
3
3
  /** A fixed group is protected from insertion, or after OLD's nullable gate is set. */
4
4
  export type RowRuleWhenIR = {
5
5
  readonly fromCreation: true;
@@ -121,26 +121,6 @@ export declare function rowRuleTriggerName(params: {
121
121
  export declare function rowRuleGateField(params: {
122
122
  rule: RowRuleIR | RowRuleSpec;
123
123
  }): string | undefined;
124
- type RowRuleOwnedObject = Pick<MigrationObjectIR, "id" | "identity">;
125
- /** Internal, invocation-local preparation shared by schema validation passes. */
126
- export type RowRuleValidationContext = {
127
- readonly objects: () => readonly RowRuleOwnedObject[];
128
- readonly generatedFields: (params: {
129
- model: ModelIR;
130
- }) => ReadonlySet<string>;
131
- readonly validate: (params: {
132
- model: ModelIR;
133
- }) => readonly RowRuleValidationIssue[];
134
- readonly assertEquality: (params: {
135
- model: ModelIR;
136
- rule: RowRuleIR;
137
- }) => void;
138
- };
139
- /** Prepare registered ownership lazily; no row rules means no migration-object reads. */
140
- export declare function createRowRuleValidationContext(params: {
141
- schema: SchemaIR;
142
- dialect?: Dialect;
143
- }): RowRuleValidationContext;
144
124
  /** Authored generated-column ownership identities mapped to logical keys. */
145
125
  export declare function rowRuleGeneratedFields(params: {
146
126
  schema: SchemaIR;
@@ -194,5 +174,4 @@ export declare function assertRowRuleReferentialActions(params: {
194
174
  export declare function rowRulePrismaAttribute(params: {
195
175
  rule: RowRuleIR;
196
176
  }): string;
197
- export {};
198
177
  //# sourceMappingURL=row-rules.d.ts.map
@@ -0,0 +1,16 @@
1
+ import type { SchemaIR } from "./ir.ts";
2
+ /**
3
+ * A deep-frozen copy of a schema. Nothing can change a sealed schema, so
4
+ * `assertValidSchemaIR` validates it once and answers from memory afterwards —
5
+ * a consumer that checks a schema per operation (native RLS readiness, policy
6
+ * rendering) pays the validation once. The caller's schema stays as it was and
7
+ * keeps being validated on every call.
8
+ *
9
+ * A schema that holds anything but plain objects, arrays and primitives (a
10
+ * function, a class instance, a symbol) cannot be copied faithfully and is
11
+ * returned as it is.
12
+ */
13
+ export declare function sealSchemaIR(params: {
14
+ schema: SchemaIR;
15
+ }): SchemaIR;
16
+ //# sourceMappingURL=sealed.d.ts.map
@@ -0,0 +1,53 @@
1
+ /**
2
+ * "Did you mean …?" for a misspelled name: a field, relation, model, operator
3
+ * or argument keyword. Meant for refusal paths only — the caller computes it
4
+ * after a lookup already failed, never on a successful one.
5
+ */
6
+ /**
7
+ * Edit distance with adjacent transpositions (optimal string alignment):
8
+ * `stauts` → `status` is one edit, not two.
9
+ */
10
+ export declare function editDistance(params: {
11
+ from: string;
12
+ to: string;
13
+ }): number;
14
+ /**
15
+ * The one known name close to `name`, or `undefined`. Close means an edit
16
+ * distance (a transposition counts as one edit) of at most 2, or at most a
17
+ * third of the longer name's length, and less than `name`'s own length, so a
18
+ * one-letter typo never "suggests" an unrelated short name. When several names
19
+ * are equally close none is suggested: a wrong guess costs more than none.
20
+ *
21
+ * @example suggestName({ name: "stauts", candidates: ["id", "status", "total"] }) // "status"
22
+ */
23
+ export declare function suggestName(params: {
24
+ readonly name: string;
25
+ readonly candidates: Iterable<string>;
26
+ }): string | undefined;
27
+ /** The message suffix for a {@link suggestName} result: ` — did you mean "status"?`, or `""` without one. */
28
+ export declare function didYouMean(params: {
29
+ readonly suggestion: string | undefined;
30
+ }): string;
31
+ /**
32
+ * A refusal's message and meta with the {@link suggestName} result for `name`
33
+ * appended (`… — did you mean "status"?`, `meta.suggestion`), or unchanged
34
+ * when no single known name is close. The returned meta is marked as an
35
+ * unknown-name refusal's ({@link isUnknownNameRefusal}).
36
+ */
37
+ export declare function withSuggestion(params: {
38
+ readonly message: string;
39
+ readonly meta: Record<string, unknown>;
40
+ readonly name: string;
41
+ readonly candidates: Iterable<string>;
42
+ }): {
43
+ message: string;
44
+ meta: Record<string, unknown>;
45
+ };
46
+ /**
47
+ * Whether an error's `meta` is an unknown-name refusal's from
48
+ * {@link withSuggestion} — the errors a delegate call names its method on.
49
+ */
50
+ export declare function isUnknownNameRefusal(params: {
51
+ readonly meta: object;
52
+ }): boolean;
53
+ //# sourceMappingURL=suggest.d.ts.map
@@ -0,0 +1,66 @@
1
+ import type { Dialect, ModelIR, SchemaIR, TableStorageValue } from "./ir.ts";
2
+ /** How one storage parameter is typed and bounded (PostgreSQL `reloptions.c`). */
3
+ export type TableStorageParameterSpec = {
4
+ readonly type: "integer" | "real" | "boolean" | "enum";
5
+ readonly min?: number;
6
+ readonly max?: number;
7
+ readonly values?: readonly string[];
8
+ };
9
+ /**
10
+ * Every table storage parameter a schema may declare, keyed by its PostgreSQL
11
+ * name (`toast.`-prefixed for the TOAST table), in the order DDL renders them.
12
+ * Parameters newer than PostgreSQL 13 (`autovacuum_vacuum_max_threshold`,
13
+ * `vacuum_max_eager_freeze_failure_rate`) and `user_catalog_table` are left out.
14
+ */
15
+ export declare const TABLE_STORAGE_PARAMETERS: Readonly<Record<string, TableStorageParameterSpec>>;
16
+ /** The declarable keys, in rendering order. */
17
+ export declare const TABLE_STORAGE_KEYS: readonly string[];
18
+ /** Whether a key sets the TOAST table's parameter rather than the table's own. */
19
+ export declare function isToastStorageKey(params: {
20
+ key: string;
21
+ }): boolean;
22
+ /**
23
+ * The `.prisma` spelling of a key: an attribute argument name cannot hold a
24
+ * dot, so `toast.autovacuum_enabled` is written `toast_autovacuum_enabled`.
25
+ */
26
+ export declare function tableStoragePrismaKey(params: {
27
+ key: string;
28
+ }): string;
29
+ /** The PostgreSQL key a `.prisma` argument name stands for; undefined when it names none. */
30
+ export declare function tableStorageKeyFromPrisma(params: {
31
+ name: string;
32
+ }): string | undefined;
33
+ /**
34
+ * Read a parameter value written as text (a `.prisma` argument, a
35
+ * `pg_class.reloptions` entry) into its IR value: undefined when the key is
36
+ * unknown or the text is not a value of its type. Bounds are not checked here.
37
+ */
38
+ export declare function parseTableStorageValue(params: {
39
+ key: string;
40
+ text: string;
41
+ }): TableStorageValue | undefined;
42
+ /** The SQL text of a value inside `WITH (…)` / `SET (…)`. */
43
+ export declare function renderTableStorageValue(params: {
44
+ value: TableStorageValue;
45
+ }): string;
46
+ /** Whether any model of the schema declares storage parameters. */
47
+ export declare function hasTableStorage(params: {
48
+ schema: SchemaIR;
49
+ }): boolean;
50
+ /**
51
+ * Refuse storage parameters that cannot be created: a malformed or empty
52
+ * record, a view, a dialect without them (`tableStorageParameters`), an
53
+ * unknown key, or a value of the wrong type or outside PostgreSQL's range.
54
+ */
55
+ export declare function assertTableStorage(params: {
56
+ schema: SchemaIR;
57
+ dialect: Dialect;
58
+ }): void;
59
+ /**
60
+ * A model's parameters as `[key, value]` pairs in rendering order, unknown keys
61
+ * last so a printer never drops one silently; empty when it declares none.
62
+ */
63
+ export declare function tableStorageEntries(params: {
64
+ model: Pick<ModelIR, "storage">;
65
+ }): readonly (readonly [string, TableStorageValue])[];
66
+ //# sourceMappingURL=table-storage.d.ts.map
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Every unique key of a model — its primary key and each unique index migrate
3
+ * creates — with a stable LOGICAL key and the PHYSICAL name the dialect gives
4
+ * it. One enumeration for every consumer: the runtime's violation lookup and
5
+ * `db.<model>.uniques`, `describeSchema`, and the generator's declarations.
6
+ *
7
+ * Physical names come from the shared naming rule (`physical-names.ts`), and
8
+ * the set of objects follows migrate's own: declared unique indexes first, a
9
+ * duplicate definition collapses into the first, and a field `@unique` folds
10
+ * into a declared index over the same column (`@unique(map: "x")` is one
11
+ * index named `x`).
12
+ */
13
+ import type { Dialect, ModelIR } from "./ir.ts";
14
+ /** One unique key of a model. */
15
+ export type UniqueKeyIR = {
16
+ /**
17
+ * Stable logical key: the declared selector name (`name:` on `@@id` /
18
+ * `@@unique`), else the field names joined with `_` — the key compound
19
+ * selectors use, and a field `@unique`'s field name. A key whose natural
20
+ * name an earlier key already holds is keyed by its physical name (the
21
+ * declared one, else the default unshortened): the same key on every dialect.
22
+ */
23
+ readonly key: string;
24
+ /**
25
+ * The physical name a violation of this key reports on the dialect: a
26
+ * catalog-backed constraint's name, else the index name. MySQL's primary
27
+ * key is `PRIMARY`; `null` for SQLite's primary key, which has no name.
28
+ */
29
+ readonly name: string | null;
30
+ /** Every physical name the database may report for this key (index and constraint), `name` first. */
31
+ readonly names: readonly string[];
32
+ /** Field names in key order; absent for an expression key. */
33
+ readonly fields?: readonly string[];
34
+ /** Fields an expression key reads, when they are known (never for raw SQL). */
35
+ readonly sourceFields?: readonly string[];
36
+ readonly primaryKey: boolean;
37
+ /** A partial unique (`where:`): it guards only the rows its predicate covers. */
38
+ readonly partial: boolean;
39
+ };
40
+ /**
41
+ * Every unique key of `model` on `dialect`, primary key first. A view has
42
+ * none. Implicit many-to-many join tables are not models and are not listed.
43
+ */
44
+ export declare function modelUniqueKeys(params: {
45
+ readonly model: ModelIR;
46
+ readonly dialect: Dialect;
47
+ }): readonly UniqueKeyIR[];
48
+ //# sourceMappingURL=unique-keys.d.ts.map
@@ -23,11 +23,37 @@ export type ValidationIssue = {
23
23
  * this list cannot silently fall behind the emitters.
24
24
  */
25
25
  export declare const RESERVED_ENUM_NAMES: readonly string[];
26
+ /**
27
+ * A model type-name family the generator renames when another owner generates
28
+ * the same name (`Call`'s to-many `CallListRelationFilter` and `CallList`'s
29
+ * to-one `CallListRelationFilter`). Every emission site of these families reads
30
+ * its name from {@link generatedTypeNames}.
31
+ */
32
+ export type DisambiguatedTypeSuffix = "ListRelationFilter" | "RelationFilter" | "RelationOrderByInput" | "RelationFindManyArgs" | "CreateArgs" | "UpdateArgs" | "UpdateWhereInput" | "UpsertArgs" | "DeleteArgs" | "CountArgs" | "CountSelect" | "AggregateArgs" | "ViewSelect" | "ViewInclude" | "ViewFindManyArgs" | "ViewFindUniqueArgs" | "ViewDelegate";
33
+ /** The declared names of one schema's generated client, shared by validation and the generator. */
34
+ export type GeneratedTypeNames = {
35
+ /** `<Model><Suffix>`, or `<Model>_<Suffix>` when an owner with a longer name keeps `<Model><Suffix>`. */
36
+ readonly model: (params: {
37
+ model: string;
38
+ suffix: DisambiguatedTypeSuffix;
39
+ }) => string;
40
+ };
41
+ /**
42
+ * The type names a valid schema's generated client declares. Validation
43
+ * reports the clashes this resolution cannot settle, so the generator only
44
+ * ever reads names that are unique.
45
+ */
46
+ export declare function generatedTypeNames(params: {
47
+ schema: SchemaIR;
48
+ }): GeneratedTypeNames;
26
49
  /** Validate a SchemaIR structurally; returns all issues found (empty = valid). */
27
50
  export declare function validateSchemaIR(params: {
28
51
  schema: SchemaIR;
29
52
  }): ValidationIssue[];
30
- /** Throw VIBE_SCHEMA_INVALID (with all issues in meta) if the schema is invalid. */
53
+ /**
54
+ * Throw VIBE_SCHEMA_INVALID (with all issues in meta) if the schema is invalid.
55
+ * A schema sealed by `sealSchemaIR` is validated once; later calls return at once.
56
+ */
31
57
  export declare function assertValidSchemaIR(params: {
32
58
  schema: SchemaIR;
33
59
  }): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibeorm/schema",
3
- "version": "5.8.0",
3
+ "version": "5.10.0",
4
4
  "description": "Canonical schema IR, validation, dialect/capability types, and error codes for VibeORM v2",
5
5
  "keywords": [
6
6
  "orm",