@antelopejs/dms-frontend 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -2
- package/dist/common.d.ts +2 -0
- package/dist/common.js +2 -0
- package/dist/derived-outputs.d.ts +22 -0
- package/dist/derived-outputs.js +296 -0
- package/dist/fs-sync.d.ts +3 -2
- package/dist/fs-sync.js +49 -2
- package/dist/layer-watch.js +31 -14
- package/dist/layers.d.ts +5 -0
- package/dist/layers.js +7 -3
- package/dist/materialize.d.ts +1 -15
- package/dist/materialize.js +4 -245
- package/dist/renderer-range.d.ts +10 -0
- package/dist/renderer-range.js +55 -0
- package/dist/verify-source-runner.js +1 -0
- package/dist/workspace-setup.js +2 -0
- package/package.json +3 -3
- package/templates/vue/app-runtime.ts +17 -1
- package/templates/vue/frontend-module.ts +116 -51
package/dist/materialize.js
CHANGED
|
@@ -4,16 +4,13 @@ exports.getPackageRoot = getPackageRoot;
|
|
|
4
4
|
exports.copyStaticTemplates = copyStaticTemplates;
|
|
5
5
|
exports.writeWorkspacePackageJson = writeWorkspacePackageJson;
|
|
6
6
|
exports.materializeLayers = materializeLayers;
|
|
7
|
-
exports.createFrontendModuleRegistry = createFrontendModuleRegistry;
|
|
8
7
|
exports.collectAuthEstablishEndpoints = collectAuthEstablishEndpoints;
|
|
9
8
|
exports.writeFrontendModuleRegistry = writeFrontendModuleRegistry;
|
|
10
|
-
exports.affectsLocaleMessages = affectsLocaleMessages;
|
|
11
|
-
exports.writeLocaleMessages = writeLocaleMessages;
|
|
12
9
|
exports.writeDmsMainCss = writeDmsMainCss;
|
|
13
10
|
const node_fs_1 = require("node:fs");
|
|
14
11
|
const node_path_1 = require("node:path");
|
|
15
12
|
const config_1 = require("./config");
|
|
16
|
-
const
|
|
13
|
+
const derived_outputs_1 = require("./derived-outputs");
|
|
17
14
|
const layers_1 = require("./layers");
|
|
18
15
|
const fs_sync_1 = require("./fs-sync");
|
|
19
16
|
function getPackageRoot() {
|
|
@@ -77,40 +74,6 @@ function sanitizeLayerPackage(pkgPath) {
|
|
|
77
74
|
return;
|
|
78
75
|
(0, fs_sync_1.applyContent)((0, fs_sync_1.sanitizedPackageContent)((0, node_fs_1.readFileSync)(pkgPath, "utf-8")), pkgPath);
|
|
79
76
|
}
|
|
80
|
-
const GENERATED_MODULE_ID = /^[A-Za-z0-9_-]+$/;
|
|
81
|
-
function validateFrontendModuleRegistry(registry, workspaceDir) {
|
|
82
|
-
const ids = new Set();
|
|
83
|
-
const moduleRoot = `${(0, node_path_1.resolve)(workspaceDir, config_1.LAYERS_SUBDIR)}${node_path_1.sep}`;
|
|
84
|
-
for (const module of registry.modules) {
|
|
85
|
-
if (!GENERATED_MODULE_ID.test(module.id) || ids.has(module.id))
|
|
86
|
-
throw new Error(`Invalid or duplicate frontend module id: ${module.id}`);
|
|
87
|
-
if (!Number.isFinite(module.priority))
|
|
88
|
-
throw new Error(`Invalid frontend module priority: ${module.id}`);
|
|
89
|
-
if (module.entry !== undefined && module.entry !== config_1.FRONTEND_MODULE_ENTRY)
|
|
90
|
-
throw new Error(`Invalid frontend module entry: ${module.id}`);
|
|
91
|
-
if (!(0, node_path_1.resolve)(module.root).startsWith(moduleRoot))
|
|
92
|
-
throw new Error(`Frontend module root escapes the workspace: ${module.id}`);
|
|
93
|
-
ids.add(module.id);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
function createFrontendModuleRegistry(workspaceDir, layers) {
|
|
97
|
-
const modules = layers.map((layer) => {
|
|
98
|
-
const sourceEntry = (0, node_path_1.join)(layer.path, config_1.FRONTEND_MODULE_ENTRY);
|
|
99
|
-
const options = layer.options ?? {};
|
|
100
|
-
return {
|
|
101
|
-
id: (0, layers_1.getLayerSafeName)(layer),
|
|
102
|
-
packageName: layer.packageName,
|
|
103
|
-
root: (0, layers_1.getLayerWorkspacePath)(workspaceDir, layer),
|
|
104
|
-
priority: layer.priority ?? 0,
|
|
105
|
-
entry: (0, node_fs_1.existsSync)(sourceEntry) ? config_1.FRONTEND_MODULE_ENTRY : undefined,
|
|
106
|
-
options: layer.configKey ? { [layer.configKey]: options } : options,
|
|
107
|
-
};
|
|
108
|
-
});
|
|
109
|
-
modules.sort((left, right) => right.priority - left.priority || left.id.localeCompare(right.id));
|
|
110
|
-
const registry = { modules };
|
|
111
|
-
validateFrontendModuleRegistry(registry, workspaceDir);
|
|
112
|
-
return registry;
|
|
113
|
-
}
|
|
114
77
|
const BACKEND_API_PATH = /^\/api\/[A-Za-z0-9][A-Za-z0-9._~-]*(?:\/[A-Za-z0-9][A-Za-z0-9._~-]*)*$/;
|
|
115
78
|
function collectAuthEstablishEndpoints(layers) {
|
|
116
79
|
const endpoints = new Set();
|
|
@@ -132,214 +95,10 @@ function writeAuthEstablishEndpoints(workspaceDir, layers) {
|
|
|
132
95
|
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(workspaceDir, config_1.AUTH_ESTABLISH_FILE), `${JSON.stringify({ endpoints }, null, 2)}\n`);
|
|
133
96
|
}
|
|
134
97
|
function writeFrontendModuleRegistry(workspaceDir, layers) {
|
|
135
|
-
const registry = createFrontendModuleRegistry(workspaceDir, layers);
|
|
136
|
-
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(workspaceDir, "generated-frontend-modules.json"), `${JSON.stringify(registry, null, 2)}\n`);
|
|
98
|
+
const registry = (0, derived_outputs_1.createFrontendModuleRegistry)(workspaceDir, layers);
|
|
137
99
|
writeAuthEstablishEndpoints(workspaceDir, layers);
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
writeLocaleMessages(workspaceDir, registry);
|
|
141
|
-
writeShortcutExports(workspaceDir, registry);
|
|
142
|
-
writePublicAssets(workspaceDir, registry);
|
|
143
|
-
}
|
|
144
|
-
function writeFrontendTypePaths(workspaceDir, registry) {
|
|
145
|
-
const paths = {
|
|
146
|
-
"#dms/frontend-module": ["./frontend-module.ts"],
|
|
147
|
-
"@frontend/*": ["./frontend-modules/*"],
|
|
148
|
-
...(0, layer_aliases_1.frontendLayerTypePaths)([...registry.modules].reverse().map((module) => module.root), { relativeTo: workspaceDir }),
|
|
149
|
-
};
|
|
150
|
-
const config = { compilerOptions: { paths } };
|
|
151
|
-
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(workspaceDir, "frontend-paths.generated.json"), `${JSON.stringify(config, null, 2)}\n`);
|
|
152
|
-
}
|
|
153
|
-
function writeFrontendModuleLoader(workspaceDir, registry) {
|
|
154
|
-
const modules = registry.modules.filter((module) => module.entry);
|
|
155
|
-
const imports = modules
|
|
156
|
-
.map((module, index) => `import module${index} from "@frontend/${module.id}/${module.entry}";`)
|
|
157
|
-
.join("\n");
|
|
158
|
-
const registrations = modules
|
|
159
|
-
.map((module, index) => `{ module: module${index}, options: { public: ${JSON.stringify(module.options)} } }`)
|
|
160
|
-
.join(", ");
|
|
161
|
-
const content = `${imports}\n\nimport type { DmsFrontendModuleRegistration } from "./frontend-module";\n\nexport const frontendModules: DmsFrontendModuleRegistration[] = [${registrations}];\n`;
|
|
162
|
-
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(workspaceDir, "frontend-modules.generated.ts"), content);
|
|
163
|
-
}
|
|
164
|
-
function moduleAssetRoots(moduleRoot) {
|
|
165
|
-
const layersRoot = (0, node_path_1.join)(moduleRoot, "layers");
|
|
166
|
-
if (!(0, node_fs_1.existsSync)(layersRoot)) {
|
|
167
|
-
return [{ absolutePath: moduleRoot, relativePrefix: "" }];
|
|
168
|
-
}
|
|
169
|
-
return (0, node_fs_1.readdirSync)(layersRoot).map((name) => ({
|
|
170
|
-
absolutePath: (0, node_path_1.join)(layersRoot, name),
|
|
171
|
-
relativePrefix: `layers/${name}/`,
|
|
172
|
-
}));
|
|
173
|
-
}
|
|
174
|
-
function writePublicAssets(workspaceDir, registry) {
|
|
175
|
-
const destination = (0, node_path_1.join)(workspaceDir, "public");
|
|
176
|
-
(0, node_fs_1.rmSync)(destination, { force: true, recursive: true });
|
|
177
|
-
for (const module of [...registry.modules].reverse()) {
|
|
178
|
-
for (const root of moduleAssetRoots(module.root)) {
|
|
179
|
-
const source = (0, node_path_1.join)(root.absolutePath, "public");
|
|
180
|
-
if ((0, node_fs_1.existsSync)(source)) {
|
|
181
|
-
(0, node_fs_1.cpSync)(source, destination, { force: true, recursive: true });
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
function discoverAssets(registry, directory, extensions) {
|
|
187
|
-
return registry.modules.flatMap((module) => {
|
|
188
|
-
return moduleAssetRoots(module.root).flatMap((assetRoot) => {
|
|
189
|
-
const root = (0, node_path_1.join)(assetRoot.absolutePath, directory);
|
|
190
|
-
return (0, fs_sync_1.collectFiles)(root)
|
|
191
|
-
.filter((file) => extensions.some((extension) => file.endsWith(extension)))
|
|
192
|
-
.sort()
|
|
193
|
-
.map((relativePath) => ({
|
|
194
|
-
moduleId: module.id,
|
|
195
|
-
relativePath: `${assetRoot.relativePrefix}${(0, fs_sync_1.toPosixPath)((0, node_path_1.join)(directory, relativePath))}`,
|
|
196
|
-
}));
|
|
197
|
-
});
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
function isRecord(value) {
|
|
201
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
202
|
-
}
|
|
203
|
-
function mergeLocaleMessages(source, existing) {
|
|
204
|
-
const merged = { ...source };
|
|
205
|
-
for (const [key, value] of Object.entries(existing)) {
|
|
206
|
-
const sourceValue = merged[key];
|
|
207
|
-
merged[key] =
|
|
208
|
-
isRecord(sourceValue) && isRecord(value)
|
|
209
|
-
? mergeLocaleMessages(sourceValue, value)
|
|
210
|
-
: value;
|
|
211
|
-
}
|
|
212
|
-
return merged;
|
|
213
|
-
}
|
|
214
|
-
const LOCALE_DIRECTORY = "i18n/locales";
|
|
215
|
-
function readLocaleFile(path) {
|
|
216
|
-
try {
|
|
217
|
-
return JSON.parse((0, node_fs_1.readFileSync)(path, "utf8"));
|
|
218
|
-
}
|
|
219
|
-
catch (error) {
|
|
220
|
-
const reason = error instanceof Error ? error.message : String(error);
|
|
221
|
-
throw new Error(`Invalid locale file ${path}: ${reason}`);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
function readLocaleMessages(assets, registry) {
|
|
225
|
-
const roots = new Map(registry.modules.map((module) => [module.id, module.root]));
|
|
226
|
-
const messages = {};
|
|
227
|
-
for (const asset of assets) {
|
|
228
|
-
const locale = asset.relativePath.match(/(?:^|[/-])([a-z]{2})-[A-Z]{2}\.json$/)?.[1];
|
|
229
|
-
const root = roots.get(asset.moduleId);
|
|
230
|
-
if (!locale || !root)
|
|
231
|
-
continue;
|
|
232
|
-
const value = readLocaleFile((0, node_path_1.join)(root, asset.relativePath));
|
|
233
|
-
messages[locale] = mergeLocaleMessages(value, messages[locale] ?? {});
|
|
234
|
-
}
|
|
235
|
-
return messages;
|
|
236
|
-
}
|
|
237
|
-
function affectsLocaleMessages(relativePath) {
|
|
238
|
-
const segments = (0, fs_sync_1.toPosixPath)(relativePath).split("/");
|
|
239
|
-
if (segments[0] === "layers" && segments.length <= 2)
|
|
240
|
-
return true;
|
|
241
|
-
const withinRoot = segments[0] === "layers" ? segments.slice(2) : segments;
|
|
242
|
-
return LOCALE_DIRECTORY.split("/").every((segment, index) => index >= withinRoot.length || withinRoot[index] === segment);
|
|
243
|
-
}
|
|
244
|
-
function localeModuleSource(supportedLocales) {
|
|
245
|
-
const loaders = supportedLocales
|
|
246
|
-
.filter((locale) => locale !== "en")
|
|
247
|
-
.map((locale) => ` ${JSON.stringify(locale)}: () => import(${JSON.stringify(`./locales.generated/${locale}`)}),`);
|
|
248
|
-
return `import defaultMessages from "./locales.generated/en";
|
|
249
|
-
|
|
250
|
-
type LocaleMessages = Record<string, unknown>;
|
|
251
|
-
type LocaleLoader = () => Promise<{ default: LocaleMessages }>;
|
|
252
|
-
interface LocaleMessagesTarget {
|
|
253
|
-
setLocaleMessage(locale: string, messages: LocaleMessages): void;
|
|
254
|
-
}
|
|
255
|
-
interface LocaleState {
|
|
256
|
-
messages: Record<string, LocaleMessages>;
|
|
257
|
-
targets: Set<LocaleMessagesTarget>;
|
|
258
|
-
version: number;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
export const supportedLocales = ${JSON.stringify(supportedLocales)};
|
|
262
|
-
const localeLoaders: Record<string, LocaleLoader> = {
|
|
263
|
-
"en": async () => ({ default: defaultMessages }),
|
|
264
|
-
${loaders.join("\n")}
|
|
265
|
-
};
|
|
266
|
-
const shared: LocaleState | undefined = import.meta.hot?.data.state;
|
|
267
|
-
const state: LocaleState = shared ?? {
|
|
268
|
-
messages: { en: defaultMessages },
|
|
269
|
-
targets: new Set(),
|
|
270
|
-
version: 0,
|
|
271
|
-
};
|
|
272
|
-
export const localeMessages = state.messages;
|
|
273
|
-
|
|
274
|
-
async function readLocaleMessages(locale: string): Promise<LocaleMessages> {
|
|
275
|
-
return (await localeLoaders[locale]()).default;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
export async function loadLocaleMessages(locale: string): Promise<LocaleMessages> {
|
|
279
|
-
const normalized = locale.slice(0, 2);
|
|
280
|
-
if (!localeLoaders[normalized]) return localeMessages.en;
|
|
281
|
-
localeMessages[normalized] ??= await readLocaleMessages(normalized);
|
|
282
|
-
return localeMessages[normalized];
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/** Development only: applies every regenerated catalog to \`target\`. */
|
|
286
|
-
export function syncLocaleMessages(target: LocaleMessagesTarget): void {
|
|
287
|
-
if (import.meta.hot) state.targets.add(target);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
async function refreshLocaleMessages(): Promise<void> {
|
|
291
|
-
const version = ++state.version;
|
|
292
|
-
const locales = Object.keys(localeMessages).filter(
|
|
293
|
-
(locale) => locale in localeLoaders,
|
|
294
|
-
);
|
|
295
|
-
const catalogs = await Promise.all(locales.map(readLocaleMessages));
|
|
296
|
-
if (version !== state.version) return;
|
|
297
|
-
locales.forEach((locale, index) => {
|
|
298
|
-
localeMessages[locale] = catalogs[index];
|
|
299
|
-
for (const target of state.targets)
|
|
300
|
-
target.setLocaleMessage(locale, catalogs[index]);
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
if (import.meta.hot) {
|
|
305
|
-
import.meta.hot.data.state = state;
|
|
306
|
-
if (shared) void refreshLocaleMessages();
|
|
307
|
-
import.meta.hot.accept((next) => {
|
|
308
|
-
if (next?.supportedLocales.join() !== supportedLocales.join())
|
|
309
|
-
import.meta.hot?.invalidate("the list of locales changed");
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
`;
|
|
313
|
-
}
|
|
314
|
-
function writeLocaleMessages(workspaceDir, registry) {
|
|
315
|
-
const locales = discoverAssets(registry, LOCALE_DIRECTORY, [".json"]);
|
|
316
|
-
const messages = readLocaleMessages(locales, registry);
|
|
317
|
-
const outputDir = (0, node_path_1.join)(workspaceDir, "locales.generated");
|
|
318
|
-
const outputs = new Set();
|
|
319
|
-
(0, node_fs_1.mkdirSync)(outputDir, { recursive: true });
|
|
320
|
-
for (const [locale, value] of Object.entries(messages)) {
|
|
321
|
-
const catalog = JSON.stringify(value);
|
|
322
|
-
(0, fs_sync_1.applyContent)(catalog, (0, node_path_1.join)(outputDir, `${locale}.json`));
|
|
323
|
-
(0, fs_sync_1.applyContent)(`const messages = ${catalog};\nexport default messages;\n`, (0, node_path_1.join)(outputDir, `${locale}.ts`));
|
|
324
|
-
outputs.add(`${locale}.json`).add(`${locale}.ts`);
|
|
325
|
-
}
|
|
326
|
-
const supportedLocales = Object.keys(messages);
|
|
327
|
-
(0, fs_sync_1.applyContent)(JSON.stringify(supportedLocales), (0, node_path_1.join)(workspaceDir, "email-locales.generated.json"));
|
|
328
|
-
(0, fs_sync_1.applyContent)(localeModuleSource(supportedLocales), (0, node_path_1.join)(workspaceDir, "locales.generated.ts"));
|
|
329
|
-
for (const name of (0, node_fs_1.readdirSync)(outputDir)) {
|
|
330
|
-
if (!outputs.has(name))
|
|
331
|
-
(0, node_fs_1.rmSync)((0, node_path_1.join)(outputDir, name), { recursive: true, force: true });
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
function writeShortcutExports(workspaceDir, registry) {
|
|
335
|
-
const registries = discoverAssets(registry, "app/config", [
|
|
336
|
-
"shortcuts-registry.ts",
|
|
337
|
-
"shortcuts-registry.js",
|
|
338
|
-
]);
|
|
339
|
-
const imports = registries.map((asset, index) => `import registry${index} from "@frontend/${asset.moduleId}/${asset.relativePath}";`);
|
|
340
|
-
const spreads = registries.map((_, index) => `...registry${index}`);
|
|
341
|
-
const content = `${imports.join("\n")}\nconst aggregatedShortcuts = [${spreads.join(", ")}];\nexport { aggregatedShortcuts };\nexport default aggregatedShortcuts;\n`;
|
|
342
|
-
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(workspaceDir, "shortcuts-aggregated.generated.ts"), content);
|
|
100
|
+
for (const output of derived_outputs_1.DERIVED_OUTPUTS)
|
|
101
|
+
output.write(workspaceDir, registry);
|
|
343
102
|
}
|
|
344
103
|
function writeDmsMainCss(workspaceDir, layers) {
|
|
345
104
|
const sources = layers
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ResolvedLayer } from "./workspace";
|
|
2
|
+
export interface RendererRelease {
|
|
3
|
+
name: string;
|
|
4
|
+
version: string;
|
|
5
|
+
}
|
|
6
|
+
export interface RendererRangeCheckOptions {
|
|
7
|
+
renderer?: RendererRelease;
|
|
8
|
+
warn?: (message: string) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function assertLayersSupportRenderer(layers: ResolvedLayer[], options?: RendererRangeCheckOptions): void;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.assertLayersSupportRenderer = assertLayersSupportRenderer;
|
|
7
|
+
const semver_1 = __importDefault(require("semver"));
|
|
8
|
+
const layers_1 = require("./layers");
|
|
9
|
+
const OWN_RELEASE = require("../package.json");
|
|
10
|
+
const noticedModules = new Set();
|
|
11
|
+
function declaredRange(layer, rendererName) {
|
|
12
|
+
return {
|
|
13
|
+
module: layer.packageName ?? layer.path,
|
|
14
|
+
range: (0, layers_1.readLayerPackage)(layer.path)?.engines?.[rendererName],
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function releaseLine(version) {
|
|
18
|
+
return semver_1.default.coerce(version)?.version ?? version;
|
|
19
|
+
}
|
|
20
|
+
function describeProblem(declaration, version) {
|
|
21
|
+
const { module, range } = declaration;
|
|
22
|
+
if (typeof range !== "string" || semver_1.default.validRange(range) === null)
|
|
23
|
+
return `${module} declares an unreadable range: ${JSON.stringify(range)}`;
|
|
24
|
+
if (semver_1.default.satisfies(releaseLine(version), range))
|
|
25
|
+
return undefined;
|
|
26
|
+
return `${module} supports ${range}`;
|
|
27
|
+
}
|
|
28
|
+
function noticeUndeclared(declarations, renderer, warn) {
|
|
29
|
+
const modules = declarations
|
|
30
|
+
.filter(({ range }) => range === undefined)
|
|
31
|
+
.map(({ module }) => module)
|
|
32
|
+
.filter((module) => !noticedModules.has(module));
|
|
33
|
+
if (modules.length === 0)
|
|
34
|
+
return;
|
|
35
|
+
for (const module of modules)
|
|
36
|
+
noticedModules.add(module);
|
|
37
|
+
warn(`⚠ No supported ${renderer.name} range declared, so not checked against ` +
|
|
38
|
+
`${renderer.version}: ${modules.join(", ")}. A frontend module declares ` +
|
|
39
|
+
`one in its package.json, under engines["${renderer.name}"].`);
|
|
40
|
+
}
|
|
41
|
+
function assertLayersSupportRenderer(layers, options = {}) {
|
|
42
|
+
const renderer = options.renderer ?? OWN_RELEASE;
|
|
43
|
+
const declarations = layers.map((layer) => declaredRange(layer, renderer.name));
|
|
44
|
+
noticeUndeclared(declarations, renderer, options.warn ?? console.warn);
|
|
45
|
+
const problems = declarations
|
|
46
|
+
.filter(({ range }) => range !== undefined)
|
|
47
|
+
.map((declaration) => describeProblem(declaration, renderer.version))
|
|
48
|
+
.filter((problem) => problem !== undefined);
|
|
49
|
+
if (problems.length === 0)
|
|
50
|
+
return;
|
|
51
|
+
throw new Error(`These frontend modules do not run on ${renderer.name} ${renderer.version}:\n` +
|
|
52
|
+
problems.map((problem) => ` - ${problem}`).join("\n") +
|
|
53
|
+
`\nInstall a ${renderer.name} release their ranges allow, or upgrade those ` +
|
|
54
|
+
`modules to releases that support ${renderer.version}.`);
|
|
55
|
+
}
|
|
@@ -74,6 +74,7 @@ const layers = roots.map((root) => ({
|
|
|
74
74
|
packageName: JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(root, "package.json"), "utf8"))
|
|
75
75
|
.name,
|
|
76
76
|
}));
|
|
77
|
+
(0, common_1.assertLayersSupportRenderer)(layers);
|
|
77
78
|
(0, common_1.materializeLayers)(workspace, layers);
|
|
78
79
|
const registry = (0, common_1.createFrontendModuleRegistry)(workspace, layers);
|
|
79
80
|
registry.modules.forEach((module) => {
|
package/dist/workspace-setup.js
CHANGED
|
@@ -14,6 +14,7 @@ const node_path_1 = require("node:path");
|
|
|
14
14
|
const layers_1 = require("./layers");
|
|
15
15
|
const manifest_1 = require("./manifest");
|
|
16
16
|
const manifest_secrets_1 = require("./manifest-secrets");
|
|
17
|
+
const renderer_range_1 = require("./renderer-range");
|
|
17
18
|
const materialize_1 = require("./materialize");
|
|
18
19
|
const workspace_1 = require("./workspace");
|
|
19
20
|
const config_1 = require("./config");
|
|
@@ -168,6 +169,7 @@ async function setupWorkspace(opts) {
|
|
|
168
169
|
}
|
|
169
170
|
layers = await (0, layers_1.buildLayersFromCache)(manifest.modules, cacheDir);
|
|
170
171
|
}
|
|
172
|
+
(0, renderer_range_1.assertLayersSupportRenderer)(layers);
|
|
171
173
|
(0, materialize_1.copyStaticTemplates)(workspaceDir);
|
|
172
174
|
(0, materialize_1.writeWorkspacePackageJson)(workspaceDir, layers);
|
|
173
175
|
(0, materialize_1.materializeLayers)(workspaceDir, layers);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antelopejs/dms-frontend",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "Frontend-agnostic loader for AntelopeJS DMS, shipping the Vue 3 renderer (Vite, Inertia, SSR)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"antelope",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"test": "node --import tsx --test tests/*.test.ts tests/*.test.mts",
|
|
60
60
|
"test:real-source": "pnpm run build && node dist/verify-source-runner.js",
|
|
61
61
|
"format": "oxfmt .",
|
|
62
|
-
"lint": "oxlint && oxfmt --check .",
|
|
62
|
+
"lint": "oxlint && oxfmt --check . && antelopejs-check-interface-ranges",
|
|
63
63
|
"typecheck": "tsc --noEmit",
|
|
64
64
|
"lint:fix": "oxlint --fix --max-warnings=1000000 && oxfmt .",
|
|
65
65
|
"knip": "knip --dependencies",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"unzipper": "^0.12.3"
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
79
|
-
"@antelopejs/tooling-configs": ">=0.0.
|
|
79
|
+
"@antelopejs/tooling-configs": ">=0.0.7 <1.0.0",
|
|
80
80
|
"@inertiajs/vue3": "^3.7.1",
|
|
81
81
|
"@types/figlet": "^1.7.0",
|
|
82
82
|
"@types/node": "^24.8.1",
|
|
@@ -2,6 +2,7 @@ import UApp from "@nuxt/ui/components/App.vue";
|
|
|
2
2
|
import UIcon from "@nuxt/ui/runtime/vue/components/Icon.vue";
|
|
3
3
|
import { useToast } from "@nuxt/ui/composables/useToast";
|
|
4
4
|
import { useAppConfig } from "@nuxt/ui/runtime/vue/composables/useAppConfig";
|
|
5
|
+
import { en as uiEn, fr as uiFr } from "@nuxt/ui/locale";
|
|
5
6
|
import ui from "@nuxt/ui/vue-plugin";
|
|
6
7
|
import { useHead } from "@unhead/vue";
|
|
7
8
|
import type { VueHeadClient } from "@unhead/vue/types";
|
|
@@ -80,6 +81,19 @@ const SSR_ASYNC_DATA_ID = "dms-ssr-async-data";
|
|
|
80
81
|
export const SSR_ASYNC_COMPONENTS_ID = "dms-ssr-async-components";
|
|
81
82
|
const DEFAULT_LOCALE = "en";
|
|
82
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Nuxt UI ships its own strings (placeholders, empty states, aria labels).
|
|
86
|
+
* Only the locales the DMS translates are imported: the full catalog would
|
|
87
|
+
* weigh on every bundle. A locale missing here falls back to English.
|
|
88
|
+
*/
|
|
89
|
+
const UI_LOCALES = { en: uiEn, fr: uiFr };
|
|
90
|
+
|
|
91
|
+
type UiLocale = (typeof UI_LOCALES)[keyof typeof UI_LOCALES];
|
|
92
|
+
|
|
93
|
+
function uiLocale(locale: string): UiLocale {
|
|
94
|
+
return UI_LOCALES[locale as keyof typeof UI_LOCALES] ?? UI_LOCALES.en;
|
|
95
|
+
}
|
|
96
|
+
|
|
83
97
|
function pageLocale(props: DmsPageProps): string {
|
|
84
98
|
const language = props.user?.language;
|
|
85
99
|
if (typeof language !== "string") return DEFAULT_LOCALE;
|
|
@@ -164,6 +178,7 @@ const DmsPersistentLayout = defineComponent({
|
|
|
164
178
|
error,
|
|
165
179
|
content,
|
|
166
180
|
overlays.value,
|
|
181
|
+
i18n.locale.value,
|
|
167
182
|
);
|
|
168
183
|
};
|
|
169
184
|
},
|
|
@@ -198,6 +213,7 @@ function renderDmsPersistentLayout(
|
|
|
198
213
|
error: DmsPageProps["error"],
|
|
199
214
|
children: VNode[] | undefined,
|
|
200
215
|
overlays: string[],
|
|
216
|
+
locale: string,
|
|
201
217
|
) {
|
|
202
218
|
const layout = error ? undefined : getDmsLayout(props);
|
|
203
219
|
const content = layout
|
|
@@ -205,7 +221,7 @@ function renderDmsPersistentLayout(
|
|
|
205
221
|
: children;
|
|
206
222
|
return h(
|
|
207
223
|
UApp,
|
|
208
|
-
{ portal: "#dms-overlays" },
|
|
224
|
+
{ portal: "#dms-overlays", locale: uiLocale(locale) },
|
|
209
225
|
{
|
|
210
226
|
default: () => [
|
|
211
227
|
...overlays.map((name) =>
|