@atscript/db 0.1.148 → 0.1.150
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/agg.d.cts +1 -1
- package/dist/agg.d.mts +1 -1
- package/dist/{buckets-DJiYlMXc.d.cts → buckets-24Ac4sIS.d.cts} +80 -5
- package/dist/{buckets-CNdTOnei.d.mts → buckets-XOz0Bw5x.d.mts} +80 -5
- package/dist/{column-diff-CUU4GvYg.cjs → column-diff-CKKBVDvx.cjs} +646 -341
- package/dist/{column-diff-Cp6ZoyRE.mjs → column-diff-CKLDWBbo.mjs} +522 -253
- package/dist/{fk-diff-BQ4krij8.d.cts → fk-diff-CCLiJ9sJ.d.cts} +2 -1
- package/dist/{fk-diff-DsaIijVX.d.mts → fk-diff-R8eU7gq-.d.mts} +2 -1
- package/dist/index.cjs +10 -3
- package/dist/index.d.cts +66 -4
- package/dist/index.d.mts +66 -4
- package/dist/index.mjs +3 -3
- package/dist/plugin.cjs +143 -36
- package/dist/plugin.mjs +138 -31
- package/dist/rel.d.cts +2 -2
- package/dist/rel.d.mts +2 -2
- package/dist/{relation-helpers-kX7jjgME.d.cts → relation-helpers-DjVJN2ng.d.cts} +1 -1
- package/dist/{relation-helpers-Ba0v49sn.d.mts → relation-helpers-H7UEVkHs.d.mts} +1 -1
- package/dist/search-fields-DBIZKwyb.mjs +117 -0
- package/dist/search-fields-DwrsJUC1.cjs +158 -0
- package/dist/shared.cjs +3 -1
- package/dist/shared.d.cts +19 -1
- package/dist/shared.d.mts +19 -1
- package/dist/shared.mjs +2 -2
- package/dist/sync.cjs +1 -1
- package/dist/sync.d.cts +2 -2
- package/dist/sync.d.mts +2 -2
- package/dist/sync.mjs +1 -1
- package/dist/{validation-utils-Dq0uZ7ef.mjs → validation-utils-DqZAH6aT.mjs} +44 -2
- package/dist/{validation-utils-Da2GjobR.cjs → validation-utils-debIYpq0.cjs} +56 -2
- package/package.json +6 -6
- package/dist/derived-rules-0sKn4f5C.mjs +0 -44
- package/dist/derived-rules-YstgIxG-.cjs +0 -67
- package/dist/numeric-operand-B1jKH7x5.mjs +0 -21
- package/dist/numeric-operand-DKfiRLYp.cjs +0 -26
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
//#region src/shared/derived-rules.ts
|
|
2
|
+
/**
|
|
3
|
+
* The rules the compiler plugin and the runtime share about entities and
|
|
4
|
+
* `@db.column.derived` fields — one dependency-free list each, so a
|
|
5
|
+
* compile-time diagnostic and its runtime mirror can never disagree.
|
|
6
|
+
* @since 0.1.141
|
|
7
|
+
*/
|
|
8
|
+
/** The annotations that make a declaration a DB entity: a table, or a managed / external view. */
|
|
9
|
+
const DB_ENTITY_ANNOTATIONS = [
|
|
10
|
+
"db.table",
|
|
11
|
+
"db.view",
|
|
12
|
+
"db.view.for"
|
|
13
|
+
];
|
|
14
|
+
/** Primitive leaf types a JSON-stored path may end at (view JSON leaves, derived columns). */
|
|
15
|
+
const JSON_LEAF_TYPES = new Set([
|
|
16
|
+
"string",
|
|
17
|
+
"number",
|
|
18
|
+
"boolean"
|
|
19
|
+
]);
|
|
20
|
+
/** Whether `type` (a resolved design type) is one of {@link JSON_LEAF_TYPES}. */
|
|
21
|
+
function isJsonLeafType(type) {
|
|
22
|
+
return JSON_LEAF_TYPES.has(type);
|
|
23
|
+
}
|
|
24
|
+
/** Annotations a `@db.column.derived` field cannot carry (D8), with the reason. */
|
|
25
|
+
const DERIVED_INCOMPATIBLE = [
|
|
26
|
+
["meta.id", "a computed column cannot identify the row"],
|
|
27
|
+
["db.rel.FK", "a foreign key needs a stored, writable column"],
|
|
28
|
+
["db.default", "the value is computed, never defaulted"],
|
|
29
|
+
["db.default.increment", "the value is computed, never defaulted"],
|
|
30
|
+
["db.default.uuid", "the value is computed, never defaulted"],
|
|
31
|
+
["db.default.now", "the value is computed, never defaulted"],
|
|
32
|
+
["db.column.version", "the version column is adapter-managed"],
|
|
33
|
+
["db.column.version.exempt", "a derived column is never written"],
|
|
34
|
+
["db.encrypted", "the value is a cleartext extraction of its source"],
|
|
35
|
+
["db.json", "a derived column is a primitive leaf, not a JSON value"],
|
|
36
|
+
["db.ignore", "an ignored field has no column to derive"],
|
|
37
|
+
["db.writeOnly", "a derived column is never written"],
|
|
38
|
+
["db.index.fulltext", "fulltext indexes need a stored text column"],
|
|
39
|
+
["db.index.geo", "a geo index needs a db.geoPoint column"],
|
|
40
|
+
["db.search.vector", "a vector index needs a stored embedding column"],
|
|
41
|
+
["db.mongo.search.text", "Atlas Search indexes the stored document, which holds no derived field"],
|
|
42
|
+
["db.mongo.search.autocomplete", "Atlas Search indexes the stored document, which holds no derived field"]
|
|
43
|
+
];
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/shared/numeric-operand.ts
|
|
46
|
+
/** Primitive tags of timestamps (MySQL may store them as native `TIMESTAMP`). */
|
|
47
|
+
const TIMESTAMP_TAGS = [
|
|
48
|
+
"timestamp",
|
|
49
|
+
"created",
|
|
50
|
+
"updated"
|
|
51
|
+
];
|
|
52
|
+
/**
|
|
53
|
+
* Why a field cannot be an arithmetic operand, or `undefined` when it can: it
|
|
54
|
+
* must be a `number` — not a decimal (exact; an expression is IEEE double) and
|
|
55
|
+
* not a timestamp-tagged number. The one rule behind `@db.compute` (declared,
|
|
56
|
+
* from the `.as` source) and query-time arithmetic (from the runtime
|
|
57
|
+
* descriptor), so the two cannot diverge. Storage rules (`@db.ignore`,
|
|
58
|
+
* encrypted, JSON) stay with the callers.
|
|
59
|
+
*/
|
|
60
|
+
function numericTypeProblem({ base, tags }) {
|
|
61
|
+
if (base !== "number" && base !== "integer") return base === "decimal" ? "is a decimal" : `is a ${base}`;
|
|
62
|
+
if (tags && TIMESTAMP_TAGS.some((t) => tags.has(t))) return "is a timestamp";
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/shared/search-fields.ts
|
|
66
|
+
/**
|
|
67
|
+
* Problem suffixes, shared by the plugin (compile time) and the runtime
|
|
68
|
+
* metadata build so both word a refusal identically.
|
|
69
|
+
*/
|
|
70
|
+
const SEARCH_PROBLEM = {
|
|
71
|
+
timestamp: "is a timestamp — filter it by range instead",
|
|
72
|
+
now: "is a timestamp (@db.default.now) — filter it by range instead",
|
|
73
|
+
precision: "has @db.column.precision (stored as a decimal)",
|
|
74
|
+
float: "is a floating-point number — declare it number.int (or a sized integer), add @expect.int, or use @db.default.increment",
|
|
75
|
+
decimal: "is a decimal"
|
|
76
|
+
};
|
|
77
|
+
/** Problem for a primitive of another base type (`boolean`, …). */
|
|
78
|
+
function otherBaseProblem(base) {
|
|
79
|
+
return `is a ${base}`;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The one rule behind `@db.column.searchable` / `@db.index.fulltext`:
|
|
83
|
+
* a string (or a non-primitive) is `"text"`; an integer is `"integer"`;
|
|
84
|
+
* floats, decimals, timestamps and other primitives are a `{ problem }`.
|
|
85
|
+
*/
|
|
86
|
+
function searchKindOf(d) {
|
|
87
|
+
const { base } = d;
|
|
88
|
+
if (base === void 0 || base === "string") return "text";
|
|
89
|
+
if (base === "decimal") return { problem: SEARCH_PROBLEM.decimal };
|
|
90
|
+
if (base !== "number" && base !== "integer") return { problem: otherBaseProblem(base) };
|
|
91
|
+
if (d.tags && TIMESTAMP_TAGS.some((t) => d.tags.has(t))) return { problem: SEARCH_PROBLEM.timestamp };
|
|
92
|
+
if (d.now) return { problem: SEARCH_PROBLEM.now };
|
|
93
|
+
if (d.precision) return { problem: SEARCH_PROBLEM.precision };
|
|
94
|
+
if (base === "integer" || d.tags?.has("int") || d.expectInt || d.increment) return "integer";
|
|
95
|
+
return { problem: SEARCH_PROBLEM.float };
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Runtime mirror of the plugin's verdict: how the annotated type takes part
|
|
99
|
+
* in `$search`. Structures, arrays, unions and unresolved types keep their
|
|
100
|
+
* legacy `"text"` treatment.
|
|
101
|
+
*/
|
|
102
|
+
function searchMemberKind(type) {
|
|
103
|
+
const def = type?.type;
|
|
104
|
+
if (!def || def.kind !== "") return "text";
|
|
105
|
+
const metadata = type.metadata;
|
|
106
|
+
const has = (key) => metadata?.has?.(key) === true;
|
|
107
|
+
return searchKindOf({
|
|
108
|
+
base: def.designType,
|
|
109
|
+
tags: def.tags,
|
|
110
|
+
expectInt: has("expect.int"),
|
|
111
|
+
increment: has("db.default.increment"),
|
|
112
|
+
now: has("db.default.now"),
|
|
113
|
+
precision: has("db.column.precision")
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
//#endregion
|
|
117
|
+
export { DERIVED_INCOMPATIBLE as a, DB_ENTITY_ANNOTATIONS as i, searchMemberKind as n, JSON_LEAF_TYPES as o, numericTypeProblem as r, isJsonLeafType as s, searchKindOf as t };
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
//#region src/shared/derived-rules.ts
|
|
2
|
+
/**
|
|
3
|
+
* The rules the compiler plugin and the runtime share about entities and
|
|
4
|
+
* `@db.column.derived` fields — one dependency-free list each, so a
|
|
5
|
+
* compile-time diagnostic and its runtime mirror can never disagree.
|
|
6
|
+
* @since 0.1.141
|
|
7
|
+
*/
|
|
8
|
+
/** The annotations that make a declaration a DB entity: a table, or a managed / external view. */
|
|
9
|
+
const DB_ENTITY_ANNOTATIONS = [
|
|
10
|
+
"db.table",
|
|
11
|
+
"db.view",
|
|
12
|
+
"db.view.for"
|
|
13
|
+
];
|
|
14
|
+
/** Primitive leaf types a JSON-stored path may end at (view JSON leaves, derived columns). */
|
|
15
|
+
const JSON_LEAF_TYPES = new Set([
|
|
16
|
+
"string",
|
|
17
|
+
"number",
|
|
18
|
+
"boolean"
|
|
19
|
+
]);
|
|
20
|
+
/** Whether `type` (a resolved design type) is one of {@link JSON_LEAF_TYPES}. */
|
|
21
|
+
function isJsonLeafType(type) {
|
|
22
|
+
return JSON_LEAF_TYPES.has(type);
|
|
23
|
+
}
|
|
24
|
+
/** Annotations a `@db.column.derived` field cannot carry (D8), with the reason. */
|
|
25
|
+
const DERIVED_INCOMPATIBLE = [
|
|
26
|
+
["meta.id", "a computed column cannot identify the row"],
|
|
27
|
+
["db.rel.FK", "a foreign key needs a stored, writable column"],
|
|
28
|
+
["db.default", "the value is computed, never defaulted"],
|
|
29
|
+
["db.default.increment", "the value is computed, never defaulted"],
|
|
30
|
+
["db.default.uuid", "the value is computed, never defaulted"],
|
|
31
|
+
["db.default.now", "the value is computed, never defaulted"],
|
|
32
|
+
["db.column.version", "the version column is adapter-managed"],
|
|
33
|
+
["db.column.version.exempt", "a derived column is never written"],
|
|
34
|
+
["db.encrypted", "the value is a cleartext extraction of its source"],
|
|
35
|
+
["db.json", "a derived column is a primitive leaf, not a JSON value"],
|
|
36
|
+
["db.ignore", "an ignored field has no column to derive"],
|
|
37
|
+
["db.writeOnly", "a derived column is never written"],
|
|
38
|
+
["db.index.fulltext", "fulltext indexes need a stored text column"],
|
|
39
|
+
["db.index.geo", "a geo index needs a db.geoPoint column"],
|
|
40
|
+
["db.search.vector", "a vector index needs a stored embedding column"],
|
|
41
|
+
["db.mongo.search.text", "Atlas Search indexes the stored document, which holds no derived field"],
|
|
42
|
+
["db.mongo.search.autocomplete", "Atlas Search indexes the stored document, which holds no derived field"]
|
|
43
|
+
];
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/shared/numeric-operand.ts
|
|
46
|
+
/** Primitive tags of timestamps (MySQL may store them as native `TIMESTAMP`). */
|
|
47
|
+
const TIMESTAMP_TAGS = [
|
|
48
|
+
"timestamp",
|
|
49
|
+
"created",
|
|
50
|
+
"updated"
|
|
51
|
+
];
|
|
52
|
+
/**
|
|
53
|
+
* Why a field cannot be an arithmetic operand, or `undefined` when it can: it
|
|
54
|
+
* must be a `number` — not a decimal (exact; an expression is IEEE double) and
|
|
55
|
+
* not a timestamp-tagged number. The one rule behind `@db.compute` (declared,
|
|
56
|
+
* from the `.as` source) and query-time arithmetic (from the runtime
|
|
57
|
+
* descriptor), so the two cannot diverge. Storage rules (`@db.ignore`,
|
|
58
|
+
* encrypted, JSON) stay with the callers.
|
|
59
|
+
*/
|
|
60
|
+
function numericTypeProblem({ base, tags }) {
|
|
61
|
+
if (base !== "number" && base !== "integer") return base === "decimal" ? "is a decimal" : `is a ${base}`;
|
|
62
|
+
if (tags && TIMESTAMP_TAGS.some((t) => tags.has(t))) return "is a timestamp";
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/shared/search-fields.ts
|
|
66
|
+
/**
|
|
67
|
+
* Problem suffixes, shared by the plugin (compile time) and the runtime
|
|
68
|
+
* metadata build so both word a refusal identically.
|
|
69
|
+
*/
|
|
70
|
+
const SEARCH_PROBLEM = {
|
|
71
|
+
timestamp: "is a timestamp — filter it by range instead",
|
|
72
|
+
now: "is a timestamp (@db.default.now) — filter it by range instead",
|
|
73
|
+
precision: "has @db.column.precision (stored as a decimal)",
|
|
74
|
+
float: "is a floating-point number — declare it number.int (or a sized integer), add @expect.int, or use @db.default.increment",
|
|
75
|
+
decimal: "is a decimal"
|
|
76
|
+
};
|
|
77
|
+
/** Problem for a primitive of another base type (`boolean`, …). */
|
|
78
|
+
function otherBaseProblem(base) {
|
|
79
|
+
return `is a ${base}`;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The one rule behind `@db.column.searchable` / `@db.index.fulltext`:
|
|
83
|
+
* a string (or a non-primitive) is `"text"`; an integer is `"integer"`;
|
|
84
|
+
* floats, decimals, timestamps and other primitives are a `{ problem }`.
|
|
85
|
+
*/
|
|
86
|
+
function searchKindOf(d) {
|
|
87
|
+
const { base } = d;
|
|
88
|
+
if (base === void 0 || base === "string") return "text";
|
|
89
|
+
if (base === "decimal") return { problem: SEARCH_PROBLEM.decimal };
|
|
90
|
+
if (base !== "number" && base !== "integer") return { problem: otherBaseProblem(base) };
|
|
91
|
+
if (d.tags && TIMESTAMP_TAGS.some((t) => d.tags.has(t))) return { problem: SEARCH_PROBLEM.timestamp };
|
|
92
|
+
if (d.now) return { problem: SEARCH_PROBLEM.now };
|
|
93
|
+
if (d.precision) return { problem: SEARCH_PROBLEM.precision };
|
|
94
|
+
if (base === "integer" || d.tags?.has("int") || d.expectInt || d.increment) return "integer";
|
|
95
|
+
return { problem: SEARCH_PROBLEM.float };
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Runtime mirror of the plugin's verdict: how the annotated type takes part
|
|
99
|
+
* in `$search`. Structures, arrays, unions and unresolved types keep their
|
|
100
|
+
* legacy `"text"` treatment.
|
|
101
|
+
*/
|
|
102
|
+
function searchMemberKind(type) {
|
|
103
|
+
const def = type?.type;
|
|
104
|
+
if (!def || def.kind !== "") return "text";
|
|
105
|
+
const metadata = type.metadata;
|
|
106
|
+
const has = (key) => metadata?.has?.(key) === true;
|
|
107
|
+
return searchKindOf({
|
|
108
|
+
base: def.designType,
|
|
109
|
+
tags: def.tags,
|
|
110
|
+
expectInt: has("expect.int"),
|
|
111
|
+
increment: has("db.default.increment"),
|
|
112
|
+
now: has("db.default.now"),
|
|
113
|
+
precision: has("db.column.precision")
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
//#endregion
|
|
117
|
+
Object.defineProperty(exports, "DB_ENTITY_ANNOTATIONS", {
|
|
118
|
+
enumerable: true,
|
|
119
|
+
get: function() {
|
|
120
|
+
return DB_ENTITY_ANNOTATIONS;
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
Object.defineProperty(exports, "DERIVED_INCOMPATIBLE", {
|
|
124
|
+
enumerable: true,
|
|
125
|
+
get: function() {
|
|
126
|
+
return DERIVED_INCOMPATIBLE;
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
Object.defineProperty(exports, "JSON_LEAF_TYPES", {
|
|
130
|
+
enumerable: true,
|
|
131
|
+
get: function() {
|
|
132
|
+
return JSON_LEAF_TYPES;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
Object.defineProperty(exports, "isJsonLeafType", {
|
|
136
|
+
enumerable: true,
|
|
137
|
+
get: function() {
|
|
138
|
+
return isJsonLeafType;
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
Object.defineProperty(exports, "numericTypeProblem", {
|
|
142
|
+
enumerable: true,
|
|
143
|
+
get: function() {
|
|
144
|
+
return numericTypeProblem;
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
Object.defineProperty(exports, "searchKindOf", {
|
|
148
|
+
enumerable: true,
|
|
149
|
+
get: function() {
|
|
150
|
+
return searchKindOf;
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
Object.defineProperty(exports, "searchMemberKind", {
|
|
154
|
+
enumerable: true,
|
|
155
|
+
get: function() {
|
|
156
|
+
return searchMemberKind;
|
|
157
|
+
}
|
|
158
|
+
});
|
package/dist/shared.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_aggregate_rules = require("./aggregate-rules-D_bsCpUI.cjs");
|
|
3
|
-
const require_validation_utils = require("./validation-utils-
|
|
3
|
+
const require_validation_utils = require("./validation-utils-debIYpq0.cjs");
|
|
4
4
|
exports.NOT_DIMENSION_REASON = require_aggregate_rules.NOT_DIMENSION_REASON;
|
|
5
5
|
exports.earlierJoinTargets = require_validation_utils.earlierJoinTargets;
|
|
6
6
|
exports.findFKFieldsPointingTo = require_validation_utils.findFKFieldsPointingTo;
|
|
@@ -12,12 +12,14 @@ exports.getNavTargetTypeName = require_validation_utils.getNavTargetTypeName;
|
|
|
12
12
|
exports.getParentStruct = require_validation_utils.getParentStruct;
|
|
13
13
|
exports.getParentTypeName = require_validation_utils.getParentTypeName;
|
|
14
14
|
exports.hasAnyViewAnnotation = require_validation_utils.hasAnyViewAnnotation;
|
|
15
|
+
exports.integerMemberIndexProblem = require_validation_utils.integerMemberIndexProblem;
|
|
15
16
|
exports.isAliasDecl = require_validation_utils.isAliasDecl;
|
|
16
17
|
exports.isDbSourceDecl = require_validation_utils.isDbSourceDecl;
|
|
17
18
|
exports.isStrictAggregateStruct = require_aggregate_rules.isStrictAggregateStruct;
|
|
18
19
|
exports.joinTargets = require_validation_utils.joinTargets;
|
|
19
20
|
exports.primitiveBaseType = require_validation_utils.primitiveBaseType;
|
|
20
21
|
exports.refActionAnnotation = require_validation_utils.refActionAnnotation;
|
|
22
|
+
exports.searchFieldVerdict = require_validation_utils.searchFieldVerdict;
|
|
21
23
|
exports.validateExclusiveWith = require_validation_utils.validateExclusiveWith;
|
|
22
24
|
exports.validateFieldBaseType = require_validation_utils.validateFieldBaseType;
|
|
23
25
|
exports.validateQueryScope = require_validation_utils.validateQueryScope;
|
package/dist/shared.d.cts
CHANGED
|
@@ -8,6 +8,24 @@ declare function validateExclusiveWith(token: Token, selfName: string, others: A
|
|
|
8
8
|
}>): TMessages;
|
|
9
9
|
/** Primitive base type (`string`, `number`, `decimal`, …) of a resolved definition, if it is a primitive. */
|
|
10
10
|
declare function primitiveBaseType(def: SemanticNode | undefined): string | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Whether a prop takes part in `$search` as text or as an integer, or why it
|
|
13
|
+
* cannot (compile-time mirror of the runtime `searchMemberKind`). Anything
|
|
14
|
+
* that is not a ref to a primitive (structures, arrays, unions, unresolved
|
|
15
|
+
* refs) is left alone.
|
|
16
|
+
*/
|
|
17
|
+
declare function searchFieldVerdict(field: SemanticNode, doc: AtscriptDoc): {
|
|
18
|
+
kind: "string" | "integer" | "other";
|
|
19
|
+
} | {
|
|
20
|
+
problem: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Why an integer fulltext member is not index-backed (its exact-number match
|
|
24
|
+
* would scan — or fail on MongoDB next to `$text`), or `undefined`. Backed:
|
|
25
|
+
* `_id`, the first `@meta.id` of the type, or the first field (in declaration
|
|
26
|
+
* order) of a `@db.index.plain` / `@db.index.unique` group.
|
|
27
|
+
*/
|
|
28
|
+
declare function integerMemberIndexProblem(token: Token): string | undefined;
|
|
11
29
|
/** Asserts `args[0]` names a sibling property whose primitive base type is `string`. */
|
|
12
30
|
declare function validateSiblingStringField(token: Token, args: Token[], doc: AtscriptDoc, selfName: string): TMessages;
|
|
13
31
|
/**
|
|
@@ -139,4 +157,4 @@ declare const NOT_DIMENSION_REASON = "not a dimension";
|
|
|
139
157
|
*/
|
|
140
158
|
declare function isStrictAggregateStruct(struct: SemanticStructureNode): boolean;
|
|
141
159
|
//#endregion
|
|
142
|
-
export { NOT_DIMENSION_REASON, TFKFieldMatch, TRefArgumentOptions, earlierJoinTargets, findFKFieldsPointingTo, findViewCycle, forEachFieldRef, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, isAliasDecl, isDbSourceDecl, isStrictAggregateStruct, joinTargets, primitiveBaseType, refActionAnnotation, validateExclusiveWith, validateFieldBaseType, validateQueryScope, validateRefArgument, validateSiblingStringField, viewJoins, viewScopeTypes };
|
|
160
|
+
export { NOT_DIMENSION_REASON, TFKFieldMatch, TRefArgumentOptions, earlierJoinTargets, findFKFieldsPointingTo, findViewCycle, forEachFieldRef, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, integerMemberIndexProblem, isAliasDecl, isDbSourceDecl, isStrictAggregateStruct, joinTargets, primitiveBaseType, refActionAnnotation, searchFieldVerdict, validateExclusiveWith, validateFieldBaseType, validateQueryScope, validateRefArgument, validateSiblingStringField, viewJoins, viewScopeTypes };
|
package/dist/shared.d.mts
CHANGED
|
@@ -8,6 +8,24 @@ declare function validateExclusiveWith(token: Token, selfName: string, others: A
|
|
|
8
8
|
}>): TMessages;
|
|
9
9
|
/** Primitive base type (`string`, `number`, `decimal`, …) of a resolved definition, if it is a primitive. */
|
|
10
10
|
declare function primitiveBaseType(def: SemanticNode | undefined): string | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Whether a prop takes part in `$search` as text or as an integer, or why it
|
|
13
|
+
* cannot (compile-time mirror of the runtime `searchMemberKind`). Anything
|
|
14
|
+
* that is not a ref to a primitive (structures, arrays, unions, unresolved
|
|
15
|
+
* refs) is left alone.
|
|
16
|
+
*/
|
|
17
|
+
declare function searchFieldVerdict(field: SemanticNode, doc: AtscriptDoc): {
|
|
18
|
+
kind: "string" | "integer" | "other";
|
|
19
|
+
} | {
|
|
20
|
+
problem: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Why an integer fulltext member is not index-backed (its exact-number match
|
|
24
|
+
* would scan — or fail on MongoDB next to `$text`), or `undefined`. Backed:
|
|
25
|
+
* `_id`, the first `@meta.id` of the type, or the first field (in declaration
|
|
26
|
+
* order) of a `@db.index.plain` / `@db.index.unique` group.
|
|
27
|
+
*/
|
|
28
|
+
declare function integerMemberIndexProblem(token: Token): string | undefined;
|
|
11
29
|
/** Asserts `args[0]` names a sibling property whose primitive base type is `string`. */
|
|
12
30
|
declare function validateSiblingStringField(token: Token, args: Token[], doc: AtscriptDoc, selfName: string): TMessages;
|
|
13
31
|
/**
|
|
@@ -139,4 +157,4 @@ declare const NOT_DIMENSION_REASON = "not a dimension";
|
|
|
139
157
|
*/
|
|
140
158
|
declare function isStrictAggregateStruct(struct: SemanticStructureNode): boolean;
|
|
141
159
|
//#endregion
|
|
142
|
-
export { NOT_DIMENSION_REASON, TFKFieldMatch, TRefArgumentOptions, earlierJoinTargets, findFKFieldsPointingTo, findViewCycle, forEachFieldRef, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, isAliasDecl, isDbSourceDecl, isStrictAggregateStruct, joinTargets, primitiveBaseType, refActionAnnotation, validateExclusiveWith, validateFieldBaseType, validateQueryScope, validateRefArgument, validateSiblingStringField, viewJoins, viewScopeTypes };
|
|
160
|
+
export { NOT_DIMENSION_REASON, TFKFieldMatch, TRefArgumentOptions, earlierJoinTargets, findFKFieldsPointingTo, findViewCycle, forEachFieldRef, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, integerMemberIndexProblem, isAliasDecl, isDbSourceDecl, isStrictAggregateStruct, joinTargets, primitiveBaseType, refActionAnnotation, searchFieldVerdict, validateExclusiveWith, validateFieldBaseType, validateQueryScope, validateRefArgument, validateSiblingStringField, viewJoins, viewScopeTypes };
|
package/dist/shared.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { n as isStrictAggregateStruct, t as NOT_DIMENSION_REASON } from "./aggregate-rules-jdPrxqWa.mjs";
|
|
2
|
-
import { S as
|
|
3
|
-
export { NOT_DIMENSION_REASON, earlierJoinTargets, findFKFieldsPointingTo, findViewCycle, forEachFieldRef, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, isAliasDecl, isDbSourceDecl, isStrictAggregateStruct, joinTargets, primitiveBaseType, refActionAnnotation, validateExclusiveWith, validateFieldBaseType, validateQueryScope, validateRefArgument, validateSiblingStringField, viewJoins, viewScopeTypes };
|
|
2
|
+
import { C as validateFieldBaseType, S as validateExclusiveWith, _ as getParentTypeName, a as hasAnyViewAnnotation, b as refActionAnnotation, c as joinTargets, d as viewJoins, f as viewScopeTypes, g as getParentStruct, h as getNavTargetTypeName, i as forEachFieldRef, l as validateQueryScope, m as getDbTableOwner, n as findFKFieldsPointingTo, o as isAliasDecl, p as getAnnotationAlias, r as findViewCycle, s as isDbSourceDecl, t as earlierJoinTargets, u as validateRefArgument, v as integerMemberIndexProblem, w as validateSiblingStringField, x as searchFieldVerdict, y as primitiveBaseType } from "./validation-utils-DqZAH6aT.mjs";
|
|
3
|
+
export { NOT_DIMENSION_REASON, earlierJoinTargets, findFKFieldsPointingTo, findViewCycle, forEachFieldRef, getAnnotationAlias, getDbTableOwner, getNavTargetTypeName, getParentStruct, getParentTypeName, hasAnyViewAnnotation, integerMemberIndexProblem, isAliasDecl, isDbSourceDecl, isStrictAggregateStruct, joinTargets, primitiveBaseType, refActionAnnotation, searchFieldVerdict, validateExclusiveWith, validateFieldBaseType, validateQueryScope, validateRefArgument, validateSiblingStringField, viewJoins, viewScopeTypes };
|
package/dist/sync.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_db_error = require("./db-error-DRQH4sLY.cjs");
|
|
3
|
-
const require_column_diff = require("./column-diff-
|
|
3
|
+
const require_column_diff = require("./column-diff-CKKBVDvx.cjs");
|
|
4
4
|
//#region src/schema/table-option-diff.ts
|
|
5
5
|
/**
|
|
6
6
|
* Computes the difference between desired and existing table options.
|
package/dist/sync.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Dt as
|
|
2
|
-
import { _ as computeTableSnapshot, a as hasForeignKeyChanges, b as snapshotToExistingTableOptions, c as TFieldSnapshot, d as TViewColumnSnapshot, f as TViewJoinSnapshot, g as computeTableHash, h as computeSchemaHash, i as fkKey, l as TForeignKeySnapshot, m as canonicalizeQueryNode, n as computeForeignKeyDiff, o as computeColumnDiff, p as TViewSnapshot, t as TForeignKeyDiff, u as TTableSnapshot, v as computeViewSnapshot, y as snapshotToExistingColumns } from "./fk-diff-
|
|
1
|
+
import { Dt as TPrimaryKeyChange, H as TDbFieldMeta, Hn as TGenericLogger, Nt as TTableOptionDiff, Ot as TReferencingForeignKey, Q as TDbObjectKind, Zt as DbSpace, _t as TExistingTableOption, ft as TDerivedChangeReason, gt as TExistingForeignKey, mt as TEnsureTableOptions } from "./buckets-24Ac4sIS.cjs";
|
|
2
|
+
import { _ as computeTableSnapshot, a as hasForeignKeyChanges, b as snapshotToExistingTableOptions, c as TFieldSnapshot, d as TViewColumnSnapshot, f as TViewJoinSnapshot, g as computeTableHash, h as computeSchemaHash, i as fkKey, l as TForeignKeySnapshot, m as canonicalizeQueryNode, n as computeForeignKeyDiff, o as computeColumnDiff, p as TViewSnapshot, t as TForeignKeyDiff, u as TTableSnapshot, v as computeViewSnapshot, y as snapshotToExistingColumns } from "./fk-diff-CCLiJ9sJ.cjs";
|
|
3
3
|
import { TAtscriptAnnotatedType } from "@atscript/typescript/utils";
|
|
4
4
|
|
|
5
5
|
//#region src/schema/sync-entry.d.ts
|
package/dist/sync.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Dt as
|
|
2
|
-
import { _ as computeTableSnapshot, a as hasForeignKeyChanges, b as snapshotToExistingTableOptions, c as TFieldSnapshot, d as TViewColumnSnapshot, f as TViewJoinSnapshot, g as computeTableHash, h as computeSchemaHash, i as fkKey, l as TForeignKeySnapshot, m as canonicalizeQueryNode, n as computeForeignKeyDiff, o as computeColumnDiff, p as TViewSnapshot, t as TForeignKeyDiff, u as TTableSnapshot, v as computeViewSnapshot, y as snapshotToExistingColumns } from "./fk-diff-
|
|
1
|
+
import { Dt as TPrimaryKeyChange, H as TDbFieldMeta, Hn as TGenericLogger, Nt as TTableOptionDiff, Ot as TReferencingForeignKey, Q as TDbObjectKind, Zt as DbSpace, _t as TExistingTableOption, ft as TDerivedChangeReason, gt as TExistingForeignKey, mt as TEnsureTableOptions } from "./buckets-XOz0Bw5x.mjs";
|
|
2
|
+
import { _ as computeTableSnapshot, a as hasForeignKeyChanges, b as snapshotToExistingTableOptions, c as TFieldSnapshot, d as TViewColumnSnapshot, f as TViewJoinSnapshot, g as computeTableHash, h as computeSchemaHash, i as fkKey, l as TForeignKeySnapshot, m as canonicalizeQueryNode, n as computeForeignKeyDiff, o as computeColumnDiff, p as TViewSnapshot, t as TForeignKeyDiff, u as TTableSnapshot, v as computeViewSnapshot, y as snapshotToExistingColumns } from "./fk-diff-R8eU7gq-.mjs";
|
|
3
3
|
import { TAtscriptAnnotatedType } from "@atscript/typescript/utils";
|
|
4
4
|
|
|
5
5
|
//#region src/schema/sync-entry.d.ts
|
package/dist/sync.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as DbError } from "./db-error-Az85UhTX.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { _t as NoopLogger, a as computeTableHash, c as snapshotToExistingColumns, d as computeForeignKeyDiff, dt as aliasTargetOf, f as fkColumns, i as computeSchemaHash, l as snapshotToExistingTableOptions, m as hasForeignKeyChanges, o as computeTableSnapshot, p as fkKey, r as canonicalizeQueryNode, s as computeViewSnapshot, t as computeColumnDiff, u as viewSnapshotSources } from "./column-diff-CKLDWBbo.mjs";
|
|
3
3
|
//#region src/schema/table-option-diff.ts
|
|
4
4
|
/**
|
|
5
5
|
* Computes the difference between desired and existing table options.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i as DB_ENTITY_ANNOTATIONS, t as searchKindOf } from "./search-fields-DBIZKwyb.mjs";
|
|
2
2
|
import { AnnotationSpec, isArray, isInterface, isPrimitive, isQueryComparison, isQueryLogical, isRef, isStructure } from "@atscript/core";
|
|
3
3
|
//#region src/shared/annotation-utils.ts
|
|
4
4
|
/** Asserts the field carrying this annotation does not also carry any of `others`. */
|
|
@@ -24,6 +24,48 @@ function getPrimitiveBaseType(node, doc) {
|
|
|
24
24
|
if (!def || !isRef(def)) return void 0;
|
|
25
25
|
return primitiveBaseType(doc.unwindType(def.id, def.chain)?.def);
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Whether a prop takes part in `$search` as text or as an integer, or why it
|
|
29
|
+
* cannot (compile-time mirror of the runtime `searchMemberKind`). Anything
|
|
30
|
+
* that is not a ref to a primitive (structures, arrays, unions, unresolved
|
|
31
|
+
* refs) is left alone.
|
|
32
|
+
*/
|
|
33
|
+
function searchFieldVerdict(field, doc) {
|
|
34
|
+
const def = field.getDefinition();
|
|
35
|
+
if (!def || !isRef(def)) return { kind: "other" };
|
|
36
|
+
const leaf = doc.unwindType(def.id, def.chain)?.def;
|
|
37
|
+
const base = primitiveBaseType(leaf);
|
|
38
|
+
if (base === void 0) return { kind: "other" };
|
|
39
|
+
const kind = searchKindOf({
|
|
40
|
+
base,
|
|
41
|
+
tags: isPrimitive(leaf) ? leaf.tags : void 0,
|
|
42
|
+
expectInt: field.countAnnotations("expect.int") > 0,
|
|
43
|
+
increment: field.countAnnotations("db.default.increment") > 0,
|
|
44
|
+
now: field.countAnnotations("db.default.now") > 0,
|
|
45
|
+
precision: field.countAnnotations("db.column.precision") > 0
|
|
46
|
+
});
|
|
47
|
+
if (typeof kind === "object") return kind;
|
|
48
|
+
return { kind: kind === "integer" ? "integer" : base === "string" ? "string" : "other" };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Why an integer fulltext member is not index-backed (its exact-number match
|
|
52
|
+
* would scan — or fail on MongoDB next to `$text`), or `undefined`. Backed:
|
|
53
|
+
* `_id`, the first `@meta.id` of the type, or the first field (in declaration
|
|
54
|
+
* order) of a `@db.index.plain` / `@db.index.unique` group.
|
|
55
|
+
*/
|
|
56
|
+
function integerMemberIndexProblem(token) {
|
|
57
|
+
const field = token.parentNode;
|
|
58
|
+
const struct = getParentStruct(token);
|
|
59
|
+
if (!struct) return void 0;
|
|
60
|
+
if (field.id === "_id") return void 0;
|
|
61
|
+
const props = [...struct.props.values()];
|
|
62
|
+
if (field.countAnnotations("meta.id") > 0 && props.find((p) => p.countAnnotations("meta.id") > 0) === field) return;
|
|
63
|
+
for (const ann of ["db.index.plain", "db.index.unique"]) for (const own of field.annotations?.filter((a) => a.name === ann) ?? []) {
|
|
64
|
+
const group = own.args[0]?.text ?? field.id;
|
|
65
|
+
if (props.find((p) => p.annotations?.some((a) => a.name === ann && (a.args[0]?.text ?? p.id) === group)) === field) return void 0;
|
|
66
|
+
}
|
|
67
|
+
return `@db.index.fulltext on the integer field "${field.id}" needs an index for its exact-number match — make it the primary key (first @meta.id) or the first field of a @db.index.plain / @db.index.unique`;
|
|
68
|
+
}
|
|
27
69
|
/** Asserts `args[0]` names a sibling property whose primitive base type is `string`. */
|
|
28
70
|
function validateSiblingStringField(token, args, doc, selfName) {
|
|
29
71
|
const errors = [];
|
|
@@ -408,4 +450,4 @@ function forEachFieldRef(expr, fn) {
|
|
|
408
450
|
}
|
|
409
451
|
}
|
|
410
452
|
//#endregion
|
|
411
|
-
export {
|
|
453
|
+
export { validateFieldBaseType as C, validateExclusiveWith as S, getParentTypeName as _, hasAnyViewAnnotation as a, refActionAnnotation as b, joinTargets as c, viewJoins as d, viewScopeTypes as f, getParentStruct as g, getNavTargetTypeName as h, forEachFieldRef as i, validateQueryScope as l, getDbTableOwner as m, findFKFieldsPointingTo as n, isAliasDecl as o, getAnnotationAlias as p, findViewCycle as r, isDbSourceDecl as s, earlierJoinTargets as t, validateRefArgument as u, integerMemberIndexProblem as v, validateSiblingStringField as w, searchFieldVerdict as x, primitiveBaseType as y };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const require_search_fields = require("./search-fields-DwrsJUC1.cjs");
|
|
2
2
|
let _atscript_core = require("@atscript/core");
|
|
3
3
|
//#region src/shared/annotation-utils.ts
|
|
4
4
|
/** Asserts the field carrying this annotation does not also carry any of `others`. */
|
|
@@ -24,6 +24,48 @@ function getPrimitiveBaseType(node, doc) {
|
|
|
24
24
|
if (!def || !(0, _atscript_core.isRef)(def)) return void 0;
|
|
25
25
|
return primitiveBaseType(doc.unwindType(def.id, def.chain)?.def);
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Whether a prop takes part in `$search` as text or as an integer, or why it
|
|
29
|
+
* cannot (compile-time mirror of the runtime `searchMemberKind`). Anything
|
|
30
|
+
* that is not a ref to a primitive (structures, arrays, unions, unresolved
|
|
31
|
+
* refs) is left alone.
|
|
32
|
+
*/
|
|
33
|
+
function searchFieldVerdict(field, doc) {
|
|
34
|
+
const def = field.getDefinition();
|
|
35
|
+
if (!def || !(0, _atscript_core.isRef)(def)) return { kind: "other" };
|
|
36
|
+
const leaf = doc.unwindType(def.id, def.chain)?.def;
|
|
37
|
+
const base = primitiveBaseType(leaf);
|
|
38
|
+
if (base === void 0) return { kind: "other" };
|
|
39
|
+
const kind = require_search_fields.searchKindOf({
|
|
40
|
+
base,
|
|
41
|
+
tags: (0, _atscript_core.isPrimitive)(leaf) ? leaf.tags : void 0,
|
|
42
|
+
expectInt: field.countAnnotations("expect.int") > 0,
|
|
43
|
+
increment: field.countAnnotations("db.default.increment") > 0,
|
|
44
|
+
now: field.countAnnotations("db.default.now") > 0,
|
|
45
|
+
precision: field.countAnnotations("db.column.precision") > 0
|
|
46
|
+
});
|
|
47
|
+
if (typeof kind === "object") return kind;
|
|
48
|
+
return { kind: kind === "integer" ? "integer" : base === "string" ? "string" : "other" };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Why an integer fulltext member is not index-backed (its exact-number match
|
|
52
|
+
* would scan — or fail on MongoDB next to `$text`), or `undefined`. Backed:
|
|
53
|
+
* `_id`, the first `@meta.id` of the type, or the first field (in declaration
|
|
54
|
+
* order) of a `@db.index.plain` / `@db.index.unique` group.
|
|
55
|
+
*/
|
|
56
|
+
function integerMemberIndexProblem(token) {
|
|
57
|
+
const field = token.parentNode;
|
|
58
|
+
const struct = getParentStruct(token);
|
|
59
|
+
if (!struct) return void 0;
|
|
60
|
+
if (field.id === "_id") return void 0;
|
|
61
|
+
const props = [...struct.props.values()];
|
|
62
|
+
if (field.countAnnotations("meta.id") > 0 && props.find((p) => p.countAnnotations("meta.id") > 0) === field) return;
|
|
63
|
+
for (const ann of ["db.index.plain", "db.index.unique"]) for (const own of field.annotations?.filter((a) => a.name === ann) ?? []) {
|
|
64
|
+
const group = own.args[0]?.text ?? field.id;
|
|
65
|
+
if (props.find((p) => p.annotations?.some((a) => a.name === ann && (a.args[0]?.text ?? p.id) === group)) === field) return void 0;
|
|
66
|
+
}
|
|
67
|
+
return `@db.index.fulltext on the integer field "${field.id}" needs an index for its exact-number match — make it the primary key (first @meta.id) or the first field of a @db.index.plain / @db.index.unique`;
|
|
68
|
+
}
|
|
27
69
|
/** Asserts `args[0]` names a sibling property whose primitive base type is `string`. */
|
|
28
70
|
function validateSiblingStringField(token, args, doc, selfName) {
|
|
29
71
|
const errors = [];
|
|
@@ -180,7 +222,7 @@ function refActionAnnotation(name) {
|
|
|
180
222
|
//#region src/shared/validation-utils.ts
|
|
181
223
|
/** Whether a declaration node is a `@db.table` or a `@db.view` (managed or external). */
|
|
182
224
|
function isDbSourceDecl(node) {
|
|
183
|
-
return
|
|
225
|
+
return require_search_fields.DB_ENTITY_ANNOTATIONS.some((name) => node.countAnnotations(name) > 0);
|
|
184
226
|
}
|
|
185
227
|
/** Whether a declaration node is a `@db.alias` type. @since 0.1.141 */
|
|
186
228
|
function isAliasDecl(node) {
|
|
@@ -468,6 +510,12 @@ Object.defineProperty(exports, "hasAnyViewAnnotation", {
|
|
|
468
510
|
return hasAnyViewAnnotation;
|
|
469
511
|
}
|
|
470
512
|
});
|
|
513
|
+
Object.defineProperty(exports, "integerMemberIndexProblem", {
|
|
514
|
+
enumerable: true,
|
|
515
|
+
get: function() {
|
|
516
|
+
return integerMemberIndexProblem;
|
|
517
|
+
}
|
|
518
|
+
});
|
|
471
519
|
Object.defineProperty(exports, "isAliasDecl", {
|
|
472
520
|
enumerable: true,
|
|
473
521
|
get: function() {
|
|
@@ -498,6 +546,12 @@ Object.defineProperty(exports, "refActionAnnotation", {
|
|
|
498
546
|
return refActionAnnotation;
|
|
499
547
|
}
|
|
500
548
|
});
|
|
549
|
+
Object.defineProperty(exports, "searchFieldVerdict", {
|
|
550
|
+
enumerable: true,
|
|
551
|
+
get: function() {
|
|
552
|
+
return searchFieldVerdict;
|
|
553
|
+
}
|
|
554
|
+
});
|
|
501
555
|
Object.defineProperty(exports, "validateExclusiveWith", {
|
|
502
556
|
enumerable: true,
|
|
503
557
|
get: function() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atscript/db",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.150",
|
|
4
4
|
"description": "Database adapter utilities for atscript.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"atscript",
|
|
@@ -71,14 +71,14 @@
|
|
|
71
71
|
"access": "public"
|
|
72
72
|
},
|
|
73
73
|
"devDependencies": {
|
|
74
|
-
"@atscript/core": "^0.1.
|
|
75
|
-
"@atscript/typescript": "^0.1.
|
|
74
|
+
"@atscript/core": "^0.1.101",
|
|
75
|
+
"@atscript/typescript": "^0.1.101",
|
|
76
76
|
"@uniqu/core": "^0.1.13",
|
|
77
|
-
"unplugin-atscript": "^0.1.
|
|
77
|
+
"unplugin-atscript": "^0.1.101"
|
|
78
78
|
},
|
|
79
79
|
"peerDependencies": {
|
|
80
|
-
"@atscript/core": "^0.1.
|
|
81
|
-
"@atscript/typescript": "^0.1.
|
|
80
|
+
"@atscript/core": "^0.1.101",
|
|
81
|
+
"@atscript/typescript": "^0.1.101",
|
|
82
82
|
"@uniqu/core": "^0.1.13"
|
|
83
83
|
},
|
|
84
84
|
"scripts": {
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
//#region src/shared/derived-rules.ts
|
|
2
|
-
/**
|
|
3
|
-
* The rules the compiler plugin and the runtime share about entities and
|
|
4
|
-
* `@db.column.derived` fields — one dependency-free list each, so a
|
|
5
|
-
* compile-time diagnostic and its runtime mirror can never disagree.
|
|
6
|
-
* @since 0.1.141
|
|
7
|
-
*/
|
|
8
|
-
/** The annotations that make a declaration a DB entity: a table, or a managed / external view. */
|
|
9
|
-
const DB_ENTITY_ANNOTATIONS = [
|
|
10
|
-
"db.table",
|
|
11
|
-
"db.view",
|
|
12
|
-
"db.view.for"
|
|
13
|
-
];
|
|
14
|
-
/** Primitive leaf types a JSON-stored path may end at (view JSON leaves, derived columns). */
|
|
15
|
-
const JSON_LEAF_TYPES = new Set([
|
|
16
|
-
"string",
|
|
17
|
-
"number",
|
|
18
|
-
"boolean"
|
|
19
|
-
]);
|
|
20
|
-
/** Whether `type` (a resolved design type) is one of {@link JSON_LEAF_TYPES}. */
|
|
21
|
-
function isJsonLeafType(type) {
|
|
22
|
-
return JSON_LEAF_TYPES.has(type);
|
|
23
|
-
}
|
|
24
|
-
/** Annotations a `@db.column.derived` field cannot carry (D8), with the reason. */
|
|
25
|
-
const DERIVED_INCOMPATIBLE = [
|
|
26
|
-
["meta.id", "a computed column cannot identify the row"],
|
|
27
|
-
["db.rel.FK", "a foreign key needs a stored, writable column"],
|
|
28
|
-
["db.default", "the value is computed, never defaulted"],
|
|
29
|
-
["db.default.increment", "the value is computed, never defaulted"],
|
|
30
|
-
["db.default.uuid", "the value is computed, never defaulted"],
|
|
31
|
-
["db.default.now", "the value is computed, never defaulted"],
|
|
32
|
-
["db.column.version", "the version column is adapter-managed"],
|
|
33
|
-
["db.encrypted", "the value is a cleartext extraction of its source"],
|
|
34
|
-
["db.json", "a derived column is a primitive leaf, not a JSON value"],
|
|
35
|
-
["db.ignore", "an ignored field has no column to derive"],
|
|
36
|
-
["db.writeOnly", "a derived column is never written"],
|
|
37
|
-
["db.index.fulltext", "fulltext indexes need a stored text column"],
|
|
38
|
-
["db.index.geo", "a geo index needs a db.geoPoint column"],
|
|
39
|
-
["db.search.vector", "a vector index needs a stored embedding column"],
|
|
40
|
-
["db.mongo.search.text", "Atlas Search indexes the stored document, which holds no derived field"],
|
|
41
|
-
["db.mongo.search.autocomplete", "Atlas Search indexes the stored document, which holds no derived field"]
|
|
42
|
-
];
|
|
43
|
-
//#endregion
|
|
44
|
-
export { isJsonLeafType as i, DERIVED_INCOMPATIBLE as n, JSON_LEAF_TYPES as r, DB_ENTITY_ANNOTATIONS as t };
|