@vibeorm/schema 2.2.0 → 2.3.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.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +101 -97
- package/dist/index.js.map +5 -5
- package/dist/ir.d.ts +5 -0
- package/dist/ir.d.ts.map +1 -1
- package/dist/migration-objects.d.ts +7 -1
- package/dist/migration-objects.d.ts.map +1 -1
- package/dist/validate.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export type { CascadeAction, DatasourceIR, DefaultValueIR, Dialect, EnumIR, Enum
|
|
|
9
9
|
export { PREDICATE_COMPARISON_OPS, isPredicateFieldRef, predicateFieldNames, predicateKey } from "./predicate.ts";
|
|
10
10
|
export type { PredicateComparisonOp, PredicateFieldRef, PredicateIR, PredicateOperand, PredicateValue } from "./predicate.ts";
|
|
11
11
|
export { assertMigrationObjects, isSqlObjectDefinition, isSqlObjectIdentity, sqlObjectKey } from "./migration-objects.ts";
|
|
12
|
-
export type { MigrationObjectIR, QualifiedSqlName, SqlObjectDefinition, SqlObjectFacts, SqlObjectIdentity } from "./migration-objects.ts";
|
|
12
|
+
export type { MigrationObjectIR, QualifiedSqlName, SqlObjectDefinition, SqlObjectDefinitionFormat, SqlObjectFacts, SqlObjectIdentity } from "./migration-objects.ts";
|
|
13
13
|
export type { AdvisoryLockMode, DialectCapabilities, FullTextEngine, RowLockStrength, RowLockWaitPolicy, } from "./capabilities.ts";
|
|
14
14
|
export { READ_ONLY_REFUSAL_REASONS, ReadOnlyClientError, SCOPED_REFUSAL_REASONS, ScopedQueryError, VIBE_ERROR_CODES, VibeError, internalError, invalidStoredData, unsupportedCapability, } from "./errors.ts";
|
|
15
15
|
export type { ReadOnlyRefusalReason, ScopedRefusalReason, VibeErrorCode } from "./errors.ts";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,YAAY,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAElH,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAElG,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,iBAAiB,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACnH,YAAY,EACV,aAAa,EACb,YAAY,EACZ,cAAc,EACd,OAAO,EACP,MAAM,EACN,WAAW,EACX,eAAe,EACf,OAAO,EACP,SAAS,EACT,YAAY,EACZ,OAAO,EACP,OAAO,EACP,SAAS,EACT,OAAO,EACP,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,UAAU,EACV,QAAQ,GACT,MAAM,SAAS,CAAC;AAIjB,OAAO,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAClH,YAAY,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,WAAW,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAE9H,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC1H,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -278,7 +278,7 @@ function isSqlObjectIdentity(value) {
|
|
|
278
278
|
}
|
|
279
279
|
}
|
|
280
280
|
function isSqlObjectDefinition(value) {
|
|
281
|
-
return record(value) && value.format === "catalog-v1" && 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);
|
|
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);
|
|
282
282
|
}
|
|
283
283
|
function assertMigrationObjects(params) {
|
|
284
284
|
if (!Array.isArray(params.objects))
|
|
@@ -469,26 +469,26 @@ function extensionManifestEntry(params) {
|
|
|
469
469
|
}
|
|
470
470
|
var EXTENSION_NAME_PATTERN = /^[a-z][a-zA-Z0-9]*$/;
|
|
471
471
|
function defineExtension(extension) {
|
|
472
|
-
const { name
|
|
473
|
-
if (!EXTENSION_NAME_PATTERN.test(
|
|
472
|
+
const { name } = extension;
|
|
473
|
+
if (!EXTENSION_NAME_PATTERN.test(name)) {
|
|
474
474
|
throw new VibeError({
|
|
475
475
|
code: "VIBE_CONFIG",
|
|
476
|
-
message: `extension name "${
|
|
477
|
-
meta: { name
|
|
476
|
+
message: `extension name "${name}" is invalid \u2014 must match ${EXTENSION_NAME_PATTERN} (it becomes a client identifier)`,
|
|
477
|
+
meta: { name }
|
|
478
478
|
});
|
|
479
479
|
}
|
|
480
|
-
if (RESERVED_DELEGATE_NAMES.includes(
|
|
480
|
+
if (RESERVED_DELEGATE_NAMES.includes(name)) {
|
|
481
481
|
throw new VibeError({
|
|
482
482
|
code: "VIBE_CONFIG",
|
|
483
|
-
message: `extension name "${
|
|
484
|
-
meta: { name
|
|
483
|
+
message: `extension name "${name}" collides with a core delegate method`,
|
|
484
|
+
meta: { name }
|
|
485
485
|
});
|
|
486
486
|
}
|
|
487
|
-
if (RESERVED_CLIENT_NAMES.includes(`$${
|
|
487
|
+
if (RESERVED_CLIENT_NAMES.includes(`$${name}`)) {
|
|
488
488
|
throw new VibeError({
|
|
489
489
|
code: "VIBE_CONFIG",
|
|
490
|
-
message: `extension name "${
|
|
491
|
-
meta: { name
|
|
490
|
+
message: `extension name "${name}" collides with the core client method "$${name}"`,
|
|
491
|
+
meta: { name }
|
|
492
492
|
});
|
|
493
493
|
}
|
|
494
494
|
return Object.freeze(extension);
|
|
@@ -1038,21 +1038,21 @@ var INVALID_BINDING_NAMES = new Set([
|
|
|
1038
1038
|
]);
|
|
1039
1039
|
function validateGeneratedNames(params) {
|
|
1040
1040
|
const { schema, issues } = params;
|
|
1041
|
-
const owners = new Map(RESERVED_ENUM_NAMES.map((
|
|
1041
|
+
const owners = new Map(RESERVED_ENUM_NAMES.map((name) => [name, "generated client"]));
|
|
1042
1042
|
if (schema.rls !== undefined) {
|
|
1043
1043
|
owners.set("RlsContext", "native RLS client");
|
|
1044
1044
|
owners.set("BoundVibeClientInstance", "native RLS client");
|
|
1045
1045
|
owners.set("BoundVibeTransactionClientInstance", "native RLS client");
|
|
1046
1046
|
}
|
|
1047
|
-
const register = (
|
|
1048
|
-
if (!/^[$_\p{ID_Start}][$_\u200c\u200d\p{ID_Continue}]*$/u.test(
|
|
1049
|
-
issues.push({ rule: "invalid-generated-identifier", message: `Generated name "${
|
|
1047
|
+
const register = (params) => {
|
|
1048
|
+
if (!/^[$_\p{ID_Start}][$_\u200c\u200d\p{ID_Continue}]*$/u.test(params.name) || INVALID_BINDING_NAMES.has(params.name)) {
|
|
1049
|
+
issues.push({ rule: "invalid-generated-identifier", message: `Generated name "${params.name}" from ${params.owner} is not a legal TypeScript identifier` });
|
|
1050
1050
|
}
|
|
1051
|
-
const previous = owners.get(
|
|
1052
|
-
if (previous !== undefined && previous !==
|
|
1053
|
-
issues.push({ rule: "generated-name-collision", message: `Generated name "${
|
|
1051
|
+
const previous = owners.get(params.name);
|
|
1052
|
+
if (previous !== undefined && previous !== params.owner) {
|
|
1053
|
+
issues.push({ rule: "generated-name-collision", message: `Generated name "${params.name}" from ${params.owner} conflicts with ${previous}` });
|
|
1054
1054
|
} else {
|
|
1055
|
-
owners.set(
|
|
1055
|
+
owners.set(params.name, params.owner);
|
|
1056
1056
|
}
|
|
1057
1057
|
};
|
|
1058
1058
|
const aliases = new Map;
|
|
@@ -1200,8 +1200,8 @@ function validateSchemaIR(params) {
|
|
|
1200
1200
|
}
|
|
1201
1201
|
}
|
|
1202
1202
|
const seenSelectorNames = new Set;
|
|
1203
|
-
const checkSelectorName = (
|
|
1204
|
-
const { clientName, fieldCount, where, isUnique, site } =
|
|
1203
|
+
const checkSelectorName = (params) => {
|
|
1204
|
+
const { clientName, fieldCount, where, isUnique, site } = params;
|
|
1205
1205
|
if (!isUnique) {
|
|
1206
1206
|
issues.push({
|
|
1207
1207
|
rule: "client-name-non-unique",
|
|
@@ -1273,6 +1273,10 @@ function validateModel(params) {
|
|
|
1273
1273
|
});
|
|
1274
1274
|
}
|
|
1275
1275
|
memberNames.add(field.name);
|
|
1276
|
+
const typeIdentity = field.nativeTypeIdentity;
|
|
1277
|
+
if (typeIdentity !== undefined && (typeIdentity === null || typeof typeIdentity !== "object" || field.isUnsupported !== true || typeof typeIdentity.source !== "string" || typeIdentity.source !== field.nativeType || typeof typeIdentity.namespace !== "string" || typeIdentity.namespace.length === 0 || typeIdentity.namespace.includes("\x00"))) {
|
|
1278
|
+
issues.push({ rule: "invalid-native-type-identity", message: `PostgreSQL type identity on "${model.name}.${field.name}" must be bound to its unsupported declaration`, model: model.name, field: field.name });
|
|
1279
|
+
}
|
|
1276
1280
|
const defaultValue = field.default;
|
|
1277
1281
|
if (defaultValue !== undefined && defaultValue.kind !== "dbgenerated" && defaultValue.kind !== "list") {
|
|
1278
1282
|
let valid = !field.isList;
|
|
@@ -1326,8 +1330,8 @@ function validateModel(params) {
|
|
|
1326
1330
|
field: field.name
|
|
1327
1331
|
});
|
|
1328
1332
|
} else {
|
|
1329
|
-
const
|
|
1330
|
-
const candidate =
|
|
1333
|
+
const defaultValue = field.default;
|
|
1334
|
+
const candidate = defaultValue === undefined ? undefined : defaultValue.kind === "enumValue" ? defaultValue.value : defaultValue.kind === "literal" && typeof defaultValue.value === "string" ? defaultValue.value : undefined;
|
|
1331
1335
|
if (candidate !== undefined && !enumDef.values.includes(candidate)) {
|
|
1332
1336
|
issues.push({
|
|
1333
1337
|
rule: "enum-default-not-member",
|
|
@@ -1519,22 +1523,22 @@ function validateModel(params) {
|
|
|
1519
1523
|
}
|
|
1520
1524
|
function validatePredicateFields(params) {
|
|
1521
1525
|
const { predicate, model, fieldNames, site, issues } = params;
|
|
1522
|
-
for (const
|
|
1523
|
-
if (!fieldNames.has(
|
|
1526
|
+
for (const name of predicateFieldNames({ predicate })) {
|
|
1527
|
+
if (!fieldNames.has(name)) {
|
|
1524
1528
|
issues.push({
|
|
1525
1529
|
rule: "predicate-unknown-field",
|
|
1526
|
-
message: `${site} on "${model.name}" references unknown field "${
|
|
1530
|
+
message: `${site} on "${model.name}" references unknown field "${name}"`,
|
|
1527
1531
|
model: model.name,
|
|
1528
|
-
field:
|
|
1532
|
+
field: name
|
|
1529
1533
|
});
|
|
1530
1534
|
continue;
|
|
1531
1535
|
}
|
|
1532
|
-
if (model.fields.find((field) => field.name ===
|
|
1536
|
+
if (model.fields.find((field) => field.name === name)?.isList === true) {
|
|
1533
1537
|
issues.push({
|
|
1534
1538
|
rule: "predicate-list-field",
|
|
1535
|
-
message: `${site} on "${model.name}" compares scalar list "${
|
|
1539
|
+
message: `${site} on "${model.name}" compares scalar list "${name}" \u2014 use a raw expression for array operators`,
|
|
1536
1540
|
model: model.name,
|
|
1537
|
-
field:
|
|
1541
|
+
field: name
|
|
1538
1542
|
});
|
|
1539
1543
|
}
|
|
1540
1544
|
}
|
|
@@ -1556,10 +1560,10 @@ function assertValidSchemaIR(params) {
|
|
|
1556
1560
|
const source = exclusion.source;
|
|
1557
1561
|
if (source !== undefined) {
|
|
1558
1562
|
const references = [...source.keys.flatMap((key) => ("field" in key) ? [key.field] : key.fields), ...[source.range.lower, source.range.upper].flatMap((endpoint) => ("field" in endpoint) ? [endpoint.field] : []), ...source.where === undefined ? [] : predicateFieldNames({ predicate: source.where })];
|
|
1559
|
-
if (references.some((
|
|
1563
|
+
if (references.some((name) => !model.fields.some((field) => field.name === name && !field.isList)))
|
|
1560
1564
|
throw new VibeError({ code: "VIBE_SCHEMA_INVALID", message: "Exclusion references an unknown or list field", meta: { rule: "exclusion-field", model: model.name } });
|
|
1561
1565
|
}
|
|
1562
|
-
if (!exclusion.name || names.has(exclusion.name) || typeof exclusion.definition !== "string" || !exclusion.definition.startsWith("EXCLUDE USING ") || !Array.isArray(exclusion.requiredExtensions) || exclusion.requiredExtensions.some((
|
|
1566
|
+
if (!exclusion.name || names.has(exclusion.name) || typeof exclusion.definition !== "string" || !exclusion.definition.startsWith("EXCLUDE USING ") || !Array.isArray(exclusion.requiredExtensions) || exclusion.requiredExtensions.some((name) => name !== "btree_gist"))
|
|
1563
1567
|
throw new VibeError({ code: "VIBE_SCHEMA_INVALID", message: "Invalid exclusion declaration", meta: { rule: "exclusion-definition", model: model.name } });
|
|
1564
1568
|
names.add(exclusion.name);
|
|
1565
1569
|
}
|
|
@@ -1581,8 +1585,8 @@ function assertValidSchemaIR(params) {
|
|
|
1581
1585
|
throw new VibeError({ code: "VIBE_SCHEMA_INVALID", message: `List default on non-list field ${model.name}.${field.name}` });
|
|
1582
1586
|
scalarListDefault({ type: field.type, values: field.default.values });
|
|
1583
1587
|
if (isEnumType(field.type)) {
|
|
1584
|
-
const
|
|
1585
|
-
const members = params.schema.enums.find((entry) => entry.name ===
|
|
1588
|
+
const name = field.type.enum;
|
|
1589
|
+
const members = params.schema.enums.find((entry) => entry.name === name)?.values ?? [];
|
|
1586
1590
|
if (field.default.values.some((value) => typeof value !== "string" || !members.includes(value)))
|
|
1587
1591
|
throw new VibeError({ code: "VIBE_SCHEMA_INVALID", message: `Invalid enum-list default on ${model.name}.${field.name}` });
|
|
1588
1592
|
}
|
|
@@ -1673,8 +1677,8 @@ function validateNativeRls(params) {
|
|
|
1673
1677
|
const tables = new Set;
|
|
1674
1678
|
const throughTargets = new Map;
|
|
1675
1679
|
for (const model of schema.models) {
|
|
1676
|
-
const add = (
|
|
1677
|
-
issues.push({ ...
|
|
1680
|
+
const add = (params) => {
|
|
1681
|
+
issues.push({ ...params, model: model.name });
|
|
1678
1682
|
};
|
|
1679
1683
|
const table = model.dbName ?? model.name;
|
|
1680
1684
|
if (tables.has(table))
|
|
@@ -1682,10 +1686,10 @@ function validateNativeRls(params) {
|
|
|
1682
1686
|
tables.add(table);
|
|
1683
1687
|
const columns = new Set;
|
|
1684
1688
|
for (const field of model.fields) {
|
|
1685
|
-
const
|
|
1686
|
-
if (columns.has(
|
|
1687
|
-
add({ rule: "rls-duplicate-column", message: `RLS model ${model.name} repeats physical column ${
|
|
1688
|
-
columns.add(
|
|
1689
|
+
const name = field.dbName ?? field.name;
|
|
1690
|
+
if (columns.has(name))
|
|
1691
|
+
add({ rule: "rls-duplicate-column", message: `RLS model ${model.name} repeats physical column ${name}`, field: field.name });
|
|
1692
|
+
columns.add(name);
|
|
1689
1693
|
}
|
|
1690
1694
|
if (model.policy !== undefined)
|
|
1691
1695
|
add({ rule: "rls-policy-conflict", message: "Native RLS cannot combine with application-level ModelIR.policy" });
|
|
@@ -1738,7 +1742,7 @@ function validateNativeRls(params) {
|
|
|
1738
1742
|
add({ rule: "rls-invalid-through", message: "Native RLS through requires a to-one relation with an actual, complete foreign key on this model" });
|
|
1739
1743
|
continue;
|
|
1740
1744
|
}
|
|
1741
|
-
if (relation.isOptional || relation.fields?.some((
|
|
1745
|
+
if (relation.isOptional || relation.fields?.some((name) => model.fields.find((field) => field.name === name)?.isOptional)) {
|
|
1742
1746
|
add({ rule: "rls-nullable-through", message: "Native RLS through requires a non-nullable parent relation and foreign key; NULL parent links cannot satisfy WITH CHECK. Make the link required or use a direct ownership rule", field: relation.name });
|
|
1743
1747
|
continue;
|
|
1744
1748
|
}
|
|
@@ -1770,8 +1774,8 @@ function validRlsForeignKey(params) {
|
|
|
1770
1774
|
const refs = relation.references;
|
|
1771
1775
|
if (fields === undefined || refs === undefined || fields.length === 0 || fields.length !== refs.length || new Set(fields).size !== fields.length || new Set(refs).size !== refs.length)
|
|
1772
1776
|
return false;
|
|
1773
|
-
const validFields = fields.every((
|
|
1774
|
-
const field = model.fields.find((f) => f.name ===
|
|
1777
|
+
const validFields = fields.every((name, index) => {
|
|
1778
|
+
const field = model.fields.find((f) => f.name === name);
|
|
1775
1779
|
const ref = target.fields.find((f) => f.name === refs[index]);
|
|
1776
1780
|
return field !== undefined && ref !== undefined && !field.isList && !ref.isList && !field.isUnsupported && !ref.isUnsupported && (field.type === ref.type || isEnumType(field.type) && isEnumType(ref.type) && field.type.enum === ref.type.enum);
|
|
1777
1781
|
});
|
|
@@ -1780,7 +1784,7 @@ function validRlsForeignKey(params) {
|
|
|
1780
1784
|
...target.primaryKey === undefined ? [] : [target.primaryKey.fields],
|
|
1781
1785
|
...target.indexes.filter((index) => index.kind === "unique" && index.where === undefined).map((index) => index.fields.map((f) => f.name))
|
|
1782
1786
|
];
|
|
1783
|
-
return validFields && uniqueSets.some((set) => set.length === refs.length && set.every((
|
|
1787
|
+
return validFields && uniqueSets.some((set) => set.length === refs.length && set.every((name) => refs.includes(name)));
|
|
1784
1788
|
}
|
|
1785
1789
|
// packages/schema/src/m2m.ts
|
|
1786
1790
|
function implicitJoinTable(params) {
|
|
@@ -1797,59 +1801,59 @@ function implicitJoinTable(params) {
|
|
|
1797
1801
|
};
|
|
1798
1802
|
}
|
|
1799
1803
|
export {
|
|
1800
|
-
|
|
1801
|
-
validateRlsContextIR,
|
|
1802
|
-
validateComputedConfig,
|
|
1803
|
-
unsupportedCapability,
|
|
1804
|
-
sqlObjectKey,
|
|
1805
|
-
serializeJsonDefault,
|
|
1806
|
-
scalarListDefault,
|
|
1807
|
-
providerToDialect,
|
|
1808
|
-
predicateKey,
|
|
1809
|
-
predicateFieldNames,
|
|
1810
|
-
mergeExtensionDeclarations,
|
|
1811
|
-
isSqlObjectIdentity,
|
|
1812
|
-
isSqlObjectDefinition,
|
|
1813
|
-
isReservedDelegateName,
|
|
1814
|
-
isReservedClientName,
|
|
1815
|
-
isPredicateFieldRef,
|
|
1816
|
-
isImplicitManyToManyRelation,
|
|
1817
|
-
isEnumType,
|
|
1818
|
-
invalidStoredData,
|
|
1819
|
-
internalError,
|
|
1820
|
-
implicitJoinTable,
|
|
1821
|
-
fieldTypeIdentity,
|
|
1822
|
-
extensionOptionsHash,
|
|
1823
|
-
extensionManifestEntry,
|
|
1824
|
-
extensionDeclarations,
|
|
1825
|
-
exactIntegerLiteral,
|
|
1826
|
-
enumStorageOf,
|
|
1827
|
-
encodePrismaString,
|
|
1828
|
-
defineExtension,
|
|
1829
|
-
decodePrismaString,
|
|
1830
|
-
buildExtensionRegistry,
|
|
1831
|
-
buildComputedManifest,
|
|
1832
|
-
assertValidSchemaIR,
|
|
1833
|
-
assertMigrationObjects,
|
|
1834
|
-
VibeError,
|
|
1835
|
-
VIBE_ERROR_CODES,
|
|
1836
|
-
ScopedQueryError,
|
|
1837
|
-
SQLITE_CAPABILITIES,
|
|
1838
|
-
SCOPED_REFUSAL_REASONS,
|
|
1839
|
-
RlsContextError,
|
|
1840
|
-
ReadOnlyClientError,
|
|
1841
|
-
RLS_CONTEXT_REASONS,
|
|
1842
|
-
RESERVED_ENUM_NAMES,
|
|
1843
|
-
RESERVED_DELEGATE_NAMES,
|
|
1844
|
-
RESERVED_CLIENT_NAMES,
|
|
1845
|
-
READ_ONLY_REFUSAL_REASONS,
|
|
1846
|
-
PREDICATE_COMPARISON_OPS,
|
|
1847
|
-
POSTGRES_CAPABILITIES,
|
|
1848
|
-
MYSQL_CAPABILITIES,
|
|
1849
|
-
ENUM_STORAGES,
|
|
1850
|
-
EMPTY_EXTENSION_REGISTRY,
|
|
1804
|
+
DIALECTS,
|
|
1851
1805
|
DIALECT_CAPABILITIES,
|
|
1852
|
-
|
|
1806
|
+
EMPTY_EXTENSION_REGISTRY,
|
|
1807
|
+
ENUM_STORAGES,
|
|
1808
|
+
MYSQL_CAPABILITIES,
|
|
1809
|
+
POSTGRES_CAPABILITIES,
|
|
1810
|
+
PREDICATE_COMPARISON_OPS,
|
|
1811
|
+
READ_ONLY_REFUSAL_REASONS,
|
|
1812
|
+
RESERVED_CLIENT_NAMES,
|
|
1813
|
+
RESERVED_DELEGATE_NAMES,
|
|
1814
|
+
RESERVED_ENUM_NAMES,
|
|
1815
|
+
RLS_CONTEXT_REASONS,
|
|
1816
|
+
ReadOnlyClientError,
|
|
1817
|
+
RlsContextError,
|
|
1818
|
+
SCOPED_REFUSAL_REASONS,
|
|
1819
|
+
SQLITE_CAPABILITIES,
|
|
1820
|
+
ScopedQueryError,
|
|
1821
|
+
VIBE_ERROR_CODES,
|
|
1822
|
+
VibeError,
|
|
1823
|
+
assertMigrationObjects,
|
|
1824
|
+
assertValidSchemaIR,
|
|
1825
|
+
buildComputedManifest,
|
|
1826
|
+
buildExtensionRegistry,
|
|
1827
|
+
decodePrismaString,
|
|
1828
|
+
defineExtension,
|
|
1829
|
+
encodePrismaString,
|
|
1830
|
+
enumStorageOf,
|
|
1831
|
+
exactIntegerLiteral,
|
|
1832
|
+
extensionDeclarations,
|
|
1833
|
+
extensionManifestEntry,
|
|
1834
|
+
extensionOptionsHash,
|
|
1835
|
+
fieldTypeIdentity,
|
|
1836
|
+
implicitJoinTable,
|
|
1837
|
+
internalError,
|
|
1838
|
+
invalidStoredData,
|
|
1839
|
+
isEnumType,
|
|
1840
|
+
isImplicitManyToManyRelation,
|
|
1841
|
+
isPredicateFieldRef,
|
|
1842
|
+
isReservedClientName,
|
|
1843
|
+
isReservedDelegateName,
|
|
1844
|
+
isSqlObjectDefinition,
|
|
1845
|
+
isSqlObjectIdentity,
|
|
1846
|
+
mergeExtensionDeclarations,
|
|
1847
|
+
predicateFieldNames,
|
|
1848
|
+
predicateKey,
|
|
1849
|
+
providerToDialect,
|
|
1850
|
+
scalarListDefault,
|
|
1851
|
+
serializeJsonDefault,
|
|
1852
|
+
sqlObjectKey,
|
|
1853
|
+
unsupportedCapability,
|
|
1854
|
+
validateComputedConfig,
|
|
1855
|
+
validateRlsContextIR,
|
|
1856
|
+
validateSchemaIR
|
|
1853
1857
|
};
|
|
1854
1858
|
|
|
1855
|
-
//# debugId=
|
|
1859
|
+
//# debugId=5275C43BC09D1F0064756E2164756E21
|