@atscript/db 0.1.40 → 0.1.41

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/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="https://atscript.dev/logo.svg" alt="Atscript" width="120" />
2
+ <img src="https://db.atscript.dev/logo.svg" alt="Atscript" width="120" />
3
3
  </p>
4
4
 
5
5
  <h1 align="center">@atscript/db</h1>
@@ -2108,13 +2108,35 @@ function createDbValidatorPlugin() {
2108
2108
  const isFrom = def.metadata.has("db.rel.from");
2109
2109
  const isVia = def.metadata.has("db.rel.via");
2110
2110
  if (isTo || isFrom || isVia) return handleNavField(ctx, def, value, dbCtx, isTo, isFrom, isVia);
2111
- if (dbCtx.mode === "patch" && require_ops.isDbFieldOp(value)) return true;
2111
+ if (dbCtx.mode === "patch" && require_ops.isDbFieldOp(value)) {
2112
+ if (dbCtx.flatMap && !isFieldOpAllowed(ctx.path, dbCtx.flatMap)) {
2113
+ ctx.error("Field operations ($inc/$dec/$mul) are not supported inside @db.json fields or nested objects without @db.patch.strategy \"merge\"");
2114
+ return false;
2115
+ }
2116
+ return true;
2117
+ }
2112
2118
  if (dbCtx.mode === "patch" && def.type.kind === "array" && dbCtx.flatMap) {
2113
2119
  const flatEntry = dbCtx.flatMap.get(ctx.path);
2114
2120
  if (flatEntry?.metadata?.has("db.__topLevelArray") && !flatEntry.metadata.has("db.json")) return handleArrayPatch(ctx, def, value);
2115
2121
  }
2116
2122
  };
2117
2123
  }
2124
+ /**
2125
+ * Checks whether a field op is valid at `path` by walking up ancestors
2126
+ * in the flatMap. Rejects if any ancestor is @db.json or a nested object
2127
+ * without @db.patch.strategy "merge".
2128
+ */
2129
+ function isFieldOpAllowed(path, flatMap) {
2130
+ let pos = path.length;
2131
+ while ((pos = path.lastIndexOf(".", pos - 1)) !== -1) {
2132
+ const ancestor = path.slice(0, pos);
2133
+ const entry = flatMap.get(ancestor);
2134
+ if (!entry) continue;
2135
+ if (entry.metadata.has("db.json")) return false;
2136
+ if (entry.type.kind === "object" && entry.metadata.get("db.patch.strategy") !== "merge") return false;
2137
+ }
2138
+ return true;
2139
+ }
2118
2140
  function handleNavField(ctx, def, value, dbCtx, isTo, isFrom, isVia) {
2119
2141
  const pathParts = ctx.path.split(".");
2120
2142
  const fieldName = pathParts[pathParts.length - 1] || ctx.path;
@@ -2653,18 +2675,21 @@ var AtscriptDbTable = class extends AtscriptDbReadable {
2653
2675
  for (const navField of this._meta.navFields) delete data[navField];
2654
2676
  const filter = this._extractPrimaryKeyFilter(data);
2655
2677
  for (const pk of this._meta.primaryKeys) delete data[pk];
2656
- const ops = require_ops.separateFieldOps(data);
2657
- if (_isEmptyObj(data) && !ops) {
2678
+ if (_isEmptyObj(data)) {
2658
2679
  matchedCount += 1;
2659
2680
  modifiedCount += 0;
2660
2681
  continue;
2661
2682
  }
2662
2683
  let result;
2663
2684
  const translatedFilter = this._fieldMapper.translateFilter(filter, this._meta);
2664
- const translatedOps = ops ? _translateOpsKeys(ops, this._meta) : void 0;
2665
- if (this.adapter.supportsNativePatch()) result = await this.adapter.nativePatch(translatedFilter, data, translatedOps);
2666
- else {
2685
+ if (this.adapter.supportsNativePatch()) {
2686
+ const ops = require_ops.separateFieldOps(data);
2687
+ const translatedOps = ops ? _translateOpsKeys(ops, this._meta) : void 0;
2688
+ result = await this.adapter.nativePatch(translatedFilter, data, translatedOps);
2689
+ } else {
2667
2690
  const update = decomposePatch(data, this);
2691
+ const ops = require_ops.separateFieldOps(update);
2692
+ const translatedOps = ops ? _translateOpsKeys(ops, this._meta) : void 0;
2668
2693
  const translatedUpdate = this._fieldMapper.translatePatchKeys(update, this._meta);
2669
2694
  if (getArrayOpsFields(translatedUpdate).size > 0) {
2670
2695
  const resolved = resolveArrayOps(translatedUpdate, await this.adapter.findOne({
@@ -2108,13 +2108,35 @@ function createDbValidatorPlugin() {
2108
2108
  const isFrom = def.metadata.has("db.rel.from");
2109
2109
  const isVia = def.metadata.has("db.rel.via");
2110
2110
  if (isTo || isFrom || isVia) return handleNavField(ctx, def, value, dbCtx, isTo, isFrom, isVia);
2111
- if (dbCtx.mode === "patch" && isDbFieldOp(value)) return true;
2111
+ if (dbCtx.mode === "patch" && isDbFieldOp(value)) {
2112
+ if (dbCtx.flatMap && !isFieldOpAllowed(ctx.path, dbCtx.flatMap)) {
2113
+ ctx.error("Field operations ($inc/$dec/$mul) are not supported inside @db.json fields or nested objects without @db.patch.strategy \"merge\"");
2114
+ return false;
2115
+ }
2116
+ return true;
2117
+ }
2112
2118
  if (dbCtx.mode === "patch" && def.type.kind === "array" && dbCtx.flatMap) {
2113
2119
  const flatEntry = dbCtx.flatMap.get(ctx.path);
2114
2120
  if (flatEntry?.metadata?.has("db.__topLevelArray") && !flatEntry.metadata.has("db.json")) return handleArrayPatch(ctx, def, value);
2115
2121
  }
2116
2122
  };
2117
2123
  }
2124
+ /**
2125
+ * Checks whether a field op is valid at `path` by walking up ancestors
2126
+ * in the flatMap. Rejects if any ancestor is @db.json or a nested object
2127
+ * without @db.patch.strategy "merge".
2128
+ */
2129
+ function isFieldOpAllowed(path, flatMap) {
2130
+ let pos = path.length;
2131
+ while ((pos = path.lastIndexOf(".", pos - 1)) !== -1) {
2132
+ const ancestor = path.slice(0, pos);
2133
+ const entry = flatMap.get(ancestor);
2134
+ if (!entry) continue;
2135
+ if (entry.metadata.has("db.json")) return false;
2136
+ if (entry.type.kind === "object" && entry.metadata.get("db.patch.strategy") !== "merge") return false;
2137
+ }
2138
+ return true;
2139
+ }
2118
2140
  function handleNavField(ctx, def, value, dbCtx, isTo, isFrom, isVia) {
2119
2141
  const pathParts = ctx.path.split(".");
2120
2142
  const fieldName = pathParts[pathParts.length - 1] || ctx.path;
@@ -2653,18 +2675,21 @@ var AtscriptDbTable = class extends AtscriptDbReadable {
2653
2675
  for (const navField of this._meta.navFields) delete data[navField];
2654
2676
  const filter = this._extractPrimaryKeyFilter(data);
2655
2677
  for (const pk of this._meta.primaryKeys) delete data[pk];
2656
- const ops = separateFieldOps(data);
2657
- if (_isEmptyObj(data) && !ops) {
2678
+ if (_isEmptyObj(data)) {
2658
2679
  matchedCount += 1;
2659
2680
  modifiedCount += 0;
2660
2681
  continue;
2661
2682
  }
2662
2683
  let result;
2663
2684
  const translatedFilter = this._fieldMapper.translateFilter(filter, this._meta);
2664
- const translatedOps = ops ? _translateOpsKeys(ops, this._meta) : void 0;
2665
- if (this.adapter.supportsNativePatch()) result = await this.adapter.nativePatch(translatedFilter, data, translatedOps);
2666
- else {
2685
+ if (this.adapter.supportsNativePatch()) {
2686
+ const ops = separateFieldOps(data);
2687
+ const translatedOps = ops ? _translateOpsKeys(ops, this._meta) : void 0;
2688
+ result = await this.adapter.nativePatch(translatedFilter, data, translatedOps);
2689
+ } else {
2667
2690
  const update = decomposePatch(data, this);
2691
+ const ops = separateFieldOps(update);
2692
+ const translatedOps = ops ? _translateOpsKeys(ops, this._meta) : void 0;
2668
2693
  const translatedUpdate = this._fieldMapper.translatePatchKeys(update, this._meta);
2669
2694
  if (getArrayOpsFields(translatedUpdate).size > 0) {
2670
2695
  const resolved = resolveArrayOps(translatedUpdate, await this.adapter.findOne({
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_nested_writer = require("./nested-writer-BDXsDMPP.cjs");
3
- const require_db_view = require("./db-view-BntnAmXO.cjs");
3
+ const require_db_view = require("./db-view-CMI9TOo1.cjs");
4
4
  const require_ops = require("./ops.cjs");
5
5
  let _uniqu_core = require("@uniqu/core");
6
6
  //#region src/table/db-space.ts
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { h as DbError } from "./nested-writer-Dmm1gbZV.mjs";
2
- import { _ as NoopLogger, a as getKeyProps, c as IntegrityStrategy, d as resolveDesignType, f as RelationalFieldMapper, g as TableMetadata, h as UniquSelect, i as createDbValidatorPlugin, l as NativeIntegrity, m as FieldMappingStrategy, n as AtscriptDbTable, o as ApplicationIntegrity, p as DocumentFieldMapper, r as decomposePatch, s as BaseDbAdapter, t as AtscriptDbView, u as AtscriptDbReadable } from "./db-view-ZsoN91-q.mjs";
2
+ import { _ as NoopLogger, a as getKeyProps, c as IntegrityStrategy, d as resolveDesignType, f as RelationalFieldMapper, g as TableMetadata, h as UniquSelect, i as createDbValidatorPlugin, l as NativeIntegrity, m as FieldMappingStrategy, n as AtscriptDbTable, o as ApplicationIntegrity, p as DocumentFieldMapper, r as decomposePatch, s as BaseDbAdapter, t as AtscriptDbView, u as AtscriptDbReadable } from "./db-view-Esy2fDxw.mjs";
3
3
  import { getDbFieldOp, isDbFieldOp, separateFieldOps } from "./ops.mjs";
4
4
  import { computeInsights, isPrimitive, walkFilter } from "@uniqu/core";
5
5
  //#region src/table/db-space.ts
package/dist/sync.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  require("./nested-writer-BDXsDMPP.cjs");
3
- const require_db_view = require("./db-view-BntnAmXO.cjs");
3
+ const require_db_view = require("./db-view-CMI9TOo1.cjs");
4
4
  //#region src/schema/schema-hash.ts
5
5
  /** Extracts sorted field snapshots from a readable's field descriptors. */
6
6
  function extractFieldSnapshots(fields, typeMapper) {
package/dist/sync.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as NoopLogger } from "./db-view-ZsoN91-q.mjs";
1
+ import { _ as NoopLogger } from "./db-view-Esy2fDxw.mjs";
2
2
  //#region src/schema/schema-hash.ts
3
3
  /** Extracts sorted field snapshots from a readable's field descriptors. */
4
4
  function extractFieldSnapshots(fields, typeMapper) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atscript/db",
3
- "version": "0.1.40",
3
+ "version": "0.1.41",
4
4
  "description": "Database adapter utilities for atscript.",
5
5
  "keywords": [
6
6
  "atscript",