@adminiumjs/meta 0.1.2 → 0.2.1
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/connect.d.ts +26 -1
- package/dist/connect.d.ts.map +1 -1
- package/dist/connect.js +32 -1
- package/dist/connect.js.map +1 -1
- package/dist/ids.d.ts +2 -0
- package/dist/ids.d.ts.map +1 -1
- package/dist/ids.js +2 -0
- package/dist/ids.js.map +1 -1
- package/dist/migrations/0011_i18n_runtime.d.ts +42 -0
- package/dist/migrations/0011_i18n_runtime.d.ts.map +1 -0
- package/dist/migrations/0011_i18n_runtime.js +101 -0
- package/dist/migrations/0011_i18n_runtime.js.map +1 -0
- package/dist/migrations/0012_locale_width.d.ts +29 -0
- package/dist/migrations/0012_locale_width.d.ts.map +1 -0
- package/dist/migrations/0012_locale_width.js +42 -0
- package/dist/migrations/0012_locale_width.js.map +1 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +4 -0
- package/dist/migrations/index.js.map +1 -1
- package/dist/repos/i18n-version.d.ts +32 -0
- package/dist/repos/i18n-version.d.ts.map +1 -0
- package/dist/repos/i18n-version.js +56 -0
- package/dist/repos/i18n-version.js.map +1 -0
- package/dist/repos/index.d.ts +3 -0
- package/dist/repos/index.d.ts.map +1 -1
- package/dist/repos/index.js +3 -0
- package/dist/repos/index.js.map +1 -1
- package/dist/repos/locales.d.ts +85 -0
- package/dist/repos/locales.d.ts.map +1 -0
- package/dist/repos/locales.js +189 -0
- package/dist/repos/locales.js.map +1 -0
- package/dist/repos/overrides.d.ts +2 -2
- package/dist/repos/overrides.d.ts.map +1 -1
- package/dist/repos/overrides.js.map +1 -1
- package/dist/repos/translations.d.ts +107 -0
- package/dist/repos/translations.d.ts.map +1 -0
- package/dist/repos/translations.js +231 -0
- package/dist/repos/translations.js.map +1 -0
- package/dist/repos/user-prefs.d.ts +8 -1
- package/dist/repos/user-prefs.d.ts.map +1 -1
- package/dist/repos/user-prefs.js +26 -3
- package/dist/repos/user-prefs.js.map +1 -1
- package/dist/schema/json-payloads.d.ts +30 -1
- package/dist/schema/json-payloads.d.ts.map +1 -1
- package/dist/schema/json-payloads.js +29 -2
- package/dist/schema/json-payloads.js.map +1 -1
- package/dist/schema/settings-registry.d.ts +16 -1
- package/dist/schema/settings-registry.d.ts.map +1 -1
- package/dist/schema/settings-registry.js +15 -0
- package/dist/schema/settings-registry.js.map +1 -1
- package/dist/schema/tables.d.ts +47 -1
- package/dist/schema/tables.d.ts.map +1 -1
- package/dist/schema/tables.js +2 -0
- package/dist/schema/tables.js.map +1 -1
- package/package.json +1 -1
package/dist/connect.d.ts
CHANGED
|
@@ -26,9 +26,34 @@ export interface MetaDb {
|
|
|
26
26
|
export declare function createSqliteMetaDb(config: SqliteDialectConfig): MetaDb;
|
|
27
27
|
/**
|
|
28
28
|
* PostgreSQL meta-store around an injected `pg` Pool. The pool must parse
|
|
29
|
-
* int8 as JS number (all ts values < 2^53 — 07-meta-store.md §2.1)
|
|
29
|
+
* int8 as JS number (all ts values < 2^53 — 07-meta-store.md §2.1); build it
|
|
30
|
+
* with {@link postgresInt8AsNumber}.
|
|
30
31
|
*/
|
|
31
32
|
export declare function createPostgresMetaDb(config: PostgresDialectConfig): MetaDb;
|
|
33
|
+
/**
|
|
34
|
+
* The `types` option that satisfies {@link createPostgresMetaDb}'s requirement:
|
|
35
|
+
* `new Pool({ …, types: postgresInt8AsNumber(pg) })`.
|
|
36
|
+
*
|
|
37
|
+
* The requirement was stated here and satisfiable nowhere, so every caller
|
|
38
|
+
* either forgot it (the product: each `ts` column arrived as a string and
|
|
39
|
+
* `GET /api/v1/bootstrap` 500'd on its own reply schema) or met it with a
|
|
40
|
+
* process-global `pg.types.setTypeParser`, which papered over the callers that
|
|
41
|
+
* had forgotten. Now there is one implementation, next to the contract.
|
|
42
|
+
*
|
|
43
|
+
* `node-postgres` decodes int8 as a string by default and is right to — int64
|
|
44
|
+
* outruns `Number.MAX_SAFE_INTEGER`. The META schema does not: `columns.ts`
|
|
45
|
+
* pins `ts` to epoch milliseconds and `bigint` to "values always < 2^53". So
|
|
46
|
+
* this is scoped to one pool ON PURPOSE. The global equivalent is a
|
|
47
|
+
* data-integrity bug waiting to happen: the server reads the USER's tables
|
|
48
|
+
* through the same `pg` module, and their `bigint` ids are under no such
|
|
49
|
+
* promise.
|
|
50
|
+
*
|
|
51
|
+
* Structurally typed over the module so this package still declares no driver
|
|
52
|
+
* dependency — the caller that imports `pg` passes it in.
|
|
53
|
+
*/
|
|
54
|
+
export declare function postgresInt8AsNumber(pgModule: Record<string, unknown>): {
|
|
55
|
+
getTypeParser: (oid: number, format?: unknown) => unknown;
|
|
56
|
+
};
|
|
32
57
|
/** MySQL/MariaDB meta-store around an injected `mysql2` pool. */
|
|
33
58
|
export declare function createMysqlMetaDb(config: MysqlDialectConfig): MetaDb;
|
|
34
59
|
/** One-time per-connection setup (currently: SQLite FK pragma). */
|
package/dist/connect.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAEL,MAAM,EAKN,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACzB,MAAM,QAAQ,CAAC;AAEhB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD,gEAAgE;AAChE,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACnB,OAAO,EAAE,WAAW,CAAC;CACtB;AAiBD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAEtE;AAED
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAEL,MAAM,EAKN,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACzB,MAAM,QAAQ,CAAC;AAEhB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD,gEAAgE;AAChE,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACnB,OAAO,EAAE,WAAW,CAAC;CACtB;AAiBD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAEtE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAE1E;AAKD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IACvE,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC;CAC3D,CASA;AAED,iEAAiE;AACjE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAEpE;AAED,mEAAmE;AACnE,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5D;AAED,8CAA8C;AAC9C,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/D"}
|
package/dist/connect.js
CHANGED
|
@@ -36,11 +36,42 @@ export function createSqliteMetaDb(config) {
|
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
38
|
* PostgreSQL meta-store around an injected `pg` Pool. The pool must parse
|
|
39
|
-
* int8 as JS number (all ts values < 2^53 — 07-meta-store.md §2.1)
|
|
39
|
+
* int8 as JS number (all ts values < 2^53 — 07-meta-store.md §2.1); build it
|
|
40
|
+
* with {@link postgresInt8AsNumber}.
|
|
40
41
|
*/
|
|
41
42
|
export function createPostgresMetaDb(config) {
|
|
42
43
|
return build('postgres', new PostgresDialect(config));
|
|
43
44
|
}
|
|
45
|
+
/** `pg`'s OID for `bigint`/`int8`. */
|
|
46
|
+
const PG_INT8_OID = 20;
|
|
47
|
+
/**
|
|
48
|
+
* The `types` option that satisfies {@link createPostgresMetaDb}'s requirement:
|
|
49
|
+
* `new Pool({ …, types: postgresInt8AsNumber(pg) })`.
|
|
50
|
+
*
|
|
51
|
+
* The requirement was stated here and satisfiable nowhere, so every caller
|
|
52
|
+
* either forgot it (the product: each `ts` column arrived as a string and
|
|
53
|
+
* `GET /api/v1/bootstrap` 500'd on its own reply schema) or met it with a
|
|
54
|
+
* process-global `pg.types.setTypeParser`, which papered over the callers that
|
|
55
|
+
* had forgotten. Now there is one implementation, next to the contract.
|
|
56
|
+
*
|
|
57
|
+
* `node-postgres` decodes int8 as a string by default and is right to — int64
|
|
58
|
+
* outruns `Number.MAX_SAFE_INTEGER`. The META schema does not: `columns.ts`
|
|
59
|
+
* pins `ts` to epoch milliseconds and `bigint` to "values always < 2^53". So
|
|
60
|
+
* this is scoped to one pool ON PURPOSE. The global equivalent is a
|
|
61
|
+
* data-integrity bug waiting to happen: the server reads the USER's tables
|
|
62
|
+
* through the same `pg` module, and their `bigint` ids are under no such
|
|
63
|
+
* promise.
|
|
64
|
+
*
|
|
65
|
+
* Structurally typed over the module so this package still declares no driver
|
|
66
|
+
* dependency — the caller that imports `pg` passes it in.
|
|
67
|
+
*/
|
|
68
|
+
export function postgresInt8AsNumber(pgModule) {
|
|
69
|
+
const types = (pgModule.types ??
|
|
70
|
+
pgModule.default?.types);
|
|
71
|
+
return {
|
|
72
|
+
getTypeParser: (oid, format) => oid === PG_INT8_OID ? Number : (types?.getTypeParser(oid, format) ?? String),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
44
75
|
/** MySQL/MariaDB meta-store around an injected `mysql2` pool. */
|
|
45
76
|
export function createMysqlMetaDb(config) {
|
|
46
77
|
return build('mysql', new MysqlDialect(config));
|
package/dist/connect.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,eAAe,EACf,MAAM,EACN,YAAY,EACZ,eAAe,EACf,aAAa,GAKd,MAAM,QAAQ,CAAC;AAGhB,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AASxD,SAAS,KAAK,CAAC,OAAoB,EAAE,aAAsB;IACzD,OAAO;QACL,EAAE,EAAE,IAAI,MAAM,CAAS;YACrB,OAAO,EAAE,aAAa;YACtB,0EAA0E;YAC1E,qEAAqE;YACrE,wEAAwE;YACxE,uEAAuE;YACvE,6DAA6D;YAC7D,OAAO,EAAE,CAAC,IAAI,eAAe,CAAC,EAAE,wBAAwB,EAAE,IAAI,EAAE,CAAC,CAAC;SACnE,CAAC;QACF,OAAO;KACR,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAA2B;IAC5D,OAAO,KAAK,CAAC,QAAQ,EAAE,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;AACpD,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,eAAe,EACf,MAAM,EACN,YAAY,EACZ,eAAe,EACf,aAAa,GAKd,MAAM,QAAQ,CAAC;AAGhB,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AASxD,SAAS,KAAK,CAAC,OAAoB,EAAE,aAAsB;IACzD,OAAO;QACL,EAAE,EAAE,IAAI,MAAM,CAAS;YACrB,OAAO,EAAE,aAAa;YACtB,0EAA0E;YAC1E,qEAAqE;YACrE,wEAAwE;YACxE,uEAAuE;YACvE,6DAA6D;YAC7D,OAAO,EAAE,CAAC,IAAI,eAAe,CAAC,EAAE,wBAAwB,EAAE,IAAI,EAAE,CAAC,CAAC;SACnE,CAAC;QACF,OAAO;KACR,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAA2B;IAC5D,OAAO,KAAK,CAAC,QAAQ,EAAE,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;AACpD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAA6B;IAChE,OAAO,KAAK,CAAC,UAAU,EAAE,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,sCAAsC;AACtC,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAiC;IAGpE,MAAM,KAAK,GAAG,CAAC,QAAQ,CAAC,KAAK;QAC1B,QAAQ,CAAC,OAA+C,EAAE,KAAK,CAErD,CAAC;IACd,OAAO;QACL,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAC7B,GAAG,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC;KAC/E,CAAC;AACJ,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,iBAAiB,CAAC,MAA0B;IAC1D,OAAO,KAAK,CAAC,OAAO,EAAE,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,mEAAmE;AACnE,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,IAAI,IAAI,CAAC,OAAO,KAAK,QAAQ;QAAE,MAAM,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,8CAA8C;AAC9C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY;IAC9C,MAAM,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC;AAC1B,CAAC"}
|
package/dist/ids.d.ts
CHANGED
|
@@ -44,6 +44,8 @@ export declare const ID_PREFIXES: {
|
|
|
44
44
|
readonly whd: "adminium_webhook_deliveries";
|
|
45
45
|
readonly flag: "adminium_feature_flags";
|
|
46
46
|
readonly mft: "adminium_manifests";
|
|
47
|
+
readonly loc: "adminium_locales";
|
|
48
|
+
readonly trn: "adminium_translations";
|
|
47
49
|
};
|
|
48
50
|
export type IdPrefix = keyof typeof ID_PREFIXES;
|
|
49
51
|
/** Maximum column width every id must fit (07-meta-store.md §2.1). */
|
package/dist/ids.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH,QAAA,MAAM,QAAQ,QAAsB,CAAC;AAErC;;;;;GAKG;AACH,eAAO,MAAM,WAAW
|
|
1
|
+
{"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH,QAAA,MAAM,QAAQ,QAAsB,CAAC;AAErC;;;;;GAKG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6Bd,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,WAAW,CAAC;AAOhD,sEAAsE;AACtE,eAAO,MAAM,aAAa,KAAK,CAAC;AAEhC,qBAAa,cAAe,SAAQ,KAAK;IAC9B,IAAI,SAAoB;CAClC;AAiDD;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAc9C;AAED,MAAM,WAAW,QAAQ;IACvB,qCAAqC;IACrC,MAAM,EAAE,QAAQ,CAAC;IACjB,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,8FAA8F;AAC9F,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,CAY5C;AAED,uFAAuF;AACvF,wBAAgB,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,OAAO,CAQ5D;AAED,yDAAyD;AACzD,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEzC;AAED,2CAA2C;AAC3C,wBAAgB,aAAa,IAAI,IAAI,CAGpC;AAED,OAAO,EAAE,QAAQ,IAAI,YAAY,EAAE,CAAC"}
|
package/dist/ids.js
CHANGED
|
@@ -49,6 +49,8 @@ export const ID_PREFIXES = {
|
|
|
49
49
|
whd: 'adminium_webhook_deliveries',
|
|
50
50
|
flag: 'adminium_feature_flags',
|
|
51
51
|
mft: 'adminium_manifests',
|
|
52
|
+
loc: 'adminium_locales',
|
|
53
|
+
trn: 'adminium_translations',
|
|
52
54
|
};
|
|
53
55
|
const PREFIX_SET = new Set(Object.keys(ID_PREFIXES));
|
|
54
56
|
/** `<prefix>_<26 Crockford chars>` — Crockford charset excludes I, L, O, U. */
|
package/dist/ids.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ids.js","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,iDAAiD;AACjD,MAAM,QAAQ,GAAG,kCAAkC,CAAC;AACpD,MAAM,QAAQ,GAAG,EAAE,CAAC;AACpB,MAAM,QAAQ,GAAG,EAAE,CAAC;AACpB,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAErC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,GAAG,EAAE,gBAAgB;IACrB,IAAI,EAAE,mBAAmB;IACzB,GAAG,EAAE,0BAA0B;IAC/B,GAAG,EAAE,mBAAmB;IACxB,IAAI,EAAE,gBAAgB;IACtB,IAAI,EAAE,2BAA2B;IACjC,GAAG,EAAE,oBAAoB;IACzB,GAAG,EAAE,eAAe;IACpB,IAAI,EAAE,sBAAsB;IAC5B,IAAI,EAAE,2BAA2B;IACjC,GAAG,EAAE,2BAA2B;IAChC,IAAI,EAAE,gBAAgB;IACtB,IAAI,EAAE,gBAAgB;IACtB,GAAG,EAAE,mBAAmB;IACxB,GAAG,EAAE,wBAAwB;IAC7B,IAAI,EAAE,sBAAsB;IAC5B,IAAI,EAAE,0BAA0B;IAChC,GAAG,EAAE,4BAA4B;IACjC,GAAG,EAAE,kBAAkB;IACvB,GAAG,EAAE,kBAAkB;IACvB,IAAI,EAAE,gBAAgB;IACtB,GAAG,EAAE,0BAA0B;IAC/B,EAAE,EAAE,mBAAmB;IACvB,GAAG,EAAE,6BAA6B;IAClC,IAAI,EAAE,wBAAwB;IAC9B,GAAG,EAAE,oBAAoB;
|
|
1
|
+
{"version":3,"file":"ids.js","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wave 0011 — runtime translations (23-runtime-translations.md §3.1, §3.2).
|
|
3
|
+
*
|
|
4
|
+
* Two tables, both deliberately SPARSE:
|
|
5
|
+
*
|
|
6
|
+
* - `adminium_locales` holds a row only when an admin deviates from a
|
|
7
|
+
* compiled locale's defaults (or invents a new one). A built-in locale
|
|
8
|
+
* with no row behaves exactly as it does today, and the immutable fields
|
|
9
|
+
* of a built-in row (`dir`, `font_hint`, `intl_tag`, names) are always
|
|
10
|
+
* read from the compiled registry — the row can only carry `enabled` and
|
|
11
|
+
* `sort_order`. That is what makes "zero rows ⇒ byte-identical to today"
|
|
12
|
+
* a structural guarantee rather than a convention, and it also means an
|
|
13
|
+
* admin cannot flip `ar_EG` to `ltr` and corrupt a shipped bundle.
|
|
14
|
+
* - `adminium_translations` holds one row per OVERRIDDEN message. Absence
|
|
15
|
+
* means "use the compiled built-in"; a row with an empty `value` means
|
|
16
|
+
* "deliberately blank" (§3.3). Reset-to-built-in is therefore a hard
|
|
17
|
+
* DELETE, which is why the version stamp is a counter in
|
|
18
|
+
* `adminium_settings` and not `MAX(updated_at)` over these rows.
|
|
19
|
+
*
|
|
20
|
+
* Column widths are index-budget driven, not guesses. The composite unique
|
|
21
|
+
* index spans scope(16) + locale(35) + namespace(16) + key(120) = 187 chars;
|
|
22
|
+
* MySQL's InnoDB utf8mb4 index-key limit of 3072 bytes allows 768, so this
|
|
23
|
+
* fits with 4x margin. The longest en-US key today is 64 chars. Widening
|
|
24
|
+
* `key` past ~200 would break MySQL, so it is bounded here rather than left
|
|
25
|
+
* to `text`.
|
|
26
|
+
*
|
|
27
|
+
* `scope` LEADS the unique index deliberately. It is reserved (always
|
|
28
|
+
* 'workspace' in v1) against a possible per-app string set; adding a leading
|
|
29
|
+
* column to a MySQL unique index later is the migration nobody wants.
|
|
30
|
+
*
|
|
31
|
+
* The column is `source_text`, NOT `src_hash`: `assertNoCredentialColumns`
|
|
32
|
+
* in the export path aborts an export on any column matching /hash$/i, and
|
|
33
|
+
* that assertion is a CI unit test.
|
|
34
|
+
*
|
|
35
|
+
* Index-guard note (index.ts): no `.ifNotExists()` on index creation — MySQL
|
|
36
|
+
* cannot parse it, and the ledger's exactly-once guarantee is the idempotency
|
|
37
|
+
* mechanism.
|
|
38
|
+
*/
|
|
39
|
+
import type { Kysely } from 'kysely';
|
|
40
|
+
import type { ColumnHelpers } from '../columns.js';
|
|
41
|
+
export declare function up(db: Kysely<unknown>, c: ColumnHelpers): Promise<void>;
|
|
42
|
+
//# sourceMappingURL=0011_i18n_runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"0011_i18n_runtime.d.ts","sourceRoot":"","sources":["../../src/migrations/0011_i18n_runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,wBAAsB,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA4E7E"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wave 0011 — runtime translations (23-runtime-translations.md §3.1, §3.2).
|
|
3
|
+
*
|
|
4
|
+
* Two tables, both deliberately SPARSE:
|
|
5
|
+
*
|
|
6
|
+
* - `adminium_locales` holds a row only when an admin deviates from a
|
|
7
|
+
* compiled locale's defaults (or invents a new one). A built-in locale
|
|
8
|
+
* with no row behaves exactly as it does today, and the immutable fields
|
|
9
|
+
* of a built-in row (`dir`, `font_hint`, `intl_tag`, names) are always
|
|
10
|
+
* read from the compiled registry — the row can only carry `enabled` and
|
|
11
|
+
* `sort_order`. That is what makes "zero rows ⇒ byte-identical to today"
|
|
12
|
+
* a structural guarantee rather than a convention, and it also means an
|
|
13
|
+
* admin cannot flip `ar_EG` to `ltr` and corrupt a shipped bundle.
|
|
14
|
+
* - `adminium_translations` holds one row per OVERRIDDEN message. Absence
|
|
15
|
+
* means "use the compiled built-in"; a row with an empty `value` means
|
|
16
|
+
* "deliberately blank" (§3.3). Reset-to-built-in is therefore a hard
|
|
17
|
+
* DELETE, which is why the version stamp is a counter in
|
|
18
|
+
* `adminium_settings` and not `MAX(updated_at)` over these rows.
|
|
19
|
+
*
|
|
20
|
+
* Column widths are index-budget driven, not guesses. The composite unique
|
|
21
|
+
* index spans scope(16) + locale(35) + namespace(16) + key(120) = 187 chars;
|
|
22
|
+
* MySQL's InnoDB utf8mb4 index-key limit of 3072 bytes allows 768, so this
|
|
23
|
+
* fits with 4x margin. The longest en-US key today is 64 chars. Widening
|
|
24
|
+
* `key` past ~200 would break MySQL, so it is bounded here rather than left
|
|
25
|
+
* to `text`.
|
|
26
|
+
*
|
|
27
|
+
* `scope` LEADS the unique index deliberately. It is reserved (always
|
|
28
|
+
* 'workspace' in v1) against a possible per-app string set; adding a leading
|
|
29
|
+
* column to a MySQL unique index later is the migration nobody wants.
|
|
30
|
+
*
|
|
31
|
+
* The column is `source_text`, NOT `src_hash`: `assertNoCredentialColumns`
|
|
32
|
+
* in the export path aborts an export on any column matching /hash$/i, and
|
|
33
|
+
* that assertion is a CI unit test.
|
|
34
|
+
*
|
|
35
|
+
* Index-guard note (index.ts): no `.ifNotExists()` on index creation — MySQL
|
|
36
|
+
* cannot parse it, and the ledger's exactly-once guarantee is the idempotency
|
|
37
|
+
* mechanism.
|
|
38
|
+
*/
|
|
39
|
+
import { metaTable } from '../prefix.js';
|
|
40
|
+
export async function up(db, c) {
|
|
41
|
+
await db.schema
|
|
42
|
+
.createTable(metaTable('locales'))
|
|
43
|
+
.ifNotExists()
|
|
44
|
+
.addColumn('id', c.id, (col) => col.primaryKey())
|
|
45
|
+
.addColumn('locale', c.str(35), (col) => col.notNull())
|
|
46
|
+
.addColumn('is_builtin', c.bool, (col) => col.notNull().defaultTo(c.boolDefault(false)))
|
|
47
|
+
.addColumn('enabled', c.bool, (col) => col.notNull().defaultTo(c.boolDefault(true)))
|
|
48
|
+
.addColumn('sort_order', c.int, (col) => col.notNull().defaultTo(0))
|
|
49
|
+
// Custom locales only — a built-in row reads these from the compiled registry.
|
|
50
|
+
.addColumn('english', c.str(80))
|
|
51
|
+
.addColumn('native', c.str(80))
|
|
52
|
+
.addColumn('dir', c.str(3))
|
|
53
|
+
.addColumn('font_hint', c.str(16))
|
|
54
|
+
// A REAL BCP-47 tag whose Intl behaviour a custom locale borrows (§5.6).
|
|
55
|
+
.addColumn('intl_tag', c.str(35))
|
|
56
|
+
// Frozen at create time from `intl_tag` so write validation is
|
|
57
|
+
// deterministic across the browser's ICU and Node's (§5.6).
|
|
58
|
+
.addColumn('plural_categories', c.json)
|
|
59
|
+
.addColumn('updated_by', c.id)
|
|
60
|
+
.addColumn('created_at', c.ts, (col) => col.notNull())
|
|
61
|
+
.addColumn('updated_at', c.ts, (col) => col.notNull())
|
|
62
|
+
.addForeignKeyConstraint('fk_adminium_locales_updated_by', ['updated_by'], metaTable('users'), ['id'], (cb) => cb.onDelete('set null'))
|
|
63
|
+
.execute();
|
|
64
|
+
await db.schema
|
|
65
|
+
.createIndex('uq_adminium_locales_locale')
|
|
66
|
+
.on(metaTable('locales'))
|
|
67
|
+
.columns(['locale'])
|
|
68
|
+
.unique()
|
|
69
|
+
.execute();
|
|
70
|
+
await db.schema
|
|
71
|
+
.createTable(metaTable('translations'))
|
|
72
|
+
.ifNotExists()
|
|
73
|
+
.addColumn('id', c.id, (col) => col.primaryKey())
|
|
74
|
+
.addColumn('scope', c.str(16), (col) => col.notNull().defaultTo('workspace'))
|
|
75
|
+
.addColumn('locale', c.str(35), (col) => col.notNull())
|
|
76
|
+
.addColumn('namespace', c.str(16), (col) => col.notNull())
|
|
77
|
+
.addColumn('key', c.str(120), (col) => col.notNull())
|
|
78
|
+
.addColumn('value', c.text, (col) => col.notNull())
|
|
79
|
+
// The en-US text this override was authored against, so the editor can
|
|
80
|
+
// flag "the English changed since this was written" (§7 stale badge).
|
|
81
|
+
.addColumn('source_text', c.text)
|
|
82
|
+
.addColumn('updated_by', c.id)
|
|
83
|
+
.addColumn('created_at', c.ts, (col) => col.notNull())
|
|
84
|
+
.addColumn('updated_at', c.ts, (col) => col.notNull())
|
|
85
|
+
.addForeignKeyConstraint('fk_adminium_translations_updated_by', ['updated_by'], metaTable('users'), ['id'], (cb) => cb.onDelete('set null'))
|
|
86
|
+
.execute();
|
|
87
|
+
await db.schema
|
|
88
|
+
.createIndex('uq_adminium_translations_scope_locale_ns_key')
|
|
89
|
+
.on(metaTable('translations'))
|
|
90
|
+
.columns(['scope', 'locale', 'namespace', 'key'])
|
|
91
|
+
.unique()
|
|
92
|
+
.execute();
|
|
93
|
+
// The bundle read path is always (scope, locale, namespace) — one index
|
|
94
|
+
// serves it and the per-locale budget count without scanning.
|
|
95
|
+
await db.schema
|
|
96
|
+
.createIndex('ix_adminium_translations_scope_locale_ns')
|
|
97
|
+
.on(metaTable('translations'))
|
|
98
|
+
.columns(['scope', 'locale', 'namespace'])
|
|
99
|
+
.execute();
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=0011_i18n_runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"0011_i18n_runtime.js","sourceRoot":"","sources":["../../src/migrations/0011_i18n_runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wave 0012 — widen the locale columns (23-runtime-translations.md §3.5).
|
|
3
|
+
*
|
|
4
|
+
* `adminium_user_prefs.locale` (0001) and `adminium_email_templates.locale`
|
|
5
|
+
* (0006) were sized `str(5)` for `en_US`. An admin-created locale id may carry
|
|
6
|
+
* a script subtag (`zh_Hant_TW`, 11 chars) and the registry allows up to 35,
|
|
7
|
+
* so both columns must widen or a custom locale can never be stored as a user
|
|
8
|
+
* preference or carry an email variant.
|
|
9
|
+
*
|
|
10
|
+
* SQLite masked the mismatch as usual (`str(n)` maps to `text`, lengths
|
|
11
|
+
* unenforced); PostgreSQL and strict-mode MySQL would reject the write.
|
|
12
|
+
*
|
|
13
|
+
* Up-only rule (index.ts): 0001 and 0006 are applied and checksummed, so this
|
|
14
|
+
* ships as a compensating migration rather than an edit. Raw dialect-branched
|
|
15
|
+
* ALTERs following 0010 verbatim, because MySQL's MODIFY restates the WHOLE
|
|
16
|
+
* column definition and Kysely's `setDataType` would silently drop the rest.
|
|
17
|
+
*
|
|
18
|
+
* NULLABILITY IS NOT SYMMETRIC HERE — get this wrong and the migration
|
|
19
|
+
* changes data semantics:
|
|
20
|
+
* - `user_prefs.locale` is NULLABLE (0001 line 44: no `.notNull()`); NULL
|
|
21
|
+
* means "inherit the workspace default", which is the whole
|
|
22
|
+
* reset-to-default affordance. MySQL's MODIFY must NOT add NOT NULL.
|
|
23
|
+
* - `email_templates.locale` is NOT NULL DEFAULT 'en_US' (0006 line 232);
|
|
24
|
+
* MySQL's MODIFY must restate both.
|
|
25
|
+
*/
|
|
26
|
+
import { type Kysely } from 'kysely';
|
|
27
|
+
import type { ColumnHelpers } from '../columns.js';
|
|
28
|
+
export declare function up(db: Kysely<unknown>, c: ColumnHelpers): Promise<void>;
|
|
29
|
+
//# sourceMappingURL=0012_locale_width.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"0012_locale_width.d.ts","sourceRoot":"","sources":["../../src/migrations/0012_locale_width.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAO,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,wBAAsB,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB7E"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wave 0012 — widen the locale columns (23-runtime-translations.md §3.5).
|
|
3
|
+
*
|
|
4
|
+
* `adminium_user_prefs.locale` (0001) and `adminium_email_templates.locale`
|
|
5
|
+
* (0006) were sized `str(5)` for `en_US`. An admin-created locale id may carry
|
|
6
|
+
* a script subtag (`zh_Hant_TW`, 11 chars) and the registry allows up to 35,
|
|
7
|
+
* so both columns must widen or a custom locale can never be stored as a user
|
|
8
|
+
* preference or carry an email variant.
|
|
9
|
+
*
|
|
10
|
+
* SQLite masked the mismatch as usual (`str(n)` maps to `text`, lengths
|
|
11
|
+
* unenforced); PostgreSQL and strict-mode MySQL would reject the write.
|
|
12
|
+
*
|
|
13
|
+
* Up-only rule (index.ts): 0001 and 0006 are applied and checksummed, so this
|
|
14
|
+
* ships as a compensating migration rather than an edit. Raw dialect-branched
|
|
15
|
+
* ALTERs following 0010 verbatim, because MySQL's MODIFY restates the WHOLE
|
|
16
|
+
* column definition and Kysely's `setDataType` would silently drop the rest.
|
|
17
|
+
*
|
|
18
|
+
* NULLABILITY IS NOT SYMMETRIC HERE — get this wrong and the migration
|
|
19
|
+
* changes data semantics:
|
|
20
|
+
* - `user_prefs.locale` is NULLABLE (0001 line 44: no `.notNull()`); NULL
|
|
21
|
+
* means "inherit the workspace default", which is the whole
|
|
22
|
+
* reset-to-default affordance. MySQL's MODIFY must NOT add NOT NULL.
|
|
23
|
+
* - `email_templates.locale` is NOT NULL DEFAULT 'en_US' (0006 line 232);
|
|
24
|
+
* MySQL's MODIFY must restate both.
|
|
25
|
+
*/
|
|
26
|
+
import { sql } from 'kysely';
|
|
27
|
+
import { metaTable } from '../prefix.js';
|
|
28
|
+
export async function up(db, c) {
|
|
29
|
+
const userPrefs = metaTable('user_prefs');
|
|
30
|
+
const emailTemplates = metaTable('email_templates');
|
|
31
|
+
if (c.dialect === 'postgres') {
|
|
32
|
+
await sql `ALTER TABLE ${sql.table(userPrefs)} ALTER COLUMN locale TYPE varchar(35)`.execute(db);
|
|
33
|
+
await sql `ALTER TABLE ${sql.table(emailTemplates)} ALTER COLUMN locale TYPE varchar(35)`.execute(db);
|
|
34
|
+
}
|
|
35
|
+
else if (c.dialect === 'mysql') {
|
|
36
|
+
// Nullable — restating NOT NULL here would destroy "inherit the default".
|
|
37
|
+
await sql `ALTER TABLE ${sql.table(userPrefs)} MODIFY COLUMN locale varchar(35) NULL`.execute(db);
|
|
38
|
+
await sql `ALTER TABLE ${sql.table(emailTemplates)} MODIFY COLUMN locale varchar(35) NOT NULL DEFAULT 'en_US'`.execute(db);
|
|
39
|
+
}
|
|
40
|
+
// sqlite: both columns are `text`; nothing to widen.
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=0012_locale_width.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"0012_locale_width.js","sourceRoot":"","sources":["../../src/migrations/0012_locale_width.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,GAAG,EAAe,MAAM,QAAQ,CAAC;AAG1C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,EAAE,CAAC,EAAmB,EAAE,CAAgB;IAC5D,MAAM,SAAS,GAAG,SAAS,CAAC,YAAY,CAAC,CAAC;IAC1C,MAAM,cAAc,GAAG,SAAS,CAAC,iBAAiB,CAAC,CAAC;IAEpD,IAAI,CAAC,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QAC7B,MAAM,GAAG,CAAA,eAAe,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,uCAAuC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAChG,MAAM,GAAG,CAAA,eAAe,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,uCAAuC,CAAC,OAAO,CAC9F,EAAE,CACH,CAAC;IACJ,CAAC;SAAM,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;QACjC,0EAA0E;QAC1E,MAAM,GAAG,CAAA,eAAe,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,wCAAwC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACjG,MAAM,GAAG,CAAA,eAAe,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,4DAA4D,CAAC,OAAO,CACnH,EAAE,CACH,CAAC;IACJ,CAAC;IACD,qDAAqD;AACvD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAcnD,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE;AAED,eAAO,MAAM,cAAc,EAAE,SAAS,aAAa,EAalD,CAAC"}
|
package/dist/migrations/index.js
CHANGED
|
@@ -28,6 +28,8 @@ import { up as up0007 } from './0007_llm_runs.js';
|
|
|
28
28
|
import { up as up0008 } from './0008_llm_overrides.js';
|
|
29
29
|
import { up as up0009 } from './0009_views_kind.js';
|
|
30
30
|
import { up as up0010 } from './0010_llm_prompt_version_width.js';
|
|
31
|
+
import { up as up0011 } from './0011_i18n_runtime.js';
|
|
32
|
+
import { up as up0012 } from './0012_locale_width.js';
|
|
31
33
|
export const ALL_MIGRATIONS = [
|
|
32
34
|
{ name: '0001_core_auth', up: up0001 },
|
|
33
35
|
{ name: '0002_rbac', up: up0002 },
|
|
@@ -39,5 +41,7 @@ export const ALL_MIGRATIONS = [
|
|
|
39
41
|
{ name: '0008_llm_overrides', up: up0008 },
|
|
40
42
|
{ name: '0009_views_kind', up: up0009 },
|
|
41
43
|
{ name: '0010_llm_prompt_version_width', up: up0010 },
|
|
44
|
+
{ name: '0011_i18n_runtime', up: up0011 },
|
|
45
|
+
{ name: '0012_locale_width', up: up0012 },
|
|
42
46
|
];
|
|
43
47
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAQtD,MAAM,CAAC,MAAM,cAAc,GAA6B;IACtD,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,MAAM,EAAE;IACtC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE;IACjC,EAAE,IAAI,EAAE,yBAAyB,EAAE,EAAE,EAAE,MAAM,EAAE;IAC/C,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,MAAM,EAAE;IACxC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE;IAChC,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,EAAE;IACrC,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,EAAE;IACrC,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAAE,EAAE,MAAM,EAAE;IAC1C,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,EAAE,MAAM,EAAE;IACvC,EAAE,IAAI,EAAE,+BAA+B,EAAE,EAAE,EAAE,MAAM,EAAE;IACrD,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,MAAM,EAAE;IACzC,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,MAAM,EAAE;CAC1C,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The runtime-translation version stamp (23-runtime-translations.md §3.4).
|
|
3
|
+
*
|
|
4
|
+
* Clients key their bundle cache — and the server its ETag — on this counter,
|
|
5
|
+
* so it must move on EVERY mutation of `adminium_locales` /
|
|
6
|
+
* `adminium_translations`, from every writer.
|
|
7
|
+
*
|
|
8
|
+
* Two decisions are load-bearing:
|
|
9
|
+
*
|
|
10
|
+
* 1. **A counter, not `MAX(updated_at)`.** Reset-to-built-in is a hard
|
|
11
|
+
* DELETE, so a max-timestamp over the rows cannot observe the single most
|
|
12
|
+
* common admin operation — the cache would go stale exactly when someone
|
|
13
|
+
* undoes a bad edit.
|
|
14
|
+
* 2. **Bumped in the repo layer, not in route handlers.** Config-bundle
|
|
15
|
+
* import has no HTTP route: it writes through repos from the CLI. A
|
|
16
|
+
* route-level bump would leave every client serving stale strings after
|
|
17
|
+
* an import, forever, with the ETag answering 304.
|
|
18
|
+
*
|
|
19
|
+
* Always call this inside the same transaction as the write it stamps.
|
|
20
|
+
*/
|
|
21
|
+
import type { Kysely, Transaction } from 'kysely';
|
|
22
|
+
import type { MetaDB } from '../schema/tables.js';
|
|
23
|
+
export type MetaExecutor = Kysely<MetaDB> | Transaction<MetaDB>;
|
|
24
|
+
/** Read the current stamp (0 when no override row exists yet). */
|
|
25
|
+
export declare function readI18nVersion(db: MetaExecutor): Promise<number>;
|
|
26
|
+
/**
|
|
27
|
+
* Increment the stamp and return the new value. Upserts by hand rather than
|
|
28
|
+
* through settingsRepo because that repo owns its own connection handle and
|
|
29
|
+
* this has to join the caller's transaction.
|
|
30
|
+
*/
|
|
31
|
+
export declare function bumpI18nVersion(db: MetaExecutor, at: number, updatedBy: string | null): Promise<number>;
|
|
32
|
+
//# sourceMappingURL=i18n-version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n-version.d.ts","sourceRoot":"","sources":["../../src/repos/i18n-version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAElD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAKlD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;AAEhE,kEAAkE;AAClE,wBAAsB,eAAe,CAAC,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CASvE;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,YAAY,EAChB,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,MAAM,GAAG,IAAI,GACvB,OAAO,CAAC,MAAM,CAAC,CAejB"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The runtime-translation version stamp (23-runtime-translations.md §3.4).
|
|
3
|
+
*
|
|
4
|
+
* Clients key their bundle cache — and the server its ETag — on this counter,
|
|
5
|
+
* so it must move on EVERY mutation of `adminium_locales` /
|
|
6
|
+
* `adminium_translations`, from every writer.
|
|
7
|
+
*
|
|
8
|
+
* Two decisions are load-bearing:
|
|
9
|
+
*
|
|
10
|
+
* 1. **A counter, not `MAX(updated_at)`.** Reset-to-built-in is a hard
|
|
11
|
+
* DELETE, so a max-timestamp over the rows cannot observe the single most
|
|
12
|
+
* common admin operation — the cache would go stale exactly when someone
|
|
13
|
+
* undoes a bad edit.
|
|
14
|
+
* 2. **Bumped in the repo layer, not in route handlers.** Config-bundle
|
|
15
|
+
* import has no HTTP route: it writes through repos from the CLI. A
|
|
16
|
+
* route-level bump would leave every client serving stale strings after
|
|
17
|
+
* an import, forever, with the ETag answering 304.
|
|
18
|
+
*
|
|
19
|
+
* Always call this inside the same transaction as the write it stamps.
|
|
20
|
+
*/
|
|
21
|
+
import { packJson, readJson } from './util.js';
|
|
22
|
+
const VERSION_KEY = 'i18n.version';
|
|
23
|
+
/** Read the current stamp (0 when no override row exists yet). */
|
|
24
|
+
export async function readI18nVersion(db) {
|
|
25
|
+
const row = await db
|
|
26
|
+
.selectFrom('adminium_settings')
|
|
27
|
+
.select(['value'])
|
|
28
|
+
.where('key', '=', VERSION_KEY)
|
|
29
|
+
.executeTakeFirst();
|
|
30
|
+
if (row === undefined)
|
|
31
|
+
return 0;
|
|
32
|
+
const parsed = readJson(row.value);
|
|
33
|
+
return typeof parsed === 'number' && Number.isFinite(parsed) ? parsed : 0;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Increment the stamp and return the new value. Upserts by hand rather than
|
|
37
|
+
* through settingsRepo because that repo owns its own connection handle and
|
|
38
|
+
* this has to join the caller's transaction.
|
|
39
|
+
*/
|
|
40
|
+
export async function bumpI18nVersion(db, at, updatedBy) {
|
|
41
|
+
const next = (await readI18nVersion(db)) + 1;
|
|
42
|
+
const packed = packJson(next);
|
|
43
|
+
const res = await db
|
|
44
|
+
.updateTable('adminium_settings')
|
|
45
|
+
.set({ value: packed, updatedAt: at, updatedBy })
|
|
46
|
+
.where('key', '=', VERSION_KEY)
|
|
47
|
+
.executeTakeFirst();
|
|
48
|
+
if (Number(res.numUpdatedRows) === 0) {
|
|
49
|
+
await db
|
|
50
|
+
.insertInto('adminium_settings')
|
|
51
|
+
.values({ key: VERSION_KEY, value: packed, updatedAt: at, updatedBy })
|
|
52
|
+
.execute();
|
|
53
|
+
}
|
|
54
|
+
return next;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=i18n-version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n-version.js","sourceRoot":"","sources":["../../src/repos/i18n-version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE/C,MAAM,WAAW,GAAG,cAAc,CAAC;AAInC,kEAAkE;AAClE,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EAAgB;IACpD,MAAM,GAAG,GAAG,MAAM,EAAE;SACjB,UAAU,CAAC,mBAAmB,CAAC;SAC/B,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC;SACjB,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,WAAW,CAAC;SAC9B,gBAAgB,EAAE,CAAC;IACtB,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,QAAQ,CAAU,GAAG,CAAC,KAAK,CAAC,CAAC;IAC5C,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,EAAgB,EAChB,EAAU,EACV,SAAwB;IAExB,MAAM,IAAI,GAAG,CAAC,MAAM,eAAe,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,MAAM,EAAE;SACjB,WAAW,CAAC,mBAAmB,CAAC;SAChC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC;SAChD,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,WAAW,CAAC;SAC9B,gBAAgB,EAAE,CAAC;IACtB,IAAI,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,EAAE;aACL,UAAU,CAAC,mBAAmB,CAAC;aAC/B,MAAM,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC;aACrE,OAAO,EAAE,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/repos/index.d.ts
CHANGED
|
@@ -23,4 +23,7 @@ export * from './notifications.js';
|
|
|
23
23
|
export * from './notification-prefs.js';
|
|
24
24
|
export * from './scheduled-reports.js';
|
|
25
25
|
export * from './email-templates.js';
|
|
26
|
+
export * from './i18n-version.js';
|
|
27
|
+
export * from './locales.js';
|
|
28
|
+
export * from './translations.js';
|
|
26
29
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/repos/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/repos/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC"}
|
package/dist/repos/index.js
CHANGED
|
@@ -23,4 +23,7 @@ export * from './notifications.js';
|
|
|
23
23
|
export * from './notification-prefs.js';
|
|
24
24
|
export * from './scheduled-reports.js';
|
|
25
25
|
export * from './email-templates.js';
|
|
26
|
+
export * from './i18n-version.js';
|
|
27
|
+
export * from './locales.js';
|
|
28
|
+
export * from './translations.js';
|
|
26
29
|
//# sourceMappingURL=index.js.map
|
package/dist/repos/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/repos/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/repos/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC"}
|