@antelopejs/interface-database-decorators 0.3.0 → 0.3.2

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.
@@ -20,7 +20,11 @@ export declare class EncryptionModifier extends TwoWayModifier<LockedType, [
20
20
  readonly autolock = true;
21
21
  lock(_locked_value: LockedType | undefined, value: unknown): LockedType;
22
22
  readonly autounlock = true;
23
- unlock([locked_value, iv_str, authTag]: LockedType): unknown;
23
+ /**
24
+ * Decrypts a stored value. `null` is no value and stays `null`, as a
25
+ * localized field read with no locale gives it.
26
+ */
27
+ unlock(locked: LockedType | null): unknown;
24
28
  unlockrequest(data: DatabaseDev.ValueProxy<LockedType>): DatabaseDev.ValueProxy<unknown>;
25
29
  [MixinSymbol]: {
26
30
  new (): {};
@@ -95,7 +95,15 @@ class EncryptionModifier extends common_1.TwoWayModifier {
95
95
  return [encrypted, iv.toString("base64"), authTag];
96
96
  }
97
97
  autounlock = true;
98
- unlock([locked_value, iv_str, authTag]) {
98
+ /**
99
+ * Decrypts a stored value. `null` is no value and stays `null`, as a
100
+ * localized field read with no locale gives it.
101
+ */
102
+ unlock(locked) {
103
+ if (locked === null) {
104
+ return null;
105
+ }
106
+ const [locked_value, iv_str, authTag] = locked;
99
107
  const decipher = (0, node_crypto_1.createDecipheriv)(this.options.algorithm || "aes-256-gcm", this.options.secretKey, Buffer.from(iv_str, "base64"));
100
108
  if (acceptsAuthTag(decipher) && authTag) {
101
109
  decipher.setAuthTag(Buffer.from(authTag, "base64"));
@@ -1 +1 @@
1
- {"version":3,"file":"encryption.js","sourceRoot":"","sources":["../../src/modifiers/encryption.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"encryption.js","sourceRoot":"","sources":["../../src/modifiers/encryption.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import type * as DatabaseDev from "@antelopejs/interface-database";
2
- import { type Constructible } from "../common";
2
+ import { type Constructible, type PlainData } from "../common";
3
3
  import { ContainerModifier, MixinSymbol } from "./common";
4
4
  type Options = {
5
5
  /**
@@ -47,7 +47,21 @@ export declare class LocalizationModifier extends ContainerModifier<Record<strin
47
47
  * it in queries too (`unlockrequest`).
48
48
  */
49
49
  lock(locked_value: Record<string, unknown> | undefined, value: unknown, key: string | undefined): Record<string, unknown>;
50
+ /**
51
+ * The value under `key`, else under the fallback locale. With no `key`, a
52
+ * field without a fallback value reads `null`, as an unset field does.
53
+ */
50
54
  unlock(locked_value: Record<string, unknown>, key: string | undefined): unknown;
55
+ /**
56
+ * Reads a field that plain data gives as a plain object as its values by
57
+ * locale, as `PlainData` types it, whatever locale the row is read with
58
+ * afterwards. A field with a modifier inside its locales, such as
59
+ * `@Localized() @Encrypted()`, keeps the value for the next locale selected:
60
+ * that modifier transforms the value before the locales are set.
61
+ */
62
+ fromPlainData<T extends {
63
+ constructor: any;
64
+ }>(object: T, field: Extract<keyof T, string>, raw: PlainData<T>): void;
51
65
  unlockrequest(data: DatabaseDev.ValueProxy<Record<string, unknown>>, meta: DatabaseDev.ValueProxy<Record<string, never>>, key: DatabaseDev.ValueProxyOrValue<string | undefined>): DatabaseDev.ValueProxy<unknown>;
52
66
  [MixinSymbol]: {
53
67
  new (): {
@@ -3,12 +3,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Localized = exports.LocalizationModifier = void 0;
4
4
  const decorators_1 = require("@antelopejs/interface-core/decorators");
5
5
  const common_1 = require("../common");
6
+ const kinds_1 = require("./internal/kinds");
6
7
  const common_2 = require("./common");
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) {
10
11
  return Object.fromEntries(Object.entries(values).filter(([, value]) => value !== EMPTY_TEXT));
11
12
  }
13
+ /** Whether `value` is an object literal, not an array, a date or a class instance. */
14
+ function isPlainObject(value) {
15
+ if (!(0, kinds_1.isRecord)(value))
16
+ return false;
17
+ const prototype = Object.getPrototypeOf(value);
18
+ return prototype === Object.prototype || prototype === null;
19
+ }
12
20
  /**
13
21
  * Localization modifier. enables the use of {@link Localized} on table fields.
14
22
  *
@@ -44,6 +52,10 @@ class LocalizationModifier extends common_2.ContainerModifier {
44
52
  value, key) {
45
53
  return withoutEmptyTexts(super.lock(locked_value, value, key));
46
54
  }
55
+ /**
56
+ * The value under `key`, else under the fallback locale. With no `key`, a
57
+ * field without a fallback value reads `null`, as an unset field does.
58
+ */
47
59
  unlock(
48
60
  // oxlint-disable-next-line anti-slop/no-unsafe-dictionary-type -- the container modifier leaves the values by locale untyped
49
61
  locked_value, key) {
@@ -51,8 +63,24 @@ class LocalizationModifier extends common_2.ContainerModifier {
51
63
  if (unlocked !== undefined && unlocked !== EMPTY_TEXT) {
52
64
  return unlocked;
53
65
  }
54
- if (this.options.fallbackLocale) {
55
- return super.unlock(locked_value, this.options.fallbackLocale);
66
+ const fallback = this.options.fallbackLocale
67
+ ? super.unlock(locked_value, this.options.fallbackLocale)
68
+ : undefined;
69
+ return key === undefined ? (fallback ?? null) : fallback;
70
+ }
71
+ /**
72
+ * Reads a field that plain data gives as a plain object as its values by
73
+ * locale, as `PlainData` types it, whatever locale the row is read with
74
+ * afterwards. A field with a modifier inside its locales, such as
75
+ * `@Localized() @Encrypted()`, keeps the value for the next locale selected:
76
+ * that modifier transforms the value before the locales are set.
77
+ */
78
+ fromPlainData(object, field, raw) {
79
+ const modifiers = (0, common_1.getMetadata)(object.constructor, common_2.ModifiersStaticMetadata)
80
+ .fields[field];
81
+ if (modifiers?.at(-1)?.id === LocalizationModifier.name &&
82
+ isPlainObject(raw[field])) {
83
+ (0, common_2.unlock)(object, LocalizationModifier, [field], "*");
56
84
  }
57
85
  }
58
86
  unlockrequest(
@@ -1 +1 @@
1
- {"version":3,"file":"localization.js","sourceRoot":"","sources":["../../src/modifiers/localization.ts"],"names":[],"mappings":";;;AACA,sEAA8E;AAE9E,sCAA4D;AAC5D,qCAMkB;AA8BlB,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;IAClB,6HAA6H;IAC7H,YAAiD;IACjD,iMAAiM;IACjM,KAAc,EACd,GAAuB;QAEvB,OAAO,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;IACjE,CAAC;IAEe,MAAM;IACpB,6HAA6H;IAC7H,YAAqC,EACrC,GAAuB;QAEvB,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;IAC3B,6HAA6H;IAC7H,IAAqD,EACrD,IAAmD,EACnD,GAAsD;QAEtD,MAAM,QAAQ,GAAG,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QACtD,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QACxC,OAAO,cAAc;YACnB,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAC5C,CAAC,CAAC,QAAQ,CAAC;IACf,CAAC;IAED,CAAC,oBAAW,CAAC,GAAG;QA2Bd,QAAQ,CAEN,MAAc,EACd,MAAkC;YAElC,IAAA,eAAM,EAAC,IAAI,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YACnD,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;CACH;AArGD,oDAqGC;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"}
1
+ {"version":3,"file":"localization.js","sourceRoot":"","sources":["../../src/modifiers/localization.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const chai_1 = require("chai");
13
+ const interface_database_1 = require("@antelopejs/interface-database");
14
+ const schema_1 = require("../schema");
15
+ const database_1 = require("../database");
16
+ const table_1 = require("../table");
17
+ const common_1 = require("../modifiers/common");
18
+ const encryption_1 = require("../modifiers/encryption");
19
+ const localization_1 = require("../modifiers/localization");
20
+ describe("Localized fields - a request without a locale", () => {
21
+ let Page = class Page extends table_1.Table.with(localization_1.LocalizationModifier, encryption_1.EncryptionModifier) {
22
+ };
23
+ __decorate([
24
+ (0, localization_1.Localized)(),
25
+ (0, table_1.Field)("string"),
26
+ __metadata("design:type", String)
27
+ ], Page.prototype, "title", void 0);
28
+ __decorate([
29
+ (0, localization_1.Localized)({ fallbackLocale: "en" }),
30
+ (0, table_1.Field)("string"),
31
+ __metadata("design:type", String)
32
+ ], Page.prototype, "summary", void 0);
33
+ __decorate([
34
+ (0, localization_1.Localized)(),
35
+ (0, encryption_1.Encrypted)({ secretKey: "12345678901234567890123456789012" }),
36
+ (0, table_1.Field)("string"),
37
+ __metadata("design:type", String)
38
+ ], Page.prototype, "secret", void 0);
39
+ Page = __decorate([
40
+ (0, schema_1.RegisterTable)("no-key-pages", "localized-no-key-schema")
41
+ ], Page);
42
+ async function createdWithoutLocale() {
43
+ await (0, database_1.RegisterSchema)("localized-no-key-schema");
44
+ const instance = interface_database_1.Schema.get("localized-no-key-schema")?.instance();
45
+ if (!instance)
46
+ throw new Error("Database not found");
47
+ const row = new Page();
48
+ row._id = "page-1";
49
+ row.title = undefined;
50
+ row.summary = undefined;
51
+ row.secret = "Sent without a locale";
52
+ (0, common_1.lock)(row, localization_1.LocalizationModifier, undefined, undefined);
53
+ await Page.table(instance).insert(row).run();
54
+ const read = (0, common_1.fromDatabase)(await Page.table(instance).get("page-1").run(), Page);
55
+ (0, common_1.unlock)(read, localization_1.LocalizationModifier, undefined, undefined);
56
+ return read;
57
+ }
58
+ afterEach(async () => {
59
+ await interface_database_1.Schema.get("localized-no-key-schema")
60
+ ?.instance()
61
+ .table("no-key-pages")
62
+ .delete()
63
+ .run();
64
+ });
65
+ it("answers null for a field the request did not send", async () => {
66
+ const answer = JSON.parse(JSON.stringify(await createdWithoutLocale()));
67
+ (0, chai_1.expect)(answer).to.deep.include({
68
+ title: null,
69
+ summary: null,
70
+ secret: null,
71
+ });
72
+ });
73
+ });
74
+ //# sourceMappingURL=localized_no_key.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localized_no_key.test.js","sourceRoot":"","sources":["../../src/tests/localized_no_key.test.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,+BAA8B;AAC9B,uEAAwD;AACxD,sCAA0C;AAC1C,0CAA6C;AAC7C,oCAAwC;AACxC,gDAAiE;AACjE,wDAAwE;AACxE,4DAA4E;AAE5E,QAAQ,CAAC,+CAA+C,EAAE,GAAG,EAAE;IAE7D,IAAM,IAAI,GAAV,MAAM,IAAK,SAAQ,aAAK,CAAC,IAAI,CAAC,mCAAoB,EAAE,+BAAkB,CAAC;KAStE,CAAA;IARuC;QAArC,IAAA,wBAAS,GAAE;QAAE,IAAA,aAAK,EAAC,QAAQ,CAAC;;uCAAwB;IAG7C;QAFP,IAAA,wBAAS,EAAC,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC;QACnC,IAAA,aAAK,EAAC,QAAQ,CAAC;;yCACS;IAIjB;QAHP,IAAA,wBAAS,GAAE;QACX,IAAA,sBAAS,EAAC,EAAE,SAAS,EAAE,kCAAkC,EAAE,CAAC;QAC5D,IAAA,aAAK,EAAC,QAAQ,CAAC;;wCACQ;IARpB,IAAI;QADT,IAAA,sBAAa,EAAC,cAAc,EAAE,yBAAyB,CAAC;OACnD,IAAI,CAST;IAED,KAAK,UAAU,oBAAoB;QACjC,MAAM,IAAA,yBAAc,EAAC,yBAAyB,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,2BAAM,CAAC,GAAG,CAAC,yBAAyB,CAAC,EAAE,QAAQ,EAAE,CAAC;QACnE,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACrD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,GAAG,CAAC,GAAG,GAAG,QAAQ,CAAC;QACnB,GAAG,CAAC,KAAK,GAAG,SAAS,CAAC;QACtB,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC;QACxB,GAAG,CAAC,MAAM,GAAG,uBAAuB,CAAC;QACrC,IAAA,aAAI,EAAC,GAAG,EAAE,mCAAoB,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QACtD,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,IAAA,qBAAY,EACvB,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAC9C,IAAI,CACL,CAAC;QACF,IAAA,eAAM,EAAC,IAAI,EAAE,mCAAoB,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,2BAAM,CAAC,GAAG,CAAC,yBAAyB,CAAC;YACzC,EAAE,QAAQ,EAAE;aACX,KAAK,CAAC,cAAc,CAAC;aACrB,MAAM,EAAE;aACR,GAAG,EAAE,CAAC;IACX,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAChC,IAAI,CAAC,SAAS,CAAC,MAAM,oBAAoB,EAAE,CAAC,CAC7C,CAAC;QAEF,IAAA,aAAM,EAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC;YAC7B,KAAK,EAAE,IAAI;YACX,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,IAAI;SACb,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const chai_1 = require("chai");
13
+ const interface_database_1 = require("@antelopejs/interface-database");
14
+ const schema_1 = require("../schema");
15
+ const database_1 = require("../database");
16
+ const model_1 = require("../model");
17
+ const table_1 = require("../table");
18
+ const encryption_1 = require("../modifiers/encryption");
19
+ const localization_1 = require("../modifiers/localization");
20
+ const records_1 = require("../modifiers/internal/records");
21
+ describe("Localized fields - plain data with values by locale", () => {
22
+ let Role = class Role extends table_1.Table.with(localization_1.LocalizationModifier, encryption_1.EncryptionModifier) {
23
+ };
24
+ __decorate([
25
+ (0, localization_1.Localized)(),
26
+ __metadata("design:type", String)
27
+ ], Role.prototype, "displayName", void 0);
28
+ __decorate([
29
+ (0, localization_1.Localized)(),
30
+ __metadata("design:type", Object)
31
+ ], Role.prototype, "tooltip", void 0);
32
+ __decorate([
33
+ (0, localization_1.Localized)(),
34
+ (0, encryption_1.Encrypted)({ secretKey: "12345678901234567890123456789012" }),
35
+ __metadata("design:type", Object)
36
+ ], Role.prototype, "note", void 0);
37
+ Role = __decorate([
38
+ (0, schema_1.RegisterTable)("roles", "localized-plain-data-schema")
39
+ ], Role);
40
+ const RoleModel = (0, model_1.BasicDataModel)(Role, "roles");
41
+ const wording = { en: "Members", fr: "Membres" };
42
+ async function model() {
43
+ await (0, database_1.RegisterSchema)("localized-plain-data-schema");
44
+ const instance = interface_database_1.Schema.get("localized-plain-data-schema")?.instance();
45
+ if (!instance)
46
+ throw new Error("Database not found");
47
+ return new RoleModel(instance);
48
+ }
49
+ async function stored(row) {
50
+ const roles = await model();
51
+ row._id = "role-1";
52
+ await roles.insert(row);
53
+ const read = await roles.get("role-1");
54
+ if (!read)
55
+ throw new Error("Row not stored");
56
+ return read;
57
+ }
58
+ afterEach(async () => {
59
+ await interface_database_1.Schema.get("localized-plain-data-schema")
60
+ ?.instance()
61
+ .table("roles")
62
+ .delete()
63
+ .run();
64
+ });
65
+ it("stores every locale of a record read under one locale", async () => {
66
+ const read = await stored(RoleModel.fromPlainData({ displayName: wording }).localize("en"));
67
+ (0, chai_1.expect)((0, records_1.getInternal)(read).data.displayName).to.deep.equal(wording);
68
+ (0, chai_1.expect)(read.localize("en").displayName).to.equal("Members");
69
+ });
70
+ it("stores every locale of a record read with no locale", async () => {
71
+ const read = await stored(RoleModel.fromPlainData({ displayName: wording }));
72
+ (0, chai_1.expect)((0, records_1.getInternal)(read).data.displayName).to.deep.equal(wording);
73
+ });
74
+ it("stores a plain value under the locale it is read with", async () => {
75
+ const read = await stored(RoleModel.fromPlainData({ displayName: "Members" }).localize("en"));
76
+ (0, chai_1.expect)((0, records_1.getInternal)(read).data.displayName).to.deep.equal({ en: "Members" });
77
+ });
78
+ it("stores a null value under the locale it is read with", async () => {
79
+ const read = await stored(RoleModel.fromPlainData({ displayName: wording, tooltip: null }).localize("en"));
80
+ (0, chai_1.expect)((0, records_1.getInternal)(read).data.tooltip).to.deep.equal({ en: null });
81
+ });
82
+ it("stores no record for a field encrypted inside its locales", async () => {
83
+ const read = await stored(RoleModel.fromPlainData({ note: wording }));
84
+ (0, chai_1.expect)((0, records_1.getInternal)(read).data.note).to.equal(undefined);
85
+ });
86
+ });
87
+ //# sourceMappingURL=localized_plain_data.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localized_plain_data.test.js","sourceRoot":"","sources":["../../src/tests/localized_plain_data.test.ts"],"names":[],"mappings":"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"}
@@ -426,7 +426,7 @@ Base64 is an encoding, not encryption. The example declares its `LockedType` as
426
426
 
427
427
  ### `ContainerModifier`
428
428
 
429
- A modifier that stores several values under keys, as `LocalizationModifier` does, extends `ContainerModifier`. Its `lock`, `unlock`, and `unlockrequest` take the key as their argument, a `string` or `undefined`. `lock` and `unlock` treat the wildcard key `"*"` as the whole record, and `lock` throws a `TypeError` for a value under `"*"` that is not a record. `undefined` is no key: `lock` stores nothing under it, and `unlock` and `unlockrequest` find no value, so a `LocalizationModifier` answers its `fallbackLocale`:
429
+ A modifier that stores several values under keys, as `LocalizationModifier` does, extends `ContainerModifier`. Its `lock`, `unlock`, and `unlockrequest` take the key as their argument, a `string` or `undefined`. `lock` and `unlock` treat the wildcard key `"*"` as the whole record, and `lock` throws a `TypeError` for a value under `"*"` that is not a record. `undefined` is no key: `lock` stores nothing under it, and `unlock` and `unlockrequest` find no value, so a `LocalizationModifier` answers its `fallbackLocale`, or `null` when that locale has no value either:
430
430
 
431
431
  ```typescript
432
432
  import { ContainerModifier } from "@antelopejs/interface-database-decorators";
@@ -129,7 +129,7 @@ const user = UserModel.fromPlainData({
129
129
  });
130
130
  ```
131
131
 
132
- The object is a `PlainData<T>`. Every field is optional and may be partial, and a field under a container modifier may hold its value per key, as a localized field holds one text per locale. `toPlainData` gives the reverse form, a `PlainRow<T>`.
132
+ The object is a `PlainData<T>`. Every field is optional and may be partial, and a field under a container modifier may hold its value per key, as a localized field holds one text per locale. A plain object given for a localized field is read as its texts by locale, so every locale is stored, whatever `localize()` call follows. A single text is stored under the locale that a later `localize()` call selects. A field with another modifier inside its locales, such as `@Localized() @Encrypted()`, does not read a plain object this way. `toPlainData` gives the reverse form, a `PlainRow<T>`.
133
133
 
134
134
  ### `fromDatabase(obj)`
135
135
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antelopejs/interface-database-decorators",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "AntelopeJS decorators for database tables and typed data models, with encrypted, hashed and localized fields",
5
5
  "keywords": [
6
6
  "antelopejs",
@@ -130,10 +130,11 @@ class Chef extends Table.with(
130
130
  - `@Hashed({ algorithm })` stores a fast digest instead of scrypt: use it only for non-secret fingerprints, never for credentials.
131
131
  - Localized fields must be written through a localized instance (`instance.localize(locale).field = ...`);
132
132
  values assigned before `localize()` are held in floating state and silently dropped on insert/update.
133
+ - In plain data, a plain object given for a localized field is its texts by locale: `fromPlainData` and `insert` store every locale, whatever `localize()` call follows, and `update` replaces the stored texts with that record. A single text still waits for a locale. A field with another modifier inside its locales, such as `@Localized() @Encrypted()`, does not read a record this way.
133
134
  - `instance.localize("*", ["motto"])` reads and writes every locale at once, typed `Record<string, string>` for each listed field (`LocalizedRecords<T, K>`); without a field list the field types stay unchanged.
134
135
  - Under `localize("*")` a localized field takes the record of texts by locale, and `undefined` or `null` clears every locale. A single text throws a `TypeError`, whether it is assigned or held from `fromPlainData` when `localize("*")` runs.
135
136
  - A localized value `""` is stored as no value: reads and queries in that locale get the `fallbackLocale` value.
136
- - A `ContainerModifier` key of `undefined` is no key: writes store nothing under it, and reads and queries get no value, or the `fallbackLocale` value for a localized field.
137
+ - A `ContainerModifier` key of `undefined` is no key: writes store nothing under it, and reads and queries get no value. A localized field reads the `fallbackLocale` value, or `null` when there is none.
137
138
  - `@Relation({ to: () => Target })` is declarative metadata only: no foreign-key enforcement, consumed by introspection tooling via `RelationStaticMetadata`.
138
139
  - `Model.validate` (and `{ validate: true }` on insert/update) only checks fields whose `@Field` type is an
139
140
  io-ts-style codec with `.decode`; plain string field tokens are skipped. Update validates with