@atscript/db 0.1.39 → 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 +18 -18
- package/dist/agg.cjs +8 -3
- package/dist/agg.d.cts +7 -0
- package/dist/agg.d.mts +7 -0
- package/dist/agg.mjs +7 -3
- package/dist/control-DRgryKeg.cjs +14 -0
- package/dist/{control_as-bjmwe24C.mjs → control-IANbnfjG.mjs} +6 -18
- package/dist/db-readable-BQQzfguJ.d.cts +1249 -0
- package/dist/db-readable-Bbr4CjMb.d.mts +1249 -0
- package/dist/db-space-BUrQ5BFm.d.mts +309 -0
- package/dist/db-space-Vxpcnyt5.d.cts +309 -0
- package/dist/db-validator-plugin-07kDiis2.d.cts +22 -0
- package/dist/db-validator-plugin-CiqsHTI_.d.mts +22 -0
- package/dist/db-view-CMI9TOo1.cjs +3096 -0
- package/dist/db-view-Esy2fDxw.mjs +2995 -0
- package/dist/index.cjs +95 -2801
- package/dist/index.d.cts +137 -0
- package/dist/index.d.mts +137 -0
- package/dist/index.mjs +55 -2761
- package/dist/{nested-writer-BkqL7cp3.cjs → nested-writer-BDXsDMPP.cjs} +196 -150
- package/dist/{nested-writer-NEN51mnR.mjs → nested-writer-Dmm1gbZV.mjs} +118 -70
- package/dist/ops-BdRAFLKY.d.mts +67 -0
- package/dist/ops-DXJ4Zw0P.d.cts +67 -0
- package/dist/ops.cjs +123 -0
- package/dist/ops.d.cts +2 -0
- package/dist/ops.d.mts +2 -0
- package/dist/ops.mjs +112 -0
- package/dist/plugin.cjs +90 -109
- package/dist/plugin.d.cts +6 -0
- package/dist/plugin.d.mts +6 -0
- package/dist/plugin.mjs +29 -49
- package/dist/rel.cjs +20 -20
- package/dist/rel.d.cts +119 -0
- package/dist/rel.d.mts +119 -0
- package/dist/rel.mjs +4 -5
- package/dist/{relation-helpers-guFL_oRf.cjs → relation-helpers-BYvsE1tR.cjs} +26 -22
- package/dist/{relation-helpers-DyBIlQnB.mjs → relation-helpers-CLasawQq.mjs} +11 -6
- package/dist/{relation-loader-Dv7qXYq7.mjs → relation-loader-BEOTXNcq.mjs} +63 -43
- package/dist/{relation-loader-CpnDRf9k.cjs → relation-loader-CRC5LcqM.cjs} +74 -49
- package/dist/shared.cjs +13 -13
- package/dist/{shared.d.ts → shared.d.cts} +14 -13
- package/dist/shared.d.mts +71 -0
- package/dist/shared.mjs +2 -3
- package/dist/sync.cjs +300 -252
- package/dist/sync.d.cts +369 -0
- package/dist/sync.d.mts +369 -0
- package/dist/sync.mjs +284 -233
- package/dist/{validation-utils-DEoCMmEb.cjs → validation-utils-DVJDijnB.cjs} +141 -109
- package/dist/{validation-utils-DhR_mtKa.mjs → validation-utils-DhjIjP1-.mjs} +71 -37
- package/package.json +30 -29
- package/LICENSE +0 -21
- package/dist/agg-BJFJ3dFQ.mjs +0 -8
- package/dist/agg-DnUWAOK8.cjs +0 -14
- package/dist/agg.d.ts +0 -13
- package/dist/chunk-CrpGerW8.cjs +0 -31
- package/dist/control_as-BFPERAF_.cjs +0 -28
- package/dist/index.d.ts +0 -1706
- package/dist/logger-B7oxCfLQ.mjs +0 -12
- package/dist/logger-Dt2v_-wb.cjs +0 -18
- package/dist/plugin.d.ts +0 -5
- package/dist/rel.d.ts +0 -1305
- package/dist/relation-loader-D4mTw6yH.cjs +0 -4
- package/dist/relation-loader-Ggy1ujwR.mjs +0 -4
- package/dist/sync.d.ts +0 -1878
package/dist/plugin.cjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
//#region
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
5
|
+
const require_validation_utils = require("./validation-utils-DVJDijnB.cjs");
|
|
6
|
+
let _atscript_core = require("@atscript/core");
|
|
7
|
+
//#region src/plugin/annotations/agg.ts
|
|
8
8
|
const dbAggAnnotations = { agg: {
|
|
9
|
-
sum: new
|
|
9
|
+
sum: new _atscript_core.AnnotationSpec({
|
|
10
10
|
description: "Declares a view field as SUM of a source column.",
|
|
11
11
|
nodeType: ["prop"],
|
|
12
12
|
argument: {
|
|
@@ -18,7 +18,7 @@ const dbAggAnnotations = { agg: {
|
|
|
18
18
|
return require_validation_utils.validateFieldBaseType(token, doc, "@db.agg.sum", ["number", "decimal"]);
|
|
19
19
|
}
|
|
20
20
|
}),
|
|
21
|
-
avg: new
|
|
21
|
+
avg: new _atscript_core.AnnotationSpec({
|
|
22
22
|
description: "Declares a view field as AVG of a source column.",
|
|
23
23
|
nodeType: ["prop"],
|
|
24
24
|
argument: {
|
|
@@ -30,7 +30,7 @@ const dbAggAnnotations = { agg: {
|
|
|
30
30
|
return require_validation_utils.validateFieldBaseType(token, doc, "@db.agg.avg", ["number", "decimal"]);
|
|
31
31
|
}
|
|
32
32
|
}),
|
|
33
|
-
count: new
|
|
33
|
+
count: new _atscript_core.AnnotationSpec({
|
|
34
34
|
description: "Declares a view field as COUNT. Without argument: COUNT(*). With field name argument: COUNT(field) (non-null count).",
|
|
35
35
|
nodeType: ["prop"],
|
|
36
36
|
argument: {
|
|
@@ -43,7 +43,7 @@ const dbAggAnnotations = { agg: {
|
|
|
43
43
|
return require_validation_utils.validateFieldBaseType(token, doc, "@db.agg.count", ["number"]);
|
|
44
44
|
}
|
|
45
45
|
}),
|
|
46
|
-
min: new
|
|
46
|
+
min: new _atscript_core.AnnotationSpec({
|
|
47
47
|
description: "Declares a view field as MIN of a source column.",
|
|
48
48
|
nodeType: ["prop"],
|
|
49
49
|
argument: {
|
|
@@ -52,7 +52,7 @@ const dbAggAnnotations = { agg: {
|
|
|
52
52
|
description: "Source column name."
|
|
53
53
|
}
|
|
54
54
|
}),
|
|
55
|
-
max: new
|
|
55
|
+
max: new _atscript_core.AnnotationSpec({
|
|
56
56
|
description: "Declares a view field as MAX of a source column.",
|
|
57
57
|
nodeType: ["prop"],
|
|
58
58
|
argument: {
|
|
@@ -62,11 +62,10 @@ const dbAggAnnotations = { agg: {
|
|
|
62
62
|
}
|
|
63
63
|
})
|
|
64
64
|
} };
|
|
65
|
-
|
|
66
65
|
//#endregion
|
|
67
|
-
//#region
|
|
66
|
+
//#region src/plugin/annotations/column.ts
|
|
68
67
|
const dbColumnAnnotations = {
|
|
69
|
-
patch: { strategy: new
|
|
68
|
+
patch: { strategy: new _atscript_core.AnnotationSpec({
|
|
70
69
|
description: "Defines the **patching strategy** for updating nested objects.\n\n- **\"replace\"** → The field or object will be **fully replaced**.\n- **\"merge\"** → The field or object will be **merged recursively** (applies only to objects, not arrays).\n\n**Example:**\n```atscript\n@db.patch.strategy \"merge\"\nsettings: {\n notifications: boolean\n preferences: {\n theme: string\n }\n}\n```\n",
|
|
71
70
|
nodeType: ["prop"],
|
|
72
71
|
multiple: false,
|
|
@@ -82,10 +81,10 @@ const dbColumnAnnotations = {
|
|
|
82
81
|
const definition = field.getDefinition();
|
|
83
82
|
if (!definition) return errors;
|
|
84
83
|
let wrongType = false;
|
|
85
|
-
if ((0,
|
|
84
|
+
if ((0, _atscript_core.isRef)(definition)) {
|
|
86
85
|
const def = doc.unwindType(definition.id, definition.chain)?.def;
|
|
87
|
-
if (!(0,
|
|
88
|
-
} else if (!(0,
|
|
86
|
+
if (!(0, _atscript_core.isStructure)(def) && !(0, _atscript_core.isInterface)(def) && !(0, _atscript_core.isArray)(def)) wrongType = true;
|
|
87
|
+
} else if (!(0, _atscript_core.isStructure)(definition) && !(0, _atscript_core.isInterface)(definition) && !(0, _atscript_core.isArray)(definition)) wrongType = true;
|
|
89
88
|
if (wrongType) errors.push({
|
|
90
89
|
message: `@db.patch.strategy requires a field of type object or array`,
|
|
91
90
|
severity: 1,
|
|
@@ -95,7 +94,7 @@ const dbColumnAnnotations = {
|
|
|
95
94
|
}
|
|
96
95
|
}) },
|
|
97
96
|
column: {
|
|
98
|
-
$self: new
|
|
97
|
+
$self: new _atscript_core.AnnotationSpec({
|
|
99
98
|
description: "Overrides the physical column name in the database. For nested (flattened) fields, the parent prefix is still prepended automatically.\n\n**Example:**\n```atscript\n@db.column \"first_name\"\nfirstName: string\n// → physical column: first_name\n\n// Nested:\naddress: {\n @db.column \"zip_code\"\n zip: string\n}\n// → physical column: address__zip_code\n```\n",
|
|
100
99
|
nodeType: ["prop"],
|
|
101
100
|
argument: {
|
|
@@ -104,7 +103,7 @@ const dbColumnAnnotations = {
|
|
|
104
103
|
description: "The column/field name (without parent prefix for nested fields)."
|
|
105
104
|
}
|
|
106
105
|
}),
|
|
107
|
-
renamed: new
|
|
106
|
+
renamed: new _atscript_core.AnnotationSpec({
|
|
108
107
|
description: "Specifies the previous local field name for column rename migration. The sync engine generates ALTER TABLE RENAME COLUMN instead of drop+add.\n\n**Example:**\n```atscript\n@db.column.renamed \"zip\"\npostalCode: string\n// Renames address__zip → address__postalCode\n```\n",
|
|
109
108
|
nodeType: ["prop"],
|
|
110
109
|
argument: {
|
|
@@ -113,7 +112,7 @@ const dbColumnAnnotations = {
|
|
|
113
112
|
description: "The old local field name (parent prefix is reconstructed automatically)."
|
|
114
113
|
}
|
|
115
114
|
}),
|
|
116
|
-
collate: new
|
|
115
|
+
collate: new _atscript_core.AnnotationSpec({
|
|
117
116
|
description: "Portable collation for string comparison and sorting. Adapters map the generic value to their native collation.\n\n- **\"binary\"** — exact byte comparison (case-sensitive)\n- **\"nocase\"** — case-insensitive comparison\n- **\"unicode\"** — full Unicode-aware sorting\n\nFor adapter-specific collations, use `@db.<engine>.collate` instead.\n\n**Example:**\n```atscript\n@db.column.collate \"nocase\"\nusername: string\n```\n",
|
|
118
117
|
nodeType: ["prop"],
|
|
119
118
|
argument: {
|
|
@@ -130,7 +129,7 @@ const dbColumnAnnotations = {
|
|
|
130
129
|
return require_validation_utils.validateFieldBaseType(token, doc, "@db.column.collate", "string");
|
|
131
130
|
}
|
|
132
131
|
}),
|
|
133
|
-
precision: new
|
|
132
|
+
precision: new _atscript_core.AnnotationSpec({
|
|
134
133
|
description: "Sets decimal precision and scale for database storage. Adapters map this to their native decimal type (e.g., `DECIMAL(10,2)` in SQL, ignored in MongoDB).\n\nFor `decimal` fields the runtime value is a string; for `number` fields this is a DB storage hint only.\n\n**Example:**\n```atscript\n@db.column.precision 10, 2\nprice: decimal\n```\n",
|
|
135
134
|
nodeType: ["prop"],
|
|
136
135
|
argument: [{
|
|
@@ -146,11 +145,11 @@ const dbColumnAnnotations = {
|
|
|
146
145
|
return require_validation_utils.validateFieldBaseType(token, doc, "@db.column.precision", ["number", "decimal"]);
|
|
147
146
|
}
|
|
148
147
|
}),
|
|
149
|
-
dimension: new
|
|
148
|
+
dimension: new _atscript_core.AnnotationSpec({
|
|
150
149
|
description: "Marks a field as a dimension — groupable in aggregate queries ($groupBy). Dimension fields automatically receive a database index during schema sync.",
|
|
151
150
|
nodeType: ["prop"]
|
|
152
151
|
}),
|
|
153
|
-
measure: new
|
|
152
|
+
measure: new _atscript_core.AnnotationSpec({
|
|
154
153
|
description: "Marks a field as a measure — aggregatable in aggregate queries (sum, avg, count, min, max). Only valid on numeric or decimal fields.",
|
|
155
154
|
nodeType: ["prop"],
|
|
156
155
|
validate(token, _args, doc) {
|
|
@@ -159,7 +158,7 @@ const dbColumnAnnotations = {
|
|
|
159
158
|
})
|
|
160
159
|
},
|
|
161
160
|
default: {
|
|
162
|
-
$self: new
|
|
161
|
+
$self: new _atscript_core.AnnotationSpec({
|
|
163
162
|
description: "Sets a static DB-level default value (used in DDL DEFAULT clause). For string fields the value is used as-is; for other types it is parsed as JSON.\n\n**Example:**\n```atscript\n@db.default \"active\"\nstatus: string\n```\n",
|
|
164
163
|
nodeType: ["prop"],
|
|
165
164
|
argument: {
|
|
@@ -168,7 +167,7 @@ const dbColumnAnnotations = {
|
|
|
168
167
|
description: "Static default value. Strings used as-is; other types parsed via JSON.parse()."
|
|
169
168
|
}
|
|
170
169
|
}),
|
|
171
|
-
increment: new
|
|
170
|
+
increment: new _atscript_core.AnnotationSpec({
|
|
172
171
|
description: "Auto-incrementing integer default. Each adapter maps this to its native mechanism (e.g., `AUTO_INCREMENT` in MySQL, `INTEGER PRIMARY KEY` in SQLite, counter collection in MongoDB).\n\n**Example:**\n```atscript\n@db.default.increment\nid: number.int\n\n// With optional start value:\n@db.default.increment 1000\nid: number.int\n```\n",
|
|
173
172
|
nodeType: ["prop"],
|
|
174
173
|
argument: {
|
|
@@ -181,14 +180,14 @@ const dbColumnAnnotations = {
|
|
|
181
180
|
return require_validation_utils.validateFieldBaseType(token, doc, "db.default.increment", "number");
|
|
182
181
|
}
|
|
183
182
|
}),
|
|
184
|
-
uuid: new
|
|
183
|
+
uuid: new _atscript_core.AnnotationSpec({
|
|
185
184
|
description: "UUID generation default. Each adapter maps this to its native mechanism (e.g., `DEFAULT (UUID())` in MySQL, `gen_random_uuid()` in PostgreSQL, app-level in SQLite).\n\n**Example:**\n```atscript\n@db.default.uuid\nid: string.uuid\n```\n",
|
|
186
185
|
nodeType: ["prop"],
|
|
187
186
|
validate(token, args, doc) {
|
|
188
187
|
return require_validation_utils.validateFieldBaseType(token, doc, "db.default.uuid", "string");
|
|
189
188
|
}
|
|
190
189
|
}),
|
|
191
|
-
now: new
|
|
190
|
+
now: new _atscript_core.AnnotationSpec({
|
|
192
191
|
description: "Current timestamp default. Each adapter maps this to its native mechanism (e.g., `DEFAULT CURRENT_TIMESTAMP` in MySQL, `DEFAULT now()` in PostgreSQL).\n\n**Example:**\n```atscript\n@db.default.now\ncreatedAt: number.timestamp\n```\n",
|
|
193
192
|
nodeType: ["prop"],
|
|
194
193
|
validate(token, args, doc) {
|
|
@@ -196,16 +195,15 @@ const dbColumnAnnotations = {
|
|
|
196
195
|
}
|
|
197
196
|
})
|
|
198
197
|
},
|
|
199
|
-
json: new
|
|
198
|
+
json: new _atscript_core.AnnotationSpec({
|
|
200
199
|
description: "Forces a field to be stored as a single JSON column instead of being flattened into separate columns. Use on nested object fields that should remain as JSON in the database.\n\n**Example:**\n```atscript\n@db.json\nmetadata: { key: string, value: string }\n```\n",
|
|
201
200
|
nodeType: ["prop"],
|
|
202
201
|
validate(token, _args, doc) {
|
|
203
202
|
const errors = [];
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
if (definition && (0, __atscript_core.isRef)(definition)) {
|
|
203
|
+
const definition = token.parentNode.getDefinition();
|
|
204
|
+
if (definition && (0, _atscript_core.isRef)(definition)) {
|
|
207
205
|
const unwound = doc.unwindType(definition.id, definition.chain);
|
|
208
|
-
if (unwound && (0,
|
|
206
|
+
if (unwound && (0, _atscript_core.isPrimitive)(unwound.def)) errors.push({
|
|
209
207
|
message: "@db.json on a primitive field has no effect — primitive fields are already stored as scalar columns",
|
|
210
208
|
severity: 2,
|
|
211
209
|
range: token.range
|
|
@@ -214,13 +212,12 @@ const dbColumnAnnotations = {
|
|
|
214
212
|
return errors;
|
|
215
213
|
}
|
|
216
214
|
}),
|
|
217
|
-
ignore: new
|
|
215
|
+
ignore: new _atscript_core.AnnotationSpec({
|
|
218
216
|
description: "Excludes a field from the database schema. The field exists in the Atscript type but has no column in the DB.\n\n**Example:**\n```atscript\n@db.ignore\ndisplayName: string\n```\n",
|
|
219
217
|
nodeType: ["prop"],
|
|
220
|
-
validate(token,
|
|
218
|
+
validate(token, _args, _doc) {
|
|
221
219
|
const errors = [];
|
|
222
|
-
|
|
223
|
-
if (field.countAnnotations("meta.id") > 0) errors.push({
|
|
220
|
+
if (token.parentNode.countAnnotations("meta.id") > 0) errors.push({
|
|
224
221
|
message: `@db.ignore cannot coexist with @meta.id — a field cannot be both a primary key and excluded from the database`,
|
|
225
222
|
severity: 1,
|
|
226
223
|
range: token.range
|
|
@@ -229,11 +226,10 @@ const dbColumnAnnotations = {
|
|
|
229
226
|
}
|
|
230
227
|
})
|
|
231
228
|
};
|
|
232
|
-
|
|
233
229
|
//#endregion
|
|
234
|
-
//#region
|
|
230
|
+
//#region src/plugin/annotations/index-ann.ts
|
|
235
231
|
const dbIndexAnnotations = { index: {
|
|
236
|
-
plain: new
|
|
232
|
+
plain: new _atscript_core.AnnotationSpec({
|
|
237
233
|
description: "Standard (non-unique) index for query performance. Fields sharing the same index name form a composite index.\n\n**Example:**\n```atscript\n@db.index.plain \"idx_timeline\", \"desc\"\ncreatedAt: number.timestamp\n```\n",
|
|
238
234
|
nodeType: ["prop"],
|
|
239
235
|
multiple: true,
|
|
@@ -251,7 +247,7 @@ const dbIndexAnnotations = { index: {
|
|
|
251
247
|
description: "Sort direction. Defaults to \"asc\"."
|
|
252
248
|
}]
|
|
253
249
|
}),
|
|
254
|
-
unique: new
|
|
250
|
+
unique: new _atscript_core.AnnotationSpec({
|
|
255
251
|
description: "Unique index — ensures no two rows/documents have the same value(s). Fields sharing the same index name form a composite unique constraint.\n\n**Example:**\n```atscript\n@db.index.unique \"tenant_email\"\nemail: string.email\n```\n",
|
|
256
252
|
nodeType: ["prop"],
|
|
257
253
|
multiple: true,
|
|
@@ -263,7 +259,7 @@ const dbIndexAnnotations = { index: {
|
|
|
263
259
|
description: "Index name / composite group name."
|
|
264
260
|
}
|
|
265
261
|
}),
|
|
266
|
-
fulltext: new
|
|
262
|
+
fulltext: new _atscript_core.AnnotationSpec({
|
|
267
263
|
description: "Full-text search index. Fields sharing the same index name form a composite full-text index.\n\n**Example:**\n```atscript\n@db.index.fulltext \"ft_content\"\ntitle: string\n\n@db.index.fulltext \"ft_content\", 5\nbio: string\n```\n",
|
|
268
264
|
nodeType: ["prop"],
|
|
269
265
|
multiple: true,
|
|
@@ -281,11 +277,10 @@ const dbIndexAnnotations = { index: {
|
|
|
281
277
|
}]
|
|
282
278
|
})
|
|
283
279
|
} };
|
|
284
|
-
|
|
285
280
|
//#endregion
|
|
286
|
-
//#region
|
|
281
|
+
//#region src/plugin/annotations/rel.ts
|
|
287
282
|
const dbRelAnnotations = { rel: {
|
|
288
|
-
FK: new
|
|
283
|
+
FK: new _atscript_core.AnnotationSpec({
|
|
289
284
|
description: "Declares a foreign key constraint on this field. The field must use a chain reference type (e.g., `User.id`) to specify the FK target.\n\n**Example:**\n```atscript\n@db.rel.FK\nauthorId: User.id\n\n// With alias (required when multiple FKs point to the same type)\n@db.rel.FK \"author\"\nauthorId: User.id\n```\n",
|
|
290
285
|
nodeType: ["prop"],
|
|
291
286
|
argument: {
|
|
@@ -310,7 +305,7 @@ const dbRelAnnotations = { rel: {
|
|
|
310
305
|
range: token.range
|
|
311
306
|
});
|
|
312
307
|
const definition = field.getDefinition();
|
|
313
|
-
if (!definition || !(0,
|
|
308
|
+
if (!definition || !(0, _atscript_core.isRef)(definition) || !definition.hasChain) {
|
|
314
309
|
errors.push({
|
|
315
310
|
message: `@db.rel.FK requires a chain reference type (e.g. User.id), got scalar type`,
|
|
316
311
|
severity: 1,
|
|
@@ -324,9 +319,9 @@ const dbRelAnnotations = { rel: {
|
|
|
324
319
|
const targetUnwound = doc.unwindType(refTypeName);
|
|
325
320
|
if (targetUnwound) {
|
|
326
321
|
const targetDef = targetUnwound.def;
|
|
327
|
-
if ((0,
|
|
328
|
-
const struct = (0,
|
|
329
|
-
if (struct && (0,
|
|
322
|
+
if ((0, _atscript_core.isInterface)(targetDef) || (0, _atscript_core.isStructure)(targetDef)) {
|
|
323
|
+
const struct = (0, _atscript_core.isInterface)(targetDef) ? targetDef.getDefinition() : targetDef;
|
|
324
|
+
if (struct && (0, _atscript_core.isStructure)(struct) && chainFields.length > 0) {
|
|
330
325
|
const targetProp = struct.props.get(chainFields[0]);
|
|
331
326
|
if (targetProp) {
|
|
332
327
|
if (targetProp.countAnnotations("meta.id") === 0 && targetProp.countAnnotations("db.index.unique") === 0) errors.push({
|
|
@@ -335,14 +330,14 @@ const dbRelAnnotations = { rel: {
|
|
|
335
330
|
range: token.range
|
|
336
331
|
});
|
|
337
332
|
const propDef = targetProp.getDefinition();
|
|
338
|
-
if (propDef && (0,
|
|
333
|
+
if (propDef && (0, _atscript_core.isRef)(propDef)) {
|
|
339
334
|
const propUnwound = targetUnwound.doc.unwindType(propDef.id, propDef.chain);
|
|
340
|
-
if (propUnwound && !(0,
|
|
335
|
+
if (propUnwound && !(0, _atscript_core.isPrimitive)(propUnwound.def)) errors.push({
|
|
341
336
|
message: `Foreign key field must resolve to a scalar type (number, string, etc.), got '${propDef.id}'`,
|
|
342
337
|
severity: 1,
|
|
343
338
|
range: token.range
|
|
344
339
|
});
|
|
345
|
-
} else if (propDef && !(0,
|
|
340
|
+
} else if (propDef && !(0, _atscript_core.isPrimitive)(propDef)) errors.push({
|
|
346
341
|
message: `Foreign key field must resolve to a scalar type (number, string, etc.)`,
|
|
347
342
|
severity: 1,
|
|
348
343
|
range: token.range
|
|
@@ -358,7 +353,7 @@ const dbRelAnnotations = { rel: {
|
|
|
358
353
|
for (const [, prop] of struct.props) {
|
|
359
354
|
if (prop.countAnnotations("db.rel.FK") === 0) continue;
|
|
360
355
|
const def = prop.getDefinition();
|
|
361
|
-
if (!def || !(0,
|
|
356
|
+
if (!def || !(0, _atscript_core.isRef)(def)) continue;
|
|
362
357
|
const r = def;
|
|
363
358
|
if (!r.hasChain) continue;
|
|
364
359
|
if (r.id === refTypeName) {
|
|
@@ -375,7 +370,7 @@ const dbRelAnnotations = { rel: {
|
|
|
375
370
|
return errors;
|
|
376
371
|
}
|
|
377
372
|
}),
|
|
378
|
-
to: new
|
|
373
|
+
to: new _atscript_core.AnnotationSpec({
|
|
379
374
|
description: "Forward navigational property — the FK is on **this** interface. The compiler resolves the matching @db.rel.FK by target type or alias.\n\n**Example:**\n```atscript\n@db.rel.to\nauthor?: User\n\n// With alias\n@db.rel.to \"author\"\nauthor?: User\n```\n",
|
|
380
375
|
nodeType: ["prop"],
|
|
381
376
|
argument: {
|
|
@@ -404,7 +399,7 @@ const dbRelAnnotations = { rel: {
|
|
|
404
399
|
const unwound = doc.unwindType(targetTypeName);
|
|
405
400
|
if (unwound) {
|
|
406
401
|
const targetDef = unwound.def;
|
|
407
|
-
const targetNode = (0,
|
|
402
|
+
const targetNode = (0, _atscript_core.isInterface)(targetDef) ? targetDef : void 0;
|
|
408
403
|
if (!targetNode || targetNode.countAnnotations("db.table") === 0) errors.push({
|
|
409
404
|
message: `@db.rel.to target '${targetTypeName}' is not a @db.table entity`,
|
|
410
405
|
severity: 1,
|
|
@@ -424,9 +419,8 @@ const dbRelAnnotations = { rel: {
|
|
|
424
419
|
if (name === fieldName) continue;
|
|
425
420
|
if (prop.countAnnotations("db.rel.to") === 0) continue;
|
|
426
421
|
const propAlias = require_validation_utils.getAnnotationAlias(prop, "db.rel.to");
|
|
427
|
-
if ((alias ||
|
|
428
|
-
|
|
429
|
-
if (otherTarget === targetTypeName) {
|
|
422
|
+
if ((alias || void 0) === (propAlias || void 0)) {
|
|
423
|
+
if (require_validation_utils.getNavTargetTypeName(prop) === targetTypeName) {
|
|
430
424
|
errors.push({
|
|
431
425
|
message: `Duplicate @db.rel.to '${alias || targetTypeName}' — only one forward navigational property per alias`,
|
|
432
426
|
severity: 1,
|
|
@@ -437,8 +431,7 @@ const dbRelAnnotations = { rel: {
|
|
|
437
431
|
}
|
|
438
432
|
}
|
|
439
433
|
if (alias) {
|
|
440
|
-
|
|
441
|
-
if (matches.length === 0) errors.push({
|
|
434
|
+
if (require_validation_utils.findFKFieldsPointingTo(doc, struct, targetTypeName, alias).length === 0) errors.push({
|
|
442
435
|
message: `No @db.rel.FK '${alias}' found on this interface`,
|
|
443
436
|
severity: 1,
|
|
444
437
|
range: token.range
|
|
@@ -450,7 +443,7 @@ const dbRelAnnotations = { rel: {
|
|
|
450
443
|
severity: 1,
|
|
451
444
|
range: token.range
|
|
452
445
|
});
|
|
453
|
-
else if (matches.length > 1) errors.push({
|
|
446
|
+
else if (matches.length > 1) errors.push({
|
|
454
447
|
message: `Multiple @db.rel.FK fields point to '${targetTypeName}' — add alias to disambiguate`,
|
|
455
448
|
severity: 1,
|
|
456
449
|
range: token.range
|
|
@@ -460,7 +453,7 @@ else if (matches.length > 1) errors.push({
|
|
|
460
453
|
return errors;
|
|
461
454
|
}
|
|
462
455
|
}),
|
|
463
|
-
from: new
|
|
456
|
+
from: new _atscript_core.AnnotationSpec({
|
|
464
457
|
description: "Inverse navigational property — the FK is on the **target** interface, pointing back to this one.\n\n**Example:**\n```atscript\n@db.rel.from\nposts: Post[]\n\n// With alias\n@db.rel.from \"original\"\ncomments: Comment[]\n```\n",
|
|
465
458
|
nodeType: ["prop"],
|
|
466
459
|
argument: {
|
|
@@ -490,7 +483,7 @@ else if (matches.length > 1) errors.push({
|
|
|
490
483
|
if (!unwound) return errors;
|
|
491
484
|
const targetDef = unwound.def;
|
|
492
485
|
const targetDoc = unwound.doc;
|
|
493
|
-
if (!(0,
|
|
486
|
+
if (!(0, _atscript_core.isInterface)(targetDef) || targetDef.countAnnotations("db.table") === 0) {
|
|
494
487
|
errors.push({
|
|
495
488
|
message: `@db.rel.from target '${targetTypeName}' is not a @db.table entity`,
|
|
496
489
|
severity: 1,
|
|
@@ -505,9 +498,8 @@ else if (matches.length > 1) errors.push({
|
|
|
505
498
|
if (name === fieldName) continue;
|
|
506
499
|
if (prop.countAnnotations("db.rel.from") === 0) continue;
|
|
507
500
|
const propAlias = require_validation_utils.getAnnotationAlias(prop, "db.rel.from");
|
|
508
|
-
if ((alias ||
|
|
509
|
-
|
|
510
|
-
if (otherTarget === targetTypeName) {
|
|
501
|
+
if ((alias || void 0) === (propAlias || void 0)) {
|
|
502
|
+
if (require_validation_utils.getNavTargetTypeName(prop) === targetTypeName) {
|
|
511
503
|
errors.push({
|
|
512
504
|
message: `Duplicate @db.rel.from '${alias || targetTypeName}' — only one inverse navigational property per alias`,
|
|
513
505
|
severity: 1,
|
|
@@ -532,15 +524,13 @@ else if (matches.length > 1) errors.push({
|
|
|
532
524
|
severity: 1,
|
|
533
525
|
range: token.range
|
|
534
526
|
});
|
|
535
|
-
else if (matches.length > 1) errors.push({
|
|
527
|
+
else if (matches.length > 1) errors.push({
|
|
536
528
|
message: `'${targetTypeName}' has multiple @db.rel.FK fields pointing to '${thisTypeName}' — add alias`,
|
|
537
529
|
severity: 1,
|
|
538
530
|
range: token.range
|
|
539
531
|
});
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
const fkProp = matches[0].prop;
|
|
543
|
-
if (fkProp.countAnnotations("db.index.unique") === 0) errors.push({
|
|
532
|
+
if (!(0, _atscript_core.isArray)(field.getDefinition()) && matches.length === 1) {
|
|
533
|
+
if (matches[0].prop.countAnnotations("db.index.unique") === 0) errors.push({
|
|
544
534
|
message: `@db.rel.from '${field.id}' has singular type '${targetTypeName}' (1:1) but the FK on '${targetTypeName}' is not @db.index.unique — did you mean '${targetTypeName}[]' (1:N)?`,
|
|
545
535
|
severity: 2,
|
|
546
536
|
range: token.range
|
|
@@ -551,7 +541,7 @@ else if (matches.length > 1) errors.push({
|
|
|
551
541
|
}),
|
|
552
542
|
onDelete: require_validation_utils.refActionAnnotation("onDelete"),
|
|
553
543
|
onUpdate: require_validation_utils.refActionAnnotation("onUpdate"),
|
|
554
|
-
via: new
|
|
544
|
+
via: new _atscript_core.AnnotationSpec({
|
|
555
545
|
description: "Declares a many-to-many navigational property through an explicit junction table. `@db.rel.via` is self-sufficient — no `@db.rel.from` pairing is needed.\n\n**Example:**\n```atscript\n@db.rel.via PostTag\ntags: Tag[]\n```\n",
|
|
556
546
|
nodeType: ["prop"],
|
|
557
547
|
argument: {
|
|
@@ -567,8 +557,7 @@ else if (matches.length > 1) errors.push({
|
|
|
567
557
|
severity: 1,
|
|
568
558
|
range: token.range
|
|
569
559
|
});
|
|
570
|
-
|
|
571
|
-
if (!(0, __atscript_core.isArray)(definition)) errors.push({
|
|
560
|
+
if (!(0, _atscript_core.isArray)(field.getDefinition())) errors.push({
|
|
572
561
|
message: "@db.rel.via requires an array type (e.g. Tag[])",
|
|
573
562
|
severity: 1,
|
|
574
563
|
range: token.range
|
|
@@ -580,7 +569,7 @@ else if (matches.length > 1) errors.push({
|
|
|
580
569
|
const junctionUnwound = doc.unwindType(junctionName);
|
|
581
570
|
if (!junctionUnwound) return errors;
|
|
582
571
|
const junctionDef = junctionUnwound.def;
|
|
583
|
-
if (!(0,
|
|
572
|
+
if (!(0, _atscript_core.isInterface)(junctionDef)) return errors;
|
|
584
573
|
const thisTypeName = require_validation_utils.getParentTypeName(token);
|
|
585
574
|
const targetTypeName = require_validation_utils.getNavTargetTypeName(field);
|
|
586
575
|
if (!thisTypeName || !targetTypeName) return errors;
|
|
@@ -590,7 +579,7 @@ else if (matches.length > 1) errors.push({
|
|
|
590
579
|
severity: 1,
|
|
591
580
|
range: args[0].range
|
|
592
581
|
});
|
|
593
|
-
else if (fksToThis.length > 1) errors.push({
|
|
582
|
+
else if (fksToThis.length > 1) errors.push({
|
|
594
583
|
message: `Junction '${junctionName}' has multiple @db.rel.FK pointing to '${thisTypeName}' — not supported`,
|
|
595
584
|
severity: 1,
|
|
596
585
|
range: args[0].range
|
|
@@ -602,7 +591,7 @@ else if (fksToThis.length > 1) errors.push({
|
|
|
602
591
|
severity: 1,
|
|
603
592
|
range: args[0].range
|
|
604
593
|
});
|
|
605
|
-
else if (fksToTarget.length > 1) errors.push({
|
|
594
|
+
else if (fksToTarget.length > 1) errors.push({
|
|
606
595
|
message: `Junction '${junctionName}' has multiple @db.rel.FK pointing to '${targetTypeName}' — not supported`,
|
|
607
596
|
severity: 1,
|
|
608
597
|
range: args[0].range
|
|
@@ -611,7 +600,7 @@ else if (fksToTarget.length > 1) errors.push({
|
|
|
611
600
|
return errors;
|
|
612
601
|
}
|
|
613
602
|
}),
|
|
614
|
-
filter: new
|
|
603
|
+
filter: new _atscript_core.AnnotationSpec({
|
|
615
604
|
description: "Applies a filter to a navigational property, restricting which related records are loaded.\n\n**Example:**\n```atscript\n@db.rel.from\n@db.rel.filter `Post.published = true`\npublishedPosts: Post[]\n```\n",
|
|
616
605
|
nodeType: ["prop"],
|
|
617
606
|
argument: {
|
|
@@ -646,12 +635,11 @@ else if (fksToTarget.length > 1) errors.push({
|
|
|
646
635
|
}
|
|
647
636
|
})
|
|
648
637
|
} };
|
|
649
|
-
|
|
650
638
|
//#endregion
|
|
651
|
-
//#region
|
|
639
|
+
//#region src/plugin/annotations/search.ts
|
|
652
640
|
const dbSearchAnnotations = { search: {
|
|
653
641
|
vector: {
|
|
654
|
-
$self: new
|
|
642
|
+
$self: new _atscript_core.AnnotationSpec({
|
|
655
643
|
description: "Marks a field as a **vector embedding** for **similarity search**.\n\n- Each adapter maps this to its native vector type and index:\n - **MongoDB** → Atlas `$vectorSearch` index\n - **MySQL 9+** → `VECTOR(N)` column + `VEC_DISTANCE_*` functions\n - **PostgreSQL** → pgvector `vector(N)` column + distance operators\n - **SQLite** → JSON storage (no native vector support)\n\n**Example:**\n```atscript\n@db.search.vector 1536, \"cosine\"\nembedding: db.vector\n```\n",
|
|
656
644
|
nodeType: ["prop"],
|
|
657
645
|
multiple: false,
|
|
@@ -689,7 +677,7 @@ const dbSearchAnnotations = { search: {
|
|
|
689
677
|
}
|
|
690
678
|
]
|
|
691
679
|
}),
|
|
692
|
-
threshold: new
|
|
680
|
+
threshold: new _atscript_core.AnnotationSpec({
|
|
693
681
|
description: "Sets a **default minimum similarity threshold** for vector search queries on this field.\n\n- Results with a similarity score below this threshold are excluded.\n- Query-time `$threshold` control overrides this default.\n- Value range: `0` to `1` (where `1` means exact match).\n\n**Example:**\n```atscript\n@db.search.vector 1536, \"cosine\"\n@db.search.vector.threshold 0.7\nembedding: db.vector\n```\n",
|
|
694
682
|
nodeType: ["prop"],
|
|
695
683
|
multiple: false,
|
|
@@ -701,7 +689,7 @@ const dbSearchAnnotations = { search: {
|
|
|
701
689
|
}
|
|
702
690
|
})
|
|
703
691
|
},
|
|
704
|
-
filter: new
|
|
692
|
+
filter: new _atscript_core.AnnotationSpec({
|
|
705
693
|
description: "Assigns a field as a **pre-filter** for a **vector search index**.\n\n- Filters allow vector search queries to return results only within a specific subset.\n- The referenced index must be defined using `@db.search.vector`.\n\n**Example:**\n```atscript\n@db.search.vector 1536, \"cosine\"\nembedding: db.vector\n\n@db.search.filter \"embedding\"\ncategory: string\n```\n",
|
|
706
694
|
nodeType: ["prop"],
|
|
707
695
|
multiple: true,
|
|
@@ -713,12 +701,11 @@ const dbSearchAnnotations = { search: {
|
|
|
713
701
|
}
|
|
714
702
|
})
|
|
715
703
|
} };
|
|
716
|
-
|
|
717
704
|
//#endregion
|
|
718
|
-
//#region
|
|
705
|
+
//#region src/plugin/annotations/table.ts
|
|
719
706
|
const dbTableAnnotations = {
|
|
720
707
|
table: {
|
|
721
|
-
$self: new
|
|
708
|
+
$self: new _atscript_core.AnnotationSpec({
|
|
722
709
|
description: "Marks an interface as a database-persisted entity (table in SQL, collection in MongoDB). If the name argument is omitted, the adapter derives the table name from the interface name.\n\n**Example:**\n```atscript\n@db.table \"users\"\nexport interface User { ... }\n```\n",
|
|
723
710
|
nodeType: ["interface"],
|
|
724
711
|
argument: {
|
|
@@ -738,7 +725,7 @@ const dbTableAnnotations = {
|
|
|
738
725
|
return errors;
|
|
739
726
|
}
|
|
740
727
|
}),
|
|
741
|
-
renamed: new
|
|
728
|
+
renamed: new _atscript_core.AnnotationSpec({
|
|
742
729
|
description: "Specifies the previous table name for table rename migration. The sync engine generates ALTER TABLE RENAME instead of drop+create.\n\n**Example:**\n```atscript\n@db.table \"app_users\"\n@db.table.renamed \"users\"\nexport interface User { ... }\n```\n",
|
|
743
730
|
nodeType: ["interface"],
|
|
744
731
|
argument: {
|
|
@@ -748,8 +735,7 @@ const dbTableAnnotations = {
|
|
|
748
735
|
},
|
|
749
736
|
validate(token, _args, _doc) {
|
|
750
737
|
const errors = [];
|
|
751
|
-
|
|
752
|
-
if (owner.countAnnotations("db.table") === 0) errors.push({
|
|
738
|
+
if (token.parentNode.countAnnotations("db.table") === 0) errors.push({
|
|
753
739
|
message: "@db.table.renamed requires @db.table on the same interface",
|
|
754
740
|
severity: 1,
|
|
755
741
|
range: token.range
|
|
@@ -758,7 +744,7 @@ const dbTableAnnotations = {
|
|
|
758
744
|
}
|
|
759
745
|
})
|
|
760
746
|
},
|
|
761
|
-
schema: new
|
|
747
|
+
schema: new _atscript_core.AnnotationSpec({
|
|
762
748
|
description: "Assigns the entity to a database schema/namespace.\n\n**Example:**\n```atscript\n@db.table \"users\"\n@db.schema \"auth\"\nexport interface User { ... }\n```\n",
|
|
763
749
|
nodeType: ["interface"],
|
|
764
750
|
argument: {
|
|
@@ -767,7 +753,7 @@ const dbTableAnnotations = {
|
|
|
767
753
|
description: "Schema/namespace name."
|
|
768
754
|
}
|
|
769
755
|
}),
|
|
770
|
-
sync: { method: new
|
|
756
|
+
sync: { method: new _atscript_core.AnnotationSpec({
|
|
771
757
|
description: "Controls how the sync engine handles structural changes that cannot be applied via ALTER TABLE.\n\n- `\"recreate\"` — lossless: create temp table, copy data, drop old, rename.\n- `\"drop\"` — lossy: drop table entirely and create from scratch.\n\nWithout this annotation, structural changes fail with an error requiring manual intervention.\n\n**Example:**\n```atscript\n@db.sync.method \"drop\"\ninterface Logs { ... }\n```\n",
|
|
772
758
|
nodeType: ["interface"],
|
|
773
759
|
argument: {
|
|
@@ -778,11 +764,10 @@ const dbTableAnnotations = {
|
|
|
778
764
|
}
|
|
779
765
|
}) }
|
|
780
766
|
};
|
|
781
|
-
|
|
782
767
|
//#endregion
|
|
783
|
-
//#region
|
|
768
|
+
//#region src/plugin/annotations/view.ts
|
|
784
769
|
const dbViewAnnotations = { view: {
|
|
785
|
-
$self: new
|
|
770
|
+
$self: new _atscript_core.AnnotationSpec({
|
|
786
771
|
description: "Marks an interface as a **database view**. Optionally takes a view name argument.\n\n**Example:**\n```atscript\n@db.view \"active_premium_users\"\n@db.view.for User\nexport interface ActivePremiumUser { ... }\n```\n",
|
|
787
772
|
nodeType: ["interface"],
|
|
788
773
|
argument: {
|
|
@@ -793,8 +778,7 @@ const dbViewAnnotations = { view: {
|
|
|
793
778
|
},
|
|
794
779
|
validate(token, _args, _doc) {
|
|
795
780
|
const errors = [];
|
|
796
|
-
|
|
797
|
-
if (owner.countAnnotations("db.table") > 0) errors.push({
|
|
781
|
+
if (token.parentNode.countAnnotations("db.table") > 0) errors.push({
|
|
798
782
|
message: "An interface cannot be both a @db.table and a @db.view",
|
|
799
783
|
severity: 1,
|
|
800
784
|
range: token.range
|
|
@@ -802,7 +786,7 @@ const dbViewAnnotations = { view: {
|
|
|
802
786
|
return errors;
|
|
803
787
|
}
|
|
804
788
|
}),
|
|
805
|
-
for: new
|
|
789
|
+
for: new _atscript_core.AnnotationSpec({
|
|
806
790
|
description: "Specifies the entry/primary table for a computed view. Required for views that map fields via chain refs.\n\n**Example:**\n```atscript\n@db.view.for Order\n@db.view.filter `Order.status = 'active'`\nexport interface ActiveOrderDetails { ... }\n```\n",
|
|
807
791
|
nodeType: ["interface"],
|
|
808
792
|
argument: {
|
|
@@ -812,8 +796,7 @@ const dbViewAnnotations = { view: {
|
|
|
812
796
|
},
|
|
813
797
|
validate(token, args, doc) {
|
|
814
798
|
const errors = [];
|
|
815
|
-
|
|
816
|
-
if (owner.countAnnotations("db.table") > 0) errors.push({
|
|
799
|
+
if (token.parentNode.countAnnotations("db.table") > 0) errors.push({
|
|
817
800
|
message: "An interface cannot be both a @db.table and a @db.view",
|
|
818
801
|
severity: 1,
|
|
819
802
|
range: token.range
|
|
@@ -822,7 +805,7 @@ const dbViewAnnotations = { view: {
|
|
|
822
805
|
return errors;
|
|
823
806
|
}
|
|
824
807
|
}),
|
|
825
|
-
joins: new
|
|
808
|
+
joins: new _atscript_core.AnnotationSpec({
|
|
826
809
|
description: "Declares an explicit join for a view. Use when no `@db.rel.*` path exists between the entry table and the target.\n\n**Example:**\n```atscript\n@db.view.for Order\n@db.view.joins Warehouse, `Warehouse.regionId = Order.regionId`\nexport interface OrderWarehouse { ... }\n```\n",
|
|
827
810
|
nodeType: ["interface"],
|
|
828
811
|
multiple: true,
|
|
@@ -864,7 +847,7 @@ const dbViewAnnotations = { view: {
|
|
|
864
847
|
return errors;
|
|
865
848
|
}
|
|
866
849
|
}),
|
|
867
|
-
filter: new
|
|
850
|
+
filter: new _atscript_core.AnnotationSpec({
|
|
868
851
|
description: "WHERE clause for a view, filtering which rows are included.\n\n**Example:**\n```atscript\n@db.view.for User\n@db.view.filter `User.status = 'active' and User.age >= 18`\nexport interface ActiveUser { ... }\n```\n",
|
|
869
852
|
nodeType: ["interface"],
|
|
870
853
|
argument: {
|
|
@@ -902,7 +885,7 @@ const dbViewAnnotations = { view: {
|
|
|
902
885
|
return errors;
|
|
903
886
|
}
|
|
904
887
|
}),
|
|
905
|
-
materialized: new
|
|
888
|
+
materialized: new _atscript_core.AnnotationSpec({
|
|
906
889
|
description: "Marks a view as materialized (precomputed, stored on disk). Supported by PostgreSQL, CockroachDB, Oracle, SQL Server (indexed views), Snowflake. MongoDB supports on-demand materialized views via $merge/$out. Not applicable to MySQL or SQLite.\n\n**Example:**\n```atscript\n@db.view.materialized\n@db.view.for User\n@db.view.filter `User.status = 'active'`\nexport interface ActiveUsers { ... }\n```\n",
|
|
907
890
|
nodeType: ["interface"],
|
|
908
891
|
validate(token, _args, _doc) {
|
|
@@ -916,7 +899,7 @@ const dbViewAnnotations = { view: {
|
|
|
916
899
|
return errors;
|
|
917
900
|
}
|
|
918
901
|
}),
|
|
919
|
-
renamed: new
|
|
902
|
+
renamed: new _atscript_core.AnnotationSpec({
|
|
920
903
|
description: "Specifies the previous view name for view rename migration. The sync engine drops the old view and creates the new one.\n\n**Example:**\n```atscript\n@db.view \"active_premium_users\"\n@db.view.renamed \"active_users\"\n@db.view.for User\nexport interface ActivePremiumUser { ... }\n```\n",
|
|
921
904
|
nodeType: ["interface"],
|
|
922
905
|
argument: {
|
|
@@ -935,7 +918,7 @@ const dbViewAnnotations = { view: {
|
|
|
935
918
|
return errors;
|
|
936
919
|
}
|
|
937
920
|
}),
|
|
938
|
-
having: new
|
|
921
|
+
having: new _atscript_core.AnnotationSpec({
|
|
939
922
|
description: "Post-aggregation filter (HAVING clause) for analytical views. References view field aliases with applied aggregate functions.\n\n**Example:**\n```atscript\n@db.view\n@db.view.for Order\n@db.view.having `totalRevenue > 100`\nexport interface TopCategories { ... }\n```\n",
|
|
940
923
|
nodeType: ["interface"],
|
|
941
924
|
argument: {
|
|
@@ -955,9 +938,8 @@ const dbViewAnnotations = { view: {
|
|
|
955
938
|
}
|
|
956
939
|
})
|
|
957
940
|
} };
|
|
958
|
-
|
|
959
941
|
//#endregion
|
|
960
|
-
//#region
|
|
942
|
+
//#region src/plugin/index.ts
|
|
961
943
|
const dbPlugin = () => ({
|
|
962
944
|
name: "db",
|
|
963
945
|
config() {
|
|
@@ -987,7 +969,6 @@ const dbPlugin = () => ({
|
|
|
987
969
|
};
|
|
988
970
|
}
|
|
989
971
|
});
|
|
990
|
-
|
|
991
972
|
//#endregion
|
|
992
|
-
exports.dbPlugin = dbPlugin
|
|
993
|
-
exports.default = dbPlugin
|
|
973
|
+
exports.dbPlugin = dbPlugin;
|
|
974
|
+
exports.default = dbPlugin;
|