@junejs/cli 0.0.25 → 0.0.27
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/package.json +3 -3
- package/src/cli.ts +3 -0
- package/src/messages.ts +48 -0
- package/src/watch.ts +9 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@junejs/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.27",
|
|
4
4
|
"description": "The `june` CLI — dev / build / deploy / gen / info. A thin bin over @junejs/server.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"typecheck": "tsc --noEmit"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@junejs/core": "0.0.
|
|
24
|
-
"@junejs/server": "0.0.
|
|
23
|
+
"@junejs/core": "0.0.27",
|
|
24
|
+
"@junejs/server": "0.0.27"
|
|
25
25
|
},
|
|
26
26
|
"repository": {
|
|
27
27
|
"type": "git",
|
package/src/cli.ts
CHANGED
|
@@ -138,6 +138,9 @@ export async function run(argv: string[]): Promise<number | undefined> {
|
|
|
138
138
|
const { generateContent } = await import("@junejs/server");
|
|
139
139
|
const cols = await generateContent(root);
|
|
140
140
|
console.log(cols.length ? `generated content: ${cols.join(", ")}` : "no content/ collections");
|
|
141
|
+
const { generateMessages } = await import("./messages");
|
|
142
|
+
const locales = await generateMessages(root);
|
|
143
|
+
if (locales) console.log(`generated messages: ${locales.join(", ")}`);
|
|
141
144
|
return 0;
|
|
142
145
|
}
|
|
143
146
|
case "db": {
|
package/src/messages.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// `june gen` for ICU messages — OPT-IN: only an app that has a `messages/` dir
|
|
2
|
+
// AND `@junejs/i18n` installed gets a generated `app/_messages.ts` (the compiled
|
|
3
|
+
// catalogs + the typed `t`). The codegen is dynamically imported so the CLI never
|
|
4
|
+
// hard-depends on the opt-in package — same seam as a data layer.
|
|
5
|
+
|
|
6
|
+
import { existsSync } from "node:fs";
|
|
7
|
+
import { writeFile } from "node:fs/promises";
|
|
8
|
+
import { createRequire } from "node:module";
|
|
9
|
+
import { join, resolve } from "node:path";
|
|
10
|
+
import { pathToFileURL } from "node:url";
|
|
11
|
+
|
|
12
|
+
// The structural shape of @junejs/i18n/codegen (avoids a CLI → i18n type dep).
|
|
13
|
+
type Codegen = {
|
|
14
|
+
generateMessagesModule: (
|
|
15
|
+
dir: string,
|
|
16
|
+
opts: { defaultLocale: string },
|
|
17
|
+
) => { code: string; locales: string[] };
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/** Generate `app/_messages.ts` from `messages/*.json`. Returns the locales, or
|
|
21
|
+
* null when there's no `messages/` dir or @junejs/i18n isn't installed. */
|
|
22
|
+
export async function generateMessages(root: string): Promise<string[] | null> {
|
|
23
|
+
const messagesDir = join(root, "messages");
|
|
24
|
+
if (!existsSync(messagesDir)) return null;
|
|
25
|
+
|
|
26
|
+
let codegen: Codegen;
|
|
27
|
+
try {
|
|
28
|
+
// Resolve from the APP's deps (where it's installed), not the CLI's own
|
|
29
|
+
// node_modules — the CLI doesn't depend on the opt-in package. createRequire
|
|
30
|
+
// rooted at the app + import the resolved path.
|
|
31
|
+
// createRequire needs an absolute referencing path.
|
|
32
|
+
const resolved = createRequire(resolve(root, "package.json")).resolve("@junejs/i18n/codegen");
|
|
33
|
+
codegen = (await import(pathToFileURL(resolved).href)) as Codegen;
|
|
34
|
+
} catch {
|
|
35
|
+
console.warn(
|
|
36
|
+
"[june] messages/ found but @junejs/i18n is not installed — skipping " +
|
|
37
|
+
"(run: bun add @junejs/i18n)",
|
|
38
|
+
);
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const { loadJuneConfig } = await import("@junejs/server");
|
|
43
|
+
const config = await loadJuneConfig(root);
|
|
44
|
+
const defaultLocale = config.i18n?.defaultLocale ?? "en";
|
|
45
|
+
const { code, locales } = codegen.generateMessagesModule(messagesDir, { defaultLocale });
|
|
46
|
+
await writeFile(join(root, "app", "_messages.ts"), code);
|
|
47
|
+
return locales;
|
|
48
|
+
}
|
package/src/watch.ts
CHANGED
|
@@ -53,6 +53,15 @@ export function superviseDev(root: string): undefined {
|
|
|
53
53
|
console.error("[june] content regen failed:", err);
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
|
+
if (file.startsWith(`messages${sep}`)) {
|
|
57
|
+
// Recompile messages/*.json → app/_messages.ts before the server reboots.
|
|
58
|
+
try {
|
|
59
|
+
const { generateMessages } = await import("./messages");
|
|
60
|
+
await generateMessages(root);
|
|
61
|
+
} catch (err) {
|
|
62
|
+
console.error("[june] messages regen failed:", err);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
56
65
|
console.log(`[june] ${file} changed — restarting`);
|
|
57
66
|
const c = child;
|
|
58
67
|
if (!c || c.exitCode !== null || c.signalCode !== null) {
|