@stardeck-customer-apps/compose 0.5.0 → 0.6.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/SKILL.md +8 -0
- package/dist/cli.js +119 -10
- package/dist/index.js +119 -10
- package/dist/index.mjs +119 -10
- package/package.json +1 -1
package/SKILL.md
CHANGED
|
@@ -81,6 +81,14 @@ a silent fallback. It holds deployment facts: gitignore it (`apps/web/.gitignore
|
|
|
81
81
|
missing or wrong makes compose refuse rather than clobber your edit.
|
|
82
82
|
- Change `module.json` (or the Module's own source under `routes/`,
|
|
83
83
|
`contributions.ts`, `i18n/`, …) and re-run compose.
|
|
84
|
+
- To reword a Module string, don't edit the Module: put the same key in
|
|
85
|
+
`apps/web/src/lib/i18n/overrides/<locale>.json` (app-owned, composed last).
|
|
86
|
+
It may only replace keys a Module or `lib/i18n/substrate/` defines; an
|
|
87
|
+
override of a missing key fails compose and names the key. An override file
|
|
88
|
+
for a locale the Modules don't ship (e.g. `ja`) translates their keys for that
|
|
89
|
+
locale; the locale also needs a `lib/i18n/substrate/<locale>.json`. New keys
|
|
90
|
+
go in `lib/i18n/substrate/<locale>.json`, never in an override. Needs compose
|
|
91
|
+
0.6.0 or later.
|
|
84
92
|
- `@stardeck-customer-apps/compose/runtime` exports `isModuleEnabledByList`,
|
|
85
93
|
the single enablement rule, and imports nothing — it is safe in client
|
|
86
94
|
components.
|
package/dist/cli.js
CHANGED
|
@@ -4267,6 +4267,40 @@ function cloneTree(value) {
|
|
|
4267
4267
|
}
|
|
4268
4268
|
return clone;
|
|
4269
4269
|
}
|
|
4270
|
+
function collectLeafPaths(value, path3, out) {
|
|
4271
|
+
if (typeof value === "string") {
|
|
4272
|
+
out.push(path3);
|
|
4273
|
+
return;
|
|
4274
|
+
}
|
|
4275
|
+
assertMessageTree(value, path3);
|
|
4276
|
+
for (const [key, child] of Object.entries(value)) collectLeafPaths(child, `${path3}.${key}`, out);
|
|
4277
|
+
}
|
|
4278
|
+
function overrideInto(target, source, owner, path3, missing) {
|
|
4279
|
+
for (const [key, value] of Object.entries(source)) {
|
|
4280
|
+
const nextPath = path3 ? `${path3}.${key}` : key;
|
|
4281
|
+
if (!Object.prototype.hasOwnProperty.call(target, key)) {
|
|
4282
|
+
collectLeafPaths(value, nextPath, missing);
|
|
4283
|
+
continue;
|
|
4284
|
+
}
|
|
4285
|
+
const existing = target[key];
|
|
4286
|
+
if (typeof value === "string") {
|
|
4287
|
+
if (typeof existing !== "string") {
|
|
4288
|
+
throw new Error(
|
|
4289
|
+
`[ModuleRail] composition artifacts: i18n merge conflict at ${nextPath}: ${owner} has string leaf but another owner has an object`
|
|
4290
|
+
);
|
|
4291
|
+
}
|
|
4292
|
+
target[key] = value;
|
|
4293
|
+
continue;
|
|
4294
|
+
}
|
|
4295
|
+
assertMessageTree(value, nextPath);
|
|
4296
|
+
if (typeof existing === "string") {
|
|
4297
|
+
throw new Error(
|
|
4298
|
+
`[ModuleRail] composition artifacts: i18n merge conflict at ${nextPath}: ${owner} has object but another owner has a string leaf`
|
|
4299
|
+
);
|
|
4300
|
+
}
|
|
4301
|
+
overrideInto(existing, value, owner, nextPath, missing);
|
|
4302
|
+
}
|
|
4303
|
+
}
|
|
4270
4304
|
function composeLocaleMessagesForPlan(layers) {
|
|
4271
4305
|
const result = createMessageTree();
|
|
4272
4306
|
const leafOwners = /* @__PURE__ */ new Map();
|
|
@@ -4318,7 +4352,17 @@ function composeLocaleMessagesForPlan(layers) {
|
|
|
4318
4352
|
}
|
|
4319
4353
|
for (const layer of layers) {
|
|
4320
4354
|
assertMessageTree(layer.messages, layer.owner);
|
|
4321
|
-
|
|
4355
|
+
if (!layer.override) {
|
|
4356
|
+
mergeInto(result, cloneTree(layer.messages), layer.owner, "");
|
|
4357
|
+
continue;
|
|
4358
|
+
}
|
|
4359
|
+
const missing = [];
|
|
4360
|
+
overrideInto(result, cloneTree(layer.messages), layer.owner, "", missing);
|
|
4361
|
+
if (missing.length > 0) {
|
|
4362
|
+
throw new Error(
|
|
4363
|
+
`[ModuleRail] composition artifacts: i18n override in ${layer.owner} replaces keys that no Module or substrate defines: ${missing.join(", ")}`
|
|
4364
|
+
);
|
|
4365
|
+
}
|
|
4322
4366
|
}
|
|
4323
4367
|
return result;
|
|
4324
4368
|
}
|
|
@@ -4497,6 +4541,7 @@ function emitModuleI18nGenTs(input) {
|
|
|
4497
4541
|
);
|
|
4498
4542
|
}
|
|
4499
4543
|
const targetLocales = substrate.map((l) => l.locale);
|
|
4544
|
+
const overrideByLocale = indexOverrideLocales(input.overrideLocales ?? [], targetLocales);
|
|
4500
4545
|
const installed = new Set(input.registry.modules.map((m) => m.name));
|
|
4501
4546
|
const allLayers = input.moduleLayers ? [...input.moduleLayers] : deriveModuleLocaleLayers(input.registry, input.facts);
|
|
4502
4547
|
const layers = allLayers.filter((layer) => installed.has(layer.owner.split("/")[0]));
|
|
@@ -4517,19 +4562,38 @@ function emitModuleI18nGenTs(input) {
|
|
|
4517
4562
|
const messages = layer.localeMessages[locale] ?? (locale === "en" ? layer.enMessages : layer.enMessages);
|
|
4518
4563
|
composeLayers.push({ owner: layer.sourceLabel, messages });
|
|
4519
4564
|
}
|
|
4565
|
+
const override = overrideByLocale.get(locale);
|
|
4566
|
+
if (override) {
|
|
4567
|
+
composeLayers.push({
|
|
4568
|
+
owner: overrideOwner(locale),
|
|
4569
|
+
messages: override.messages,
|
|
4570
|
+
override: true
|
|
4571
|
+
});
|
|
4572
|
+
}
|
|
4520
4573
|
composeLocaleMessagesForPlan(composeLayers);
|
|
4521
4574
|
}
|
|
4522
4575
|
const composeImport = 'import { composeLocaleMessages } from "@/lib/i18n/compose-messages";';
|
|
4523
4576
|
const moduleJsonImports = [];
|
|
4524
4577
|
const relativeSubstrateImports = [];
|
|
4525
4578
|
const substrateIdentByLocale = {};
|
|
4579
|
+
const overrideIdentByLocale = {};
|
|
4526
4580
|
targetLocales.forEach((locale, localeIdx) => {
|
|
4527
4581
|
const ident = `i18nSubstrateLoc${localeIdx}`;
|
|
4528
4582
|
relativeSubstrateImports.push(
|
|
4529
4583
|
`import ${ident} from ${JSON.stringify(`./lib/i18n/substrate/${locale}.json`)};`
|
|
4530
4584
|
);
|
|
4531
4585
|
substrateIdentByLocale[locale] = ident;
|
|
4586
|
+
if (overrideByLocale.has(locale)) {
|
|
4587
|
+
const overrideIdent = `i18nOverrideLoc${localeIdx}`;
|
|
4588
|
+
relativeSubstrateImports.push(
|
|
4589
|
+
`import ${overrideIdent} from ${JSON.stringify(`./${overrideOwner(locale)}`)};`
|
|
4590
|
+
);
|
|
4591
|
+
overrideIdentByLocale[locale] = overrideIdent;
|
|
4592
|
+
}
|
|
4532
4593
|
});
|
|
4594
|
+
relativeSubstrateImports.sort(
|
|
4595
|
+
(a, b) => compareImportSpecifiers(a.match(/ from (.+);$/)[1], b.match(/ from (.+);$/)[1])
|
|
4596
|
+
);
|
|
4533
4597
|
const layerIdents = [];
|
|
4534
4598
|
layers.forEach((layer, layerIdx) => {
|
|
4535
4599
|
const localeIdents = {};
|
|
@@ -4563,15 +4627,29 @@ function emitModuleI18nGenTs(input) {
|
|
|
4563
4627
|
(layer) => ` { owner: ${JSON.stringify(layer.owner)}, messages: ${layer.localeIdents[locale]} },`
|
|
4564
4628
|
)
|
|
4565
4629
|
];
|
|
4630
|
+
const overrideIdent = overrideIdentByLocale[locale];
|
|
4631
|
+
const messageLines = overrideIdent ? [
|
|
4632
|
+
" messages: composeLocaleMessages([",
|
|
4633
|
+
" ...[",
|
|
4634
|
+
...layerLines,
|
|
4635
|
+
" ].map((layer) => ({",
|
|
4636
|
+
" ...layer,",
|
|
4637
|
+
' disabled: layer.owner !== "substrate" && !layer.owner.split("/").every(enabled),',
|
|
4638
|
+
" })),",
|
|
4639
|
+
` { owner: ${JSON.stringify(overrideOwner(locale))}, messages: ${overrideIdent}, override: true },`,
|
|
4640
|
+
" ]),"
|
|
4641
|
+
] : [
|
|
4642
|
+
" messages: composeLocaleMessages([",
|
|
4643
|
+
...layerLines,
|
|
4644
|
+
" ].filter((layer) =>",
|
|
4645
|
+
' layer.owner === "substrate" || layer.owner.split("/").every(enabled)',
|
|
4646
|
+
" )),"
|
|
4647
|
+
];
|
|
4566
4648
|
bundleBlocks.push(
|
|
4567
4649
|
[
|
|
4568
4650
|
` ${JSON.stringify(locale)}: {`,
|
|
4569
4651
|
` locale: ${JSON.stringify(locale)},`,
|
|
4570
|
-
|
|
4571
|
-
...layerLines,
|
|
4572
|
-
" ].filter((layer) =>",
|
|
4573
|
-
' layer.owner === "substrate" || layer.owner.split("/").every(enabled)',
|
|
4574
|
-
" )),",
|
|
4652
|
+
...messageLines,
|
|
4575
4653
|
" }"
|
|
4576
4654
|
].join("\n")
|
|
4577
4655
|
);
|
|
@@ -4616,6 +4694,26 @@ function emitModuleI18nGenTs(input) {
|
|
|
4616
4694
|
""
|
|
4617
4695
|
].join("\n");
|
|
4618
4696
|
}
|
|
4697
|
+
function indexOverrideLocales(overrideLocales, targetLocales) {
|
|
4698
|
+
const byLocale = /* @__PURE__ */ new Map();
|
|
4699
|
+
for (const layer of overrideLocales) {
|
|
4700
|
+
if (!isValidLocaleBasename(layer.locale)) {
|
|
4701
|
+
throw new Error(
|
|
4702
|
+
`[ModuleRail] composition artifacts: unsafe override locale basename "${layer.locale}"`
|
|
4703
|
+
);
|
|
4704
|
+
}
|
|
4705
|
+
if (!targetLocales.includes(layer.locale)) {
|
|
4706
|
+
throw new Error(
|
|
4707
|
+
`[ModuleRail] composition artifacts: ${overrideOwner(layer.locale)} has no matching lib/i18n/substrate/${layer.locale}.json; add that substrate file to make ${layer.locale} an app locale`
|
|
4708
|
+
);
|
|
4709
|
+
}
|
|
4710
|
+
byLocale.set(layer.locale, layer);
|
|
4711
|
+
}
|
|
4712
|
+
return byLocale;
|
|
4713
|
+
}
|
|
4714
|
+
function overrideOwner(locale) {
|
|
4715
|
+
return `lib/i18n/overrides/${locale}.json`;
|
|
4716
|
+
}
|
|
4619
4717
|
function deriveModuleLocaleLayers(registry, facts) {
|
|
4620
4718
|
const layers = [];
|
|
4621
4719
|
const installed = new Set(registry.modules.map((m) => m.name));
|
|
@@ -5494,7 +5592,8 @@ function planCompositionArtifacts(input) {
|
|
|
5494
5592
|
registry: input.registry,
|
|
5495
5593
|
facts: compositionEntryFacts,
|
|
5496
5594
|
substrateLocales,
|
|
5497
|
-
moduleLayers: input.moduleLocaleLayers
|
|
5595
|
+
moduleLayers: input.moduleLocaleLayers,
|
|
5596
|
+
overrideLocales: input.overrideLocales
|
|
5498
5597
|
});
|
|
5499
5598
|
initContent = emitModuleInitServerGenTs({
|
|
5500
5599
|
registry: input.registry,
|
|
@@ -6839,7 +6938,8 @@ async function collectCompositionEntryFacts(context, registry) {
|
|
|
6839
6938
|
`[ModuleRail] runId=${context.runId} collecting composition entry facts modules=${registry.modules.length}`
|
|
6840
6939
|
);
|
|
6841
6940
|
const substrateDir = `${APP_PACKAGE_DIR}/src/lib/i18n/substrate`;
|
|
6842
|
-
const
|
|
6941
|
+
const overridesDir = `${APP_PACKAGE_DIR}/src/lib/i18n/overrides`;
|
|
6942
|
+
const localeDirs = [substrateDir, overridesDir];
|
|
6843
6943
|
const conventionalPaths = [];
|
|
6844
6944
|
for (const mod of registry.modules) {
|
|
6845
6945
|
const modulePath = `${MODULES_SANDBOX_DIR}/${mod.name}`;
|
|
@@ -6890,6 +6990,12 @@ async function collectCompositionEntryFacts(context, registry) {
|
|
|
6890
6990
|
messages: await readJsonObjectFile(localePath, files)
|
|
6891
6991
|
});
|
|
6892
6992
|
}
|
|
6993
|
+
const overrideLocales = [];
|
|
6994
|
+
for (const locale of localesByDir.get(overridesDir) ?? []) {
|
|
6995
|
+
const localePath = `${overridesDir}/${locale}.json`;
|
|
6996
|
+
assertRealLocaleJsonFilePresence(localePath, localePresences.get(localePath) ?? "unreadable");
|
|
6997
|
+
overrideLocales.push({ locale, messages: await readJsonObjectFile(localePath, files) });
|
|
6998
|
+
}
|
|
6893
6999
|
const facts = [];
|
|
6894
7000
|
const moduleLocaleLayers = [];
|
|
6895
7001
|
for (const mod of registry.modules) {
|
|
@@ -7016,9 +7122,9 @@ async function collectCompositionEntryFacts(context, registry) {
|
|
|
7016
7122
|
facts.sort((a, b) => a.moduleName.localeCompare(b.moduleName));
|
|
7017
7123
|
moduleLocaleLayers.sort((a, b) => a.sourceLabel.localeCompare(b.sourceLabel));
|
|
7018
7124
|
console.log(
|
|
7019
|
-
`[ModuleRail] runId=${context.runId} composition entry facts modules=${facts.length} substrateLocales=${substrateLocales.length} moduleLocaleLayers=${moduleLocaleLayers.length}`
|
|
7125
|
+
`[ModuleRail] runId=${context.runId} composition entry facts modules=${facts.length} substrateLocales=${substrateLocales.length} overrideLocales=${overrideLocales.map((layer) => layer.locale).join(",") || "none"} moduleLocaleLayers=${moduleLocaleLayers.length}`
|
|
7020
7126
|
);
|
|
7021
|
-
return { facts, substrateLocales, moduleLocaleLayers };
|
|
7127
|
+
return { facts, substrateLocales, overrideLocales, moduleLocaleLayers };
|
|
7022
7128
|
}
|
|
7023
7129
|
function selectComposedModules(presentNames, manifestsByName, enabledRaw) {
|
|
7024
7130
|
if (enabledRaw) {
|
|
@@ -7158,6 +7264,7 @@ async function reconcileCompositionArtifacts(context, options = {}) {
|
|
|
7158
7264
|
const {
|
|
7159
7265
|
facts: compositionEntryFacts,
|
|
7160
7266
|
substrateLocales,
|
|
7267
|
+
overrideLocales,
|
|
7161
7268
|
moduleLocaleLayers
|
|
7162
7269
|
} = await collectCompositionEntryFacts(context, registry);
|
|
7163
7270
|
const candidatePaths = /* @__PURE__ */ new Set([
|
|
@@ -7180,6 +7287,7 @@ async function reconcileCompositionArtifacts(context, options = {}) {
|
|
|
7180
7287
|
existingAppRoutes,
|
|
7181
7288
|
compositionEntryFacts,
|
|
7182
7289
|
substrateLocales,
|
|
7290
|
+
overrideLocales,
|
|
7183
7291
|
moduleLocaleLayers,
|
|
7184
7292
|
moduleDataStoreBindings
|
|
7185
7293
|
});
|
|
@@ -7248,6 +7356,7 @@ async function reconcileCompositionArtifacts(context, options = {}) {
|
|
|
7248
7356
|
existingAppRoutes,
|
|
7249
7357
|
compositionEntryFacts,
|
|
7250
7358
|
substrateLocales,
|
|
7359
|
+
overrideLocales,
|
|
7251
7360
|
moduleLocaleLayers,
|
|
7252
7361
|
moduleDataStoreBindings
|
|
7253
7362
|
});
|
package/dist/index.js
CHANGED
|
@@ -4276,6 +4276,40 @@ function cloneTree(value) {
|
|
|
4276
4276
|
}
|
|
4277
4277
|
return clone;
|
|
4278
4278
|
}
|
|
4279
|
+
function collectLeafPaths(value, path3, out) {
|
|
4280
|
+
if (typeof value === "string") {
|
|
4281
|
+
out.push(path3);
|
|
4282
|
+
return;
|
|
4283
|
+
}
|
|
4284
|
+
assertMessageTree(value, path3);
|
|
4285
|
+
for (const [key, child] of Object.entries(value)) collectLeafPaths(child, `${path3}.${key}`, out);
|
|
4286
|
+
}
|
|
4287
|
+
function overrideInto(target, source, owner, path3, missing) {
|
|
4288
|
+
for (const [key, value] of Object.entries(source)) {
|
|
4289
|
+
const nextPath = path3 ? `${path3}.${key}` : key;
|
|
4290
|
+
if (!Object.prototype.hasOwnProperty.call(target, key)) {
|
|
4291
|
+
collectLeafPaths(value, nextPath, missing);
|
|
4292
|
+
continue;
|
|
4293
|
+
}
|
|
4294
|
+
const existing = target[key];
|
|
4295
|
+
if (typeof value === "string") {
|
|
4296
|
+
if (typeof existing !== "string") {
|
|
4297
|
+
throw new Error(
|
|
4298
|
+
`[ModuleRail] composition artifacts: i18n merge conflict at ${nextPath}: ${owner} has string leaf but another owner has an object`
|
|
4299
|
+
);
|
|
4300
|
+
}
|
|
4301
|
+
target[key] = value;
|
|
4302
|
+
continue;
|
|
4303
|
+
}
|
|
4304
|
+
assertMessageTree(value, nextPath);
|
|
4305
|
+
if (typeof existing === "string") {
|
|
4306
|
+
throw new Error(
|
|
4307
|
+
`[ModuleRail] composition artifacts: i18n merge conflict at ${nextPath}: ${owner} has object but another owner has a string leaf`
|
|
4308
|
+
);
|
|
4309
|
+
}
|
|
4310
|
+
overrideInto(existing, value, owner, nextPath, missing);
|
|
4311
|
+
}
|
|
4312
|
+
}
|
|
4279
4313
|
function composeLocaleMessagesForPlan(layers) {
|
|
4280
4314
|
const result = createMessageTree();
|
|
4281
4315
|
const leafOwners = /* @__PURE__ */ new Map();
|
|
@@ -4327,7 +4361,17 @@ function composeLocaleMessagesForPlan(layers) {
|
|
|
4327
4361
|
}
|
|
4328
4362
|
for (const layer of layers) {
|
|
4329
4363
|
assertMessageTree(layer.messages, layer.owner);
|
|
4330
|
-
|
|
4364
|
+
if (!layer.override) {
|
|
4365
|
+
mergeInto(result, cloneTree(layer.messages), layer.owner, "");
|
|
4366
|
+
continue;
|
|
4367
|
+
}
|
|
4368
|
+
const missing = [];
|
|
4369
|
+
overrideInto(result, cloneTree(layer.messages), layer.owner, "", missing);
|
|
4370
|
+
if (missing.length > 0) {
|
|
4371
|
+
throw new Error(
|
|
4372
|
+
`[ModuleRail] composition artifacts: i18n override in ${layer.owner} replaces keys that no Module or substrate defines: ${missing.join(", ")}`
|
|
4373
|
+
);
|
|
4374
|
+
}
|
|
4331
4375
|
}
|
|
4332
4376
|
return result;
|
|
4333
4377
|
}
|
|
@@ -4506,6 +4550,7 @@ function emitModuleI18nGenTs(input) {
|
|
|
4506
4550
|
);
|
|
4507
4551
|
}
|
|
4508
4552
|
const targetLocales = substrate.map((l) => l.locale);
|
|
4553
|
+
const overrideByLocale = indexOverrideLocales(input.overrideLocales ?? [], targetLocales);
|
|
4509
4554
|
const installed = new Set(input.registry.modules.map((m) => m.name));
|
|
4510
4555
|
const allLayers = input.moduleLayers ? [...input.moduleLayers] : deriveModuleLocaleLayers(input.registry, input.facts);
|
|
4511
4556
|
const layers = allLayers.filter((layer) => installed.has(layer.owner.split("/")[0]));
|
|
@@ -4526,19 +4571,38 @@ function emitModuleI18nGenTs(input) {
|
|
|
4526
4571
|
const messages = layer.localeMessages[locale] ?? (locale === "en" ? layer.enMessages : layer.enMessages);
|
|
4527
4572
|
composeLayers.push({ owner: layer.sourceLabel, messages });
|
|
4528
4573
|
}
|
|
4574
|
+
const override = overrideByLocale.get(locale);
|
|
4575
|
+
if (override) {
|
|
4576
|
+
composeLayers.push({
|
|
4577
|
+
owner: overrideOwner(locale),
|
|
4578
|
+
messages: override.messages,
|
|
4579
|
+
override: true
|
|
4580
|
+
});
|
|
4581
|
+
}
|
|
4529
4582
|
composeLocaleMessagesForPlan(composeLayers);
|
|
4530
4583
|
}
|
|
4531
4584
|
const composeImport = 'import { composeLocaleMessages } from "@/lib/i18n/compose-messages";';
|
|
4532
4585
|
const moduleJsonImports = [];
|
|
4533
4586
|
const relativeSubstrateImports = [];
|
|
4534
4587
|
const substrateIdentByLocale = {};
|
|
4588
|
+
const overrideIdentByLocale = {};
|
|
4535
4589
|
targetLocales.forEach((locale, localeIdx) => {
|
|
4536
4590
|
const ident = `i18nSubstrateLoc${localeIdx}`;
|
|
4537
4591
|
relativeSubstrateImports.push(
|
|
4538
4592
|
`import ${ident} from ${JSON.stringify(`./lib/i18n/substrate/${locale}.json`)};`
|
|
4539
4593
|
);
|
|
4540
4594
|
substrateIdentByLocale[locale] = ident;
|
|
4595
|
+
if (overrideByLocale.has(locale)) {
|
|
4596
|
+
const overrideIdent = `i18nOverrideLoc${localeIdx}`;
|
|
4597
|
+
relativeSubstrateImports.push(
|
|
4598
|
+
`import ${overrideIdent} from ${JSON.stringify(`./${overrideOwner(locale)}`)};`
|
|
4599
|
+
);
|
|
4600
|
+
overrideIdentByLocale[locale] = overrideIdent;
|
|
4601
|
+
}
|
|
4541
4602
|
});
|
|
4603
|
+
relativeSubstrateImports.sort(
|
|
4604
|
+
(a, b) => compareImportSpecifiers(a.match(/ from (.+);$/)[1], b.match(/ from (.+);$/)[1])
|
|
4605
|
+
);
|
|
4542
4606
|
const layerIdents = [];
|
|
4543
4607
|
layers.forEach((layer, layerIdx) => {
|
|
4544
4608
|
const localeIdents = {};
|
|
@@ -4572,15 +4636,29 @@ function emitModuleI18nGenTs(input) {
|
|
|
4572
4636
|
(layer) => ` { owner: ${JSON.stringify(layer.owner)}, messages: ${layer.localeIdents[locale]} },`
|
|
4573
4637
|
)
|
|
4574
4638
|
];
|
|
4639
|
+
const overrideIdent = overrideIdentByLocale[locale];
|
|
4640
|
+
const messageLines = overrideIdent ? [
|
|
4641
|
+
" messages: composeLocaleMessages([",
|
|
4642
|
+
" ...[",
|
|
4643
|
+
...layerLines,
|
|
4644
|
+
" ].map((layer) => ({",
|
|
4645
|
+
" ...layer,",
|
|
4646
|
+
' disabled: layer.owner !== "substrate" && !layer.owner.split("/").every(enabled),',
|
|
4647
|
+
" })),",
|
|
4648
|
+
` { owner: ${JSON.stringify(overrideOwner(locale))}, messages: ${overrideIdent}, override: true },`,
|
|
4649
|
+
" ]),"
|
|
4650
|
+
] : [
|
|
4651
|
+
" messages: composeLocaleMessages([",
|
|
4652
|
+
...layerLines,
|
|
4653
|
+
" ].filter((layer) =>",
|
|
4654
|
+
' layer.owner === "substrate" || layer.owner.split("/").every(enabled)',
|
|
4655
|
+
" )),"
|
|
4656
|
+
];
|
|
4575
4657
|
bundleBlocks.push(
|
|
4576
4658
|
[
|
|
4577
4659
|
` ${JSON.stringify(locale)}: {`,
|
|
4578
4660
|
` locale: ${JSON.stringify(locale)},`,
|
|
4579
|
-
|
|
4580
|
-
...layerLines,
|
|
4581
|
-
" ].filter((layer) =>",
|
|
4582
|
-
' layer.owner === "substrate" || layer.owner.split("/").every(enabled)',
|
|
4583
|
-
" )),",
|
|
4661
|
+
...messageLines,
|
|
4584
4662
|
" }"
|
|
4585
4663
|
].join("\n")
|
|
4586
4664
|
);
|
|
@@ -4625,6 +4703,26 @@ function emitModuleI18nGenTs(input) {
|
|
|
4625
4703
|
""
|
|
4626
4704
|
].join("\n");
|
|
4627
4705
|
}
|
|
4706
|
+
function indexOverrideLocales(overrideLocales, targetLocales) {
|
|
4707
|
+
const byLocale = /* @__PURE__ */ new Map();
|
|
4708
|
+
for (const layer of overrideLocales) {
|
|
4709
|
+
if (!isValidLocaleBasename(layer.locale)) {
|
|
4710
|
+
throw new Error(
|
|
4711
|
+
`[ModuleRail] composition artifacts: unsafe override locale basename "${layer.locale}"`
|
|
4712
|
+
);
|
|
4713
|
+
}
|
|
4714
|
+
if (!targetLocales.includes(layer.locale)) {
|
|
4715
|
+
throw new Error(
|
|
4716
|
+
`[ModuleRail] composition artifacts: ${overrideOwner(layer.locale)} has no matching lib/i18n/substrate/${layer.locale}.json; add that substrate file to make ${layer.locale} an app locale`
|
|
4717
|
+
);
|
|
4718
|
+
}
|
|
4719
|
+
byLocale.set(layer.locale, layer);
|
|
4720
|
+
}
|
|
4721
|
+
return byLocale;
|
|
4722
|
+
}
|
|
4723
|
+
function overrideOwner(locale) {
|
|
4724
|
+
return `lib/i18n/overrides/${locale}.json`;
|
|
4725
|
+
}
|
|
4628
4726
|
function deriveModuleLocaleLayers(registry, facts) {
|
|
4629
4727
|
const layers = [];
|
|
4630
4728
|
const installed = new Set(registry.modules.map((m) => m.name));
|
|
@@ -5503,7 +5601,8 @@ function planCompositionArtifacts(input) {
|
|
|
5503
5601
|
registry: input.registry,
|
|
5504
5602
|
facts: compositionEntryFacts,
|
|
5505
5603
|
substrateLocales,
|
|
5506
|
-
moduleLayers: input.moduleLocaleLayers
|
|
5604
|
+
moduleLayers: input.moduleLocaleLayers,
|
|
5605
|
+
overrideLocales: input.overrideLocales
|
|
5507
5606
|
});
|
|
5508
5607
|
initContent = emitModuleInitServerGenTs({
|
|
5509
5608
|
registry: input.registry,
|
|
@@ -6848,7 +6947,8 @@ async function collectCompositionEntryFacts(context, registry) {
|
|
|
6848
6947
|
`[ModuleRail] runId=${context.runId} collecting composition entry facts modules=${registry.modules.length}`
|
|
6849
6948
|
);
|
|
6850
6949
|
const substrateDir = `${APP_PACKAGE_DIR}/src/lib/i18n/substrate`;
|
|
6851
|
-
const
|
|
6950
|
+
const overridesDir = `${APP_PACKAGE_DIR}/src/lib/i18n/overrides`;
|
|
6951
|
+
const localeDirs = [substrateDir, overridesDir];
|
|
6852
6952
|
const conventionalPaths = [];
|
|
6853
6953
|
for (const mod of registry.modules) {
|
|
6854
6954
|
const modulePath = `${MODULES_SANDBOX_DIR}/${mod.name}`;
|
|
@@ -6899,6 +6999,12 @@ async function collectCompositionEntryFacts(context, registry) {
|
|
|
6899
6999
|
messages: await readJsonObjectFile(localePath, files)
|
|
6900
7000
|
});
|
|
6901
7001
|
}
|
|
7002
|
+
const overrideLocales = [];
|
|
7003
|
+
for (const locale of localesByDir.get(overridesDir) ?? []) {
|
|
7004
|
+
const localePath = `${overridesDir}/${locale}.json`;
|
|
7005
|
+
assertRealLocaleJsonFilePresence(localePath, localePresences.get(localePath) ?? "unreadable");
|
|
7006
|
+
overrideLocales.push({ locale, messages: await readJsonObjectFile(localePath, files) });
|
|
7007
|
+
}
|
|
6902
7008
|
const facts = [];
|
|
6903
7009
|
const moduleLocaleLayers = [];
|
|
6904
7010
|
for (const mod of registry.modules) {
|
|
@@ -7025,9 +7131,9 @@ async function collectCompositionEntryFacts(context, registry) {
|
|
|
7025
7131
|
facts.sort((a, b) => a.moduleName.localeCompare(b.moduleName));
|
|
7026
7132
|
moduleLocaleLayers.sort((a, b) => a.sourceLabel.localeCompare(b.sourceLabel));
|
|
7027
7133
|
console.log(
|
|
7028
|
-
`[ModuleRail] runId=${context.runId} composition entry facts modules=${facts.length} substrateLocales=${substrateLocales.length} moduleLocaleLayers=${moduleLocaleLayers.length}`
|
|
7134
|
+
`[ModuleRail] runId=${context.runId} composition entry facts modules=${facts.length} substrateLocales=${substrateLocales.length} overrideLocales=${overrideLocales.map((layer) => layer.locale).join(",") || "none"} moduleLocaleLayers=${moduleLocaleLayers.length}`
|
|
7029
7135
|
);
|
|
7030
|
-
return { facts, substrateLocales, moduleLocaleLayers };
|
|
7136
|
+
return { facts, substrateLocales, overrideLocales, moduleLocaleLayers };
|
|
7031
7137
|
}
|
|
7032
7138
|
function selectComposedModules(presentNames, manifestsByName, enabledRaw) {
|
|
7033
7139
|
if (enabledRaw) {
|
|
@@ -7167,6 +7273,7 @@ async function reconcileCompositionArtifacts(context, options = {}) {
|
|
|
7167
7273
|
const {
|
|
7168
7274
|
facts: compositionEntryFacts,
|
|
7169
7275
|
substrateLocales,
|
|
7276
|
+
overrideLocales,
|
|
7170
7277
|
moduleLocaleLayers
|
|
7171
7278
|
} = await collectCompositionEntryFacts(context, registry);
|
|
7172
7279
|
const candidatePaths = /* @__PURE__ */ new Set([
|
|
@@ -7189,6 +7296,7 @@ async function reconcileCompositionArtifacts(context, options = {}) {
|
|
|
7189
7296
|
existingAppRoutes,
|
|
7190
7297
|
compositionEntryFacts,
|
|
7191
7298
|
substrateLocales,
|
|
7299
|
+
overrideLocales,
|
|
7192
7300
|
moduleLocaleLayers,
|
|
7193
7301
|
moduleDataStoreBindings
|
|
7194
7302
|
});
|
|
@@ -7257,6 +7365,7 @@ async function reconcileCompositionArtifacts(context, options = {}) {
|
|
|
7257
7365
|
existingAppRoutes,
|
|
7258
7366
|
compositionEntryFacts,
|
|
7259
7367
|
substrateLocales,
|
|
7368
|
+
overrideLocales,
|
|
7260
7369
|
moduleLocaleLayers,
|
|
7261
7370
|
moduleDataStoreBindings
|
|
7262
7371
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -4261,6 +4261,40 @@ function cloneTree(value) {
|
|
|
4261
4261
|
}
|
|
4262
4262
|
return clone;
|
|
4263
4263
|
}
|
|
4264
|
+
function collectLeafPaths(value, path3, out) {
|
|
4265
|
+
if (typeof value === "string") {
|
|
4266
|
+
out.push(path3);
|
|
4267
|
+
return;
|
|
4268
|
+
}
|
|
4269
|
+
assertMessageTree(value, path3);
|
|
4270
|
+
for (const [key, child] of Object.entries(value)) collectLeafPaths(child, `${path3}.${key}`, out);
|
|
4271
|
+
}
|
|
4272
|
+
function overrideInto(target, source, owner, path3, missing) {
|
|
4273
|
+
for (const [key, value] of Object.entries(source)) {
|
|
4274
|
+
const nextPath = path3 ? `${path3}.${key}` : key;
|
|
4275
|
+
if (!Object.prototype.hasOwnProperty.call(target, key)) {
|
|
4276
|
+
collectLeafPaths(value, nextPath, missing);
|
|
4277
|
+
continue;
|
|
4278
|
+
}
|
|
4279
|
+
const existing = target[key];
|
|
4280
|
+
if (typeof value === "string") {
|
|
4281
|
+
if (typeof existing !== "string") {
|
|
4282
|
+
throw new Error(
|
|
4283
|
+
`[ModuleRail] composition artifacts: i18n merge conflict at ${nextPath}: ${owner} has string leaf but another owner has an object`
|
|
4284
|
+
);
|
|
4285
|
+
}
|
|
4286
|
+
target[key] = value;
|
|
4287
|
+
continue;
|
|
4288
|
+
}
|
|
4289
|
+
assertMessageTree(value, nextPath);
|
|
4290
|
+
if (typeof existing === "string") {
|
|
4291
|
+
throw new Error(
|
|
4292
|
+
`[ModuleRail] composition artifacts: i18n merge conflict at ${nextPath}: ${owner} has object but another owner has a string leaf`
|
|
4293
|
+
);
|
|
4294
|
+
}
|
|
4295
|
+
overrideInto(existing, value, owner, nextPath, missing);
|
|
4296
|
+
}
|
|
4297
|
+
}
|
|
4264
4298
|
function composeLocaleMessagesForPlan(layers) {
|
|
4265
4299
|
const result = createMessageTree();
|
|
4266
4300
|
const leafOwners = /* @__PURE__ */ new Map();
|
|
@@ -4312,7 +4346,17 @@ function composeLocaleMessagesForPlan(layers) {
|
|
|
4312
4346
|
}
|
|
4313
4347
|
for (const layer of layers) {
|
|
4314
4348
|
assertMessageTree(layer.messages, layer.owner);
|
|
4315
|
-
|
|
4349
|
+
if (!layer.override) {
|
|
4350
|
+
mergeInto(result, cloneTree(layer.messages), layer.owner, "");
|
|
4351
|
+
continue;
|
|
4352
|
+
}
|
|
4353
|
+
const missing = [];
|
|
4354
|
+
overrideInto(result, cloneTree(layer.messages), layer.owner, "", missing);
|
|
4355
|
+
if (missing.length > 0) {
|
|
4356
|
+
throw new Error(
|
|
4357
|
+
`[ModuleRail] composition artifacts: i18n override in ${layer.owner} replaces keys that no Module or substrate defines: ${missing.join(", ")}`
|
|
4358
|
+
);
|
|
4359
|
+
}
|
|
4316
4360
|
}
|
|
4317
4361
|
return result;
|
|
4318
4362
|
}
|
|
@@ -4491,6 +4535,7 @@ function emitModuleI18nGenTs(input) {
|
|
|
4491
4535
|
);
|
|
4492
4536
|
}
|
|
4493
4537
|
const targetLocales = substrate.map((l) => l.locale);
|
|
4538
|
+
const overrideByLocale = indexOverrideLocales(input.overrideLocales ?? [], targetLocales);
|
|
4494
4539
|
const installed = new Set(input.registry.modules.map((m) => m.name));
|
|
4495
4540
|
const allLayers = input.moduleLayers ? [...input.moduleLayers] : deriveModuleLocaleLayers(input.registry, input.facts);
|
|
4496
4541
|
const layers = allLayers.filter((layer) => installed.has(layer.owner.split("/")[0]));
|
|
@@ -4511,19 +4556,38 @@ function emitModuleI18nGenTs(input) {
|
|
|
4511
4556
|
const messages = layer.localeMessages[locale] ?? (locale === "en" ? layer.enMessages : layer.enMessages);
|
|
4512
4557
|
composeLayers.push({ owner: layer.sourceLabel, messages });
|
|
4513
4558
|
}
|
|
4559
|
+
const override = overrideByLocale.get(locale);
|
|
4560
|
+
if (override) {
|
|
4561
|
+
composeLayers.push({
|
|
4562
|
+
owner: overrideOwner(locale),
|
|
4563
|
+
messages: override.messages,
|
|
4564
|
+
override: true
|
|
4565
|
+
});
|
|
4566
|
+
}
|
|
4514
4567
|
composeLocaleMessagesForPlan(composeLayers);
|
|
4515
4568
|
}
|
|
4516
4569
|
const composeImport = 'import { composeLocaleMessages } from "@/lib/i18n/compose-messages";';
|
|
4517
4570
|
const moduleJsonImports = [];
|
|
4518
4571
|
const relativeSubstrateImports = [];
|
|
4519
4572
|
const substrateIdentByLocale = {};
|
|
4573
|
+
const overrideIdentByLocale = {};
|
|
4520
4574
|
targetLocales.forEach((locale, localeIdx) => {
|
|
4521
4575
|
const ident = `i18nSubstrateLoc${localeIdx}`;
|
|
4522
4576
|
relativeSubstrateImports.push(
|
|
4523
4577
|
`import ${ident} from ${JSON.stringify(`./lib/i18n/substrate/${locale}.json`)};`
|
|
4524
4578
|
);
|
|
4525
4579
|
substrateIdentByLocale[locale] = ident;
|
|
4580
|
+
if (overrideByLocale.has(locale)) {
|
|
4581
|
+
const overrideIdent = `i18nOverrideLoc${localeIdx}`;
|
|
4582
|
+
relativeSubstrateImports.push(
|
|
4583
|
+
`import ${overrideIdent} from ${JSON.stringify(`./${overrideOwner(locale)}`)};`
|
|
4584
|
+
);
|
|
4585
|
+
overrideIdentByLocale[locale] = overrideIdent;
|
|
4586
|
+
}
|
|
4526
4587
|
});
|
|
4588
|
+
relativeSubstrateImports.sort(
|
|
4589
|
+
(a, b) => compareImportSpecifiers(a.match(/ from (.+);$/)[1], b.match(/ from (.+);$/)[1])
|
|
4590
|
+
);
|
|
4527
4591
|
const layerIdents = [];
|
|
4528
4592
|
layers.forEach((layer, layerIdx) => {
|
|
4529
4593
|
const localeIdents = {};
|
|
@@ -4557,15 +4621,29 @@ function emitModuleI18nGenTs(input) {
|
|
|
4557
4621
|
(layer) => ` { owner: ${JSON.stringify(layer.owner)}, messages: ${layer.localeIdents[locale]} },`
|
|
4558
4622
|
)
|
|
4559
4623
|
];
|
|
4624
|
+
const overrideIdent = overrideIdentByLocale[locale];
|
|
4625
|
+
const messageLines = overrideIdent ? [
|
|
4626
|
+
" messages: composeLocaleMessages([",
|
|
4627
|
+
" ...[",
|
|
4628
|
+
...layerLines,
|
|
4629
|
+
" ].map((layer) => ({",
|
|
4630
|
+
" ...layer,",
|
|
4631
|
+
' disabled: layer.owner !== "substrate" && !layer.owner.split("/").every(enabled),',
|
|
4632
|
+
" })),",
|
|
4633
|
+
` { owner: ${JSON.stringify(overrideOwner(locale))}, messages: ${overrideIdent}, override: true },`,
|
|
4634
|
+
" ]),"
|
|
4635
|
+
] : [
|
|
4636
|
+
" messages: composeLocaleMessages([",
|
|
4637
|
+
...layerLines,
|
|
4638
|
+
" ].filter((layer) =>",
|
|
4639
|
+
' layer.owner === "substrate" || layer.owner.split("/").every(enabled)',
|
|
4640
|
+
" )),"
|
|
4641
|
+
];
|
|
4560
4642
|
bundleBlocks.push(
|
|
4561
4643
|
[
|
|
4562
4644
|
` ${JSON.stringify(locale)}: {`,
|
|
4563
4645
|
` locale: ${JSON.stringify(locale)},`,
|
|
4564
|
-
|
|
4565
|
-
...layerLines,
|
|
4566
|
-
" ].filter((layer) =>",
|
|
4567
|
-
' layer.owner === "substrate" || layer.owner.split("/").every(enabled)',
|
|
4568
|
-
" )),",
|
|
4646
|
+
...messageLines,
|
|
4569
4647
|
" }"
|
|
4570
4648
|
].join("\n")
|
|
4571
4649
|
);
|
|
@@ -4610,6 +4688,26 @@ function emitModuleI18nGenTs(input) {
|
|
|
4610
4688
|
""
|
|
4611
4689
|
].join("\n");
|
|
4612
4690
|
}
|
|
4691
|
+
function indexOverrideLocales(overrideLocales, targetLocales) {
|
|
4692
|
+
const byLocale = /* @__PURE__ */ new Map();
|
|
4693
|
+
for (const layer of overrideLocales) {
|
|
4694
|
+
if (!isValidLocaleBasename(layer.locale)) {
|
|
4695
|
+
throw new Error(
|
|
4696
|
+
`[ModuleRail] composition artifacts: unsafe override locale basename "${layer.locale}"`
|
|
4697
|
+
);
|
|
4698
|
+
}
|
|
4699
|
+
if (!targetLocales.includes(layer.locale)) {
|
|
4700
|
+
throw new Error(
|
|
4701
|
+
`[ModuleRail] composition artifacts: ${overrideOwner(layer.locale)} has no matching lib/i18n/substrate/${layer.locale}.json; add that substrate file to make ${layer.locale} an app locale`
|
|
4702
|
+
);
|
|
4703
|
+
}
|
|
4704
|
+
byLocale.set(layer.locale, layer);
|
|
4705
|
+
}
|
|
4706
|
+
return byLocale;
|
|
4707
|
+
}
|
|
4708
|
+
function overrideOwner(locale) {
|
|
4709
|
+
return `lib/i18n/overrides/${locale}.json`;
|
|
4710
|
+
}
|
|
4613
4711
|
function deriveModuleLocaleLayers(registry, facts) {
|
|
4614
4712
|
const layers = [];
|
|
4615
4713
|
const installed = new Set(registry.modules.map((m) => m.name));
|
|
@@ -5488,7 +5586,8 @@ function planCompositionArtifacts(input) {
|
|
|
5488
5586
|
registry: input.registry,
|
|
5489
5587
|
facts: compositionEntryFacts,
|
|
5490
5588
|
substrateLocales,
|
|
5491
|
-
moduleLayers: input.moduleLocaleLayers
|
|
5589
|
+
moduleLayers: input.moduleLocaleLayers,
|
|
5590
|
+
overrideLocales: input.overrideLocales
|
|
5492
5591
|
});
|
|
5493
5592
|
initContent = emitModuleInitServerGenTs({
|
|
5494
5593
|
registry: input.registry,
|
|
@@ -6833,7 +6932,8 @@ async function collectCompositionEntryFacts(context, registry) {
|
|
|
6833
6932
|
`[ModuleRail] runId=${context.runId} collecting composition entry facts modules=${registry.modules.length}`
|
|
6834
6933
|
);
|
|
6835
6934
|
const substrateDir = `${APP_PACKAGE_DIR}/src/lib/i18n/substrate`;
|
|
6836
|
-
const
|
|
6935
|
+
const overridesDir = `${APP_PACKAGE_DIR}/src/lib/i18n/overrides`;
|
|
6936
|
+
const localeDirs = [substrateDir, overridesDir];
|
|
6837
6937
|
const conventionalPaths = [];
|
|
6838
6938
|
for (const mod of registry.modules) {
|
|
6839
6939
|
const modulePath = `${MODULES_SANDBOX_DIR}/${mod.name}`;
|
|
@@ -6884,6 +6984,12 @@ async function collectCompositionEntryFacts(context, registry) {
|
|
|
6884
6984
|
messages: await readJsonObjectFile(localePath, files)
|
|
6885
6985
|
});
|
|
6886
6986
|
}
|
|
6987
|
+
const overrideLocales = [];
|
|
6988
|
+
for (const locale of localesByDir.get(overridesDir) ?? []) {
|
|
6989
|
+
const localePath = `${overridesDir}/${locale}.json`;
|
|
6990
|
+
assertRealLocaleJsonFilePresence(localePath, localePresences.get(localePath) ?? "unreadable");
|
|
6991
|
+
overrideLocales.push({ locale, messages: await readJsonObjectFile(localePath, files) });
|
|
6992
|
+
}
|
|
6887
6993
|
const facts = [];
|
|
6888
6994
|
const moduleLocaleLayers = [];
|
|
6889
6995
|
for (const mod of registry.modules) {
|
|
@@ -7010,9 +7116,9 @@ async function collectCompositionEntryFacts(context, registry) {
|
|
|
7010
7116
|
facts.sort((a, b) => a.moduleName.localeCompare(b.moduleName));
|
|
7011
7117
|
moduleLocaleLayers.sort((a, b) => a.sourceLabel.localeCompare(b.sourceLabel));
|
|
7012
7118
|
console.log(
|
|
7013
|
-
`[ModuleRail] runId=${context.runId} composition entry facts modules=${facts.length} substrateLocales=${substrateLocales.length} moduleLocaleLayers=${moduleLocaleLayers.length}`
|
|
7119
|
+
`[ModuleRail] runId=${context.runId} composition entry facts modules=${facts.length} substrateLocales=${substrateLocales.length} overrideLocales=${overrideLocales.map((layer) => layer.locale).join(",") || "none"} moduleLocaleLayers=${moduleLocaleLayers.length}`
|
|
7014
7120
|
);
|
|
7015
|
-
return { facts, substrateLocales, moduleLocaleLayers };
|
|
7121
|
+
return { facts, substrateLocales, overrideLocales, moduleLocaleLayers };
|
|
7016
7122
|
}
|
|
7017
7123
|
function selectComposedModules(presentNames, manifestsByName, enabledRaw) {
|
|
7018
7124
|
if (enabledRaw) {
|
|
@@ -7152,6 +7258,7 @@ async function reconcileCompositionArtifacts(context, options = {}) {
|
|
|
7152
7258
|
const {
|
|
7153
7259
|
facts: compositionEntryFacts,
|
|
7154
7260
|
substrateLocales,
|
|
7261
|
+
overrideLocales,
|
|
7155
7262
|
moduleLocaleLayers
|
|
7156
7263
|
} = await collectCompositionEntryFacts(context, registry);
|
|
7157
7264
|
const candidatePaths = /* @__PURE__ */ new Set([
|
|
@@ -7174,6 +7281,7 @@ async function reconcileCompositionArtifacts(context, options = {}) {
|
|
|
7174
7281
|
existingAppRoutes,
|
|
7175
7282
|
compositionEntryFacts,
|
|
7176
7283
|
substrateLocales,
|
|
7284
|
+
overrideLocales,
|
|
7177
7285
|
moduleLocaleLayers,
|
|
7178
7286
|
moduleDataStoreBindings
|
|
7179
7287
|
});
|
|
@@ -7242,6 +7350,7 @@ async function reconcileCompositionArtifacts(context, options = {}) {
|
|
|
7242
7350
|
existingAppRoutes,
|
|
7243
7351
|
compositionEntryFacts,
|
|
7244
7352
|
substrateLocales,
|
|
7353
|
+
overrideLocales,
|
|
7245
7354
|
moduleLocaleLayers,
|
|
7246
7355
|
moduleDataStoreBindings
|
|
7247
7356
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stardeck-customer-apps/compose",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Regenerates a Stardeck app's Module-rail artifacts — the five src/*.gen.ts registries and every route/endpoint stub — from src/modules/*/module.json",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|