@atscript/db-mongo 0.1.67 → 0.1.68

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.cjs CHANGED
@@ -84,6 +84,12 @@ var CollectionPatcher = class {
84
84
  this.currentSetStage = { $set: { [key]: val } };
85
85
  this.updatePipeline.push(this.currentSetStage);
86
86
  }
87
+ /** Set a leaf, lifting an `$inc`/`$mul` field op into an aggregation expression if present. */
88
+ _setLeaf(key, value) {
89
+ const fieldOp = (0, _atscript_db.getDbFieldOp)(value);
90
+ if (fieldOp) this._set(key, this._fieldOpExpr(key, fieldOp.op, fieldOp.value));
91
+ else this._set(key, value);
92
+ }
87
93
  /**
88
94
  * Recursively walk through the patch *payload* and convert it into `$set`/…
89
95
  * statements. Top‑level arrays are delegated to {@link parseArrayPatch}.
@@ -98,17 +104,40 @@ var CollectionPatcher = class {
98
104
  const key = evalKey(_key);
99
105
  const flatType = this.collection.flatMap.get(key);
100
106
  const topLevelArray = flatType?.metadata?.get("db.__topLevelArray");
101
- if (typeof value === "object" && !Array.isArray(value) && topLevelArray && !flatType?.metadata?.has("db.json")) this.parseArrayPatch(key, value, flatType);
102
- else if (typeof value === "object" && flatType?.metadata?.get("db.patch.strategy") === "merge") this.flattenPayload(value, key);
103
- else if (key !== "_id") {
104
- const fieldOp = (0, _atscript_db.getDbFieldOp)(value);
105
- if (fieldOp) this._set(key, this._fieldOpExpr(key, fieldOp.op, fieldOp.value));
106
- else this._set(key, value);
107
- }
107
+ const isObjectValue = typeof value === "object" && value !== null && !Array.isArray(value);
108
+ if (isObjectValue && topLevelArray && !flatType?.metadata?.has("db.json")) this.parseArrayPatch(key, value, flatType);
109
+ else if (isObjectValue && flatType?.metadata?.get("db.patch.strategy") === "merge") this.flattenPayload(value, key);
110
+ else if (isObjectValue && flatType?.type.kind === "object" && !flatType.metadata?.has("db.json")) this._flattenReplaceObject(value, key, flatType);
111
+ else if (key !== "_id") this._setLeaf(key, value);
108
112
  }
109
113
  return this.updatePipeline;
110
114
  }
111
115
  /**
116
+ * Walk the schema's props for a replace-strategy nested object so omitted
117
+ * optional children become explicit nulls (parity with SQL `column = NULL`).
118
+ * Required-missing leaves are caught earlier by the strict validator.
119
+ */
120
+ _flattenReplaceObject(value, prefix, flatType) {
121
+ const propsMap = flatType.type.props;
122
+ for (const [propKey, propType] of propsMap) {
123
+ const childKey = `${prefix}.${propKey}`;
124
+ const childValue = value[propKey];
125
+ if (childValue === void 0) {
126
+ if (propType.optional === true) this._set(childKey, null);
127
+ continue;
128
+ }
129
+ const childIsObject = typeof childValue === "object" && childValue !== null && !Array.isArray(childValue);
130
+ const propIsJson = propType.metadata?.has("db.json");
131
+ const propIsMerge = propType.metadata?.get("db.patch.strategy") === "merge";
132
+ if (childIsObject && propType.type.kind === "object" && !propIsJson) {
133
+ if (propIsMerge) this.flattenPayload(childValue, childKey);
134
+ else this._flattenReplaceObject(childValue, childKey, propType);
135
+ continue;
136
+ }
137
+ this._setLeaf(childKey, childValue);
138
+ }
139
+ }
140
+ /**
112
141
  * Dispatch a *single* array patch. Exactly one of `$replace`, `$insert`,
113
142
  * `$upsert`, `$update`, `$remove` must be present – otherwise we throw.
114
143
  *
package/dist/index.d.cts CHANGED
@@ -72,6 +72,8 @@ declare class CollectionPatcher {
72
72
  * @private
73
73
  */
74
74
  private _set;
75
+ /** Set a leaf, lifting an `$inc`/`$mul` field op into an aggregation expression if present. */
76
+ private _setLeaf;
75
77
  /**
76
78
  * Recursively walk through the patch *payload* and convert it into `$set`/…
77
79
  * statements. Top‑level arrays are delegated to {@link parseArrayPatch}.
@@ -81,6 +83,12 @@ declare class CollectionPatcher {
81
83
  * @private
82
84
  */
83
85
  private flattenPayload;
86
+ /**
87
+ * Walk the schema's props for a replace-strategy nested object so omitted
88
+ * optional children become explicit nulls (parity with SQL `column = NULL`).
89
+ * Required-missing leaves are caught earlier by the strict validator.
90
+ */
91
+ private _flattenReplaceObject;
84
92
  /**
85
93
  * Dispatch a *single* array patch. Exactly one of `$replace`, `$insert`,
86
94
  * `$upsert`, `$update`, `$remove` must be present – otherwise we throw.
package/dist/index.d.mts CHANGED
@@ -72,6 +72,8 @@ declare class CollectionPatcher {
72
72
  * @private
73
73
  */
74
74
  private _set;
75
+ /** Set a leaf, lifting an `$inc`/`$mul` field op into an aggregation expression if present. */
76
+ private _setLeaf;
75
77
  /**
76
78
  * Recursively walk through the patch *payload* and convert it into `$set`/…
77
79
  * statements. Top‑level arrays are delegated to {@link parseArrayPatch}.
@@ -81,6 +83,12 @@ declare class CollectionPatcher {
81
83
  * @private
82
84
  */
83
85
  private flattenPayload;
86
+ /**
87
+ * Walk the schema's props for a replace-strategy nested object so omitted
88
+ * optional children become explicit nulls (parity with SQL `column = NULL`).
89
+ * Required-missing leaves are caught earlier by the strict validator.
90
+ */
91
+ private _flattenReplaceObject;
84
92
  /**
85
93
  * Dispatch a *single* array patch. Exactly one of `$replace`, `$insert`,
86
94
  * `$upsert`, `$update`, `$remove` must be present – otherwise we throw.
package/dist/index.mjs CHANGED
@@ -83,6 +83,12 @@ var CollectionPatcher = class {
83
83
  this.currentSetStage = { $set: { [key]: val } };
84
84
  this.updatePipeline.push(this.currentSetStage);
85
85
  }
86
+ /** Set a leaf, lifting an `$inc`/`$mul` field op into an aggregation expression if present. */
87
+ _setLeaf(key, value) {
88
+ const fieldOp = getDbFieldOp(value);
89
+ if (fieldOp) this._set(key, this._fieldOpExpr(key, fieldOp.op, fieldOp.value));
90
+ else this._set(key, value);
91
+ }
86
92
  /**
87
93
  * Recursively walk through the patch *payload* and convert it into `$set`/…
88
94
  * statements. Top‑level arrays are delegated to {@link parseArrayPatch}.
@@ -97,17 +103,40 @@ var CollectionPatcher = class {
97
103
  const key = evalKey(_key);
98
104
  const flatType = this.collection.flatMap.get(key);
99
105
  const topLevelArray = flatType?.metadata?.get("db.__topLevelArray");
100
- if (typeof value === "object" && !Array.isArray(value) && topLevelArray && !flatType?.metadata?.has("db.json")) this.parseArrayPatch(key, value, flatType);
101
- else if (typeof value === "object" && flatType?.metadata?.get("db.patch.strategy") === "merge") this.flattenPayload(value, key);
102
- else if (key !== "_id") {
103
- const fieldOp = getDbFieldOp(value);
104
- if (fieldOp) this._set(key, this._fieldOpExpr(key, fieldOp.op, fieldOp.value));
105
- else this._set(key, value);
106
- }
106
+ const isObjectValue = typeof value === "object" && value !== null && !Array.isArray(value);
107
+ if (isObjectValue && topLevelArray && !flatType?.metadata?.has("db.json")) this.parseArrayPatch(key, value, flatType);
108
+ else if (isObjectValue && flatType?.metadata?.get("db.patch.strategy") === "merge") this.flattenPayload(value, key);
109
+ else if (isObjectValue && flatType?.type.kind === "object" && !flatType.metadata?.has("db.json")) this._flattenReplaceObject(value, key, flatType);
110
+ else if (key !== "_id") this._setLeaf(key, value);
107
111
  }
108
112
  return this.updatePipeline;
109
113
  }
110
114
  /**
115
+ * Walk the schema's props for a replace-strategy nested object so omitted
116
+ * optional children become explicit nulls (parity with SQL `column = NULL`).
117
+ * Required-missing leaves are caught earlier by the strict validator.
118
+ */
119
+ _flattenReplaceObject(value, prefix, flatType) {
120
+ const propsMap = flatType.type.props;
121
+ for (const [propKey, propType] of propsMap) {
122
+ const childKey = `${prefix}.${propKey}`;
123
+ const childValue = value[propKey];
124
+ if (childValue === void 0) {
125
+ if (propType.optional === true) this._set(childKey, null);
126
+ continue;
127
+ }
128
+ const childIsObject = typeof childValue === "object" && childValue !== null && !Array.isArray(childValue);
129
+ const propIsJson = propType.metadata?.has("db.json");
130
+ const propIsMerge = propType.metadata?.get("db.patch.strategy") === "merge";
131
+ if (childIsObject && propType.type.kind === "object" && !propIsJson) {
132
+ if (propIsMerge) this.flattenPayload(childValue, childKey);
133
+ else this._flattenReplaceObject(childValue, childKey, propType);
134
+ continue;
135
+ }
136
+ this._setLeaf(childKey, childValue);
137
+ }
138
+ }
139
+ /**
111
140
  * Dispatch a *single* array patch. Exactly one of `$replace`, `$insert`,
112
141
  * `$upsert`, `$update`, `$remove` must be present – otherwise we throw.
113
142
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atscript/db-mongo",
3
- "version": "0.1.67",
3
+ "version": "0.1.68",
4
4
  "description": "Mongodb plugin for atscript.",
5
5
  "keywords": [
6
6
  "atscript",
@@ -55,7 +55,7 @@
55
55
  "@atscript/core": "^0.1.50",
56
56
  "@atscript/typescript": "^0.1.50",
57
57
  "mongodb": "^6.17.0",
58
- "@atscript/db": "^0.1.67"
58
+ "@atscript/db": "^0.1.68"
59
59
  },
60
60
  "scripts": {
61
61
  "postinstall": "asc -f dts",