@junejs/cli 0.0.24 → 0.0.26

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@junejs/cli",
3
- "version": "0.0.24",
3
+ "version": "0.0.26",
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",
24
- "@junejs/server": "0.0.24"
23
+ "@junejs/core": "0.0.25",
24
+ "@junejs/server": "0.0.25"
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": {
@@ -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) {