@vibeorm/schema 5.4.0 → 5.6.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.
@@ -151,6 +151,15 @@ export type DialectCapabilities = {
151
151
  * built.
152
152
  */
153
153
  readonly dateTruncation: boolean;
154
+ /**
155
+ * Row capture (`$transaction(…, { capture })`): a data-modifying statement
156
+ * reports the declared columns of the rows it changed as they were before
157
+ * and after it, as text — `RETURNING old."col"::text, new."col"::text`,
158
+ * PostgreSQL 18 or later (the server version is checked when a captured
159
+ * transaction opens). Without it `capture` is refused before the
160
+ * transaction opens.
161
+ */
162
+ readonly rowCapture: boolean;
154
163
  };
155
164
  export declare const POSTGRES_CAPABILITIES: DialectCapabilities;
156
165
  export declare const SQLITE_CAPABILITIES: DialectCapabilities;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Which dialect renders a field's `@collation`.
3
+ *
4
+ * MySQL and PostgreSQL both have column collations, in disjoint name
5
+ * namespaces: every MySQL collation is `binary` or `<character set>_<suffix>`
6
+ * over a closed list of character sets, while PostgreSQL names are libc
7
+ * locales (`C`, `POSIX`, `en_US.utf8`), ICU tags (`und-x-icu`), `ucs_basic`,
8
+ * `pg_c_utf8` or user-created collations. A portable schema that carries a
9
+ * MySQL collation for its MySQL target therefore stays valid on PostgreSQL,
10
+ * and a PostgreSQL schema's collation reaches PostgreSQL DDL.
11
+ */
12
+ import type { Dialect, FieldIR } from "./ir.ts";
13
+ /** Whether a collation name is a MySQL collation: `binary`, or `<MySQL character set>_<suffix>` (case-insensitive, as MySQL reads it). */
14
+ export declare function isMysqlCollationName(params: {
15
+ name: string;
16
+ }): boolean;
17
+ /**
18
+ * The collation `dialect` renders for `field`, or `undefined` where the
19
+ * declaration is inert: MySQL renders every `@collation`, PostgreSQL every one
20
+ * that is not a MySQL collation name ({@link isMysqlCollationName}), SQLite none.
21
+ */
22
+ export declare function dialectCollation(params: {
23
+ field: Pick<FieldIR, "collation">;
24
+ dialect: Dialect;
25
+ }): string | undefined;
26
+ //# sourceMappingURL=collation.d.ts.map
package/dist/errors.d.ts CHANGED
@@ -163,7 +163,7 @@ export declare const SCOPED_REFUSAL_REASONS: readonly [
163
163
  "unknown_column",
164
164
  /** A { column } entry names a field that cannot carry a scope (list/enum/non-scalar type). */
165
165
  "column_not_scopeable",
166
- /** A { through } entry names an unknown or to-many relation. */
166
+ /** A { through } entry names an unknown or to-many relation, or the side of a to-one relation without the foreign key. */
167
167
  "unknown_relation",
168
168
  /** A { through } chain cycles or ends on a "none" model instead of a { column } one. */
169
169
  "through_chain_invalid",
@@ -188,7 +188,13 @@ export declare const SCOPED_REFUSAL_REASONS: readonly [
188
188
  /** An unfiltered relation _count of a scoped model would count foreign rows. */
189
189
  "count_on_scoped_relation",
190
190
  /** An upsertMany conflict target could match another tenant's row (it omits the tenant column, or hides its columns). */
191
- "conflict_target_unscoped"];
191
+ "conflict_target_unscoped",
192
+ /** The call reaches a model a bound scope maps to "deny" — as its own call, a relation filter, a selection, a count, an order or a nested write. */
193
+ "model_denied",
194
+ /** A create leaves out a column a list scope restricts — the handle never picks a value from the list. */
195
+ "scope_value_required",
196
+ /** `$scoped({ scopes: {} })` — the named form binds at least one scope. */
197
+ "no_scope_bound"];
192
198
  export type ScopedRefusalReason = (typeof SCOPED_REFUSAL_REASONS)[number];
193
199
  /**
194
200
  * A refusal from a tenant-scoped handle (`$scoped`). Carries the model, the
package/dist/index.d.ts CHANGED
@@ -29,6 +29,7 @@ export { timeOfDayType } from "./time-of-day.ts";
29
29
  export { DATE_TRUNCATION_UNITS, dateTruncationStorage } from "./date-truncation.ts";
30
30
  export type { DateTruncationStorage, DateTruncationUnit } from "./date-truncation.ts";
31
31
  export { isLocalDateField, isCanonicalLocalDate, localDateCheckName } from "./local-date.ts";
32
+ export { dialectCollation, isMysqlCollationName } from "./collation.ts";
32
33
  export { READ_ONLY_REFUSAL_REASONS, ReadOnlyClientError, SCOPED_REFUSAL_REASONS, ScopedQueryError, VIBE_ERROR_CODES, VibeError, internalError, invalidStoredData, unsupportedCapability, } from "./errors.ts";
33
34
  export type { ReadOnlyRefusalReason, ScopedRefusalReason, VibeErrorCode } from "./errors.ts";
34
35
  export { decodePrismaString, encodePrismaString, exactDecimalLiteral, exactIntegerLiteral } from "./prisma-literal.ts";
package/dist/index.js CHANGED
@@ -106,7 +106,10 @@ var SCOPED_REFUSAL_REASONS = [
106
106
  "nested_refused",
107
107
  "relation_orderby_on_scoped",
108
108
  "count_on_scoped_relation",
109
- "conflict_target_unscoped"
109
+ "conflict_target_unscoped",
110
+ "model_denied",
111
+ "scope_value_required",
112
+ "no_scope_bound"
110
113
  ];
111
114
 
112
115
  class ScopedQueryError extends VibeError {
@@ -468,7 +471,8 @@ var POSTGRES_CAPABILITIES = Object.freeze({
468
471
  timeOfDayTypes: Object.freeze(["time", "timetz"]),
469
472
  uuidColumns: "native",
470
473
  localDateColumns: true,
471
- dateTruncation: true
474
+ dateTruncation: true,
475
+ rowCapture: true
472
476
  });
473
477
  var SQLITE_CAPABILITIES = Object.freeze({
474
478
  rowRuleAppendOnly: true,
@@ -509,7 +513,8 @@ var SQLITE_CAPABILITIES = Object.freeze({
509
513
  timeOfDayTypes: Object.freeze([]),
510
514
  uuidColumns: "text",
511
515
  localDateColumns: true,
512
- dateTruncation: false
516
+ dateTruncation: false,
517
+ rowCapture: false
513
518
  });
514
519
  var MYSQL_CAPABILITIES = Object.freeze({
515
520
  rowRuleAppendOnly: true,
@@ -550,7 +555,8 @@ var MYSQL_CAPABILITIES = Object.freeze({
550
555
  timeOfDayTypes: Object.freeze(["time"]),
551
556
  uuidColumns: "unsupported",
552
557
  localDateColumns: true,
553
- dateTruncation: false
558
+ dateTruncation: false,
559
+ rowCapture: false
554
560
  });
555
561
  var DIALECT_CAPABILITIES = Object.freeze({
556
562
  postgres: POSTGRES_CAPABILITIES,
@@ -2457,6 +2463,71 @@ function dateTruncationStorage(params) {
2457
2463
  return "timestamp";
2458
2464
  return;
2459
2465
  }
2466
+ // packages/schema/src/collation.ts
2467
+ var MYSQL_CHARACTER_SETS = new Set([
2468
+ "armscii8",
2469
+ "ascii",
2470
+ "big5",
2471
+ "binary",
2472
+ "cp1250",
2473
+ "cp1251",
2474
+ "cp1256",
2475
+ "cp1257",
2476
+ "cp850",
2477
+ "cp852",
2478
+ "cp866",
2479
+ "cp932",
2480
+ "dec8",
2481
+ "eucjpms",
2482
+ "euckr",
2483
+ "gb18030",
2484
+ "gb2312",
2485
+ "gbk",
2486
+ "geostd8",
2487
+ "greek",
2488
+ "hebrew",
2489
+ "hp8",
2490
+ "keybcs2",
2491
+ "koi8r",
2492
+ "koi8u",
2493
+ "latin1",
2494
+ "latin2",
2495
+ "latin5",
2496
+ "latin7",
2497
+ "macce",
2498
+ "macroman",
2499
+ "sjis",
2500
+ "swe7",
2501
+ "tis620",
2502
+ "ucs2",
2503
+ "ujis",
2504
+ "utf16",
2505
+ "utf16le",
2506
+ "utf32",
2507
+ "utf8",
2508
+ "utf8mb3",
2509
+ "utf8mb4"
2510
+ ]);
2511
+ function isMysqlCollationName(params) {
2512
+ const name = params.name.toLowerCase();
2513
+ if (name === "binary")
2514
+ return true;
2515
+ const separator = name.indexOf("_");
2516
+ return separator > 0 && separator < name.length - 1 && MYSQL_CHARACTER_SETS.has(name.slice(0, separator));
2517
+ }
2518
+ function dialectCollation(params) {
2519
+ const { collation } = params.field;
2520
+ if (collation === undefined)
2521
+ return;
2522
+ switch (params.dialect) {
2523
+ case "mysql":
2524
+ return collation;
2525
+ case "postgres":
2526
+ return isMysqlCollationName({ name: collation }) ? undefined : collation;
2527
+ case "sqlite":
2528
+ return;
2529
+ }
2530
+ }
2460
2531
  // packages/schema/src/computed.ts
2461
2532
  function buildComputedManifest(params) {
2462
2533
  const { computed } = params;
@@ -2838,6 +2909,7 @@ var RESERVED_ENUM_NAMES = [
2838
2909
  "ScopedClientInstance",
2839
2910
  "ScopedModelsConfig",
2840
2911
  "ScopedNestedMode",
2912
+ "ScopedScopeConfig",
2841
2913
  "VibeTransactionClientInstance",
2842
2914
  "ScopedTransactionClientInstance",
2843
2915
  "ReadOnlyClientInstance",
@@ -2847,6 +2919,9 @@ var RESERVED_ENUM_NAMES = [
2847
2919
  "createClient",
2848
2920
  "DatabaseAdapter",
2849
2921
  "DbNow",
2922
+ "JoinedField",
2923
+ "TransactionLocalSettings",
2924
+ "VibeUpdateManySources",
2850
2925
  "ClientContext",
2851
2926
  "QueryOperation",
2852
2927
  "QueryEvent",
@@ -2910,6 +2985,8 @@ var GENERATED_TYPE_NAMES = {
2910
2985
  "UpdateInput",
2911
2986
  "UncheckedUpdateInput",
2912
2987
  "UpdateManyInput",
2988
+ "UpdateManyJoinedInput",
2989
+ "UpdateManyFrom",
2913
2990
  "CountAggregateInput",
2914
2991
  "AvgAggregateInput",
2915
2992
  "SumAggregateInput",
@@ -4480,6 +4557,7 @@ export {
4480
4557
  defaultPrimaryKeyName,
4481
4558
  defaultRowRuleName,
4482
4559
  defineExtension,
4560
+ dialectCollation,
4483
4561
  encodePrismaString,
4484
4562
  enumStorageOf,
4485
4563
  exactDecimalLiteral,
@@ -4510,6 +4588,7 @@ export {
4510
4588
  isExpressionIndex,
4511
4589
  isImplicitManyToManyRelation,
4512
4590
  isLocalDateField,
4591
+ isMysqlCollationName,
4513
4592
  isPredicateFieldRef,
4514
4593
  isReservedClientName,
4515
4594
  isReservedDelegateName,
@@ -4563,4 +4642,4 @@ export {
4563
4642
  validatorRefIssue
4564
4643
  };
4565
4644
 
4566
- //# debugId=DBFAE1DBBF57344464756E2164756E21
4645
+ //# debugId=908B9801B15F7FB564756E2164756E21