@atscript/mongo 0.1.31 → 0.1.32
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 +522 -643
- package/dist/index.d.ts +241 -106
- package/dist/index.mjs +519 -642
- package/dist/plugin.cjs +228 -0
- package/dist/plugin.d.ts +5 -0
- package/dist/plugin.mjs +204 -0
- package/package.json +28 -3
- package/skills/atscript-mongo/core.md +1 -1
package/dist/plugin.cjs
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//#region rolldown:runtime
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
20
|
+
value: mod,
|
|
21
|
+
enumerable: true
|
|
22
|
+
}) : target, mod));
|
|
23
|
+
|
|
24
|
+
//#endregion
|
|
25
|
+
const __atscript_core = __toESM(require("@atscript/core"));
|
|
26
|
+
|
|
27
|
+
//#region packages/mongo/src/plugin/annotations.ts
|
|
28
|
+
const analyzers = [
|
|
29
|
+
"lucene.standard",
|
|
30
|
+
"lucene.simple",
|
|
31
|
+
"lucene.whitespace",
|
|
32
|
+
"lucene.english",
|
|
33
|
+
"lucene.french",
|
|
34
|
+
"lucene.german",
|
|
35
|
+
"lucene.italian",
|
|
36
|
+
"lucene.portuguese",
|
|
37
|
+
"lucene.spanish",
|
|
38
|
+
"lucene.chinese",
|
|
39
|
+
"lucene.hindi",
|
|
40
|
+
"lucene.bengali",
|
|
41
|
+
"lucene.russian",
|
|
42
|
+
"lucene.arabic"
|
|
43
|
+
];
|
|
44
|
+
const annotations = {
|
|
45
|
+
collection: new __atscript_core.AnnotationSpec({
|
|
46
|
+
description: "Marks an interface as a **MongoDB collection**.\n\n- Use together with `@db.table \"name\"` which provides the collection name.\n- Automatically injects a **non-optional** `_id` field if not explicitly defined.\n- `_id` must be of type **`string`**, **`number`**, or **`mongo.objectId`**.\n\n**Example:**\n```atscript\n@db.table \"users\"\n@db.mongo.collection\nexport interface User {\n _id: mongo.objectId\n email: string.email\n}\n```\n",
|
|
47
|
+
nodeType: ["interface"],
|
|
48
|
+
validate(token, args, doc) {
|
|
49
|
+
const parent = token.parentNode;
|
|
50
|
+
const struc = parent?.getDefinition();
|
|
51
|
+
const errors = [];
|
|
52
|
+
if ((0, __atscript_core.isInterface)(parent) && parent.props.has("_id") && (0, __atscript_core.isStructure)(struc)) {
|
|
53
|
+
const _id = parent.props.get("_id");
|
|
54
|
+
const isOptional = !!_id.token("optional");
|
|
55
|
+
if (isOptional) errors.push({
|
|
56
|
+
message: `[db.mongo] _id can't be optional in Mongo Collection`,
|
|
57
|
+
severity: 1,
|
|
58
|
+
range: _id.token("identifier").range
|
|
59
|
+
});
|
|
60
|
+
const definition = _id.getDefinition();
|
|
61
|
+
if (!definition) return errors;
|
|
62
|
+
let wrongType = false;
|
|
63
|
+
if ((0, __atscript_core.isRef)(definition)) {
|
|
64
|
+
const def = doc.unwindType(definition.id, definition.chain)?.def;
|
|
65
|
+
if ((0, __atscript_core.isPrimitive)(def) && !["string", "number"].includes(def.config.type)) wrongType = true;
|
|
66
|
+
} else wrongType = true;
|
|
67
|
+
if (wrongType) errors.push({
|
|
68
|
+
message: `[db.mongo] _id must be of type string, number or mongo.objectId`,
|
|
69
|
+
severity: 1,
|
|
70
|
+
range: _id.token("identifier").range
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
return errors;
|
|
74
|
+
},
|
|
75
|
+
modify(token, args, doc) {
|
|
76
|
+
const parent = token.parentNode;
|
|
77
|
+
const struc = parent?.getDefinition();
|
|
78
|
+
if ((0, __atscript_core.isInterface)(parent) && !parent.props.has("_id") && (0, __atscript_core.isStructure)(struc)) struc.addVirtualProp({
|
|
79
|
+
name: "_id",
|
|
80
|
+
type: "mongo.objectId",
|
|
81
|
+
documentation: "Mongodb Primary Key ObjectId"
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}),
|
|
85
|
+
search: {
|
|
86
|
+
dynamic: new __atscript_core.AnnotationSpec({
|
|
87
|
+
description: "Creates a **dynamic MongoDB Search Index** that applies to the entire collection.\n\n- **Indexes all text fields automatically** (no need to specify fields).\n- Supports **language analyzers** for text tokenization.\n- Enables **fuzzy search** (typo tolerance) if needed.\n\n**Example:**\n```atscript\n@db.mongo.search.dynamic \"lucene.english\", 1\nexport interface MongoCollection {}\n```\n",
|
|
88
|
+
nodeType: ["interface"],
|
|
89
|
+
multiple: false,
|
|
90
|
+
argument: [{
|
|
91
|
+
optional: true,
|
|
92
|
+
name: "analyzer",
|
|
93
|
+
type: "string",
|
|
94
|
+
description: "The **text analyzer** for tokenization. Defaults to `\"lucene.standard\"`.\n\n**Available options:** `\"lucene.standard\"`, `\"lucene.english\"`, `\"lucene.spanish\"`, etc.",
|
|
95
|
+
values: analyzers
|
|
96
|
+
}, {
|
|
97
|
+
optional: true,
|
|
98
|
+
name: "fuzzy",
|
|
99
|
+
type: "number",
|
|
100
|
+
description: "Maximum typo tolerance (`0-2`). Defaults to `0` (no fuzzy search).\n\n- `0` → Exact match required.\n- `1` → Allows small typos (e.g., `\"mongo\"` ≈ `\"mango\"`).\n- `2` → More typo tolerance (e.g., `\"mongodb\"` ≈ `\"mangodb\"`)."
|
|
101
|
+
}]
|
|
102
|
+
}),
|
|
103
|
+
static: new __atscript_core.AnnotationSpec({
|
|
104
|
+
description: "Defines a **MongoDB Atlas Search Index** for the collection. The props can refer to this index using `@db.mongo.search.text` annotation.\n\n- **Creates a named search index** for full-text search.\n- **Specify analyzers and fuzzy search** behavior at the index level.\n- **Fields must explicitly use `@db.mongo.search.text`** to be included in this search index.\n\n**Example:**\n```atscript\n@db.mongo.search.static \"lucene.english\", 1, \"mySearchIndex\"\nexport interface MongoCollection {}\n```\n",
|
|
105
|
+
nodeType: ["interface"],
|
|
106
|
+
multiple: true,
|
|
107
|
+
argument: [
|
|
108
|
+
{
|
|
109
|
+
optional: true,
|
|
110
|
+
name: "analyzer",
|
|
111
|
+
type: "string",
|
|
112
|
+
description: "The text analyzer for tokenization. Defaults to `\"lucene.standard\"`.\n\n**Available options:** `\"lucene.standard\"`, `\"lucene.english\"`, `\"lucene.spanish\"`, `\"lucene.german\"`, etc.",
|
|
113
|
+
values: analyzers
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
optional: true,
|
|
117
|
+
name: "fuzzy",
|
|
118
|
+
type: "number",
|
|
119
|
+
description: "Maximum typo tolerance (`0-2`). **Defaults to `0` (no fuzzy matching).**\n\n- `0` → No typos allowed (exact match required).\n- `1` → Allows small typos (e.g., \"mongo\" ≈ \"mango\").\n- `2` → More typo tolerance (e.g., \"mongodb\" ≈ \"mangodb\")."
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
optional: true,
|
|
123
|
+
name: "indexName",
|
|
124
|
+
type: "string",
|
|
125
|
+
description: "The name of the search index. Fields must reference this name using `@db.mongo.search.text`. If not set, defaults to `\"DEFAULT\"`."
|
|
126
|
+
}
|
|
127
|
+
]
|
|
128
|
+
}),
|
|
129
|
+
text: new __atscript_core.AnnotationSpec({
|
|
130
|
+
description: "Marks a field to be **included in a MongoDB Atlas Search Index** defined by `@db.mongo.search.static`.\n\n- **The field has to reference an existing search index name**.\n- If index name is not defined, a new search index with default attributes will be created.\n\n**Example:**\n```atscript\n@db.mongo.search.text \"lucene.english\", \"mySearchIndex\"\nfirstName: string\n```\n",
|
|
131
|
+
nodeType: ["prop"],
|
|
132
|
+
multiple: true,
|
|
133
|
+
argument: [{
|
|
134
|
+
optional: true,
|
|
135
|
+
name: "analyzer",
|
|
136
|
+
type: "string",
|
|
137
|
+
description: "The text analyzer for tokenization. Defaults to `\"lucene.standard\"`.\n\n**Available options:** `\"lucene.standard\"`, `\"lucene.english\"`, `\"lucene.spanish\"`, `\"lucene.german\"`, etc.",
|
|
138
|
+
values: analyzers
|
|
139
|
+
}, {
|
|
140
|
+
optional: true,
|
|
141
|
+
name: "indexName",
|
|
142
|
+
type: "string",
|
|
143
|
+
description: "The **name of the search index** defined in `@db.mongo.search.static`. This links the field to the correct index. If not set, defaults to `\"DEFAULT\"`."
|
|
144
|
+
}]
|
|
145
|
+
}),
|
|
146
|
+
vector: new __atscript_core.AnnotationSpec({
|
|
147
|
+
description: "Creates a **MongoDB Vector Search Index** for **semantic search, embeddings, and AI-powered search**.\n\n- Each field that stores vector embeddings **must define its own vector index**.\n- Supports **cosine similarity, Euclidean distance, and dot product similarity**.\n- Vector fields must be an **array of numbers**.\n\n**Example:**\n```atscript\n@db.mongo.search.vector 512, \"cosine\"\nembedding: mongo.vector\n```\n",
|
|
148
|
+
nodeType: ["prop"],
|
|
149
|
+
multiple: false,
|
|
150
|
+
argument: [
|
|
151
|
+
{
|
|
152
|
+
optional: false,
|
|
153
|
+
name: "dimensions",
|
|
154
|
+
type: "number",
|
|
155
|
+
description: "The **number of dimensions in the vector** (e.g., 512 for OpenAI embeddings).",
|
|
156
|
+
values: [
|
|
157
|
+
"512",
|
|
158
|
+
"768",
|
|
159
|
+
"1024",
|
|
160
|
+
"1536",
|
|
161
|
+
"3072",
|
|
162
|
+
"4096"
|
|
163
|
+
]
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
optional: true,
|
|
167
|
+
name: "similarity",
|
|
168
|
+
type: "string",
|
|
169
|
+
description: "The **similarity metric** used for vector search. Defaults to `\"cosine\"`.\n\n**Available options:** `\"cosine\"`, `\"euclidean\"`, `\"dotProduct\"`.",
|
|
170
|
+
values: [
|
|
171
|
+
"cosine",
|
|
172
|
+
"euclidean",
|
|
173
|
+
"dotProduct"
|
|
174
|
+
]
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
optional: true,
|
|
178
|
+
name: "indexName",
|
|
179
|
+
type: "string",
|
|
180
|
+
description: "The **name of the vector search index** (optional, defaults to property name)."
|
|
181
|
+
}
|
|
182
|
+
]
|
|
183
|
+
}),
|
|
184
|
+
filter: new __atscript_core.AnnotationSpec({
|
|
185
|
+
description: "Assigns a field as a **filter field** for a **MongoDB Vector Search Index**.\n\n- The assigned field **must be indexed** for efficient filtering.\n- Filters allow vector search queries to return results **only within a specific category, user group, or tag**.\n- The vector index must be defined using `@db.mongo.search.vector`.\n\n**Example:**\n```atscript\n@db.mongo.search.vector 512, \"cosine\"\nembedding: number[]\n\n@db.mongo.search.filter \"embedding\"\ncategory: string\n```\n",
|
|
186
|
+
nodeType: ["prop"],
|
|
187
|
+
multiple: true,
|
|
188
|
+
argument: [{
|
|
189
|
+
optional: false,
|
|
190
|
+
name: "indexName",
|
|
191
|
+
type: "string",
|
|
192
|
+
description: "The **name of the vector search index** this field should be used as a filter for."
|
|
193
|
+
}]
|
|
194
|
+
})
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
//#endregion
|
|
199
|
+
//#region packages/mongo/src/plugin/primitives.ts
|
|
200
|
+
const primitives = { mongo: { extensions: {
|
|
201
|
+
objectId: {
|
|
202
|
+
type: "string",
|
|
203
|
+
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",
|
|
204
|
+
annotations: { "expect.pattern": { pattern: "^[a-fA-F0-9]{24}$" } }
|
|
205
|
+
},
|
|
206
|
+
vector: {
|
|
207
|
+
type: {
|
|
208
|
+
kind: "array",
|
|
209
|
+
of: "number"
|
|
210
|
+
},
|
|
211
|
+
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"
|
|
212
|
+
}
|
|
213
|
+
} } };
|
|
214
|
+
|
|
215
|
+
//#endregion
|
|
216
|
+
//#region packages/mongo/src/plugin/index.ts
|
|
217
|
+
const MongoPlugin = () => ({
|
|
218
|
+
name: "mongo",
|
|
219
|
+
config() {
|
|
220
|
+
return {
|
|
221
|
+
primitives,
|
|
222
|
+
annotations: { db: { mongo: annotations } }
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
//#endregion
|
|
228
|
+
exports.MongoPlugin = MongoPlugin
|
package/dist/plugin.d.ts
ADDED
package/dist/plugin.mjs
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { AnnotationSpec, isInterface, isPrimitive, isRef, isStructure } from "@atscript/core";
|
|
2
|
+
|
|
3
|
+
//#region packages/mongo/src/plugin/annotations.ts
|
|
4
|
+
const analyzers = [
|
|
5
|
+
"lucene.standard",
|
|
6
|
+
"lucene.simple",
|
|
7
|
+
"lucene.whitespace",
|
|
8
|
+
"lucene.english",
|
|
9
|
+
"lucene.french",
|
|
10
|
+
"lucene.german",
|
|
11
|
+
"lucene.italian",
|
|
12
|
+
"lucene.portuguese",
|
|
13
|
+
"lucene.spanish",
|
|
14
|
+
"lucene.chinese",
|
|
15
|
+
"lucene.hindi",
|
|
16
|
+
"lucene.bengali",
|
|
17
|
+
"lucene.russian",
|
|
18
|
+
"lucene.arabic"
|
|
19
|
+
];
|
|
20
|
+
const annotations = {
|
|
21
|
+
collection: new AnnotationSpec({
|
|
22
|
+
description: "Marks an interface as a **MongoDB collection**.\n\n- Use together with `@db.table \"name\"` which provides the collection name.\n- Automatically injects a **non-optional** `_id` field if not explicitly defined.\n- `_id` must be of type **`string`**, **`number`**, or **`mongo.objectId`**.\n\n**Example:**\n```atscript\n@db.table \"users\"\n@db.mongo.collection\nexport interface User {\n _id: mongo.objectId\n email: string.email\n}\n```\n",
|
|
23
|
+
nodeType: ["interface"],
|
|
24
|
+
validate(token, args, doc) {
|
|
25
|
+
const parent = token.parentNode;
|
|
26
|
+
const struc = parent?.getDefinition();
|
|
27
|
+
const errors = [];
|
|
28
|
+
if (isInterface(parent) && parent.props.has("_id") && isStructure(struc)) {
|
|
29
|
+
const _id = parent.props.get("_id");
|
|
30
|
+
const isOptional = !!_id.token("optional");
|
|
31
|
+
if (isOptional) errors.push({
|
|
32
|
+
message: `[db.mongo] _id can't be optional in Mongo Collection`,
|
|
33
|
+
severity: 1,
|
|
34
|
+
range: _id.token("identifier").range
|
|
35
|
+
});
|
|
36
|
+
const definition = _id.getDefinition();
|
|
37
|
+
if (!definition) return errors;
|
|
38
|
+
let wrongType = false;
|
|
39
|
+
if (isRef(definition)) {
|
|
40
|
+
const def = doc.unwindType(definition.id, definition.chain)?.def;
|
|
41
|
+
if (isPrimitive(def) && !["string", "number"].includes(def.config.type)) wrongType = true;
|
|
42
|
+
} else wrongType = true;
|
|
43
|
+
if (wrongType) errors.push({
|
|
44
|
+
message: `[db.mongo] _id must be of type string, number or mongo.objectId`,
|
|
45
|
+
severity: 1,
|
|
46
|
+
range: _id.token("identifier").range
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return errors;
|
|
50
|
+
},
|
|
51
|
+
modify(token, args, doc) {
|
|
52
|
+
const parent = token.parentNode;
|
|
53
|
+
const struc = parent?.getDefinition();
|
|
54
|
+
if (isInterface(parent) && !parent.props.has("_id") && isStructure(struc)) struc.addVirtualProp({
|
|
55
|
+
name: "_id",
|
|
56
|
+
type: "mongo.objectId",
|
|
57
|
+
documentation: "Mongodb Primary Key ObjectId"
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}),
|
|
61
|
+
search: {
|
|
62
|
+
dynamic: new AnnotationSpec({
|
|
63
|
+
description: "Creates a **dynamic MongoDB Search Index** that applies to the entire collection.\n\n- **Indexes all text fields automatically** (no need to specify fields).\n- Supports **language analyzers** for text tokenization.\n- Enables **fuzzy search** (typo tolerance) if needed.\n\n**Example:**\n```atscript\n@db.mongo.search.dynamic \"lucene.english\", 1\nexport interface MongoCollection {}\n```\n",
|
|
64
|
+
nodeType: ["interface"],
|
|
65
|
+
multiple: false,
|
|
66
|
+
argument: [{
|
|
67
|
+
optional: true,
|
|
68
|
+
name: "analyzer",
|
|
69
|
+
type: "string",
|
|
70
|
+
description: "The **text analyzer** for tokenization. Defaults to `\"lucene.standard\"`.\n\n**Available options:** `\"lucene.standard\"`, `\"lucene.english\"`, `\"lucene.spanish\"`, etc.",
|
|
71
|
+
values: analyzers
|
|
72
|
+
}, {
|
|
73
|
+
optional: true,
|
|
74
|
+
name: "fuzzy",
|
|
75
|
+
type: "number",
|
|
76
|
+
description: "Maximum typo tolerance (`0-2`). Defaults to `0` (no fuzzy search).\n\n- `0` → Exact match required.\n- `1` → Allows small typos (e.g., `\"mongo\"` ≈ `\"mango\"`).\n- `2` → More typo tolerance (e.g., `\"mongodb\"` ≈ `\"mangodb\"`)."
|
|
77
|
+
}]
|
|
78
|
+
}),
|
|
79
|
+
static: new AnnotationSpec({
|
|
80
|
+
description: "Defines a **MongoDB Atlas Search Index** for the collection. The props can refer to this index using `@db.mongo.search.text` annotation.\n\n- **Creates a named search index** for full-text search.\n- **Specify analyzers and fuzzy search** behavior at the index level.\n- **Fields must explicitly use `@db.mongo.search.text`** to be included in this search index.\n\n**Example:**\n```atscript\n@db.mongo.search.static \"lucene.english\", 1, \"mySearchIndex\"\nexport interface MongoCollection {}\n```\n",
|
|
81
|
+
nodeType: ["interface"],
|
|
82
|
+
multiple: true,
|
|
83
|
+
argument: [
|
|
84
|
+
{
|
|
85
|
+
optional: true,
|
|
86
|
+
name: "analyzer",
|
|
87
|
+
type: "string",
|
|
88
|
+
description: "The text analyzer for tokenization. Defaults to `\"lucene.standard\"`.\n\n**Available options:** `\"lucene.standard\"`, `\"lucene.english\"`, `\"lucene.spanish\"`, `\"lucene.german\"`, etc.",
|
|
89
|
+
values: analyzers
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
optional: true,
|
|
93
|
+
name: "fuzzy",
|
|
94
|
+
type: "number",
|
|
95
|
+
description: "Maximum typo tolerance (`0-2`). **Defaults to `0` (no fuzzy matching).**\n\n- `0` → No typos allowed (exact match required).\n- `1` → Allows small typos (e.g., \"mongo\" ≈ \"mango\").\n- `2` → More typo tolerance (e.g., \"mongodb\" ≈ \"mangodb\")."
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
optional: true,
|
|
99
|
+
name: "indexName",
|
|
100
|
+
type: "string",
|
|
101
|
+
description: "The name of the search index. Fields must reference this name using `@db.mongo.search.text`. If not set, defaults to `\"DEFAULT\"`."
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
}),
|
|
105
|
+
text: new AnnotationSpec({
|
|
106
|
+
description: "Marks a field to be **included in a MongoDB Atlas Search Index** defined by `@db.mongo.search.static`.\n\n- **The field has to reference an existing search index name**.\n- If index name is not defined, a new search index with default attributes will be created.\n\n**Example:**\n```atscript\n@db.mongo.search.text \"lucene.english\", \"mySearchIndex\"\nfirstName: string\n```\n",
|
|
107
|
+
nodeType: ["prop"],
|
|
108
|
+
multiple: true,
|
|
109
|
+
argument: [{
|
|
110
|
+
optional: true,
|
|
111
|
+
name: "analyzer",
|
|
112
|
+
type: "string",
|
|
113
|
+
description: "The text analyzer for tokenization. Defaults to `\"lucene.standard\"`.\n\n**Available options:** `\"lucene.standard\"`, `\"lucene.english\"`, `\"lucene.spanish\"`, `\"lucene.german\"`, etc.",
|
|
114
|
+
values: analyzers
|
|
115
|
+
}, {
|
|
116
|
+
optional: true,
|
|
117
|
+
name: "indexName",
|
|
118
|
+
type: "string",
|
|
119
|
+
description: "The **name of the search index** defined in `@db.mongo.search.static`. This links the field to the correct index. If not set, defaults to `\"DEFAULT\"`."
|
|
120
|
+
}]
|
|
121
|
+
}),
|
|
122
|
+
vector: new AnnotationSpec({
|
|
123
|
+
description: "Creates a **MongoDB Vector Search Index** for **semantic search, embeddings, and AI-powered search**.\n\n- Each field that stores vector embeddings **must define its own vector index**.\n- Supports **cosine similarity, Euclidean distance, and dot product similarity**.\n- Vector fields must be an **array of numbers**.\n\n**Example:**\n```atscript\n@db.mongo.search.vector 512, \"cosine\"\nembedding: mongo.vector\n```\n",
|
|
124
|
+
nodeType: ["prop"],
|
|
125
|
+
multiple: false,
|
|
126
|
+
argument: [
|
|
127
|
+
{
|
|
128
|
+
optional: false,
|
|
129
|
+
name: "dimensions",
|
|
130
|
+
type: "number",
|
|
131
|
+
description: "The **number of dimensions in the vector** (e.g., 512 for OpenAI embeddings).",
|
|
132
|
+
values: [
|
|
133
|
+
"512",
|
|
134
|
+
"768",
|
|
135
|
+
"1024",
|
|
136
|
+
"1536",
|
|
137
|
+
"3072",
|
|
138
|
+
"4096"
|
|
139
|
+
]
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
optional: true,
|
|
143
|
+
name: "similarity",
|
|
144
|
+
type: "string",
|
|
145
|
+
description: "The **similarity metric** used for vector search. Defaults to `\"cosine\"`.\n\n**Available options:** `\"cosine\"`, `\"euclidean\"`, `\"dotProduct\"`.",
|
|
146
|
+
values: [
|
|
147
|
+
"cosine",
|
|
148
|
+
"euclidean",
|
|
149
|
+
"dotProduct"
|
|
150
|
+
]
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
optional: true,
|
|
154
|
+
name: "indexName",
|
|
155
|
+
type: "string",
|
|
156
|
+
description: "The **name of the vector search index** (optional, defaults to property name)."
|
|
157
|
+
}
|
|
158
|
+
]
|
|
159
|
+
}),
|
|
160
|
+
filter: new AnnotationSpec({
|
|
161
|
+
description: "Assigns a field as a **filter field** for a **MongoDB Vector Search Index**.\n\n- The assigned field **must be indexed** for efficient filtering.\n- Filters allow vector search queries to return results **only within a specific category, user group, or tag**.\n- The vector index must be defined using `@db.mongo.search.vector`.\n\n**Example:**\n```atscript\n@db.mongo.search.vector 512, \"cosine\"\nembedding: number[]\n\n@db.mongo.search.filter \"embedding\"\ncategory: string\n```\n",
|
|
162
|
+
nodeType: ["prop"],
|
|
163
|
+
multiple: true,
|
|
164
|
+
argument: [{
|
|
165
|
+
optional: false,
|
|
166
|
+
name: "indexName",
|
|
167
|
+
type: "string",
|
|
168
|
+
description: "The **name of the vector search index** this field should be used as a filter for."
|
|
169
|
+
}]
|
|
170
|
+
})
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
//#endregion
|
|
175
|
+
//#region packages/mongo/src/plugin/primitives.ts
|
|
176
|
+
const primitives = { mongo: { extensions: {
|
|
177
|
+
objectId: {
|
|
178
|
+
type: "string",
|
|
179
|
+
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",
|
|
180
|
+
annotations: { "expect.pattern": { pattern: "^[a-fA-F0-9]{24}$" } }
|
|
181
|
+
},
|
|
182
|
+
vector: {
|
|
183
|
+
type: {
|
|
184
|
+
kind: "array",
|
|
185
|
+
of: "number"
|
|
186
|
+
},
|
|
187
|
+
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"
|
|
188
|
+
}
|
|
189
|
+
} } };
|
|
190
|
+
|
|
191
|
+
//#endregion
|
|
192
|
+
//#region packages/mongo/src/plugin/index.ts
|
|
193
|
+
const MongoPlugin = () => ({
|
|
194
|
+
name: "mongo",
|
|
195
|
+
config() {
|
|
196
|
+
return {
|
|
197
|
+
primitives,
|
|
198
|
+
annotations: { db: { mongo: annotations } }
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
//#endregion
|
|
204
|
+
export { MongoPlugin };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atscript/mongo",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.32",
|
|
4
4
|
"description": "Mongodb plugin for atscript.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"atscript",
|
|
@@ -29,12 +29,27 @@
|
|
|
29
29
|
},
|
|
30
30
|
"main": "dist/index.mjs",
|
|
31
31
|
"types": "dist/index.d.ts",
|
|
32
|
+
"typesVersions": {
|
|
33
|
+
"*": {
|
|
34
|
+
"plugin": [
|
|
35
|
+
"dist/plugin.d.ts"
|
|
36
|
+
],
|
|
37
|
+
"": [
|
|
38
|
+
"dist/index.d.ts"
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
},
|
|
32
42
|
"exports": {
|
|
33
43
|
".": {
|
|
34
44
|
"types": "./dist/index.d.ts",
|
|
35
45
|
"import": "./dist/index.mjs",
|
|
36
46
|
"require": "./dist/index.cjs"
|
|
37
47
|
},
|
|
48
|
+
"./plugin": {
|
|
49
|
+
"types": "./dist/plugin.d.ts",
|
|
50
|
+
"import": "./dist/plugin.mjs",
|
|
51
|
+
"require": "./dist/plugin.cjs"
|
|
52
|
+
},
|
|
38
53
|
"./package.json": "./package.json"
|
|
39
54
|
},
|
|
40
55
|
"devDependencies": {
|
|
@@ -42,9 +57,19 @@
|
|
|
42
57
|
},
|
|
43
58
|
"peerDependencies": {
|
|
44
59
|
"mongodb": "^6.17.0",
|
|
45
|
-
"@atscript/core": "^0.1.
|
|
46
|
-
"@atscript/
|
|
60
|
+
"@atscript/core": "^0.1.32",
|
|
61
|
+
"@atscript/utils-db": "^0.1.32",
|
|
62
|
+
"@atscript/typescript": "^0.1.32"
|
|
47
63
|
},
|
|
64
|
+
"build": [
|
|
65
|
+
{},
|
|
66
|
+
{
|
|
67
|
+
"entries": [
|
|
68
|
+
"src/plugin.ts"
|
|
69
|
+
],
|
|
70
|
+
"dts": true
|
|
71
|
+
}
|
|
72
|
+
],
|
|
48
73
|
"scripts": {
|
|
49
74
|
"pub": "pnpm publish --access public",
|
|
50
75
|
"test": "vitest",
|
|
@@ -17,7 +17,7 @@ Add `MongoPlugin()` to your `atscript.config.ts`:
|
|
|
17
17
|
```typescript
|
|
18
18
|
import { defineConfig } from '@atscript/core'
|
|
19
19
|
import { ts } from '@atscript/typescript'
|
|
20
|
-
import { MongoPlugin } from '@atscript/mongo'
|
|
20
|
+
import { MongoPlugin } from '@atscript/mongo/plugin'
|
|
21
21
|
|
|
22
22
|
export default defineConfig({
|
|
23
23
|
rootDir: 'src',
|