@objectstack/core 12.1.0 → 12.3.0
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/index.cjs +143 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +44 -1
- package/dist/index.d.ts +44 -1
- package/dist/index.js +139 -6
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -66,6 +66,7 @@ __export(index_exports, {
|
|
|
66
66
|
createMemoryQueue: () => createMemoryQueue,
|
|
67
67
|
createPluginConfigValidator: () => createPluginConfigValidator,
|
|
68
68
|
createPluginPermissionEnforcer: () => createPluginPermissionEnforcer,
|
|
69
|
+
deepMerge: () => deepMerge,
|
|
69
70
|
evaluateAuthGate: () => evaluateAuthGate,
|
|
70
71
|
extractApiKey: () => extractApiKey,
|
|
71
72
|
generateApiKey: () => generateApiKey,
|
|
@@ -78,6 +79,7 @@ __export(index_exports, {
|
|
|
78
79
|
isNode: () => isNode,
|
|
79
80
|
parseScopes: () => parseScopes,
|
|
80
81
|
parseSignature: () => parseSignature,
|
|
82
|
+
readAuthoredTranslationLayer: () => readAuthoredTranslationLayer,
|
|
81
83
|
resolveApiKeyPrincipal: () => resolveApiKeyPrincipal,
|
|
82
84
|
resolveAuthzContext: () => resolveAuthzContext,
|
|
83
85
|
resolveLocale: () => resolveLocale,
|
|
@@ -87,7 +89,8 @@ __export(index_exports, {
|
|
|
87
89
|
verifyPayload: () => verifyPayload,
|
|
88
90
|
verifyPlatformSignature: () => verifyPlatformSignature,
|
|
89
91
|
verifyPluginArtifact: () => verifyPluginArtifact,
|
|
90
|
-
verifyPublisherSignature: () => verifyPublisherSignature
|
|
92
|
+
verifyPublisherSignature: () => verifyPublisherSignature,
|
|
93
|
+
wireAuthoredTranslationSync: () => wireAuthoredTranslationSync
|
|
91
94
|
});
|
|
92
95
|
module.exports = __toCommonJS(index_exports);
|
|
93
96
|
|
|
@@ -1142,6 +1145,7 @@ function resolveLocale(requestedLocale, availableLocales) {
|
|
|
1142
1145
|
}
|
|
1143
1146
|
function createMemoryI18n() {
|
|
1144
1147
|
const translations = /* @__PURE__ */ new Map();
|
|
1148
|
+
const authored = /* @__PURE__ */ new Map();
|
|
1145
1149
|
let defaultLocale = "en";
|
|
1146
1150
|
function resolveKey(data, key) {
|
|
1147
1151
|
const parts = key.split(".");
|
|
@@ -1152,17 +1156,25 @@ function createMemoryI18n() {
|
|
|
1152
1156
|
}
|
|
1153
1157
|
return typeof current === "string" ? current : void 0;
|
|
1154
1158
|
}
|
|
1159
|
+
function mergedLocale(locale) {
|
|
1160
|
+
const stat = translations.get(locale);
|
|
1161
|
+
const auth = authored.get(locale);
|
|
1162
|
+
if (stat && auth) return deepMerge(stat, auth);
|
|
1163
|
+
return auth ?? stat;
|
|
1164
|
+
}
|
|
1155
1165
|
function resolveTranslations(locale) {
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1166
|
+
const exact = mergedLocale(locale);
|
|
1167
|
+
if (exact) return exact;
|
|
1168
|
+
const allLocales = [.../* @__PURE__ */ new Set([...translations.keys(), ...authored.keys()])];
|
|
1169
|
+
const resolved = resolveLocale(locale, allLocales);
|
|
1170
|
+
if (resolved) return mergedLocale(resolved);
|
|
1159
1171
|
return void 0;
|
|
1160
1172
|
}
|
|
1161
1173
|
return {
|
|
1162
1174
|
_fallback: true,
|
|
1163
1175
|
_serviceName: "i18n",
|
|
1164
1176
|
t(key, locale, params) {
|
|
1165
|
-
const data = resolveTranslations(locale) ??
|
|
1177
|
+
const data = resolveTranslations(locale) ?? mergedLocale(defaultLocale);
|
|
1166
1178
|
const value = data ? resolveKey(data, key) : void 0;
|
|
1167
1179
|
if (value == null) return key;
|
|
1168
1180
|
if (!params) return value;
|
|
@@ -1179,8 +1191,21 @@ function createMemoryI18n() {
|
|
|
1179
1191
|
translations.set(locale, { ...data });
|
|
1180
1192
|
}
|
|
1181
1193
|
},
|
|
1194
|
+
/**
|
|
1195
|
+
* Replace the ENTIRE runtime-authored translation layer (#2591). Called
|
|
1196
|
+
* by the authored-translation sync with the full current set of active
|
|
1197
|
+
* `translation` metadata items keyed by locale. Wholesale replacement —
|
|
1198
|
+
* not a merge — so deleted items/keys stop resolving on the next sync.
|
|
1199
|
+
*/
|
|
1200
|
+
replaceAuthoredTranslations(byLocale) {
|
|
1201
|
+
authored.clear();
|
|
1202
|
+
for (const [locale, data] of Object.entries(byLocale ?? {})) {
|
|
1203
|
+
if (!data || typeof data !== "object") continue;
|
|
1204
|
+
authored.set(locale, { ...data });
|
|
1205
|
+
}
|
|
1206
|
+
},
|
|
1182
1207
|
getLocales() {
|
|
1183
|
-
return [...translations.keys()];
|
|
1208
|
+
return [.../* @__PURE__ */ new Set([...translations.keys(), ...authored.keys()])];
|
|
1184
1209
|
},
|
|
1185
1210
|
getDefaultLocale() {
|
|
1186
1211
|
return defaultLocale;
|
|
@@ -1245,6 +1270,114 @@ function createMemoryMetadata() {
|
|
|
1245
1270
|
};
|
|
1246
1271
|
}
|
|
1247
1272
|
|
|
1273
|
+
// src/fallbacks/authored-translation-sync.ts
|
|
1274
|
+
var OWNER_PROP = "__authoredTranslationSyncOwner";
|
|
1275
|
+
var LOCALE_LIKE = /^[a-z]{2,3}([_-]([A-Za-z]{4}|[A-Za-z]{2}|[0-9]{3}))?$/;
|
|
1276
|
+
async function readAuthoredTranslationLayer(engine, logger) {
|
|
1277
|
+
let rows;
|
|
1278
|
+
try {
|
|
1279
|
+
rows = await engine.find("sys_metadata", {
|
|
1280
|
+
where: { type: "translation", state: "active" }
|
|
1281
|
+
}) ?? [];
|
|
1282
|
+
if (rows.length === 0) {
|
|
1283
|
+
rows = await engine.find("sys_metadata", {
|
|
1284
|
+
where: { type: "translations", state: "active" }
|
|
1285
|
+
}) ?? [];
|
|
1286
|
+
}
|
|
1287
|
+
} catch (err) {
|
|
1288
|
+
logger?.debug?.("[i18n] authored-translation read failed \u2014 keeping current layer", {
|
|
1289
|
+
error: err?.message
|
|
1290
|
+
});
|
|
1291
|
+
return null;
|
|
1292
|
+
}
|
|
1293
|
+
const byLocale = {};
|
|
1294
|
+
const sorted = [...rows].sort((a, b) => String(a?.name ?? "").localeCompare(String(b?.name ?? "")));
|
|
1295
|
+
for (const row of sorted) {
|
|
1296
|
+
let data;
|
|
1297
|
+
try {
|
|
1298
|
+
data = typeof row.metadata === "string" ? JSON.parse(row.metadata) : row.metadata;
|
|
1299
|
+
} catch {
|
|
1300
|
+
continue;
|
|
1301
|
+
}
|
|
1302
|
+
if (!data || typeof data !== "object") continue;
|
|
1303
|
+
const locale = typeof data?._meta?.locale === "string" && data._meta.locale || typeof data?.locale === "string" && data.locale || (typeof row?.name === "string" && LOCALE_LIKE.test(row.name) ? row.name : void 0) || void 0;
|
|
1304
|
+
if (!locale) {
|
|
1305
|
+
logger?.warn?.(
|
|
1306
|
+
`[i18n] authored translation '${row?.name}' has no resolvable locale (set _meta.locale, or name the item after its BCP-47 locale) \u2014 skipped`
|
|
1307
|
+
);
|
|
1308
|
+
continue;
|
|
1309
|
+
}
|
|
1310
|
+
const { name: _n, locale: _l, _packageId: _p, _provenance: _pr, _lock: _lk, ...payload } = data;
|
|
1311
|
+
byLocale[locale] = deepMerge(byLocale[locale] ?? {}, payload);
|
|
1312
|
+
}
|
|
1313
|
+
return byLocale;
|
|
1314
|
+
}
|
|
1315
|
+
function wireAuthoredTranslationSync(ctx) {
|
|
1316
|
+
if (typeof ctx.hook !== "function") return;
|
|
1317
|
+
const token = /* @__PURE__ */ Symbol("authored-translation-sync");
|
|
1318
|
+
const resolveOwnedI18n = () => {
|
|
1319
|
+
let i18n;
|
|
1320
|
+
try {
|
|
1321
|
+
i18n = ctx.getService("i18n");
|
|
1322
|
+
} catch {
|
|
1323
|
+
return null;
|
|
1324
|
+
}
|
|
1325
|
+
if (!i18n || typeof i18n.replaceAuthoredTranslations !== "function") return null;
|
|
1326
|
+
const current = i18n[OWNER_PROP];
|
|
1327
|
+
if (current === void 0) {
|
|
1328
|
+
i18n[OWNER_PROP] = token;
|
|
1329
|
+
return i18n;
|
|
1330
|
+
}
|
|
1331
|
+
return current === token ? i18n : null;
|
|
1332
|
+
};
|
|
1333
|
+
let chain = Promise.resolve();
|
|
1334
|
+
const sync = () => {
|
|
1335
|
+
const run = chain.then(async () => {
|
|
1336
|
+
const i18n = resolveOwnedI18n();
|
|
1337
|
+
if (!i18n) return;
|
|
1338
|
+
let engine;
|
|
1339
|
+
try {
|
|
1340
|
+
engine = ctx.getService("objectql");
|
|
1341
|
+
} catch {
|
|
1342
|
+
return;
|
|
1343
|
+
}
|
|
1344
|
+
if (!engine || typeof engine.find !== "function") return;
|
|
1345
|
+
const layer = await readAuthoredTranslationLayer(engine, ctx.logger);
|
|
1346
|
+
if (layer === null) return;
|
|
1347
|
+
i18n.replaceAuthoredTranslations(layer);
|
|
1348
|
+
ctx.logger.info?.("[i18n] synced runtime-authored translations", {
|
|
1349
|
+
locales: Object.keys(layer)
|
|
1350
|
+
});
|
|
1351
|
+
});
|
|
1352
|
+
chain = run.catch(() => void 0);
|
|
1353
|
+
return run;
|
|
1354
|
+
};
|
|
1355
|
+
ctx.hook("kernel:ready", async () => {
|
|
1356
|
+
if (resolveOwnedI18n()) {
|
|
1357
|
+
let protocol = null;
|
|
1358
|
+
try {
|
|
1359
|
+
protocol = ctx.getService("protocol");
|
|
1360
|
+
} catch {
|
|
1361
|
+
}
|
|
1362
|
+
if (protocol && typeof protocol.onMetadataMutation === "function") {
|
|
1363
|
+
protocol.onMetadataMutation((evt) => {
|
|
1364
|
+
if (evt?.type !== "translation" || evt.state === "draft") return;
|
|
1365
|
+
void sync().catch((err) => {
|
|
1366
|
+
ctx.logger.warn?.("[i18n] authored-translation re-sync after mutation failed", {
|
|
1367
|
+
item: evt.name,
|
|
1368
|
+
error: err?.message
|
|
1369
|
+
});
|
|
1370
|
+
});
|
|
1371
|
+
});
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
await sync();
|
|
1375
|
+
});
|
|
1376
|
+
ctx.hook("metadata:reloaded", async () => {
|
|
1377
|
+
await sync();
|
|
1378
|
+
});
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1248
1381
|
// src/fallbacks/index.ts
|
|
1249
1382
|
var CORE_FALLBACK_FACTORIES = {
|
|
1250
1383
|
metadata: createMemoryMetadata,
|
|
@@ -5281,6 +5414,7 @@ var NamespaceResolver = class {
|
|
|
5281
5414
|
createMemoryQueue,
|
|
5282
5415
|
createPluginConfigValidator,
|
|
5283
5416
|
createPluginPermissionEnforcer,
|
|
5417
|
+
deepMerge,
|
|
5284
5418
|
evaluateAuthGate,
|
|
5285
5419
|
extractApiKey,
|
|
5286
5420
|
generateApiKey,
|
|
@@ -5293,6 +5427,7 @@ var NamespaceResolver = class {
|
|
|
5293
5427
|
isNode,
|
|
5294
5428
|
parseScopes,
|
|
5295
5429
|
parseSignature,
|
|
5430
|
+
readAuthoredTranslationLayer,
|
|
5296
5431
|
resolveApiKeyPrincipal,
|
|
5297
5432
|
resolveAuthzContext,
|
|
5298
5433
|
resolveLocale,
|
|
@@ -5302,6 +5437,7 @@ var NamespaceResolver = class {
|
|
|
5302
5437
|
verifyPayload,
|
|
5303
5438
|
verifyPlatformSignature,
|
|
5304
5439
|
verifyPluginArtifact,
|
|
5305
|
-
verifyPublisherSignature
|
|
5440
|
+
verifyPublisherSignature,
|
|
5441
|
+
wireAuthoredTranslationSync
|
|
5306
5442
|
});
|
|
5307
5443
|
//# sourceMappingURL=index.cjs.map
|