@prisma-idb/client-idb 0.7.0 → 0.9.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.
@@ -1,4 +1,4 @@
1
- import { n as createIdbClient, t as createManagedIdbClient } from "./managed-client-BLdCyxUi.mjs";
1
+ import { n as createIdbClient, t as createManagedIdbClient } from "./managed-client-DofL09P8.mjs";
2
2
  import { isIdbDdlOp, openAndUpgrade, readMarker } from "@prisma-idb/target-idb/runtime";
3
3
  import { APP_SPACE_ID } from "@prisma/orm-framework/components/control";
4
4
  import { canonicalizeJson } from "@prisma/orm-framework/components/utils";
package/dist/client.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { n as createIdbClient, t as createManagedIdbClient } from "./managed-client-BLdCyxUi.mjs";
1
+ import { n as createIdbClient, t as createManagedIdbClient } from "./managed-client-DofL09P8.mjs";
2
2
  export { createIdbClient, createManagedIdbClient };
@@ -504,6 +504,69 @@ function createGroupedAccessor(init) {
504
504
  } };
505
505
  }
506
506
  //#endregion
507
+ //#region src/core/enum-validation.ts
508
+ const rulesByContract = /* @__PURE__ */ new WeakMap();
509
+ function resolveEnumRule(contract, field) {
510
+ const ref = field.valueSet;
511
+ if (ref === void 0 || ref.plane !== "domain" || ref.entityKind !== "enum") return void 0;
512
+ const contractEnum = contract.domain.namespaces[ref.namespaceId]?.enum?.[ref.entityName];
513
+ if (contractEnum === void 0) throw new Error(`Enum "${ref.entityName}" referenced by the contract is not declared in its domain.`);
514
+ return {
515
+ enumName: ref.entityName,
516
+ values: new Set(contractEnum.members.map((member) => member.value)),
517
+ nullable: field.nullable,
518
+ many: field.many === true
519
+ };
520
+ }
521
+ function getModelEnumRules(contract, modelName) {
522
+ let byModel = rulesByContract.get(contract);
523
+ if (byModel === void 0) {
524
+ byModel = /* @__PURE__ */ new Map();
525
+ rulesByContract.set(contract, byModel);
526
+ }
527
+ const cached = byModel.get(modelName);
528
+ if (cached !== void 0) return cached;
529
+ const rules = /* @__PURE__ */ new Map();
530
+ const fields = domainModelsAtDefaultNamespace(contract.domain)[modelName]?.fields ?? {};
531
+ for (const [fieldName, field] of Object.entries(fields)) {
532
+ const rule = resolveEnumRule(contract, field);
533
+ if (rule !== void 0) rules.set(fieldName, rule);
534
+ }
535
+ byModel.set(modelName, rules);
536
+ return rules;
537
+ }
538
+ function describe(value) {
539
+ return typeof value === "string" ? JSON.stringify(value) : `${String(value)} (${typeof value})`;
540
+ }
541
+ function invalidValueError(modelName, fieldName, rule, value) {
542
+ const expected = [...rule.values].map((v) => JSON.stringify(v)).join(", ");
543
+ return /* @__PURE__ */ new Error(`Invalid value ${describe(value)} for enum field "${modelName}.${fieldName}". Expected one of enum "${rule.enumName}": ${expected}.`);
544
+ }
545
+ /**
546
+ * Throws if `data` sets an enum field to a value its enum doesn't declare.
547
+ * Fields left `undefined` are not checked. `null` is accepted only on an
548
+ * optional (`Role?`) field; a list (`Role[]`) field must be an array whose
549
+ * every element is a declared value.
550
+ */
551
+ function assertEnumValues(contract, modelName, data) {
552
+ const rules = getModelEnumRules(contract, modelName);
553
+ if (rules.size === 0) return;
554
+ for (const [fieldName, rule] of rules) {
555
+ const value = data[fieldName];
556
+ if (value === void 0) continue;
557
+ if (value === null) {
558
+ if (rule.nullable) continue;
559
+ throw new Error(`Enum field "${modelName}.${fieldName}" is required and cannot be null.`);
560
+ }
561
+ if (rule.many) {
562
+ if (!Array.isArray(value)) throw new Error(`Enum list field "${modelName}.${fieldName}" expects an array of "${rule.enumName}" values, got ${describe(value)}.`);
563
+ for (const element of value) if (!rule.values.has(element)) throw invalidValueError(modelName, fieldName, rule, element);
564
+ continue;
565
+ }
566
+ if (!rule.values.has(value)) throw invalidValueError(modelName, fieldName, rule, value);
567
+ }
568
+ }
569
+ //#endregion
507
570
  //#region src/core/mutation-defaults.ts
508
571
  function createMutationDefaultsCache() {
509
572
  return /* @__PURE__ */ new Map();
@@ -939,6 +1002,7 @@ async function updateFirstGraph(scope, contract, modelName, filters, input, defa
939
1002
  const key = extractKeyFromRow(existingRow, getKeyPath(contract, modelName));
940
1003
  const meta = makePlanMeta(contract);
941
1004
  const patch = applyUpdateDefaults(contract.execution?.mutations.defaults, storeName, scalarData, defaultsCache);
1005
+ assertEnumValues(contract, modelName, patch);
942
1006
  await validateScalarFks(scope, contract, modelName, patch, existingRow);
943
1007
  await applyReferentialActionsForRowOnUpdate(scope, contract, modelName, existingRow, patch);
944
1008
  const updated = (await scope.execute({
@@ -1093,6 +1157,7 @@ async function insertSingleRow(scope, contract, modelName, data, defaultsCache)
1093
1157
  const storeName = getStoreName(contract, modelName);
1094
1158
  const meta = makePlanMeta(contract);
1095
1159
  const record = applyCreateDefaults(contract.execution?.mutations.defaults, storeName, data, defaultsCache);
1160
+ assertEnumValues(contract, modelName, record);
1096
1161
  await validateScalarFks(scope, contract, modelName, record);
1097
1162
  return (await scope.execute({
1098
1163
  meta,
@@ -1601,6 +1666,7 @@ async function executeScalarUpdateWithFkValidation(options) {
1601
1666
  const { executor, contract, modelName, filters, data } = options;
1602
1667
  const storeName = getStoreName(contract, modelName);
1603
1668
  const patch = applyUpdateDefaults(contract.execution?.mutations.defaults, storeName, data, createMutationDefaultsCache());
1669
+ assertEnumValues(contract, modelName, patch);
1604
1670
  const { storeNames, enforcesOnUpdate } = collectUpdateStoreNames(contract, modelName, patch);
1605
1671
  const needsRowForFks = fkCheckNeedsExistingRow(contract, modelName, patch);
1606
1672
  return withMutationScope(executor, storeNames, async (scope) => {
@@ -1661,6 +1727,7 @@ async function executeBulkUpdateWithFkValidation(options) {
1661
1727
  const { executor, contract, modelName, filters, data } = options;
1662
1728
  const storeName = getStoreName(contract, modelName);
1663
1729
  const patch = applyUpdateDefaults(contract.execution?.mutations.defaults, storeName, data, createMutationDefaultsCache());
1730
+ assertEnumValues(contract, modelName, patch);
1664
1731
  const { storeNames, enforcesOnUpdate } = collectUpdateStoreNames(contract, modelName, patch);
1665
1732
  const needsRowForFks = fkCheckNeedsExistingRow(contract, modelName, patch);
1666
1733
  return withMutationScope(executor, storeNames, async (scope) => {
@@ -1996,6 +2063,7 @@ var IdbStoreAccessorImpl = class IdbStoreAccessorImpl {
1996
2063
  data: record
1997
2064
  });
1998
2065
  const withDefaults = applyCreateDefaults(this.#contract.execution?.mutations.defaults, this.#storeName, record, createMutationDefaultsCache());
2066
+ assertEnumValues(this.#contract, this.#modelName, withDefaults);
1999
2067
  if (hasScalarFkFields(this.#contract, this.#modelName, withDefaults)) return await executeScalarCreateWithFkValidation({
2000
2068
  executor: requireTransactionExecutor(this.#executor),
2001
2069
  contract: this.#contract,
@@ -2128,6 +2196,8 @@ var IdbStoreAccessorImpl = class IdbStoreAccessorImpl {
2128
2196
  const exec = requireTransactionExecutor(this.#executor);
2129
2197
  const effectivePatch = applyUpdateDefaults(executionDefaults, storeName, patchRecord, createMutationDefaultsCache());
2130
2198
  const createWithDefaults = applyCreateDefaults(executionDefaults, storeName, createRecord, createMutationDefaultsCache());
2199
+ assertEnumValues(this.#contract, this.#modelName, effectivePatch);
2200
+ assertEnumValues(this.#contract, this.#modelName, createWithDefaults);
2131
2201
  const { storeNames: onUpdateStoreNames } = collectOnUpdateEnforcementStoreNames(this.#contract, this.#modelName, effectivePatch);
2132
2202
  return withMutationScope(exec, [.../* @__PURE__ */ new Set([
2133
2203
  storeName,
@@ -2203,7 +2273,10 @@ var IdbStoreAccessorImpl = class IdbStoreAccessorImpl {
2203
2273
  }
2204
2274
  };
2205
2275
  const executorQuery = this.#executor.query.bind(this.#executor);
2276
+ const contract = this.#contract;
2277
+ const modelName = this.#modelName;
2206
2278
  return new AsyncIterableResult((async function* () {
2279
+ for (const record of records) assertEnumValues(contract, modelName, record);
2207
2280
  for await (const row of executorQuery(plan)) yield row;
2208
2281
  })());
2209
2282
  }
@@ -2511,4 +2584,4 @@ function idbOrm(options) {
2511
2584
  //#endregion
2512
2585
  export { createRelationMutator as a, withMutationScope as c, getStoreName as d, keyEquals as f, hasNestedMutationCallbacks as i, extractKeyFromRow as l, applyReferentialActionsForRow as n, isRelationMutationCallback as o, keyToken as p, collectDeleteStoreNames as r, isRelationMutationDescriptor as s, idbOrm as t, getKeyPath as u };
2513
2586
 
2514
- //# sourceMappingURL=idb-orm-JBg6si7u.mjs.map
2587
+ //# sourceMappingURL=idb-orm-C8yXJp6R.mjs.map