@atscript/mongo 0.1.17 → 0.1.18
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 +64 -55
- package/dist/index.d.ts +15 -15
- package/dist/index.mjs +64 -55
- package/package.json +24 -24
package/dist/index.cjs
CHANGED
|
@@ -26,23 +26,6 @@ const __atscript_core = __toESM(require("@atscript/core"));
|
|
|
26
26
|
const __atscript_typescript_utils = __toESM(require("@atscript/typescript/utils"));
|
|
27
27
|
const mongodb = __toESM(require("mongodb"));
|
|
28
28
|
|
|
29
|
-
//#region packages/mongo/src/plugin/primitives.ts
|
|
30
|
-
const primitives = { mongo: { extensions: {
|
|
31
|
-
objectId: {
|
|
32
|
-
type: "string",
|
|
33
|
-
documentation: "Represents a **MongoDB ObjectId**.\n\n- Stored as a **string** but can be converted to an ObjectId at runtime.\n- Useful for handling `_id` fields and queries that require ObjectId conversion.\n- Automatically converts string `_id` values into **MongoDB ObjectId** when needed.\n\n**Example:**\n```atscript\nuserId: mongo.objectId\n```\n",
|
|
34
|
-
expect: { pattern: /^[a-fA-F0-9]{24}$/ }
|
|
35
|
-
},
|
|
36
|
-
vector: {
|
|
37
|
-
type: {
|
|
38
|
-
kind: "array",
|
|
39
|
-
of: "number"
|
|
40
|
-
},
|
|
41
|
-
documentation: "Represents a **MongoDB Vector (Array of Numbers)** for **Vector Search**.\n\n- Equivalent to `number[]` but explicitly used for **vector embeddings**.\n\n**Example:**\n```atscript\nembedding: mongo.vector\n```\n"
|
|
42
|
-
}
|
|
43
|
-
} } };
|
|
44
|
-
|
|
45
|
-
//#endregion
|
|
46
29
|
//#region packages/mongo/src/plugin/annotations.ts
|
|
47
30
|
const analyzers = [
|
|
48
31
|
"lucene.standard",
|
|
@@ -313,28 +296,33 @@ const annotations = { mongo: {
|
|
|
313
296
|
} };
|
|
314
297
|
|
|
315
298
|
//#endregion
|
|
316
|
-
//#region packages/mongo/src/plugin/
|
|
317
|
-
const
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
}
|
|
299
|
+
//#region packages/mongo/src/plugin/primitives.ts
|
|
300
|
+
const primitives = { mongo: { extensions: {
|
|
301
|
+
objectId: {
|
|
302
|
+
type: "string",
|
|
303
|
+
documentation: "Represents a **MongoDB ObjectId**.\n\n- Stored as a **string** but can be converted to an ObjectId at runtime.\n- Useful for handling `_id` fields and queries that require ObjectId conversion.\n- Automatically converts string `_id` values into **MongoDB ObjectId** when needed.\n\n**Example:**\n```atscript\nuserId: mongo.objectId\n```\n",
|
|
304
|
+
expect: { pattern: /^[a-fA-F0-9]{24}$/ }
|
|
305
|
+
},
|
|
306
|
+
vector: {
|
|
307
|
+
type: {
|
|
308
|
+
kind: "array",
|
|
309
|
+
of: "number"
|
|
310
|
+
},
|
|
311
|
+
documentation: "Represents a **MongoDB Vector (Array of Numbers)** for **Vector Search**.\n\n- Equivalent to `number[]` but explicitly used for **vector embeddings**.\n\n**Example:**\n```atscript\nembedding: mongo.vector\n```\n"
|
|
312
|
+
}
|
|
313
|
+
} } };
|
|
328
314
|
|
|
329
315
|
//#endregion
|
|
330
|
-
//#region packages/mongo/src/
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
};
|
|
316
|
+
//#region packages/mongo/src/plugin/index.ts
|
|
317
|
+
const MongoPlugin = () => ({
|
|
318
|
+
name: "mongo",
|
|
319
|
+
config() {
|
|
320
|
+
return {
|
|
321
|
+
primitives,
|
|
322
|
+
annotations
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
});
|
|
338
326
|
|
|
339
327
|
//#endregion
|
|
340
328
|
//#region packages/mongo/src/lib/validate-plugins.ts
|
|
@@ -349,7 +337,7 @@ const validateMongoUniqueArrayItemsPlugin = (ctx, def, value) => {
|
|
|
349
337
|
const keyProps = CollectionPatcher.getKeyProps(def);
|
|
350
338
|
for (const item of value) {
|
|
351
339
|
let key = "";
|
|
352
|
-
if (keyProps.size) for (const prop of keyProps) key += JSON.stringify(item[prop]) + separator;
|
|
340
|
+
if (keyProps.size > 0) for (const prop of keyProps) key += JSON.stringify(item[prop]) + separator;
|
|
353
341
|
else key = JSON.stringify(item);
|
|
354
342
|
if (seen.has(key)) {
|
|
355
343
|
ctx.error(`Duplicate items are not allowed`);
|
|
@@ -418,7 +406,7 @@ var CollectionPatcher = class CollectionPatcher {
|
|
|
418
406
|
const objType = defArray.type.of.type;
|
|
419
407
|
const t = (0, __atscript_typescript_utils.defineAnnotatedType)("object").copyMetadata(defArray.type.of.metadata);
|
|
420
408
|
const keyProps = CollectionPatcher.getKeyProps(defArray);
|
|
421
|
-
for (const [key, val] of objType.props.entries()) if (keyProps.size) if (keyProps.has(key)) t.prop(key, (0, __atscript_typescript_utils.defineAnnotatedType)().refTo(val).copyMetadata(def.metadata).$type);
|
|
409
|
+
for (const [key, val] of objType.props.entries()) if (keyProps.size > 0) if (keyProps.has(key)) t.prop(key, (0, __atscript_typescript_utils.defineAnnotatedType)().refTo(val).copyMetadata(def.metadata).$type);
|
|
422
410
|
else t.prop(key, (0, __atscript_typescript_utils.defineAnnotatedType)().refTo(val).copyMetadata(def.metadata).optional().$type);
|
|
423
411
|
else t.prop(key, (0, __atscript_typescript_utils.defineAnnotatedType)().refTo(val).copyMetadata(def.metadata).optional(!!val.optional).$type);
|
|
424
412
|
return (0, __atscript_typescript_utils.defineAnnotatedType)("array").of(t.$type).copyMetadata(def.metadata).annotate("mongo.__patchArrayValue").optional().$type;
|
|
@@ -442,7 +430,7 @@ else t.prop(key, (0, __atscript_typescript_utils.defineAnnotatedType)().refTo(va
|
|
|
442
430
|
*/ preparePatch() {
|
|
443
431
|
this.filterObj = { _id: this.collection.prepareId(this.payload._id) };
|
|
444
432
|
this.flattenPayload(this.payload);
|
|
445
|
-
|
|
433
|
+
const updateFilter = this.updatePipeline;
|
|
446
434
|
return {
|
|
447
435
|
toArgs: () => [
|
|
448
436
|
this.filterObj,
|
|
@@ -548,7 +536,7 @@ else this._set(key, { $concatArrays: [{ $ifNull: [`$${key}`, []] }, input] });
|
|
|
548
536
|
* - unique → $setUnion (deep equality)
|
|
549
537
|
*/ _upsert(key, input, keyProps) {
|
|
550
538
|
if (!input?.length) return;
|
|
551
|
-
if (keyProps.size) {
|
|
539
|
+
if (keyProps.size > 0) {
|
|
552
540
|
const keys = [...keyProps];
|
|
553
541
|
this._set(key, { $reduce: {
|
|
554
542
|
input,
|
|
@@ -575,7 +563,7 @@ else this._set(key, { $concatArrays: [{ $ifNull: [`$${key}`, []] }, input] });
|
|
|
575
563
|
* - non-keyed → behave like `$addToSet` (insert only when not present)
|
|
576
564
|
*/ _update(key, input, keyProps) {
|
|
577
565
|
if (!input?.length) return;
|
|
578
|
-
if (keyProps.size) {
|
|
566
|
+
if (keyProps.size > 0) {
|
|
579
567
|
const mergeStrategy = this.collection.flatMap.get(key)?.metadata?.get("mongo.patch.strategy") === "merge";
|
|
580
568
|
const keys = [...keyProps];
|
|
581
569
|
this._set(key, { $reduce: {
|
|
@@ -599,7 +587,7 @@ else this._set(key, { $concatArrays: [{ $ifNull: [`$${key}`, []] }, input] });
|
|
|
599
587
|
* - non-keyed → deep equality remove (`$setDifference`)
|
|
600
588
|
*/ _remove(key, input, keyProps) {
|
|
601
589
|
if (!input?.length) return;
|
|
602
|
-
if (keyProps.size) {
|
|
590
|
+
if (keyProps.size > 0) {
|
|
603
591
|
const keys = [...keyProps];
|
|
604
592
|
this._set(key, { $let: {
|
|
605
593
|
vars: { rem: input },
|
|
@@ -632,6 +620,16 @@ else this._set(key, { $concatArrays: [{ $ifNull: [`$${key}`, []] }, input] });
|
|
|
632
620
|
}
|
|
633
621
|
};
|
|
634
622
|
|
|
623
|
+
//#endregion
|
|
624
|
+
//#region packages/mongo/src/lib/logger.ts
|
|
625
|
+
const NoopLogger = {
|
|
626
|
+
error: () => {},
|
|
627
|
+
warn: () => {},
|
|
628
|
+
log: () => {},
|
|
629
|
+
info: () => {},
|
|
630
|
+
debug: () => {}
|
|
631
|
+
};
|
|
632
|
+
|
|
635
633
|
//#endregion
|
|
636
634
|
//#region packages/mongo/src/lib/as-collection.ts
|
|
637
635
|
function _define_property$1(obj, key, value) {
|
|
@@ -834,19 +832,23 @@ else {
|
|
|
834
832
|
this._searchIndexesMap = new Map();
|
|
835
833
|
let deafultIndex;
|
|
836
834
|
for (const index of this.indexes.values()) switch (index.type) {
|
|
837
|
-
case "text":
|
|
835
|
+
case "text": {
|
|
838
836
|
if (!deafultIndex) deafultIndex = index;
|
|
839
837
|
break;
|
|
840
|
-
|
|
838
|
+
}
|
|
839
|
+
case "dynamic_text": {
|
|
841
840
|
deafultIndex = index;
|
|
842
841
|
break;
|
|
843
|
-
|
|
842
|
+
}
|
|
843
|
+
case "search_text": {
|
|
844
844
|
if (!deafultIndex || deafultIndex?.type === "text") deafultIndex = index;
|
|
845
845
|
this._searchIndexesMap.set(index.name, index);
|
|
846
846
|
break;
|
|
847
|
-
|
|
847
|
+
}
|
|
848
|
+
case "vector": {
|
|
848
849
|
this._searchIndexesMap.set(index.name, index);
|
|
849
850
|
break;
|
|
851
|
+
}
|
|
850
852
|
default:
|
|
851
853
|
}
|
|
852
854
|
if (deafultIndex && !this._searchIndexesMap.has(DEFAULT_INDEX_NAME)) this._searchIndexesMap.set(DEFAULT_INDEX_NAME, deafultIndex);
|
|
@@ -871,13 +873,14 @@ else {
|
|
|
871
873
|
switch (local.type) {
|
|
872
874
|
case "plain":
|
|
873
875
|
case "unique":
|
|
874
|
-
case "text":
|
|
876
|
+
case "text": {
|
|
875
877
|
if ((local.type === "text" || objMatch(local.fields, remote.key)) && objMatch(local.weights || {}, remote.weights || {})) indexesToCreate.delete(remote.name);
|
|
876
878
|
else {
|
|
877
879
|
this.logger.debug(`dropping index "${remote.name}"`);
|
|
878
880
|
await this.collection.dropIndex(remote.name);
|
|
879
881
|
}
|
|
880
882
|
break;
|
|
883
|
+
}
|
|
881
884
|
default:
|
|
882
885
|
}
|
|
883
886
|
} else {
|
|
@@ -894,15 +897,17 @@ else {
|
|
|
894
897
|
const right = remote.latestDefinition;
|
|
895
898
|
switch (local.type) {
|
|
896
899
|
case "dynamic_text":
|
|
897
|
-
case "search_text":
|
|
898
|
-
|
|
900
|
+
case "search_text": {
|
|
901
|
+
const left = local.definition;
|
|
899
902
|
if (left.analyzer === right.analyzer && fieldsMatch(left.mappings.fields || {}, right.mappings.fields || {})) indexesToCreate.delete(remote.name);
|
|
900
903
|
else toUpdate.add(remote.name);
|
|
901
904
|
break;
|
|
902
|
-
|
|
905
|
+
}
|
|
906
|
+
case "vector": {
|
|
903
907
|
if (vectorFieldsMatch(local.definition.fields || [], right.fields || [])) indexesToCreate.delete(remote.name);
|
|
904
908
|
else toUpdate.add(remote.name);
|
|
905
909
|
break;
|
|
910
|
+
}
|
|
906
911
|
default:
|
|
907
912
|
}
|
|
908
913
|
} else if (remote.status !== "DELETING") {
|
|
@@ -911,27 +916,30 @@ else toUpdate.add(remote.name);
|
|
|
911
916
|
} else this.logger.debug(`search index "${remote.name}" is in deleting status`);
|
|
912
917
|
}
|
|
913
918
|
for (const [key, value] of Array.from(indexesToCreate.entries())) switch (value.type) {
|
|
914
|
-
case "plain":
|
|
919
|
+
case "plain": {
|
|
915
920
|
this.logger.debug(`creating index "${key}"`);
|
|
916
921
|
await this.collection.createIndex(value.fields, { name: key });
|
|
917
922
|
break;
|
|
918
|
-
|
|
923
|
+
}
|
|
924
|
+
case "unique": {
|
|
919
925
|
this.logger.debug(`creating index "${key}"`);
|
|
920
926
|
await this.collection.createIndex(value.fields, {
|
|
921
927
|
name: key,
|
|
922
928
|
unique: true
|
|
923
929
|
});
|
|
924
930
|
break;
|
|
925
|
-
|
|
931
|
+
}
|
|
932
|
+
case "text": {
|
|
926
933
|
this.logger.debug(`creating index "${key}"`);
|
|
927
934
|
await this.collection.createIndex(value.fields, {
|
|
928
935
|
weights: value.weights,
|
|
929
936
|
name: key
|
|
930
937
|
});
|
|
931
938
|
break;
|
|
939
|
+
}
|
|
932
940
|
case "dynamic_text":
|
|
933
941
|
case "search_text":
|
|
934
|
-
case "vector":
|
|
942
|
+
case "vector": {
|
|
935
943
|
if (toUpdate.has(key)) {
|
|
936
944
|
this.logger.debug(`updating search index "${key}"`);
|
|
937
945
|
await this.collection.updateSearchIndex(key, value.definition);
|
|
@@ -944,6 +952,7 @@ else toUpdate.add(remote.name);
|
|
|
944
952
|
});
|
|
945
953
|
}
|
|
946
954
|
break;
|
|
955
|
+
}
|
|
947
956
|
default:
|
|
948
957
|
}
|
|
949
958
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TAtscriptPlugin } from '@atscript/core';
|
|
2
2
|
import * as mongodb from 'mongodb';
|
|
3
3
|
import { MongoClient, Collection, ObjectId, InsertOneOptions, ReplaceOptions, UpdateOptions, Filter } from 'mongodb';
|
|
4
|
-
import * as
|
|
4
|
+
import * as _atscript_typescript_annotated_type from '@atscript/typescript/annotated-type';
|
|
5
5
|
import { TAtscriptAnnotatedType, Validator, TValidatorOptions, TAtscriptTypeObject, TMetadataMap } from '@atscript/typescript/utils';
|
|
6
6
|
|
|
7
7
|
declare const MongoPlugin: () => TAtscriptPlugin;
|
|
@@ -26,19 +26,19 @@ declare class AsMongo {
|
|
|
26
26
|
private _collections;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
interface TPlainIndex {
|
|
30
30
|
key: string;
|
|
31
31
|
name: string;
|
|
32
32
|
type: 'plain' | 'unique' | 'text';
|
|
33
33
|
fields: Record<string, 1 | 'text'>;
|
|
34
34
|
weights: Record<string, number>;
|
|
35
|
-
}
|
|
36
|
-
|
|
35
|
+
}
|
|
36
|
+
interface TSearchIndex {
|
|
37
37
|
key: string;
|
|
38
38
|
name: string;
|
|
39
39
|
type: 'dynamic_text' | 'search_text' | 'vector';
|
|
40
40
|
definition: TMongoSearchIndexDefinition;
|
|
41
|
-
}
|
|
41
|
+
}
|
|
42
42
|
type TIndex = TPlainIndex | TSearchIndex;
|
|
43
43
|
type TValidatorPurpose = 'insert' | 'update' | 'patch';
|
|
44
44
|
declare class AsCollection<T extends TAtscriptAnnotatedType = TAtscriptAnnotatedType, DataType = T extends {
|
|
@@ -95,7 +95,7 @@ declare class AsCollection<T extends TAtscriptAnnotatedType = TAtscriptAnnotated
|
|
|
95
95
|
protected _searchIndexesMap?: Map<string, TIndex>;
|
|
96
96
|
getSearchIndexes(): Map<string, TIndex>;
|
|
97
97
|
getSearchIndex(name?: string): TIndex | undefined;
|
|
98
|
-
get flatMap(): Map<string, TAtscriptAnnotatedType<
|
|
98
|
+
get flatMap(): Map<string, TAtscriptAnnotatedType<_atscript_typescript_annotated_type.TAtscriptTypeDef<unknown>, unknown>>;
|
|
99
99
|
syncIndexes(): Promise<void>;
|
|
100
100
|
insert(payload: (Omit<DataType, '_id'> & {
|
|
101
101
|
_id?: string | number | ObjectId;
|
|
@@ -131,7 +131,7 @@ declare class AsCollection<T extends TAtscriptAnnotatedType = TAtscriptAnnotated
|
|
|
131
131
|
};
|
|
132
132
|
}
|
|
133
133
|
type TVectorSimilarity = 'cosine' | 'euclidean' | 'dotProduct';
|
|
134
|
-
|
|
134
|
+
interface TMongoSearchIndexDefinition {
|
|
135
135
|
mappings?: {
|
|
136
136
|
dynamic?: boolean;
|
|
137
137
|
fields?: Record<string, {
|
|
@@ -139,27 +139,27 @@ type TMongoSearchIndexDefinition = {
|
|
|
139
139
|
analyzer?: string;
|
|
140
140
|
}>;
|
|
141
141
|
};
|
|
142
|
-
fields?: {
|
|
142
|
+
fields?: Array<{
|
|
143
143
|
path: string;
|
|
144
144
|
type: 'filter' | 'vector';
|
|
145
145
|
similarity?: TVectorSimilarity;
|
|
146
146
|
numDimensions?: number;
|
|
147
|
-
}
|
|
147
|
+
}>;
|
|
148
148
|
analyzer?: string;
|
|
149
149
|
text?: {
|
|
150
150
|
fuzzy?: {
|
|
151
151
|
maxEdits: number;
|
|
152
152
|
};
|
|
153
153
|
};
|
|
154
|
-
}
|
|
155
|
-
|
|
154
|
+
}
|
|
155
|
+
interface TArrayPatch<A extends readonly unknown[]> {
|
|
156
156
|
$replace?: A;
|
|
157
157
|
$insert?: A;
|
|
158
158
|
$upsert?: A;
|
|
159
|
-
$update?: Partial<TArrayElement<A
|
|
160
|
-
$remove?: Partial<TArrayElement<A
|
|
161
|
-
}
|
|
162
|
-
type TArrayElement<ArrayType extends readonly unknown[]> = ArrayType extends
|
|
159
|
+
$update?: Array<Partial<TArrayElement<A>>>;
|
|
160
|
+
$remove?: Array<Partial<TArrayElement<A>>>;
|
|
161
|
+
}
|
|
162
|
+
type TArrayElement<ArrayType extends readonly unknown[]> = ArrayType extends ReadonlyArray<infer ElementType> ? ElementType : never;
|
|
163
163
|
/**
|
|
164
164
|
* AsMongoPatch<T>
|
|
165
165
|
* ─────────────────
|
package/dist/index.mjs
CHANGED
|
@@ -2,23 +2,6 @@ import { AnnotationSpec, isArray, isInterface, isPrimitive, isRef, isStructure }
|
|
|
2
2
|
import { defineAnnotatedType, flattenAnnotatedType, isAnnotatedType, isAnnotatedTypeOfPrimitive } from "@atscript/typescript/utils";
|
|
3
3
|
import { MongoClient, ObjectId } from "mongodb";
|
|
4
4
|
|
|
5
|
-
//#region packages/mongo/src/plugin/primitives.ts
|
|
6
|
-
const primitives = { mongo: { extensions: {
|
|
7
|
-
objectId: {
|
|
8
|
-
type: "string",
|
|
9
|
-
documentation: "Represents a **MongoDB ObjectId**.\n\n- Stored as a **string** but can be converted to an ObjectId at runtime.\n- Useful for handling `_id` fields and queries that require ObjectId conversion.\n- Automatically converts string `_id` values into **MongoDB ObjectId** when needed.\n\n**Example:**\n```atscript\nuserId: mongo.objectId\n```\n",
|
|
10
|
-
expect: { pattern: /^[a-fA-F0-9]{24}$/ }
|
|
11
|
-
},
|
|
12
|
-
vector: {
|
|
13
|
-
type: {
|
|
14
|
-
kind: "array",
|
|
15
|
-
of: "number"
|
|
16
|
-
},
|
|
17
|
-
documentation: "Represents a **MongoDB Vector (Array of Numbers)** for **Vector Search**.\n\n- Equivalent to `number[]` but explicitly used for **vector embeddings**.\n\n**Example:**\n```atscript\nembedding: mongo.vector\n```\n"
|
|
18
|
-
}
|
|
19
|
-
} } };
|
|
20
|
-
|
|
21
|
-
//#endregion
|
|
22
5
|
//#region packages/mongo/src/plugin/annotations.ts
|
|
23
6
|
const analyzers = [
|
|
24
7
|
"lucene.standard",
|
|
@@ -289,28 +272,33 @@ const annotations = { mongo: {
|
|
|
289
272
|
} };
|
|
290
273
|
|
|
291
274
|
//#endregion
|
|
292
|
-
//#region packages/mongo/src/plugin/
|
|
293
|
-
const
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
}
|
|
275
|
+
//#region packages/mongo/src/plugin/primitives.ts
|
|
276
|
+
const primitives = { mongo: { extensions: {
|
|
277
|
+
objectId: {
|
|
278
|
+
type: "string",
|
|
279
|
+
documentation: "Represents a **MongoDB ObjectId**.\n\n- Stored as a **string** but can be converted to an ObjectId at runtime.\n- Useful for handling `_id` fields and queries that require ObjectId conversion.\n- Automatically converts string `_id` values into **MongoDB ObjectId** when needed.\n\n**Example:**\n```atscript\nuserId: mongo.objectId\n```\n",
|
|
280
|
+
expect: { pattern: /^[a-fA-F0-9]{24}$/ }
|
|
281
|
+
},
|
|
282
|
+
vector: {
|
|
283
|
+
type: {
|
|
284
|
+
kind: "array",
|
|
285
|
+
of: "number"
|
|
286
|
+
},
|
|
287
|
+
documentation: "Represents a **MongoDB Vector (Array of Numbers)** for **Vector Search**.\n\n- Equivalent to `number[]` but explicitly used for **vector embeddings**.\n\n**Example:**\n```atscript\nembedding: mongo.vector\n```\n"
|
|
288
|
+
}
|
|
289
|
+
} } };
|
|
304
290
|
|
|
305
291
|
//#endregion
|
|
306
|
-
//#region packages/mongo/src/
|
|
307
|
-
const
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
};
|
|
292
|
+
//#region packages/mongo/src/plugin/index.ts
|
|
293
|
+
const MongoPlugin = () => ({
|
|
294
|
+
name: "mongo",
|
|
295
|
+
config() {
|
|
296
|
+
return {
|
|
297
|
+
primitives,
|
|
298
|
+
annotations
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
});
|
|
314
302
|
|
|
315
303
|
//#endregion
|
|
316
304
|
//#region packages/mongo/src/lib/validate-plugins.ts
|
|
@@ -325,7 +313,7 @@ const validateMongoUniqueArrayItemsPlugin = (ctx, def, value) => {
|
|
|
325
313
|
const keyProps = CollectionPatcher.getKeyProps(def);
|
|
326
314
|
for (const item of value) {
|
|
327
315
|
let key = "";
|
|
328
|
-
if (keyProps.size) for (const prop of keyProps) key += JSON.stringify(item[prop]) + separator;
|
|
316
|
+
if (keyProps.size > 0) for (const prop of keyProps) key += JSON.stringify(item[prop]) + separator;
|
|
329
317
|
else key = JSON.stringify(item);
|
|
330
318
|
if (seen.has(key)) {
|
|
331
319
|
ctx.error(`Duplicate items are not allowed`);
|
|
@@ -394,7 +382,7 @@ var CollectionPatcher = class CollectionPatcher {
|
|
|
394
382
|
const objType = defArray.type.of.type;
|
|
395
383
|
const t = defineAnnotatedType("object").copyMetadata(defArray.type.of.metadata);
|
|
396
384
|
const keyProps = CollectionPatcher.getKeyProps(defArray);
|
|
397
|
-
for (const [key, val] of objType.props.entries()) if (keyProps.size) if (keyProps.has(key)) t.prop(key, defineAnnotatedType().refTo(val).copyMetadata(def.metadata).$type);
|
|
385
|
+
for (const [key, val] of objType.props.entries()) if (keyProps.size > 0) if (keyProps.has(key)) t.prop(key, defineAnnotatedType().refTo(val).copyMetadata(def.metadata).$type);
|
|
398
386
|
else t.prop(key, defineAnnotatedType().refTo(val).copyMetadata(def.metadata).optional().$type);
|
|
399
387
|
else t.prop(key, defineAnnotatedType().refTo(val).copyMetadata(def.metadata).optional(!!val.optional).$type);
|
|
400
388
|
return defineAnnotatedType("array").of(t.$type).copyMetadata(def.metadata).annotate("mongo.__patchArrayValue").optional().$type;
|
|
@@ -418,7 +406,7 @@ else t.prop(key, defineAnnotatedType().refTo(val).copyMetadata(def.metadata).opt
|
|
|
418
406
|
*/ preparePatch() {
|
|
419
407
|
this.filterObj = { _id: this.collection.prepareId(this.payload._id) };
|
|
420
408
|
this.flattenPayload(this.payload);
|
|
421
|
-
|
|
409
|
+
const updateFilter = this.updatePipeline;
|
|
422
410
|
return {
|
|
423
411
|
toArgs: () => [
|
|
424
412
|
this.filterObj,
|
|
@@ -524,7 +512,7 @@ else this._set(key, { $concatArrays: [{ $ifNull: [`$${key}`, []] }, input] });
|
|
|
524
512
|
* - unique → $setUnion (deep equality)
|
|
525
513
|
*/ _upsert(key, input, keyProps) {
|
|
526
514
|
if (!input?.length) return;
|
|
527
|
-
if (keyProps.size) {
|
|
515
|
+
if (keyProps.size > 0) {
|
|
528
516
|
const keys = [...keyProps];
|
|
529
517
|
this._set(key, { $reduce: {
|
|
530
518
|
input,
|
|
@@ -551,7 +539,7 @@ else this._set(key, { $concatArrays: [{ $ifNull: [`$${key}`, []] }, input] });
|
|
|
551
539
|
* - non-keyed → behave like `$addToSet` (insert only when not present)
|
|
552
540
|
*/ _update(key, input, keyProps) {
|
|
553
541
|
if (!input?.length) return;
|
|
554
|
-
if (keyProps.size) {
|
|
542
|
+
if (keyProps.size > 0) {
|
|
555
543
|
const mergeStrategy = this.collection.flatMap.get(key)?.metadata?.get("mongo.patch.strategy") === "merge";
|
|
556
544
|
const keys = [...keyProps];
|
|
557
545
|
this._set(key, { $reduce: {
|
|
@@ -575,7 +563,7 @@ else this._set(key, { $concatArrays: [{ $ifNull: [`$${key}`, []] }, input] });
|
|
|
575
563
|
* - non-keyed → deep equality remove (`$setDifference`)
|
|
576
564
|
*/ _remove(key, input, keyProps) {
|
|
577
565
|
if (!input?.length) return;
|
|
578
|
-
if (keyProps.size) {
|
|
566
|
+
if (keyProps.size > 0) {
|
|
579
567
|
const keys = [...keyProps];
|
|
580
568
|
this._set(key, { $let: {
|
|
581
569
|
vars: { rem: input },
|
|
@@ -608,6 +596,16 @@ else this._set(key, { $concatArrays: [{ $ifNull: [`$${key}`, []] }, input] });
|
|
|
608
596
|
}
|
|
609
597
|
};
|
|
610
598
|
|
|
599
|
+
//#endregion
|
|
600
|
+
//#region packages/mongo/src/lib/logger.ts
|
|
601
|
+
const NoopLogger = {
|
|
602
|
+
error: () => {},
|
|
603
|
+
warn: () => {},
|
|
604
|
+
log: () => {},
|
|
605
|
+
info: () => {},
|
|
606
|
+
debug: () => {}
|
|
607
|
+
};
|
|
608
|
+
|
|
611
609
|
//#endregion
|
|
612
610
|
//#region packages/mongo/src/lib/as-collection.ts
|
|
613
611
|
function _define_property$1(obj, key, value) {
|
|
@@ -810,19 +808,23 @@ else {
|
|
|
810
808
|
this._searchIndexesMap = new Map();
|
|
811
809
|
let deafultIndex;
|
|
812
810
|
for (const index of this.indexes.values()) switch (index.type) {
|
|
813
|
-
case "text":
|
|
811
|
+
case "text": {
|
|
814
812
|
if (!deafultIndex) deafultIndex = index;
|
|
815
813
|
break;
|
|
816
|
-
|
|
814
|
+
}
|
|
815
|
+
case "dynamic_text": {
|
|
817
816
|
deafultIndex = index;
|
|
818
817
|
break;
|
|
819
|
-
|
|
818
|
+
}
|
|
819
|
+
case "search_text": {
|
|
820
820
|
if (!deafultIndex || deafultIndex?.type === "text") deafultIndex = index;
|
|
821
821
|
this._searchIndexesMap.set(index.name, index);
|
|
822
822
|
break;
|
|
823
|
-
|
|
823
|
+
}
|
|
824
|
+
case "vector": {
|
|
824
825
|
this._searchIndexesMap.set(index.name, index);
|
|
825
826
|
break;
|
|
827
|
+
}
|
|
826
828
|
default:
|
|
827
829
|
}
|
|
828
830
|
if (deafultIndex && !this._searchIndexesMap.has(DEFAULT_INDEX_NAME)) this._searchIndexesMap.set(DEFAULT_INDEX_NAME, deafultIndex);
|
|
@@ -847,13 +849,14 @@ else {
|
|
|
847
849
|
switch (local.type) {
|
|
848
850
|
case "plain":
|
|
849
851
|
case "unique":
|
|
850
|
-
case "text":
|
|
852
|
+
case "text": {
|
|
851
853
|
if ((local.type === "text" || objMatch(local.fields, remote.key)) && objMatch(local.weights || {}, remote.weights || {})) indexesToCreate.delete(remote.name);
|
|
852
854
|
else {
|
|
853
855
|
this.logger.debug(`dropping index "${remote.name}"`);
|
|
854
856
|
await this.collection.dropIndex(remote.name);
|
|
855
857
|
}
|
|
856
858
|
break;
|
|
859
|
+
}
|
|
857
860
|
default:
|
|
858
861
|
}
|
|
859
862
|
} else {
|
|
@@ -870,15 +873,17 @@ else {
|
|
|
870
873
|
const right = remote.latestDefinition;
|
|
871
874
|
switch (local.type) {
|
|
872
875
|
case "dynamic_text":
|
|
873
|
-
case "search_text":
|
|
874
|
-
|
|
876
|
+
case "search_text": {
|
|
877
|
+
const left = local.definition;
|
|
875
878
|
if (left.analyzer === right.analyzer && fieldsMatch(left.mappings.fields || {}, right.mappings.fields || {})) indexesToCreate.delete(remote.name);
|
|
876
879
|
else toUpdate.add(remote.name);
|
|
877
880
|
break;
|
|
878
|
-
|
|
881
|
+
}
|
|
882
|
+
case "vector": {
|
|
879
883
|
if (vectorFieldsMatch(local.definition.fields || [], right.fields || [])) indexesToCreate.delete(remote.name);
|
|
880
884
|
else toUpdate.add(remote.name);
|
|
881
885
|
break;
|
|
886
|
+
}
|
|
882
887
|
default:
|
|
883
888
|
}
|
|
884
889
|
} else if (remote.status !== "DELETING") {
|
|
@@ -887,27 +892,30 @@ else toUpdate.add(remote.name);
|
|
|
887
892
|
} else this.logger.debug(`search index "${remote.name}" is in deleting status`);
|
|
888
893
|
}
|
|
889
894
|
for (const [key, value] of Array.from(indexesToCreate.entries())) switch (value.type) {
|
|
890
|
-
case "plain":
|
|
895
|
+
case "plain": {
|
|
891
896
|
this.logger.debug(`creating index "${key}"`);
|
|
892
897
|
await this.collection.createIndex(value.fields, { name: key });
|
|
893
898
|
break;
|
|
894
|
-
|
|
899
|
+
}
|
|
900
|
+
case "unique": {
|
|
895
901
|
this.logger.debug(`creating index "${key}"`);
|
|
896
902
|
await this.collection.createIndex(value.fields, {
|
|
897
903
|
name: key,
|
|
898
904
|
unique: true
|
|
899
905
|
});
|
|
900
906
|
break;
|
|
901
|
-
|
|
907
|
+
}
|
|
908
|
+
case "text": {
|
|
902
909
|
this.logger.debug(`creating index "${key}"`);
|
|
903
910
|
await this.collection.createIndex(value.fields, {
|
|
904
911
|
weights: value.weights,
|
|
905
912
|
name: key
|
|
906
913
|
});
|
|
907
914
|
break;
|
|
915
|
+
}
|
|
908
916
|
case "dynamic_text":
|
|
909
917
|
case "search_text":
|
|
910
|
-
case "vector":
|
|
918
|
+
case "vector": {
|
|
911
919
|
if (toUpdate.has(key)) {
|
|
912
920
|
this.logger.debug(`updating search index "${key}"`);
|
|
913
921
|
await this.collection.updateSearchIndex(key, value.definition);
|
|
@@ -920,6 +928,7 @@ else toUpdate.add(remote.name);
|
|
|
920
928
|
});
|
|
921
929
|
}
|
|
922
930
|
break;
|
|
931
|
+
}
|
|
923
932
|
default:
|
|
924
933
|
}
|
|
925
934
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atscript/mongo",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"description": "Mongodb plugin for atscript.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"atscript",
|
|
7
|
+
"mongodb",
|
|
8
|
+
"plugin"
|
|
9
|
+
],
|
|
10
|
+
"homepage": "https://github.com/moostjs/atscript/tree/main/packages/mongo#readme",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/moostjs/atscript/issues"
|
|
13
|
+
},
|
|
14
|
+
"license": "ISC",
|
|
15
|
+
"author": "Artem Maltsev",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/moostjs/atscript.git",
|
|
19
|
+
"directory": "packages/mongo"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
5
24
|
"type": "module",
|
|
6
25
|
"main": "dist/index.mjs",
|
|
7
26
|
"types": "dist/index.d.ts",
|
|
@@ -13,32 +32,13 @@
|
|
|
13
32
|
},
|
|
14
33
|
"./package.json": "./package.json"
|
|
15
34
|
},
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
],
|
|
19
|
-
"keywords": [
|
|
20
|
-
"atscript",
|
|
21
|
-
"plugin",
|
|
22
|
-
"mongodb"
|
|
23
|
-
],
|
|
24
|
-
"author": "Artem Maltsev",
|
|
25
|
-
"repository": {
|
|
26
|
-
"type": "git",
|
|
27
|
-
"url": "git+https://github.com/moostjs/atscript.git",
|
|
28
|
-
"directory": "packages/mongo"
|
|
29
|
-
},
|
|
30
|
-
"bugs": {
|
|
31
|
-
"url": "https://github.com/moostjs/atscript/issues"
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"vitest": "3.2.4"
|
|
32
37
|
},
|
|
33
|
-
"homepage": "https://github.com/moostjs/atscript/tree/main/packages/mongo#readme",
|
|
34
|
-
"license": "ISC",
|
|
35
38
|
"peerDependencies": {
|
|
36
39
|
"mongodb": "^6.17.0",
|
|
37
|
-
"@atscript/core": "^0.1.
|
|
38
|
-
"@atscript/typescript": "^0.1.
|
|
39
|
-
},
|
|
40
|
-
"devDependencies": {
|
|
41
|
-
"vitest": "3.2.4"
|
|
40
|
+
"@atscript/core": "^0.1.18",
|
|
41
|
+
"@atscript/typescript": "^0.1.18"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
44
|
"pub": "pnpm publish --access public",
|