@atscript/db-mongo 0.1.88 → 0.1.89
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 +48 -5
- package/dist/index.mjs +49 -6
- package/package.json +7 -7
package/dist/index.cjs
CHANGED
|
@@ -919,16 +919,20 @@ async function syncColumnsImpl(host, diff) {
|
|
|
919
919
|
if (diff.renamed.length > 0) {
|
|
920
920
|
const renameSpec = {};
|
|
921
921
|
for (const r of diff.renamed) {
|
|
922
|
+
if (pathCrossesArray(host, r.field.path)) {
|
|
923
|
+
host._log("syncColumns: skipping $rename for array-element field", r.oldName, "→", r.field.physicalName, "(Mongo $rename cannot traverse arrays)");
|
|
924
|
+
continue;
|
|
925
|
+
}
|
|
922
926
|
renameSpec[r.oldName] = r.field.physicalName;
|
|
923
927
|
renamed.push(r.field.physicalName);
|
|
924
928
|
}
|
|
925
|
-
update.$rename = renameSpec;
|
|
929
|
+
if (Object.keys(renameSpec).length > 0) update.$rename = renameSpec;
|
|
926
930
|
}
|
|
927
931
|
if (diff.added.length > 0) {
|
|
928
932
|
const setSpec = {};
|
|
929
933
|
for (const field of diff.added) {
|
|
930
934
|
const defaultVal = resolveSyncDefault(field);
|
|
931
|
-
if (defaultVal !== void 0) setSpec[field.physicalName] = defaultVal;
|
|
935
|
+
if (defaultVal !== void 0) setSpec[arraySafePath(host, field.physicalName, field.path)] = defaultVal;
|
|
932
936
|
added.push(field.physicalName);
|
|
933
937
|
}
|
|
934
938
|
if (Object.keys(setSpec).length > 0) update.$set = setSpec;
|
|
@@ -942,13 +946,52 @@ async function syncColumnsImpl(host, diff) {
|
|
|
942
946
|
async function dropColumnsImpl(host, columns) {
|
|
943
947
|
if (columns.length === 0) return;
|
|
944
948
|
const unsetSpec = {};
|
|
945
|
-
for (const col of columns) unsetSpec[col] = "";
|
|
949
|
+
for (const col of columns) unsetSpec[arraySafePath(host, col, col)] = "";
|
|
946
950
|
await host.collection.updateMany({}, { $unset: unsetSpec }, host._getSessionOpts());
|
|
947
951
|
}
|
|
952
|
+
/**
|
|
953
|
+
* Rewrites a dotted physical path to use Mongo's all-positional $[] operator
|
|
954
|
+
* at every segment that's typed as an array in the table's flatMap. Returns
|
|
955
|
+
* the input unchanged when no segment crosses an array boundary.
|
|
956
|
+
*
|
|
957
|
+
* `logicalPath` drives the array-boundary walk (flatMap is keyed by logical
|
|
958
|
+
* path); the leaf of `physicalPath` is preserved so any `@db.column` rename
|
|
959
|
+
* on the leaf still applies.
|
|
960
|
+
*/
|
|
961
|
+
function arraySafePath(host, physicalPath, logicalPath) {
|
|
962
|
+
const logicalSegments = logicalPath.split(".");
|
|
963
|
+
if (logicalSegments.length < 2) return physicalPath;
|
|
964
|
+
const physicalSegments = physicalPath.split(".");
|
|
965
|
+
const physicalLeaf = physicalSegments[physicalSegments.length - 1];
|
|
966
|
+
const out = [];
|
|
967
|
+
let prefix = "";
|
|
968
|
+
for (let i = 0; i < logicalSegments.length; i++) {
|
|
969
|
+
const isLeaf = i === logicalSegments.length - 1;
|
|
970
|
+
out.push(isLeaf ? physicalLeaf : logicalSegments[i]);
|
|
971
|
+
prefix = prefix ? `${prefix}.${logicalSegments[i]}` : logicalSegments[i];
|
|
972
|
+
if (!isLeaf) {
|
|
973
|
+
const type = host._table.flatMap.get(prefix);
|
|
974
|
+
if (type && (0, _atscript_db.resolveDesignType)(type) === "array") out.push("$[]");
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
return out.join(".");
|
|
978
|
+
}
|
|
979
|
+
/** Returns true if any non-leaf segment of the path is typed as an array. */
|
|
980
|
+
function pathCrossesArray(host, logicalPath) {
|
|
981
|
+
const segments = logicalPath.split(".");
|
|
982
|
+
if (segments.length < 2) return false;
|
|
983
|
+
let prefix = "";
|
|
984
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
985
|
+
prefix = prefix ? `${prefix}.${segments[i]}` : segments[i];
|
|
986
|
+
const type = host._table.flatMap.get(prefix);
|
|
987
|
+
if (type && (0, _atscript_db.resolveDesignType)(type) === "array") return true;
|
|
988
|
+
}
|
|
989
|
+
return false;
|
|
990
|
+
}
|
|
948
991
|
/** Resolves a field's default value for bulk $set during column sync. */
|
|
949
992
|
function resolveSyncDefault(field) {
|
|
950
|
-
if (!field.defaultValue) return
|
|
951
|
-
if (field.defaultValue.kind === "value") return field.defaultValue.value;
|
|
993
|
+
if (!field.defaultValue) return;
|
|
994
|
+
if (field.defaultValue.kind === "value") return field.designType === "string" ? field.defaultValue.value : JSON.parse(field.defaultValue.value);
|
|
952
995
|
}
|
|
953
996
|
async function syncIndexesImpl(host) {
|
|
954
997
|
await host.ensureCollectionExists();
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as buildMongoFilter } from "./mongo-filter-BsocUQG3.mjs";
|
|
2
|
-
import { AtscriptDbView, BaseDbAdapter, DbError, DbSpace, computeInsights, getDbFieldOp, getKeyProps } from "@atscript/db";
|
|
2
|
+
import { AtscriptDbView, BaseDbAdapter, DbError, DbSpace, computeInsights, getDbFieldOp, getKeyProps, resolveDesignType } from "@atscript/db";
|
|
3
3
|
import { MongoClient, MongoServerError, ObjectId } from "mongodb";
|
|
4
4
|
//#region src/lib/collection-patcher.ts
|
|
5
5
|
/**
|
|
@@ -918,16 +918,20 @@ async function syncColumnsImpl(host, diff) {
|
|
|
918
918
|
if (diff.renamed.length > 0) {
|
|
919
919
|
const renameSpec = {};
|
|
920
920
|
for (const r of diff.renamed) {
|
|
921
|
+
if (pathCrossesArray(host, r.field.path)) {
|
|
922
|
+
host._log("syncColumns: skipping $rename for array-element field", r.oldName, "→", r.field.physicalName, "(Mongo $rename cannot traverse arrays)");
|
|
923
|
+
continue;
|
|
924
|
+
}
|
|
921
925
|
renameSpec[r.oldName] = r.field.physicalName;
|
|
922
926
|
renamed.push(r.field.physicalName);
|
|
923
927
|
}
|
|
924
|
-
update.$rename = renameSpec;
|
|
928
|
+
if (Object.keys(renameSpec).length > 0) update.$rename = renameSpec;
|
|
925
929
|
}
|
|
926
930
|
if (diff.added.length > 0) {
|
|
927
931
|
const setSpec = {};
|
|
928
932
|
for (const field of diff.added) {
|
|
929
933
|
const defaultVal = resolveSyncDefault(field);
|
|
930
|
-
if (defaultVal !== void 0) setSpec[field.physicalName] = defaultVal;
|
|
934
|
+
if (defaultVal !== void 0) setSpec[arraySafePath(host, field.physicalName, field.path)] = defaultVal;
|
|
931
935
|
added.push(field.physicalName);
|
|
932
936
|
}
|
|
933
937
|
if (Object.keys(setSpec).length > 0) update.$set = setSpec;
|
|
@@ -941,13 +945,52 @@ async function syncColumnsImpl(host, diff) {
|
|
|
941
945
|
async function dropColumnsImpl(host, columns) {
|
|
942
946
|
if (columns.length === 0) return;
|
|
943
947
|
const unsetSpec = {};
|
|
944
|
-
for (const col of columns) unsetSpec[col] = "";
|
|
948
|
+
for (const col of columns) unsetSpec[arraySafePath(host, col, col)] = "";
|
|
945
949
|
await host.collection.updateMany({}, { $unset: unsetSpec }, host._getSessionOpts());
|
|
946
950
|
}
|
|
951
|
+
/**
|
|
952
|
+
* Rewrites a dotted physical path to use Mongo's all-positional $[] operator
|
|
953
|
+
* at every segment that's typed as an array in the table's flatMap. Returns
|
|
954
|
+
* the input unchanged when no segment crosses an array boundary.
|
|
955
|
+
*
|
|
956
|
+
* `logicalPath` drives the array-boundary walk (flatMap is keyed by logical
|
|
957
|
+
* path); the leaf of `physicalPath` is preserved so any `@db.column` rename
|
|
958
|
+
* on the leaf still applies.
|
|
959
|
+
*/
|
|
960
|
+
function arraySafePath(host, physicalPath, logicalPath) {
|
|
961
|
+
const logicalSegments = logicalPath.split(".");
|
|
962
|
+
if (logicalSegments.length < 2) return physicalPath;
|
|
963
|
+
const physicalSegments = physicalPath.split(".");
|
|
964
|
+
const physicalLeaf = physicalSegments[physicalSegments.length - 1];
|
|
965
|
+
const out = [];
|
|
966
|
+
let prefix = "";
|
|
967
|
+
for (let i = 0; i < logicalSegments.length; i++) {
|
|
968
|
+
const isLeaf = i === logicalSegments.length - 1;
|
|
969
|
+
out.push(isLeaf ? physicalLeaf : logicalSegments[i]);
|
|
970
|
+
prefix = prefix ? `${prefix}.${logicalSegments[i]}` : logicalSegments[i];
|
|
971
|
+
if (!isLeaf) {
|
|
972
|
+
const type = host._table.flatMap.get(prefix);
|
|
973
|
+
if (type && resolveDesignType(type) === "array") out.push("$[]");
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
return out.join(".");
|
|
977
|
+
}
|
|
978
|
+
/** Returns true if any non-leaf segment of the path is typed as an array. */
|
|
979
|
+
function pathCrossesArray(host, logicalPath) {
|
|
980
|
+
const segments = logicalPath.split(".");
|
|
981
|
+
if (segments.length < 2) return false;
|
|
982
|
+
let prefix = "";
|
|
983
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
984
|
+
prefix = prefix ? `${prefix}.${segments[i]}` : segments[i];
|
|
985
|
+
const type = host._table.flatMap.get(prefix);
|
|
986
|
+
if (type && resolveDesignType(type) === "array") return true;
|
|
987
|
+
}
|
|
988
|
+
return false;
|
|
989
|
+
}
|
|
947
990
|
/** Resolves a field's default value for bulk $set during column sync. */
|
|
948
991
|
function resolveSyncDefault(field) {
|
|
949
|
-
if (!field.defaultValue) return
|
|
950
|
-
if (field.defaultValue.kind === "value") return field.defaultValue.value;
|
|
992
|
+
if (!field.defaultValue) return;
|
|
993
|
+
if (field.defaultValue.kind === "value") return field.designType === "string" ? field.defaultValue.value : JSON.parse(field.defaultValue.value);
|
|
951
994
|
}
|
|
952
995
|
async function syncIndexesImpl(host) {
|
|
953
996
|
await host.ensureCollectionExists();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atscript/db-mongo",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.89",
|
|
4
4
|
"description": "Mongodb plugin for atscript.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"atscript",
|
|
@@ -46,17 +46,17 @@
|
|
|
46
46
|
"access": "public"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@atscript/core": "^0.1.
|
|
50
|
-
"@atscript/typescript": "^0.1.
|
|
49
|
+
"@atscript/core": "^0.1.63",
|
|
50
|
+
"@atscript/typescript": "^0.1.63",
|
|
51
51
|
"mongodb": "^6.17.0",
|
|
52
52
|
"mongodb-memory-server-core": "^10.0.0",
|
|
53
|
-
"unplugin-atscript": "^0.1.
|
|
53
|
+
"unplugin-atscript": "^0.1.63"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"@atscript/core": "^0.1.
|
|
57
|
-
"@atscript/typescript": "^0.1.
|
|
56
|
+
"@atscript/core": "^0.1.63",
|
|
57
|
+
"@atscript/typescript": "^0.1.63",
|
|
58
58
|
"mongodb": "^6.17.0",
|
|
59
|
-
"@atscript/db": "^0.1.
|
|
59
|
+
"@atscript/db": "^0.1.89"
|
|
60
60
|
},
|
|
61
61
|
"scripts": {
|
|
62
62
|
"postinstall": "asc -f dts",
|