@antelopejs/interface-database-decorators 0.1.10 → 0.1.12
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 +9 -7
- package/dist/common.js.map +1 -1
- package/dist/database.js +18 -2
- package/dist/database.js.map +1 -1
- package/dist/model.js +48 -29
- package/dist/model.js.map +1 -1
- package/dist/modifiers/common.d.ts +24 -4
- package/dist/modifiers/common.js +104 -130
- package/dist/modifiers/common.js.map +1 -1
- package/dist/modifiers/encryption.js +14 -9
- package/dist/modifiers/encryption.js.map +1 -1
- package/dist/modifiers/hash.d.ts +46 -4
- package/dist/modifiers/hash.js +172 -14
- package/dist/modifiers/hash.js.map +1 -1
- package/dist/modifiers/internal/kinds.d.ts +13 -0
- package/dist/modifiers/internal/kinds.js +33 -0
- package/dist/modifiers/internal/kinds.js.map +1 -0
- package/dist/modifiers/internal/records.d.ts +31 -0
- package/dist/modifiers/internal/records.js +56 -0
- package/dist/modifiers/internal/records.js.map +1 -0
- package/dist/modifiers/localization.js +4 -2
- package/dist/modifiers/localization.js.map +1 -1
- package/dist/schema.js +1 -2
- package/dist/schema.js.map +1 -1
- package/dist/table.js +21 -6
- package/dist/table.js.map +1 -1
- package/dist/tests/codec_helpers.d.ts +6 -2
- package/dist/tests/codec_helpers.js +18 -14
- package/dist/tests/codec_helpers.js.map +1 -1
- package/dist/tests/common.test.js +38 -46
- package/dist/tests/common.test.js.map +1 -1
- package/dist/tests/cross_instance.test.js +27 -2
- package/dist/tests/cross_instance.test.js.map +1 -1
- package/dist/tests/database.test.js +278 -256
- package/dist/tests/database.test.js.map +1 -1
- package/dist/tests/hash_upgrade.test.d.ts +1 -0
- package/dist/tests/hash_upgrade.test.js +132 -0
- package/dist/tests/hash_upgrade.test.js.map +1 -0
- package/dist/tests/helpers/hash-rows.d.ts +40 -0
- package/dist/tests/helpers/hash-rows.js +41 -0
- package/dist/tests/helpers/hash-rows.js.map +1 -0
- package/dist/tests/helpers/other-instance.d.ts +1 -1
- package/dist/tests/helpers/other-instance.js +41 -9
- package/dist/tests/helpers/other-instance.js.map +1 -1
- package/dist/tests/integration.test.js +485 -485
- package/dist/tests/integration.test.js.map +1 -1
- package/dist/tests/model.test.js +293 -308
- package/dist/tests/model.test.js.map +1 -1
- package/dist/tests/modifiers/autodate.test.js +80 -86
- package/dist/tests/modifiers/autodate.test.js.map +1 -1
- package/dist/tests/modifiers/common.test.js +181 -195
- package/dist/tests/modifiers/common.test.js.map +1 -1
- package/dist/tests/modifiers/encryption.test.js +149 -155
- package/dist/tests/modifiers/encryption.test.js.map +1 -1
- package/dist/tests/modifiers/hash.test.js +386 -99
- package/dist/tests/modifiers/hash.test.js.map +1 -1
- package/dist/tests/modifiers/localization.test.js +186 -196
- package/dist/tests/modifiers/localization.test.js.map +1 -1
- package/dist/tests/partial_update.test.d.ts +1 -0
- package/dist/tests/partial_update.test.js +55 -0
- package/dist/tests/partial_update.test.js.map +1 -0
- package/dist/tests/relation.test.js +92 -97
- package/dist/tests/relation.test.js.map +1 -1
- package/dist/tests/schema.test.js +101 -106
- package/dist/tests/schema.test.js.map +1 -1
- package/dist/tests/table.test.js +124 -132
- package/dist/tests/table.test.js.map +1 -1
- package/docs/3.table-modifiers.md +36 -15
- package/package.json +14 -3
- package/skills/database-decorators-interface/SKILL.md +4 -2
- package/skills/database-decorators-interface/cases.json +71 -0
package/dist/modifiers/hash.js
CHANGED
|
@@ -4,31 +4,166 @@ exports.Hashed = exports.HashModifier = void 0;
|
|
|
4
4
|
const randomstring_1 = require("randomstring");
|
|
5
5
|
const node_crypto_1 = require("node:crypto");
|
|
6
6
|
const decorators_1 = require("@antelopejs/interface-core/decorators");
|
|
7
|
-
const common_1 = require("
|
|
7
|
+
const common_1 = require("../common");
|
|
8
|
+
const common_2 = require("./common");
|
|
9
|
+
const records_1 = require("./internal/records");
|
|
10
|
+
const SCRYPT_COST = { ln: 15, r: 8, p: 3 };
|
|
11
|
+
const SALT_BYTES = 16;
|
|
12
|
+
const KEY_BYTES = 32;
|
|
13
|
+
const DECOY_SALT = Buffer.alloc(SALT_BYTES);
|
|
14
|
+
const LEGACY_DIGEST = "sha256";
|
|
15
|
+
/** Most scrypt memory (128 * N * r bytes) a stored hash may ask for. */
|
|
16
|
+
const STORED_MAX_MEMORY = 128 * 1024 * 1024;
|
|
17
|
+
const STORED_MAX_P = 16;
|
|
18
|
+
const CURRENT_PREFIX = `$scrypt$ln=${SCRYPT_COST.ln},r=${SCRYPT_COST.r},p=${SCRYPT_COST.p}$`;
|
|
19
|
+
/** Salt and key take 22 to 86 characters, so 16 to 64 bytes. */
|
|
20
|
+
const STORED_SCRYPT = /^\$scrypt\$ln=([1-9]\d?),r=([1-9]\d?),p=([1-9]\d?)\$([A-Za-z0-9+/]{22,86})\$([A-Za-z0-9+/]{22,86})$/;
|
|
21
|
+
function unpaddedBase64(bytes) {
|
|
22
|
+
return bytes.toString("base64").replace(/=+$/, "");
|
|
23
|
+
}
|
|
24
|
+
function scryptArgs(password, salt, keylen, { ln, r, p }) {
|
|
25
|
+
return [
|
|
26
|
+
password,
|
|
27
|
+
salt,
|
|
28
|
+
keylen,
|
|
29
|
+
{ N: 2 ** ln, r, p, maxmem: 2 * STORED_MAX_MEMORY },
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
function scryptAsync(...[password, salt, keylen, options]) {
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
(0, node_crypto_1.scrypt)(password, salt, keylen, options, (error, key) => {
|
|
35
|
+
if (error)
|
|
36
|
+
reject(error);
|
|
37
|
+
else
|
|
38
|
+
resolve(key);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function parseScrypt(stored) {
|
|
43
|
+
const match = STORED_SCRYPT.exec(stored);
|
|
44
|
+
if (!match)
|
|
45
|
+
return undefined;
|
|
46
|
+
const cost = {
|
|
47
|
+
ln: Number(match[1]),
|
|
48
|
+
r: Number(match[2]),
|
|
49
|
+
p: Number(match[3]),
|
|
50
|
+
};
|
|
51
|
+
if (128 * cost.r * 2 ** cost.ln > STORED_MAX_MEMORY ||
|
|
52
|
+
cost.p > STORED_MAX_P ||
|
|
53
|
+
cost.ln >= 16 * cost.r) {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
cost,
|
|
58
|
+
salt: Buffer.from(match[4], "base64"),
|
|
59
|
+
key: Buffer.from(match[5], "base64"),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function digestOf(algorithm, salt, candidate) {
|
|
63
|
+
return (0, node_crypto_1.createHash)(algorithm).update(salt).update(candidate).digest("base64");
|
|
64
|
+
}
|
|
65
|
+
function digestMatches(stored, salt, algorithm, candidate) {
|
|
66
|
+
if (!salt || candidate === undefined)
|
|
67
|
+
return false;
|
|
68
|
+
const expected = Buffer.from(stored);
|
|
69
|
+
const actual = Buffer.from(digestOf(algorithm, salt, candidate));
|
|
70
|
+
return expected.length === actual.length && (0, node_crypto_1.timingSafeEqual)(expected, actual);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Plans the test of a candidate from what the row holds. A field that uses
|
|
74
|
+
* scrypt spends one scrypt run in every case, so the time of a refusal does not
|
|
75
|
+
* tell a missing or an older hash from a current one.
|
|
76
|
+
*/
|
|
77
|
+
function planCheck(row, algorithm, candidate) {
|
|
78
|
+
const hash = parseScrypt(row.stored);
|
|
79
|
+
if (hash && candidate !== undefined) {
|
|
80
|
+
return {
|
|
81
|
+
run: scryptArgs(candidate, hash.salt, hash.key.length, hash.cost),
|
|
82
|
+
verdict: (derived) => derived !== undefined && (0, node_crypto_1.timingSafeEqual)(derived, hash.key),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const matches = digestMatches(row.stored, row.salt, algorithm ?? LEGACY_DIGEST, candidate);
|
|
86
|
+
return {
|
|
87
|
+
run: algorithm
|
|
88
|
+
? undefined
|
|
89
|
+
: scryptArgs(candidate ?? "", DECOY_SALT, KEY_BYTES, SCRYPT_COST),
|
|
90
|
+
verdict: () => matches,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/** A row stores a string or nothing. Anything else cannot match a candidate. */
|
|
94
|
+
function storedText(stored) {
|
|
95
|
+
return String(stored ?? "");
|
|
96
|
+
}
|
|
97
|
+
function withHashedField(row, field, use) {
|
|
98
|
+
const metaTable = (0, common_1.getMetadata)(row.constructor, common_2.ModifiersStaticMetadata);
|
|
99
|
+
const entry = (0, records_1.fieldsByKey)(metaTable)[field]?.find(({ modifier }) => modifier instanceof HashModifier);
|
|
100
|
+
if (!entry || !(entry.modifier instanceof HashModifier)) {
|
|
101
|
+
throw new Error(`Field ${String(field)} is not hashed`);
|
|
102
|
+
}
|
|
103
|
+
const internal = (0, records_1.getInternal)(row);
|
|
104
|
+
return (0, records_1.withRef)(internal, entry.id, entry.modifier, entry.metaRef, (modifier) => use(modifier, storedText((0, records_1.dataByKey)(internal)[field])));
|
|
105
|
+
}
|
|
8
106
|
/**
|
|
9
107
|
* Hash modifier. enables the use of {@link Hashed} on table fields.
|
|
10
108
|
*
|
|
11
|
-
* Hashed fields only contain a hash of the inserted value
|
|
109
|
+
* Hashed fields only contain a hash of the inserted value, by default a scrypt
|
|
110
|
+
* hash in the self-describing form `$scrypt$ln=15,r=8,p=3$<salt>$<key>`.
|
|
12
111
|
* Because of this, you lose the ability to query the information directly.
|
|
13
112
|
* You can test equality using {@link testHash}
|
|
14
113
|
*/
|
|
15
|
-
class HashModifier extends
|
|
114
|
+
class HashModifier extends common_2.OneWayModifier {
|
|
16
115
|
autolock = true;
|
|
17
|
-
|
|
116
|
+
/**
|
|
117
|
+
* Hashes a new value. Assigning the stored hash back keeps it as it is.
|
|
118
|
+
* Blocks the event loop for one scrypt run: a setter and the conversions
|
|
119
|
+
* behind `insert` and `update` are synchronous.
|
|
120
|
+
*/
|
|
121
|
+
lock(locked_value, value) {
|
|
18
122
|
if (value === undefined) {
|
|
19
123
|
return value;
|
|
20
124
|
}
|
|
21
|
-
if (
|
|
22
|
-
|
|
125
|
+
if (value === locked_value) {
|
|
126
|
+
return locked_value;
|
|
127
|
+
}
|
|
128
|
+
const candidate = JSON.stringify(value);
|
|
129
|
+
const { algorithm } = this.options;
|
|
130
|
+
if (algorithm) {
|
|
131
|
+
if (!this.meta.salt) {
|
|
132
|
+
this.meta.salt = (0, randomstring_1.generate)();
|
|
133
|
+
}
|
|
134
|
+
return digestOf(algorithm, this.meta.salt, candidate);
|
|
23
135
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
.digest("base64");
|
|
136
|
+
const salt = (0, node_crypto_1.randomBytes)(SALT_BYTES);
|
|
137
|
+
const key = (0, node_crypto_1.scryptSync)(...scryptArgs(candidate, salt, KEY_BYTES, SCRYPT_COST));
|
|
138
|
+
return `${CURRENT_PREFIX}${unpaddedBase64(salt)}$${unpaddedBase64(key)}`;
|
|
28
139
|
}
|
|
29
|
-
|
|
140
|
+
test(locked_value, value) {
|
|
141
|
+
const check = this.plan(storedText(locked_value), value);
|
|
142
|
+
return check.verdict(check.run && (0, node_crypto_1.scryptSync)(...check.run));
|
|
143
|
+
}
|
|
144
|
+
/** {@link test} on the thread pool, without blocking the event loop. */
|
|
145
|
+
async testAsync(locked_value, value) {
|
|
146
|
+
const check = this.plan(locked_value, value);
|
|
147
|
+
return check.verdict(check.run && (await scryptAsync(...check.run)));
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* @returns Whether a stored hash differs from what this field writes today. A
|
|
151
|
+
* field with an explicit `algorithm` never reports one: hashing again would
|
|
152
|
+
* give the same digest, or weaken a scrypt hash.
|
|
153
|
+
*/
|
|
154
|
+
isOutdated(locked_value) {
|
|
155
|
+
return (!this.options.algorithm &&
|
|
156
|
+
locked_value !== "" &&
|
|
157
|
+
!locked_value.startsWith(CURRENT_PREFIX));
|
|
158
|
+
}
|
|
159
|
+
/** Reads the salt now: `this.meta` is bound to a row only synchronously. */
|
|
160
|
+
plan(locked_value, value) {
|
|
161
|
+
return planCheck({ stored: locked_value, salt: this.meta.salt }, this.options.algorithm, value === undefined ? undefined : JSON.stringify(value));
|
|
162
|
+
}
|
|
163
|
+
[common_2.MixinSymbol] = class {
|
|
30
164
|
/**
|
|
31
|
-
* Test a value against the stored hash.
|
|
165
|
+
* Test a value against the stored hash. Blocks the event loop for one
|
|
166
|
+
* scrypt run: on a server, prefer {@link testHashAsync}.
|
|
32
167
|
*
|
|
33
168
|
* @param field - Name of the field to test against.
|
|
34
169
|
* @param value - Value to hash and test.
|
|
@@ -36,7 +171,30 @@ class HashModifier extends common_1.OneWayModifier {
|
|
|
36
171
|
* @returns Whether the new value is identical to the original or not.
|
|
37
172
|
*/
|
|
38
173
|
testHash(field, value) {
|
|
39
|
-
return (0,
|
|
174
|
+
return (0, common_2.testValue)(this, field, value);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Test a value against the stored hash on the thread pool.
|
|
178
|
+
*
|
|
179
|
+
* @param field - Name of the field to test against.
|
|
180
|
+
* @param value - Value to hash and test.
|
|
181
|
+
*
|
|
182
|
+
* @returns Whether the new value is identical to the original or not.
|
|
183
|
+
*/
|
|
184
|
+
async testHashAsync(field, value) {
|
|
185
|
+
return withHashedField(this, field, (modifier, stored) => modifier.testAsync(stored, value));
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Tell whether a stored hash needs writing again: it uses an older format
|
|
189
|
+
* or cost. After a successful test, assign the tested value to the field
|
|
190
|
+
* and save the row.
|
|
191
|
+
*
|
|
192
|
+
* @param field - Name of the field to inspect.
|
|
193
|
+
*
|
|
194
|
+
* @returns Whether the stored hash is outdated. False when nothing is stored.
|
|
195
|
+
*/
|
|
196
|
+
isHashOutdated(field) {
|
|
197
|
+
return withHashedField(this, field, (modifier, stored) => modifier.isOutdated(stored));
|
|
40
198
|
}
|
|
41
199
|
};
|
|
42
200
|
}
|
|
@@ -49,6 +207,6 @@ exports.HashModifier = HashModifier;
|
|
|
49
207
|
* @param options Hash options.
|
|
50
208
|
*/
|
|
51
209
|
exports.Hashed = (0, decorators_1.MakePropertyDecorator)((target, propertyKey, options) => {
|
|
52
|
-
(0,
|
|
210
|
+
(0, common_2.attachModifier)(target.constructor, HashModifier, propertyKey, options || {});
|
|
53
211
|
});
|
|
54
212
|
//# sourceMappingURL=hash.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/modifiers/hash.ts"],"names":[],"mappings":";;;AAAA,+CAAwC;AACxC,
|
|
1
|
+
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/modifiers/hash.ts"],"names":[],"mappings":";;;AAAA,+CAAwC;AACxC,6CAOqB;AACrB,sEAA8E;AAE9E,sCAAwC;AACxC,qCAMkB;AAClB,gDAK4B;AA4B5B,MAAM,WAAW,GAAe,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AACvD,MAAM,UAAU,GAAG,EAAE,CAAC;AACtB,MAAM,SAAS,GAAG,EAAE,CAAC;AACrB,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;AAC5C,MAAM,aAAa,GAAG,QAAQ,CAAC;AAE/B,wEAAwE;AACxE,MAAM,iBAAiB,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AAC5C,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,MAAM,cAAc,GAAG,cAAc,WAAW,CAAC,EAAE,MAAM,WAAW,CAAC,CAAC,MAAM,WAAW,CAAC,CAAC,GAAG,CAAC;AAE7F,gEAAgE;AAChE,MAAM,aAAa,GACjB,qGAAqG,CAAC;AAExG,SAAS,cAAc,CAAC,KAAa;IACnC,OAAO,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,SAAS,UAAU,CACjB,QAAgB,EAChB,IAAY,EACZ,MAAc,EACd,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAc;IAExB,OAAO;QACL,QAAQ;QACR,IAAI;QACJ,MAAM;QACN,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,iBAAiB,EAAE;KACpD,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAa;IACnE,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC7C,IAAA,oBAAM,EAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACrD,IAAI,KAAK;gBAAE,MAAM,CAAC,KAAK,CAAC,CAAC;;gBACpB,OAAO,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAC,MAAc;IACjC,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,MAAM,IAAI,GAAG;QACX,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACnB,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KACpB,CAAC;IACF,IACE,GAAG,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,EAAE,GAAG,iBAAiB;QAC/C,IAAI,CAAC,CAAC,GAAG,YAAY;QACrB,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC,EACtB,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC;QACrC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC;KACrC,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,SAAiB,EAAE,IAAY,EAAE,SAAiB;IAClE,OAAO,IAAA,wBAAU,EAAC,SAAS,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC/E,CAAC;AAED,SAAS,aAAa,CACpB,MAAc,EACd,IAAwB,EACxB,SAAiB,EACjB,SAA6B;IAE7B,IAAI,CAAC,IAAI,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;IACjE,OAAO,QAAQ,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,IAAI,IAAA,6BAAe,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAChF,CAAC;AAED;;;;GAIG;AACH,SAAS,SAAS,CAChB,GAAiD,EACjD,SAA6B,EAC7B,SAA6B;IAE7B,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,IAAI,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QACpC,OAAO;YACL,GAAG,EAAE,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC;YACjE,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CACnB,OAAO,KAAK,SAAS,IAAI,IAAA,6BAAe,EAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC;SAC9D,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,aAAa,CAC3B,GAAG,CAAC,MAAM,EACV,GAAG,CAAC,IAAI,EACR,SAAS,IAAI,aAAa,EAC1B,SAAS,CACV,CAAC;IACF,OAAO;QACL,GAAG,EAAE,SAAS;YACZ,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,UAAU,CAAC,SAAS,IAAI,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,CAAC;QACnE,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO;KACvB,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,SAAS,UAAU,CAAC,MAA0B;IAC5C,OAAO,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,eAAe,CACtB,GAAyB,EACzB,KAAkB,EAClB,GAAkD;IAElD,MAAM,SAAS,GAAG,IAAA,oBAAW,EAAC,GAAG,CAAC,WAAW,EAAE,gCAAuB,CAAC,CAAC;IACxE,MAAM,KAAK,GAAG,IAAA,qBAAW,EAAC,SAAS,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,CAC/C,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,QAAQ,YAAY,YAAY,CACnD,CAAC;IACF,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,QAAQ,YAAY,YAAY,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAC1D,CAAC;IACD,MAAM,QAAQ,GAAG,IAAA,qBAAW,EAAC,GAAG,CAAC,CAAC;IAClC,OAAO,IAAA,iBAAO,EACZ,QAAQ,EACR,KAAK,CAAC,EAAE,EACR,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,OAAO,EACb,CAAC,QAAQ,EAAE,EAAE,CACX,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAA,mBAAS,EAAqB,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAC5E,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAa,YAAa,SAAQ,uBAKjC;IACiB,QAAQ,GAAG,IAAI,CAAC;IAEhC;;;;OAIG;IACa,IAAI,CAAC,YAAgC,EAAE,KAAc;QACnE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,KAAK,KAAK,YAAY,EAAE,CAAC;YAC3B,OAAO,YAAY,CAAC;QACtB,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QACnC,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACpB,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAA,uBAAQ,GAAE,CAAC;YAC9B,CAAC;YACD,OAAO,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACxD,CAAC;QACD,MAAM,IAAI,GAAG,IAAA,yBAAW,EAAC,UAAU,CAAC,CAAC;QACrC,MAAM,GAAG,GAAG,IAAA,wBAAU,EACpB,GAAG,UAAU,CAAC,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,CAAC,CACvD,CAAC;QACF,OAAO,GAAG,cAAc,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;IAC3E,CAAC;IAEe,IAAI,CAAC,YAAgC,EAAE,KAAgB;QACrE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,KAAK,CAAC,CAAC;QACzD,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,IAAA,wBAAU,EAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,wEAAwE;IACjE,KAAK,CAAC,SAAS,CAAC,YAAoB,EAAE,KAAgB;QAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QAC7C,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,WAAW,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC;IAED;;;;OAIG;IACI,UAAU,CAAC,YAAoB;QACpC,OAAO,CACL,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS;YACvB,YAAY,KAAK,EAAE;YACnB,CAAC,YAAY,CAAC,UAAU,CAAC,cAAc,CAAC,CACzC,CAAC;IACJ,CAAC;IAED,4EAA4E;IACpE,IAAI,CAAC,YAAoB,EAAE,KAAgB;QACjD,OAAO,SAAS,CACd,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAC9C,IAAI,CAAC,OAAO,CAAC,SAAS,EACtB,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CACxD,CAAC;IACJ,CAAC;IAED,CAAC,oBAAW,CAAC,GAAG;QACd;;;;;;;;WAQG;QACH,QAAQ,CAEN,KAAQ,EACR,KAAc;YAEd,OAAO,IAAA,kBAAS,EAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QACvC,CAAC;QAED;;;;;;;WAOG;QACH,KAAK,CAAC,aAAa,CAEjB,KAAQ,EACR,KAAc;YAEd,OAAO,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CACvD,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAClC,CAAC;QACJ,CAAC;QAED;;;;;;;;WAQG;QACH,cAAc,CAA8B,KAAiB;YAC3D,OAAO,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CACvD,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAC5B,CAAC;QACJ,CAAC;KACF,CAAC;CACH;AAvHD,oCAuHC;AAED;;;;;;GAMG;AACU,QAAA,MAAM,GAAG,IAAA,kCAAqB,EACzC,CAAC,MAAM,EAAE,WAAW,EAAE,OAAiB,EAAE,EAAE;IACzC,IAAA,uBAAc,EACZ,MAAM,CAAC,WAAW,EAClB,YAAY,EACZ,WAAW,EACX,OAAO,IAAI,EAAE,CACd,CAAC;AACJ,CAAC,CACF,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** @internal @packageDocumentation */
|
|
2
|
+
import type { Modifier, OneWayModifier, TwoWayModifier } from "../common";
|
|
3
|
+
export declare function isWriteOnly(m: Modifier): m is OneWayModifier<unknown, any[]>;
|
|
4
|
+
export declare function isLocking(m: Modifier): m is OneWayModifier<unknown, any[]>;
|
|
5
|
+
export declare function isTwoWay(m: Modifier): m is TwoWayModifier<unknown, any[]>;
|
|
6
|
+
export declare function isOnlyEvents(modifier: Modifier): boolean;
|
|
7
|
+
export declare const ignoredEventNames: {
|
|
8
|
+
constructor: boolean;
|
|
9
|
+
lock: boolean;
|
|
10
|
+
unlock: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare function isCallable(value: unknown): value is CallableFunction;
|
|
13
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ignoredEventNames = void 0;
|
|
4
|
+
exports.isWriteOnly = isWriteOnly;
|
|
5
|
+
exports.isLocking = isLocking;
|
|
6
|
+
exports.isTwoWay = isTwoWay;
|
|
7
|
+
exports.isOnlyEvents = isOnlyEvents;
|
|
8
|
+
exports.isCallable = isCallable;
|
|
9
|
+
exports.isRecord = isRecord;
|
|
10
|
+
function isWriteOnly(m) {
|
|
11
|
+
return "lock" in m && !("unlock" in m);
|
|
12
|
+
}
|
|
13
|
+
function isLocking(m) {
|
|
14
|
+
return "lock" in m;
|
|
15
|
+
}
|
|
16
|
+
function isTwoWay(m) {
|
|
17
|
+
return "unlock" in m;
|
|
18
|
+
}
|
|
19
|
+
function isOnlyEvents(modifier) {
|
|
20
|
+
return !("lock" in modifier);
|
|
21
|
+
}
|
|
22
|
+
exports.ignoredEventNames = {
|
|
23
|
+
constructor: true,
|
|
24
|
+
lock: true,
|
|
25
|
+
unlock: true,
|
|
26
|
+
};
|
|
27
|
+
function isCallable(value) {
|
|
28
|
+
return typeof value === "function";
|
|
29
|
+
}
|
|
30
|
+
function isRecord(value) {
|
|
31
|
+
return typeof value === "object" && value !== null;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=kinds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kinds.js","sourceRoot":"","sources":["../../../src/modifiers/internal/kinds.ts"],"names":[],"mappings":";;;AAGA,kCAEC;AAED,8BAEC;AAED,4BAEC;AAED,oCAEC;AAQD,gCAEC;AAED,4BAEC;AA5BD,SAAgB,WAAW,CAAC,CAAW;IACrC,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,SAAgB,SAAS,CAAC,CAAW;IACnC,OAAO,MAAM,IAAI,CAAC,CAAC;AACrB,CAAC;AAED,SAAgB,QAAQ,CAAC,CAAW;IAClC,OAAO,QAAQ,IAAI,CAAC,CAAC;AACvB,CAAC;AAED,SAAgB,YAAY,CAAC,QAAkB;IAC7C,OAAO,CAAC,CAAC,MAAM,IAAI,QAAQ,CAAC,CAAC;AAC/B,CAAC;AAEY,QAAA,iBAAiB,GAAG;IAC/B,WAAW,EAAE,IAAI;IACjB,IAAI,EAAE,IAAI;IACV,MAAM,EAAE,IAAI;CACb,CAAC;AAEF,SAAgB,UAAU,CAAC,KAAc;IACvC,OAAO,OAAO,KAAK,KAAK,UAAU,CAAC;AACrC,CAAC;AAED,SAAgB,QAAQ,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** @internal @packageDocumentation */
|
|
2
|
+
import type { DatumStaticMetadata } from "../../common";
|
|
3
|
+
import type { Modifier, ModifiersDynamicMetadata, ModifiersStaticMetadata } from "../common";
|
|
4
|
+
type ModifiedFieldList = ModifiersStaticMetadata["fields"][string];
|
|
5
|
+
type ModifiedField = ModifiedFieldList[number];
|
|
6
|
+
export type InternalRecord = Parameters<ModifiersDynamicMetadata["get"]>[1];
|
|
7
|
+
export declare function fieldsByKey(meta: ModifiersStaticMetadata): {
|
|
8
|
+
[field: PropertyKey]: ModifiedFieldList;
|
|
9
|
+
};
|
|
10
|
+
export declare function eventsByKey(meta: ModifiersStaticMetadata): Map<string, Array<[field: PropertyKey, modified: ModifiedFieldList[number]]>>;
|
|
11
|
+
export declare function unlockArgsOf(meta: ModifiersDynamicMetadata, field: PropertyKey): ModifiersDynamicMetadata["fields"][string];
|
|
12
|
+
export declare function fieldTypesByKey(meta: DatumStaticMetadata): {
|
|
13
|
+
[field: PropertyKey]: DatumStaticMetadata["fields"][string];
|
|
14
|
+
};
|
|
15
|
+
export declare function floatingOf<V>(meta: {
|
|
16
|
+
floating: Record<string, V>;
|
|
17
|
+
}, field: PropertyKey): V;
|
|
18
|
+
export declare function floatingByKey<V>(meta: {
|
|
19
|
+
floating: Record<string, V>;
|
|
20
|
+
}): {
|
|
21
|
+
[field: PropertyKey]: V;
|
|
22
|
+
};
|
|
23
|
+
export declare function dataByKey<V>(internal: {
|
|
24
|
+
data: Record<string, V>;
|
|
25
|
+
}): {
|
|
26
|
+
[field: PropertyKey]: V;
|
|
27
|
+
};
|
|
28
|
+
export declare function getInternal(object: any): InternalRecord;
|
|
29
|
+
export declare function isEmptyInternal({ meta, data }: InternalRecord): boolean;
|
|
30
|
+
export declare function withRef<T extends Modifier, U>(internal: InternalRecord, id: ModifiedField["id"], modifier: T, metaRef: ModifiedField["metaRef"], callback: (modifier: T) => U): U;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fieldsByKey = fieldsByKey;
|
|
4
|
+
exports.eventsByKey = eventsByKey;
|
|
5
|
+
exports.unlockArgsOf = unlockArgsOf;
|
|
6
|
+
exports.fieldTypesByKey = fieldTypesByKey;
|
|
7
|
+
exports.floatingOf = floatingOf;
|
|
8
|
+
exports.floatingByKey = floatingByKey;
|
|
9
|
+
exports.dataByKey = dataByKey;
|
|
10
|
+
exports.getInternal = getInternal;
|
|
11
|
+
exports.isEmptyInternal = isEmptyInternal;
|
|
12
|
+
exports.withRef = withRef;
|
|
13
|
+
function fieldsByKey(meta) {
|
|
14
|
+
return meta.fields;
|
|
15
|
+
}
|
|
16
|
+
function eventsByKey(meta) {
|
|
17
|
+
return meta.events;
|
|
18
|
+
}
|
|
19
|
+
function unlockArgsOf(meta, field) {
|
|
20
|
+
const byKey = meta.fields;
|
|
21
|
+
return byKey[field];
|
|
22
|
+
}
|
|
23
|
+
function fieldTypesByKey(meta) {
|
|
24
|
+
return meta.fields;
|
|
25
|
+
}
|
|
26
|
+
function floatingOf(meta, field) {
|
|
27
|
+
const byKey = meta.floating;
|
|
28
|
+
return byKey[field];
|
|
29
|
+
}
|
|
30
|
+
function floatingByKey(meta) {
|
|
31
|
+
return meta.floating;
|
|
32
|
+
}
|
|
33
|
+
function dataByKey(internal) {
|
|
34
|
+
return internal.data;
|
|
35
|
+
}
|
|
36
|
+
function getInternal(object) {
|
|
37
|
+
if (!object._internal) {
|
|
38
|
+
object._internal = {
|
|
39
|
+
meta: {},
|
|
40
|
+
data: {},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return object._internal;
|
|
44
|
+
}
|
|
45
|
+
function isEmptyInternal({ meta, data }) {
|
|
46
|
+
return Object.keys(meta).length === 0 && Object.keys(data).length === 0;
|
|
47
|
+
}
|
|
48
|
+
function withRef(internal, id, modifier, metaRef, callback) {
|
|
49
|
+
metaRef._ref = internal.meta[id];
|
|
50
|
+
const ret = callback(modifier);
|
|
51
|
+
if (metaRef._ref !== internal.meta[id]) {
|
|
52
|
+
internal.meta[id] = metaRef._ref;
|
|
53
|
+
}
|
|
54
|
+
return ret;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=records.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"records.js","sourceRoot":"","sources":["../../../src/modifiers/internal/records.ts"],"names":[],"mappings":";;AAYA,kCAIC;AAED,kCAOC;AAED,oCAQC;AAED,0CAIC;AAED,gCAMC;AAED,sCAIC;AAED,8BAIC;AAED,kCAQC;AAED,0CAEC;AAED,0BAaC;AA9ED,SAAgB,WAAW,CAAC,IAA6B;IAGvD,OAAO,IAAI,CAAC,MAAM,CAAC;AACrB,CAAC;AAED,SAAgB,WAAW,CACzB,IAA6B;IAK7B,OAAO,IAAI,CAAC,MAAM,CAAC;AACrB,CAAC;AAED,SAAgB,YAAY,CAC1B,IAA8B,EAC9B,KAAkB;IAElB,MAAM,KAAK,GAEP,IAAI,CAAC,MAAM,CAAC;IAChB,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC;AACtB,CAAC;AAED,SAAgB,eAAe,CAAC,IAAyB;IAGvD,OAAO,IAAI,CAAC,MAAM,CAAC;AACrB,CAAC;AAED,SAAgB,UAAU,CACxB,IAAqC,EACrC,KAAkB;IAElB,MAAM,KAAK,GAAgC,IAAI,CAAC,QAAQ,CAAC;IACzD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC;AACtB,CAAC;AAED,SAAgB,aAAa,CAAI,IAAqC;IAGpE,OAAO,IAAI,CAAC,QAAQ,CAAC;AACvB,CAAC;AAED,SAAgB,SAAS,CAAI,QAAqC;IAGhE,OAAO,QAAQ,CAAC,IAAI,CAAC;AACvB,CAAC;AAED,SAAgB,WAAW,CAAC,MAAW;IACrC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACtB,MAAM,CAAC,SAAS,GAAG;YACjB,IAAI,EAAE,EAAE;YACR,IAAI,EAAE,EAAE;SACT,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,SAAS,CAAC;AAC1B,CAAC;AAED,SAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,IAAI,EAAkB;IAC5D,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;AAC1E,CAAC;AAED,SAAgB,OAAO,CACrB,QAAwB,EACxB,EAAuB,EACvB,QAAW,EACX,OAAiC,EACjC,QAA4B;IAE5B,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjC,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC/B,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;QACvC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IACnC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -4,6 +4,7 @@ exports.Localized = exports.LocalizationModifier = void 0;
|
|
|
4
4
|
const decorators_1 = require("@antelopejs/interface-core/decorators");
|
|
5
5
|
const common_1 = require("../common");
|
|
6
6
|
const common_2 = require("./common");
|
|
7
|
+
const kinds_1 = require("./internal/kinds");
|
|
7
8
|
/** A text left empty in one language counts as no text in that language. */
|
|
8
9
|
const EMPTY_TEXT = "";
|
|
9
10
|
function withoutEmptyTexts(values) {
|
|
@@ -29,6 +30,7 @@ class LocalizationModifier extends common_2.ContainerModifier {
|
|
|
29
30
|
*/
|
|
30
31
|
static fallbackLocaleOf(TableClass, field) {
|
|
31
32
|
const modified = (0, common_1.getMetadata)(TableClass, common_2.ModifiersStaticMetadata).fields[field]?.find(({ id }) => id === LocalizationModifier.name);
|
|
33
|
+
// SAFETY: attachModifier stores id = Modifier.name together with `new Modifier()`, so the entry found by id === LocalizationModifier.name holds an instance of the class of that name, as in every id lookup of the modifier machinery (unlock, lock, getModifiedFields).
|
|
32
34
|
return modified?.modifier?.options
|
|
33
35
|
.fallbackLocale;
|
|
34
36
|
}
|
|
@@ -38,9 +40,9 @@ class LocalizationModifier extends common_2.ContainerModifier {
|
|
|
38
40
|
*/
|
|
39
41
|
lock(locked_value, value, key) {
|
|
40
42
|
if (key === "*") {
|
|
41
|
-
return
|
|
43
|
+
return (0, kinds_1.isRecord)(value)
|
|
42
44
|
? withoutEmptyTexts(value)
|
|
43
|
-
: value;
|
|
45
|
+
: super.lock(locked_value, value, key);
|
|
44
46
|
}
|
|
45
47
|
return withoutEmptyTexts(super.lock(locked_value, value, key));
|
|
46
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localization.js","sourceRoot":"","sources":["../../src/modifiers/localization.ts"],"names":[],"mappings":";;;AACA,sEAA8E;AAE9E,sCAA4D;AAC5D,qCAMkB;
|
|
1
|
+
{"version":3,"file":"localization.js","sourceRoot":"","sources":["../../src/modifiers/localization.ts"],"names":[],"mappings":";;;AACA,sEAA8E;AAE9E,sCAA4D;AAC5D,qCAMkB;AAClB,4CAA4C;AAU5C,4EAA4E;AAC5E,MAAM,UAAU,GAAG,EAAE,CAAC;AAEtB,SAAS,iBAAiB,CAAI,MAAyB;IACrD,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,UAAU,CAAC,CACnE,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAa,oBAAqB,SAAQ,0BAGzC;IACC;;;;;;;OAOG;IACI,MAAM,CAAC,gBAAgB,CAC5B,UAAyB,EACzB,KAAa;QAEb,MAAM,QAAQ,GAAG,IAAA,oBAAW,EAAC,UAAU,EAAE,gCAAuB,CAAC,CAAC,MAAM,CACtE,KAAK,CACN,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,oBAAoB,CAAC,IAAI,CAAC,CAAC;QACtD,0QAA0Q;QAC1Q,OAAQ,QAAQ,EAAE,QAA6C,EAAE,OAAO;aACrE,cAAc,CAAC;IACpB,CAAC;IAED;;;OAGG;IACa,IAAI,CAClB,YAAiD,EACjD,KAAc,EACd,GAAW;QAEX,IAAI,GAAG,KAAK,GAAG,EAAE,CAAC;YAChB,OAAO,IAAA,gBAAQ,EAAC,KAAK,CAAC;gBACpB,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC;gBAC1B,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;IACjE,CAAC;IAEe,MAAM,CAAC,YAAqC,EAAE,GAAW;QACvE,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QACjD,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;YACtD,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;YAChC,OAAO,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAEe,aAAa,CAC3B,IAAqD,EACrD,KAAoD,EACpD,GAA0C;QAE1C,IAAI,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC;IAED,CAAC,oBAAW,CAAC,GAAG;QACd;;;;;;;WAOG;QACH,QAAQ,CAEN,MAAc,EACd,MAA0B;YAE1B,IAAA,eAAM,EAAC,IAAI,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YACnD,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;CACH;AAhFD,oDAgFC;AAED;;;;;;GAMG;AACU,QAAA,SAAS,GAAG,IAAA,kCAAqB,EAC5C,CAAC,MAAM,EAAE,WAAW,EAAE,OAAiB,EAAE,EAAE;IACzC,IAAA,uBAAc,EACZ,MAAM,CAAC,WAAW,EAClB,oBAAoB,EACpB,WAAW,EACX,OAAO,IAAI,EAAE,CACd,CAAC;AACJ,CAAC,CACF,CAAC"}
|
package/dist/schema.js
CHANGED
|
@@ -14,8 +14,7 @@ exports.RegisterTable = (0, decorators_1.MakeClassDecorator)((target, tableName,
|
|
|
14
14
|
if (!(schemaName in schemaTableRegistry)) {
|
|
15
15
|
schemaTableRegistry[schemaName] = {};
|
|
16
16
|
}
|
|
17
|
-
schemaTableRegistry[schemaName][tableName] =
|
|
18
|
-
target;
|
|
17
|
+
schemaTableRegistry[schemaName][tableName] = target;
|
|
19
18
|
});
|
|
20
19
|
function getTablesForSchema(schemaName) {
|
|
21
20
|
return schemaTableRegistry[schemaName];
|
package/dist/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":";;;AA6BA,gDAIC;AAjCD,sEAI+C;AAC/C,uEAAwD;AAGxD,qCAA4D;AAE5D,MAAM,mBAAmB,GAAiD,EAAE,CAAC;AAEhE,QAAA,aAAa,GAGU,IAAA,+BAAkB,EACpD,CAAC,MAAM,EAAE,SAAiB,EAAE,UAAkB,EAAE,EAAE;IAChD,MAAM,QAAQ,GAAG,IAAA,oBAAW,EAAC,MAAM,EAAE,4BAAmB,CAAC,CAAC;IAC1D,QAAQ,CAAC,SAAS,GAAG,SAAS,CAAC;IAC/B,QAAQ,CAAC,UAAU,GAAG,UAAU,CAAC;IACjC,QAAQ,CAAC,MAAM,GAAG,2BAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAEzC,IAAI,CAAC,CAAC,UAAU,IAAI,mBAAmB,CAAC,EAAE,CAAC;QACzC,mBAAmB,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;IACvC,CAAC;IACD,mBAAmB,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC;AACtD,CAAC,CACF,CAAC;AAEF,SAAgB,kBAAkB,CAChC,UAAkB;IAElB,OAAO,mBAAmB,CAAC,UAAU,CAAC,CAAC;AACzC,CAAC"}
|
package/dist/table.js
CHANGED
|
@@ -7,12 +7,17 @@ exports.Fixture = exports.Field = exports.Index = exports.Table = exports.TableR
|
|
|
7
7
|
const node_assert_1 = __importDefault(require("node:assert"));
|
|
8
8
|
const decorators_1 = require("@antelopejs/interface-core/decorators");
|
|
9
9
|
const common_1 = require("./modifiers/common");
|
|
10
|
+
const records_1 = require("./modifiers/internal/records");
|
|
10
11
|
const common_2 = require("./common");
|
|
11
12
|
exports.TableMetaSymbol = Symbol();
|
|
12
13
|
exports.TableRefSymbol = Symbol();
|
|
13
14
|
function isSchemaInstance(target) {
|
|
14
15
|
return typeof target === "object" && target !== null;
|
|
15
16
|
}
|
|
17
|
+
function extendTable(Base) {
|
|
18
|
+
return class _internal_table extends Base {
|
|
19
|
+
};
|
|
20
|
+
}
|
|
16
21
|
/**
|
|
17
22
|
* Database Table superclass
|
|
18
23
|
*/
|
|
@@ -44,20 +49,29 @@ class Table {
|
|
|
44
49
|
* @returns New superclass
|
|
45
50
|
*/
|
|
46
51
|
static with(...others) {
|
|
47
|
-
const c =
|
|
48
|
-
};
|
|
52
|
+
const c = extendTable(this);
|
|
49
53
|
for (const mixin of others
|
|
50
54
|
.map((otherClass) => otherClass.prototype && new otherClass())
|
|
51
55
|
.map((other) => other?.[common_1.MixinSymbol])
|
|
52
56
|
.filter((mixin) => mixin?.prototype)) {
|
|
53
57
|
for (const key of Object.getOwnPropertyNames(mixin.prototype)) {
|
|
54
58
|
if (key !== "constructor" && !(key in c.prototype)) {
|
|
55
|
-
c.prototype
|
|
59
|
+
Object.defineProperty(c.prototype, key, {
|
|
60
|
+
value: mixin.prototype[key],
|
|
61
|
+
writable: true,
|
|
62
|
+
enumerable: true,
|
|
63
|
+
configurable: true,
|
|
64
|
+
});
|
|
56
65
|
}
|
|
57
66
|
}
|
|
58
67
|
for (const key of Object.getOwnPropertySymbols(mixin.prototype)) {
|
|
59
68
|
if (!(key in c.prototype)) {
|
|
60
|
-
c.prototype
|
|
69
|
+
Object.defineProperty(c.prototype, key, {
|
|
70
|
+
value: mixin.prototype[key],
|
|
71
|
+
writable: true,
|
|
72
|
+
enumerable: true,
|
|
73
|
+
configurable: true,
|
|
74
|
+
});
|
|
61
75
|
}
|
|
62
76
|
}
|
|
63
77
|
}
|
|
@@ -77,14 +91,15 @@ exports.Table = Table;
|
|
|
77
91
|
*/
|
|
78
92
|
exports.Index = (0, decorators_1.MakePropertyDecorator)((target, propertyKey, options) => {
|
|
79
93
|
const metadata = (0, common_2.getMetadata)(target.constructor, common_2.DatumStaticMetadata);
|
|
80
|
-
|
|
94
|
+
const key = propertyKey;
|
|
95
|
+
metadata.addIndex(key, options?.group || key, options?.crossInstance, options?.unique);
|
|
81
96
|
});
|
|
82
97
|
/**
|
|
83
98
|
* Database Table Field type decorator.
|
|
84
99
|
*/
|
|
85
100
|
exports.Field = (0, decorators_1.MakePropertyDecorator)((target, propertyKey, type) => {
|
|
86
101
|
const metadata = (0, common_2.getMetadata)(target.constructor, common_2.DatumStaticMetadata);
|
|
87
|
-
metadata
|
|
102
|
+
(0, records_1.fieldTypesByKey)(metadata)[propertyKey] = type;
|
|
88
103
|
});
|
|
89
104
|
/**
|
|
90
105
|
* Database Table class decorator to create default data on table creation.
|
package/dist/table.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table.js","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":";;;;;;AAAA,8DAAiC;AAOjC,
|
|
1
|
+
{"version":3,"file":"table.js","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,16 +12,20 @@ export type DecodeRight<T> = {
|
|
|
12
12
|
right: T;
|
|
13
13
|
};
|
|
14
14
|
export type DecodeResult<T> = DecodeLeft | DecodeRight<T>;
|
|
15
|
+
type FieldCodec = Extract<FieldType, {
|
|
16
|
+
decode: unknown;
|
|
17
|
+
}>;
|
|
15
18
|
export type TestCodec<T> = {
|
|
16
19
|
readonly _A: T;
|
|
17
20
|
readonly _O: T;
|
|
18
21
|
readonly _I: unknown;
|
|
19
22
|
readonly name: string;
|
|
20
23
|
is(u: unknown): u is T;
|
|
21
|
-
encode(a: T):
|
|
22
|
-
decode(u:
|
|
24
|
+
encode(a: T): ReturnType<FieldCodec["encode"]>;
|
|
25
|
+
decode(u: Parameters<FieldCodec["decode"]>[0]): DecodeResult<T>;
|
|
23
26
|
};
|
|
24
27
|
export declare function makeCodec<T>(name: string, guard: (u: unknown) => u is T): TestCodec<T>;
|
|
25
28
|
export declare const stringCodec: TestCodec<string>;
|
|
26
29
|
export declare const numberCodec: TestCodec<number>;
|
|
27
30
|
export declare function asFieldType(codec: TestCodec<unknown>): FieldType;
|
|
31
|
+
export {};
|
|
@@ -3,21 +3,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.numberCodec = exports.stringCodec = void 0;
|
|
4
4
|
exports.makeCodec = makeCodec;
|
|
5
5
|
exports.asFieldType = asFieldType;
|
|
6
|
+
class GuardCodec {
|
|
7
|
+
name;
|
|
8
|
+
guard;
|
|
9
|
+
_I = undefined;
|
|
10
|
+
constructor(name, guard) {
|
|
11
|
+
this.name = name;
|
|
12
|
+
this.guard = guard;
|
|
13
|
+
}
|
|
14
|
+
is = (u) => this.guard(u);
|
|
15
|
+
encode = (a) => a;
|
|
16
|
+
decode = (u) => this.guard(u)
|
|
17
|
+
? { _tag: "Right", right: u }
|
|
18
|
+
: {
|
|
19
|
+
_tag: "Left",
|
|
20
|
+
left: [{ value: u, context: [], message: `not ${this.name}` }],
|
|
21
|
+
};
|
|
22
|
+
}
|
|
6
23
|
function makeCodec(name, guard) {
|
|
7
|
-
return
|
|
8
|
-
_A: undefined,
|
|
9
|
-
_O: undefined,
|
|
10
|
-
_I: undefined,
|
|
11
|
-
name,
|
|
12
|
-
is: guard,
|
|
13
|
-
encode: (a) => a,
|
|
14
|
-
decode: (u) => guard(u)
|
|
15
|
-
? { _tag: "Right", right: u }
|
|
16
|
-
: {
|
|
17
|
-
_tag: "Left",
|
|
18
|
-
left: [{ value: u, context: [], message: `not ${name}` }],
|
|
19
|
-
},
|
|
20
|
-
};
|
|
24
|
+
return new GuardCodec(name, guard);
|
|
21
25
|
}
|
|
22
26
|
exports.stringCodec = makeCodec("string", (u) => typeof u === "string");
|
|
23
27
|
exports.numberCodec = makeCodec("number", (u) => typeof u === "number");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codec_helpers.js","sourceRoot":"","sources":["../../src/tests/codec_helpers.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"codec_helpers.js","sourceRoot":"","sources":["../../src/tests/codec_helpers.ts"],"names":[],"mappings":";;;AA8CA,8BAKC;AAWD,kCAEC;AA3CD,MAAM,UAAU;IAMH;IACQ;IAJV,EAAE,GAAY,SAAS,CAAC;IAEjC,YACW,IAAY,EACJ,KAA6B;QADrC,SAAI,GAAJ,IAAI,CAAQ;QACJ,UAAK,GAAL,KAAK,CAAwB;IAC7C,CAAC;IAEK,EAAE,GAAG,CAAC,CAAU,EAAU,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAE3C,MAAM,GAAG,CAAC,CAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IAErB,MAAM,GAAG,CAChB,CAAsC,EACrB,EAAE,CACnB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACX,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE;QAC7B,CAAC,CAAC;YACE,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;SAC/D,CAAC;CACT;AAED,SAAgB,SAAS,CACvB,IAAY,EACZ,KAA6B;IAE7B,OAAO,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACrC,CAAC;AAEY,QAAA,WAAW,GAAsB,SAAS,CACrD,QAAQ,EACR,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAC1C,CAAC;AACW,QAAA,WAAW,GAAsB,SAAS,CACrD,QAAQ,EACR,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAC1C,CAAC;AAEF,SAAgB,WAAW,CAAC,KAAyB;IACnD,OAAO,KAAK,CAAC;AACf,CAAC"}
|