@moonsjs/vite 0.1.17 → 0.1.18

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.
@@ -80,11 +80,11 @@ export async function runPrerender(options: PrerenderOptions): Promise<Prerender
80
80
  throw new MoonsError({
81
81
  code: "E_ISR_INVALID",
82
82
  file: route.file,
83
- message: "`revalidate` tidak valid atau dipakai tanpa `prerender = true`",
84
- details: "ISR berbasis file: `revalidate` (detik, number >= 0) + `prerender`.",
83
+ message: "`revalidate` is invalid or used without `prerender = true`",
84
+ details: "File-based ISR: `revalidate` (seconds, number >= 0) + `prerender`.",
85
85
  suggestions: [
86
- "Gunakan angka detik, mis. `export const revalidate = 60`",
87
- "Tambahkan `export const prerender = true` pada page yang sama",
86
+ "Use a number of seconds, e.g. `export const revalidate = 60`",
87
+ "Add `export const prerender = true` to the same page",
88
88
  ],
89
89
  });
90
90
  }
@@ -92,7 +92,7 @@ export async function runPrerender(options: PrerenderOptions): Promise<Prerender
92
92
 
93
93
  if (prerender !== true) {
94
94
  if (prerender !== undefined && prerender !== false) {
95
- throw prerenderError(route, "`prerender` harus boolean (`true`/`false`)");
95
+ throw prerenderError(route, "`prerender` must be a boolean (`true`/`false`)");
96
96
  }
97
97
  continue;
98
98
  }
@@ -107,15 +107,15 @@ export async function runPrerender(options: PrerenderOptions): Promise<Prerender
107
107
  );
108
108
 
109
109
  if (response.status === 404) {
110
- log(`[moons] prerender: lewati ${pathname} (notFound)`);
110
+ log(`[moons] prerender: skipped ${pathname} (notFound)`);
111
111
  skipped += 1;
112
112
  continue;
113
113
  }
114
114
  if (response.status >= 300 && response.status < 400) {
115
- throw prerenderError(route, `\`redirect()\` tidak didukung saat prerender (${pathname})`);
115
+ throw prerenderError(route, `\`redirect()\` is not supported during prerender (${pathname})`);
116
116
  }
117
117
  if (response.status !== 200) {
118
- throw prerenderError(route, `status ${response.status} saat merender ${pathname}`);
118
+ throw prerenderError(route, `status ${response.status} while rendering ${pathname}`);
119
119
  }
120
120
 
121
121
  const html = await response.text();
@@ -152,7 +152,7 @@ export async function runPrerender(options: PrerenderOptions): Promise<Prerender
152
152
 
153
153
  const extras = [...(wrote404 ? [NOT_FOUND_FILE] : []), ...emitted];
154
154
  log(
155
- `[moons] prerender selesai: ${written} file${extras.length > 0 ? ` + ${extras.join(" + ")}` : ""} (${skipped} dilewati)`,
155
+ `[moons] prerender done: ${written} file${extras.length > 0 ? ` + ${extras.join(" + ")}` : ""} (${skipped} skipped)`,
156
156
  );
157
157
  return { written, skipped };
158
158
  }
@@ -237,7 +237,7 @@ async function renderStaticNotFound(
237
237
  );
238
238
  if (response.status !== 404) {
239
239
  log(
240
- `[moons] prerender: ${NOT_FOUND_FILE} dilewati (sentinel \`${NOT_FOUND_SENTINEL}\` → ${response.status})`,
240
+ `[moons] prerender: ${NOT_FOUND_FILE} skipped (sentinel \`${NOT_FOUND_SENTINEL}\` → ${response.status})`,
241
241
  );
242
242
  return null;
243
243
  }
@@ -267,11 +267,11 @@ function assertNoLeak(
267
267
  throw new MoonsError({
268
268
  code: "E_PRERENDER_LEAK",
269
269
  file,
270
- message: `hasil prerender \`${pathname}\` memuat ${labels}`,
271
- details: "HTML statis permanen — rahasia yang ter-prerender tidak bisa ditarik kembali.",
270
+ message: `prerender output \`${pathname}\` contains ${labels}`,
271
+ details: "Static HTML is permanent — a prerendered secret cannot be retracted.",
272
272
  suggestions: [
273
- "Jangan mengembalikan nilai env rahasia dari loader yang di-prerender",
274
- "Matikan `prerender` untuk route ini atau pindahkan datanya ke serverFn request-time",
273
+ "Do not return secret env values from a loader that runs at prerender time",
274
+ "Turn off `prerender` for this route or move the data to a request-time serverFn",
275
275
  ],
276
276
  });
277
277
  }
@@ -291,37 +291,37 @@ async function resolvePathnames(route: RouteDefinition, module: RouteModule): Pr
291
291
  throw new MoonsError({
292
292
  code: "E_PRERENDER_NO_PATHS",
293
293
  file: route.file,
294
- message: "route dynamic ber-`prerender = true` tanpa `export const paths`",
295
- details: "Prerender butuh daftar param untuk merender tiap path.",
294
+ message: "dynamic route with `prerender = true` without `export const paths`",
295
+ details: "Prerendering needs a param list to render each path.",
296
296
  suggestions: [
297
- 'Tambahkan `export const paths = () => [{ id: "…" }]`',
298
- "Atau hapus `prerender` agar dirender SSR saat request",
297
+ 'Add `export const paths = () => [{ id: "…" }]`',
298
+ "Or remove `prerender` so the route renders at request time (SSR)",
299
299
  ],
300
300
  });
301
301
  }
302
302
 
303
303
  const raw = await (paths as () => unknown | Promise<unknown>)();
304
304
  if (!Array.isArray(raw)) {
305
- throw prerenderError(route, "`paths()` harus mengembalikan array");
305
+ throw prerenderError(route, "`paths()` must return an array");
306
306
  }
307
307
 
308
308
  const expected = new Set(route.params);
309
309
  const result: string[] = [];
310
310
  for (const item of raw as unknown[]) {
311
311
  if (item === null || typeof item !== "object" || Array.isArray(item)) {
312
- throw prerenderError(route, "item `paths()` harus objek param string");
312
+ throw prerenderError(route, "`paths()` items must be objects with string params");
313
313
  }
314
314
  const record = item as Record<string, unknown>;
315
315
  const keys = Object.keys(record);
316
316
  for (const name of expected) {
317
317
  const value = record[name];
318
318
  if (typeof value !== "string" || value.length === 0) {
319
- throw prerenderError(route, `param \`${name}\` wajib string non-kosong`);
319
+ throw prerenderError(route, `param \`${name}\` must be a non-empty string`);
320
320
  }
321
321
  }
322
322
  for (const key of keys) {
323
323
  if (!expected.has(key)) {
324
- throw prerenderError(route, `param \`${key}\` tidak ada di pola route`);
324
+ throw prerenderError(route, `param \`${key}\` is not in the route pattern`);
325
325
  }
326
326
  }
327
327
  result.push(buildPathname(route, record as Record<string, string>));
@@ -356,7 +356,7 @@ function buildPathname(route: RouteDefinition, params: Record<string, string>):
356
356
 
357
357
  function encodeSegment(route: RouteDefinition, value: string): string {
358
358
  if (value.length === 0 || /^\.+$/.test(value)) {
359
- throw prerenderError(route, `nilai param \`${value}\` tidak valid untuk path file`);
359
+ throw prerenderError(route, `param value \`${value}\` is not valid for a file path`);
360
360
  }
361
361
  return encodeURIComponent(value);
362
362
  }
@@ -368,9 +368,9 @@ function outputFile(clientDir: string, pathname: string): string {
368
368
  if (file !== base && !file.startsWith(base + sep)) {
369
369
  throw new MoonsError({
370
370
  code: "E_PRERENDER_INVALID",
371
- message: `path prerender keluar dari direktori client (\`${pathname}\`)`,
372
- details: "Nama file harus berada di dalam `dist/client`.",
373
- suggestions: ["Periksa nilai param `paths` — jangan memakai `..`"],
371
+ message: `prerender path escapes the client directory (\`${pathname}\`)`,
372
+ details: "The file name must stay inside `dist/client`.",
373
+ suggestions: ["Check the `paths` param values — do not use `..`"],
374
374
  });
375
375
  }
376
376
  return file;
@@ -381,10 +381,10 @@ function prerenderError(route: RouteDefinition, message: string): MoonsError {
381
381
  code: "E_PRERENDER_INVALID",
382
382
  file: route.file,
383
383
  message,
384
- details: "Kontrak prerender mengikuti.",
384
+ details: "The prerender contract is enforced.",
385
385
  suggestions: [
386
- "Perbaiki bentuk `paths`/param agar cocok dengan pola route",
387
- "Jangan memakai `redirect()` pada route yang di-prerender",
386
+ "Fix the `paths`/params shape so it matches the route pattern",
387
+ "Do not use `redirect()` on a prerendered route",
388
388
  ],
389
389
  });
390
390
  }
@@ -14,7 +14,7 @@ export const ROOT_PLACEHOLDER = '<div id="root"></div>';
14
14
 
15
15
  export const DEFAULT_TEMPLATE = [
16
16
  "<!doctype html>",
17
- '<html lang="id">',
17
+ '<html lang="en">',
18
18
  "<head>",
19
19
  ' <meta charset="utf-8" />',
20
20
  ' <meta name="viewport" content="width=device-width, initial-scale=1" />',
@@ -38,11 +38,11 @@ export function injectShell(
38
38
  if (!template.includes(ROOT_PLACEHOLDER)) {
39
39
  throw new MoonsError({
40
40
  code: "E_INTERNAL",
41
- message: `shell HTML tidak memuat \`${ROOT_PLACEHOLDER}\``,
42
- details: "index.html aplikasi wajib memuat elemen root tersebut agar SSR bisa meng-inject markup.",
41
+ message: `shell HTML does not contain \`${ROOT_PLACEHOLDER}\``,
42
+ details: "The app's index.html must contain that root element so SSR can inject markup.",
43
43
  suggestions: [
44
- `Tambahkan ${ROOT_PLACEHOLDER} ke index.html`,
45
- "Atau hapus index.html untuk memakai shell bawaan",
44
+ `Add ${ROOT_PLACEHOLDER} to index.html`,
45
+ "Or remove index.html to use the built-in shell",
46
46
  ],
47
47
  });
48
48
  }
@@ -119,9 +119,9 @@ export function createFileShell(options: { clientDir?: string } = {}): Shell {
119
119
  throw new MoonsError({
120
120
  code: "E_INTERNAL",
121
121
  file,
122
- message: "`dist/client/index.html` tidak ditemukan",
123
- details: "Build client harus dijalankan sebelum server produksi dinyalakan.",
124
- suggestions: ["Jalankan `bun run build` lebih dulu"],
122
+ message: "`dist/client/index.html` not found",
123
+ details: "The client build must run before starting the production server.",
124
+ suggestions: ["Run `bun run build` first"],
125
125
  });
126
126
  }
127
127
  cached = readFileSync(file, "utf8");
@@ -36,10 +36,10 @@ export function installGracefulShutdown(
36
36
  return;
37
37
  }
38
38
  shuttingDown = true;
39
- log(`[moons] menerima ${signal} — berhenti menerima koneksi, drain...`);
39
+ log(`[moons] received ${signal} — no longer accepting connections, draining...`);
40
40
 
41
41
  const timer = setTimeout(() => {
42
- log(`[moons] drain melewati ${timeoutMs}ms — keluar paksa`);
42
+ log(`[moons] drain exceeded ${timeoutMs}ms — forcing exit`);
43
43
  const closeAll = (server as { closeAllConnections?: () => void }).closeAllConnections;
44
44
  try {
45
45
  closeAll?.call(server);
@@ -59,7 +59,7 @@ export function installGracefulShutdown(
59
59
  server.close(async (error?: Error) => {
60
60
  if (error !== undefined) {
61
61
  clearTimeout(timer);
62
- log(`[moons] penutupan server gagal: ${error.message}`);
62
+ log(`[moons] server close failed: ${error.message}`);
63
63
  exit(1);
64
64
  return;
65
65
  }
@@ -70,11 +70,11 @@ export function installGracefulShutdown(
70
70
  try {
71
71
  await options.onShutdown();
72
72
  } catch (hookError) {
73
- log(`[moons] onShutdown gagal: ${String(hookError)}`);
73
+ log(`[moons] onShutdown failed: ${String(hookError)}`);
74
74
  }
75
75
  }
76
76
  clearTimeout(timer);
77
- log("[moons] shutdown selesai (drain penuh)");
77
+ log("[moons] shutdown complete (full drain)");
78
78
  exit(0);
79
79
  });
80
80
  };
@@ -21,7 +21,7 @@ export function createFileStorage(clientDir: string): PrerenderStorage {
21
21
  async write(pathname: string, body: Uint8Array): Promise<void> {
22
22
  const target = staticFileTarget(clientDir, pathname);
23
23
  if (target === null) {
24
- throw new Error(`[moons] isr: path tidak valid untuk ditulis: ${pathname}`);
24
+ throw new Error(`[moons] isr: invalid path to write: ${pathname}`);
25
25
  }
26
26
  mkdirSync(dirname(target), { recursive: true });
27
27
  const tmp = `${target}.tmp-${process.pid}`;
@@ -202,19 +202,19 @@ export function serverOnlyImportError(input: {
202
202
  }): MoonsError {
203
203
  const sourceLabel =
204
204
  input.source === "builtin"
205
- ? "Sumber kecocokan: daftar bawaan paket server-only framework."
205
+ ? "Match source: framework built-in server-only package list."
206
206
  : input.source === "config"
207
- ? "Sumber kecocokan: `security.serverOnlyPackages` di moons.config.ts."
208
- : `Sumber kecocokan: marker \`"moons": { "serverOnly": true }\` di ${input.markerPath ?? "package.json"}.`;
207
+ ? "Match source: `security.serverOnlyPackages` in moons.config.ts."
208
+ : `Match source: marker \`"moons": { "serverOnly": true }\` in ${input.markerPath ?? "package.json"}.`;
209
209
  return new MoonsError({
210
210
  code: "E_FORBIDDEN_SERVER_IMPORT",
211
211
  file: input.relativeFile,
212
212
  line: input.line,
213
- message: `mengimpor${input.dynamic === true ? " (dynamic)" : ""} \`${input.specifier}\` — paket server-only \`${input.packageName}\``,
214
- details: `${sourceLabel}\nPaket server-only tidak boleh masuk bundle client.`,
213
+ message: `importing${input.dynamic === true ? " (dynamic)" : ""} \`${input.specifier}\` — server-only package \`${input.packageName}\``,
214
+ details: `${sourceLabel}\nServer-only packages must not enter the client bundle.`,
215
215
  suggestions: [
216
- "Pindahkan operasi tersebut ke `*.server.ts` dan panggil lewat serverFn",
217
- "Atau ganti/hapus import tersebut di modul client",
216
+ "Move the operation into `*.server.ts` and call it via a serverFn",
217
+ "Or replace/remove the import in the client module",
218
218
  ],
219
219
  });
220
220
  }
package/src/transform.ts CHANGED
@@ -552,17 +552,17 @@ export function renderServerFnStub(
552
552
  file: filename,
553
553
  line: fn.line,
554
554
  annotation: fn.name,
555
- message: `schema ${kind} serverFn \`${fn.name}\` merujuk nilai server \`${reference}\` dari \`${serverImport.specifier}\``,
555
+ message: `schema ${kind} of serverFn \`${fn.name}\` references server value \`${reference}\` from \`${serverImport.specifier}\``,
556
556
  details:
557
- `\`${reference}\` diimpor dari file server lain dan bukan serverFn — stub client tidak mengekspornya (dulu gagal dengan error mentah bundler \`MISSING_EXPORT\`).\n\n` +
558
- "Pilih salah satu:\n" +
559
- " // a) pindahkan konstanta/schema ke modul client-safe\n" +
557
+ `\`${reference}\` is imported from another server file and is not a serverFn — the client stub does not export it (previously a raw bundler \`MISSING_EXPORT\` error).\n\n` +
558
+ "Pick one:\n" +
559
+ " // a) move the constant/schema to a client-safe module\n" +
560
560
  ` import { ${reference} } from "../shared/schemas";\n` +
561
- " // b) inline nilai yang memang publik di schema, atau\n" +
562
- " // c) validasi tambahan di handler (server) tanpa mereferensikan nilai server di schema",
561
+ " // b) inline the value if it is genuinely public in the schema, or\n" +
562
+ " // c) do extra validation in the server handler without referencing server values in the schema",
563
563
  suggestions: [
564
- "Pindahkan deklarasi yang dirujuk ke modul bersama yang client-safe (mis. `src/shared/schemas.ts`)",
565
- "Atau lakukan validasi di handler server, bukan di ekspresi schema",
564
+ "Move the referenced declaration to a client-safe shared module (e.g. `src/shared/schemas.ts`)",
565
+ "Or do the validation in the server handler instead of the schema expression",
566
566
  ],
567
567
  });
568
568
  }
@@ -576,21 +576,21 @@ export function renderServerFnStub(
576
576
  file: filename,
577
577
  line: fn.line,
578
578
  annotation: fn.name,
579
- message: `schema ${kind} serverFn \`${fn.name}\` merujuk deklarasi lokal \`${reference}\``,
579
+ message: `schema ${kind} of serverFn \`${fn.name}\` references local declaration \`${reference}\``,
580
580
  details:
581
- `\`${reference}\` dibuang dari stub client, sehingga nilainya \`undefined\` di browser (crash hydration).\n\n` +
582
- "Sebelum (ditolak):\n" +
583
- ` const ${reference} = z.object({ … }); // deklarasi lokal di file yang sama\n` +
581
+ `\`${reference}\` is dropped from the client stub, so its value is \`undefined\` in the browser (hydration crash).\n\n` +
582
+ "Before (rejected):\n" +
583
+ ` const ${reference} = z.object({ … }); // local declaration in the same file\n` +
584
584
  ` export const ${fn.name} = serverFn({ ${kind}: ${reference}, … });\n\n` +
585
- "Sesudah (pilih salah satu):\n" +
586
- ` // a) inline schema di argumen\n` +
585
+ "After (pick one):\n" +
586
+ ` // a) inline the schema in the argument\n` +
587
587
  ` export const ${fn.name} = serverFn({ ${kind}: z.object({ … }), … });\n` +
588
- ` // b) pindahkan deklarasi ke modul bersama yang boleh masuk client (mis. src/shared/schemas.ts)\n` +
588
+ ` // b) move the declaration to a shared module that may enter the client (e.g. src/shared/schemas.ts)\n` +
589
589
  ` import { ${reference} } from "../shared/schemas";`,
590
590
  suggestions: [
591
- `Inline schema di argumen \`serverFn({ ${kind}: … })\`, atau`,
592
- `Pindahkan \`${reference}\` ke modul bersama (mis. \`src/shared/schemas.ts\`) lalu impor dari sana`,
593
- "Jangan memindahkan nilai rahasia ke shared — schema harus client-safe (zod/Standard Schema)",
591
+ `Inline the schema in the argument \`serverFn({ ${kind}: … })\`, or`,
592
+ `Move \`${reference}\` to a shared module (e.g. \`src/shared/schemas.ts\`) and import it from there`,
593
+ "Never move secret values to shared — the schema must be client-safe (zod/Standard Schema)",
594
594
  ],
595
595
  });
596
596
  }
@@ -607,9 +607,9 @@ export function renderServerFnStub(
607
607
  throw new MoonsError({
608
608
  code: "E_SERVER_IMPORT_IN_CLIENT",
609
609
  file: filename,
610
- message: `tidak bisa me-resolve \`${reExport.source}\` untuk re-export`,
611
- details: "Re-export dari `*.server.ts` harus bisa di-resolve statis.",
612
- suggestions: ["Perbaiki path re-export", "Hindari re-export dinamis dari file server"],
610
+ message: `cannot resolve \`${reExport.source}\` for re-export`,
611
+ details: "Re-exports from `*.server.ts` must be statically resolvable.",
612
+ suggestions: ["Fix the re-export path", "Avoid dynamic re-exports from server files"],
613
613
  });
614
614
  }
615
615
  const targetNames = serverFnExportNames(target, (specifier) =>
@@ -630,9 +630,9 @@ export function renderServerFnStub(
630
630
  throw new MoonsError({
631
631
  code: "E_SERVER_IMPORT_IN_CLIENT",
632
632
  file: filename,
633
- message: `\`export *\` dari \`${specifier}\` tidak bisa di-resolve`,
634
- details: "`export *` dari `*.server.ts` wajib bisa di-expand statis.",
635
- suggestions: ["Perbaiki path re-export", "Ganti menjadi named re-export"],
633
+ message: `\`export *\` from \`${specifier}\` cannot be resolved`,
634
+ details: "`export *` from `*.server.ts` must be statically expandable.",
635
+ suggestions: ["Fix the re-export path", "Replace it with named re-exports"],
636
636
  });
637
637
  }
638
638
  const targetNames = serverFnExportNames(target, (nested) =>
@@ -646,7 +646,7 @@ export function renderServerFnStub(
646
646
  }
647
647
 
648
648
  if (importLines.length === 0 && exportLines.length === 0) {
649
- return { code: "// @moons: tidak ada serverFn yang di-export\nexport {};\n", referenced };
649
+ return { code: "// @moons: no serverFn exported\nexport {};\n", referenced };
650
650
  }
651
651
 
652
652
  return { code: `${[...importLines, "", ...exportLines].join("\n")}\n`, referenced };
@@ -747,12 +747,12 @@ export function nonContractServerFileError(file: string, projectRoot: string): M
747
747
  return new MoonsError({
748
748
  code: "E_SERVER_IMPORT_IN_CLIENT",
749
749
  file: toRelative(projectRoot, file),
750
- message: "file server memakai ekstensi di luar kontrak `*.server.ts`",
750
+ message: "server file uses an extension outside the `*.server.ts` contract",
751
751
  details:
752
- "Transform zero-trust hanya menangani `*.server.ts`/`*.server.tsx`; file server dengan ekstensi lain tidak bisa di-stub dan tidak boleh masuk graph client.",
752
+ "The zero-trust transform only handles `*.server.ts`/`*.server.tsx`; server files with other extensions cannot be stubbed and must not enter the client graph.",
753
753
  suggestions: [
754
- "Ganti nama file menjadi `*.server.ts`/`*.server.tsx` dan taruh `serverFn` di dalamnya",
755
- "Atau pindahkan nilai yang dibutuhkan ke file non-server",
754
+ "Rename the file to `*.server.ts`/`*.server.tsx` and put the `serverFn` inside it",
755
+ "Or move the value you need into a non-server file",
756
756
  ],
757
757
  });
758
758
  }
@@ -942,12 +942,12 @@ export async function checkClientModuleImports(
942
942
  code: "E_FORBIDDEN_SERVER_IMPORT",
943
943
  file: relativeFile,
944
944
  line,
945
- message: `mengimpor \`${specifier}\` — \`moons.config.ts\` adalah modul server-only`,
945
+ message: `importing \`${specifier}\` — \`moons.config.ts\` is a server-only module`,
946
946
  details:
947
- "Config memuat `context`/`middleware` (kode server) dan tidak pernah masuk bundle client (Addendum J.4).",
947
+ "The config contains `context`/`middleware` (server code) and never enters the client bundle (Addendum J.4).",
948
948
  suggestions: [
949
- "Pindahkan nilai yang dibutuhkan ke modul client-safe (mis. `src/shared/…`)",
950
- "Ambil nilai dari server lewat loader/serverFn",
949
+ "Move the value you need into a client-safe module (e.g. `src/shared/…`)",
950
+ "Get the value from the server via a loader/serverFn",
951
951
  ],
952
952
  });
953
953
  };
@@ -957,12 +957,12 @@ export async function checkClientModuleImports(
957
957
  code: "E_FORBIDDEN_SERVER_IMPORT",
958
958
  file: relativeFile,
959
959
  line,
960
- message: `mengimpor \`${specifier}\` — \`${toRelative(projectRoot, resolvedTarget)}\` ada di \`src/server/**\` (server-only)`,
960
+ message: `importing \`${specifier}\` — \`${toRelative(projectRoot, resolvedTarget)}\` is inside \`src/server/**\` (server-only)`,
961
961
  details:
962
- "Direktori `src/server/**` hanya untuk kode server (Addendum J.4); suffix `.server.ts` bukan satu-satunya jaminan.",
962
+ "The `src/server/**` directory is for server code only (Addendum J.4); the `.server.ts` suffix is not the only guarantee.",
963
963
  suggestions: [
964
- "Pindahkan kode yang client-safe ke `src/shared/`",
965
- "Akses nilainya dari server lewat loader/serverFn",
964
+ "Move client-safe code to `src/shared/`",
965
+ "Access the value from the server via a loader/serverFn",
966
966
  ],
967
967
  });
968
968
  };
@@ -973,12 +973,12 @@ export async function checkClientModuleImports(
973
973
  code: "E_FORBIDDEN_SERVER_IMPORT",
974
974
  file: relativeFile,
975
975
  line,
976
- message: `mengimpor \`${specifier}\` — \`${relApi}\` adalah modul API server-only`,
976
+ message: `importing \`${specifier}\` — \`${relApi}\` is a server-only API module`,
977
977
  details:
978
- "`src/api/**` hanya berjalan di server (endpoint HTTP) dan tidak pernah masuk bundle client.",
978
+ "`src/api/**` only runs on the server (HTTP endpoints) and never enters the client bundle.",
979
979
  suggestions: [
980
- "Pindahkan operasi tersebut ke `*.server.ts` dan panggil lewat serverFn",
981
- "Jangan mengimpor file `src/api` dari route/komponen client",
980
+ "Move the operation into `*.server.ts` and call it via a serverFn",
981
+ "Do not import `src/api` files from client routes/components",
982
982
  ],
983
983
  });
984
984
  };
@@ -1034,8 +1034,8 @@ export async function checkClientModuleImports(
1034
1034
  message,
1035
1035
  details,
1036
1036
  suggestions: [
1037
- "Buat server function yang mengembalikan data yang dibutuhkan, atau",
1038
- "Jika nilainya memang publik, definisikan ulang konstanta itu di modul yang boleh masuk client (jangan memindahkan nilai rahasia)",
1037
+ "Create a server function that returns the data you need, or",
1038
+ "If the value is genuinely public, redefine the constant in a client-safe module (never move secret values)",
1039
1039
  ],
1040
1040
  });
1041
1041
  };
@@ -1045,11 +1045,11 @@ export async function checkClientModuleImports(
1045
1045
  code: "E_FORBIDDEN_SERVER_IMPORT",
1046
1046
  file: relativeFile,
1047
1047
  line,
1048
- message: `mengimpor \`${specifier}\` di modul client`,
1049
- details: "Modul server-only hanya boleh di-import dari *.server.ts.",
1048
+ message: `importing \`${specifier}\` in a client module`,
1049
+ details: "Server-only modules may only be imported from *.server.ts.",
1050
1050
  suggestions: [
1051
- "Pindahkan operasi tersebut ke serverFn, atau",
1052
- "Hapus import tersebut",
1051
+ "Move the operation into a serverFn, or",
1052
+ "Remove the import",
1053
1053
  ],
1054
1054
  });
1055
1055
  };
@@ -1177,13 +1177,13 @@ export async function checkClientModuleImports(
1177
1177
  code: "E_SERVER_IMPORT_IN_CLIENT",
1178
1178
  file: relativeFile,
1179
1179
  line,
1180
- message: `mengimpor \`${name}\` — berasal dari \`${toRelative(projectRoot, serverFile)}\` (via rantai re-export)`,
1180
+ message: `importing \`${name}\` — comes from \`${toRelative(projectRoot, serverFile)}\` (via a re-export chain)`,
1181
1181
  details:
1182
- `\`${toRelative(projectRoot, resolvedTarget)}\` me-re-export nilai dari file server; ` +
1183
- "stub client tidak mengekspornya (dulu gagal dengan error mentah bundler `MISSING_EXPORT`).",
1182
+ `\`${toRelative(projectRoot, resolvedTarget)}\` re-exports a value from a server file; ` +
1183
+ "the client stub does not export it (previously a raw bundler `MISSING_EXPORT` error).",
1184
1184
  suggestions: [
1185
- "Buat server function yang mengembalikan data yang dibutuhkan, atau",
1186
- "Definisikan ulang konstanta publik itu di modul client-safe (jangan pindahkan nilai rahasia)",
1185
+ "Create a server function that returns the data you need, or",
1186
+ "Redefine the public constant in a client-safe module (never move secret values)",
1187
1187
  ],
1188
1188
  });
1189
1189
  }
@@ -1197,7 +1197,7 @@ export async function checkClientModuleImports(
1197
1197
 
1198
1198
  if (statement.type === "ExportAllDeclaration") {
1199
1199
  if (resolvedTarget === null) {
1200
- reject(line, `\`export *\` dari \`${targetRelative}\` tidak bisa di-resolve`, "Re-export dari `*.server.ts` wajib bisa di-resolve statis.");
1200
+ reject(line, `\`export *\` from \`${targetRelative}\` cannot be resolved`, "Re-exports from `*.server.ts` must be statically resolvable.");
1201
1201
  }
1202
1202
  continue; // aman: target menjadi stub
1203
1203
  }
@@ -1205,10 +1205,10 @@ export async function checkClientModuleImports(
1205
1205
  const specifiers = (statement["specifiers"] ?? []) as AstNode[];
1206
1206
  for (const item of specifiers) {
1207
1207
  if (item.type === "ImportDefaultSpecifier") {
1208
- reject(line, `mengimpor default dari ${targetRelative}`, "Default export dari file server tidak boleh menyeberang ke client.");
1208
+ reject(line, `importing the default export from ${targetRelative}`, "Default exports from a server file must not cross to the client.");
1209
1209
  }
1210
1210
  if (item.type === "ImportNamespaceSpecifier") {
1211
- reject(line, `mengimpor namespace (\`* as\`) dari ${targetRelative}`, "Import namespace dari file server tidak boleh menyeberang ke client.");
1211
+ reject(line, `importing the namespace (\`* as\`) from ${targetRelative}`, "Namespace imports from a server file must not cross to the client.");
1212
1212
  }
1213
1213
  const name = ((item["local"] as AstNode | undefined)?.["name"] as string) ?? "";
1214
1214
  // Type-only (Addendum J.5): Babel menaruh `importKind: "type"` di
@@ -1222,8 +1222,8 @@ export async function checkClientModuleImports(
1222
1222
  if (name.length > 0 && !(await isAllowedServerFnImport(resolvedTarget, specifier, name))) {
1223
1223
  reject(
1224
1224
  line,
1225
- `mengimpor \`${name}\` dari ${targetRelative}`,
1226
- "Kode server tidak boleh muncul di client.\nHanya `serverFn` yang diizinkan menyeberang.",
1225
+ `importing \`${name}\` from ${targetRelative}`,
1226
+ "Server code must not appear in the client.\nOnly `serverFn` may cross.",
1227
1227
  );
1228
1228
  }
1229
1229
  }
@@ -1270,11 +1270,11 @@ export async function checkClientModuleImports(
1270
1270
  code: "E_ENV_IN_CLIENT",
1271
1271
  file: relativeFile,
1272
1272
  line: node.loc?.start.line ?? 1,
1273
- message: `memanggil \`${callText}\` di modul yang masuk client`,
1274
- details: "`env()` hanya legal di server.",
1273
+ message: `calling \`${callText}\` in a client module`,
1274
+ details: "`env()` is only legal on the server.",
1275
1275
  suggestions: [
1276
- "Pindahkan pemanggilan ke dalam serverFn, atau",
1277
- "Gunakan import.meta.env untuk nilai publik",
1276
+ "Move the call into a serverFn, or",
1277
+ "Use import.meta.env for public values",
1278
1278
  ],
1279
1279
  });
1280
1280
  });
@@ -1338,7 +1338,7 @@ export async function checkClientModuleImports(
1338
1338
 
1339
1339
  const targetRelative =
1340
1340
  resolvedTarget === null ? request.text : toRelative(projectRoot, resolvedTarget);
1341
- reject(request.node.loc?.start.line ?? 1, `mengimpor (dynamic) \`${request.text}\` dari ${targetRelative}`, "Client tidak boleh melakukan dynamic import ke `*.server.ts`.");
1341
+ reject(request.node.loc?.start.line ?? 1, `importing (dynamic) \`${request.text}\` from ${targetRelative}`, "The client must not dynamically import `*.server.ts`.");
1342
1342
  }
1343
1343
 
1344
1344
  // `import.meta.glob` yang mencakup `*.server.ts` (§12.7) — audit adversarial M6.
@@ -1368,11 +1368,11 @@ export async function checkClientModuleImports(
1368
1368
  code: "E_SERVER_IMPORT_IN_CLIENT",
1369
1369
  file: relativeFile,
1370
1370
  line: node.loc?.start.line ?? 1,
1371
- message: `mengimpor (glob) \`${pattern}\` di modul client`,
1372
- details: "`import.meta.glob` yang mencakup `*.server.ts` dilarang di client.",
1371
+ message: `importing (glob) \`${pattern}\` in a client module`,
1372
+ details: "`import.meta.glob` patterns covering `*.server.ts` are forbidden in the client.",
1373
1373
  suggestions: [
1374
- "Import statis `serverFn` dari `*.server.ts` (hanya itu yang boleh menyeberang), atau",
1375
- "Pindahkan kebutuhan data ke dalam server function",
1374
+ "Statically import the `serverFn` from `*.server.ts` (that is all that may cross), or",
1375
+ "Move the data requirement into a server function",
1376
1376
  ],
1377
1377
  });
1378
1378
  }
@@ -1506,7 +1506,7 @@ export function checkRouteModuleExports(context: RouteExportCheckContext): void
1506
1506
  : base === "_error.tsx" || base === "_404.tsx"
1507
1507
  ? ["default"]
1508
1508
  : ["default", "loader", "meta", "prerender", "paths", "revalidate"];
1509
- const allowedText = `Hanya ${allowed.map((name) => `\`${name}\``).join(", ")} yang boleh di-export.`;
1509
+ const allowedText = `Only ${allowed.map((name) => `\`${name}\``).join(", ")} may be exported.`;
1510
1510
  const relativeFile = toRelative(projectRoot, file);
1511
1511
  const ast = parseModule(code, file);
1512
1512
 
@@ -1524,11 +1524,11 @@ export function checkRouteModuleExports(context: RouteExportCheckContext): void
1524
1524
  code: "E_ROUTE_EXPORT_INVALID",
1525
1525
  file: relativeFile,
1526
1526
  line: statement.loc?.start.line ?? 1,
1527
- message: "`export *` tidak diizinkan di modul route",
1527
+ message: "`export *` is not allowed in route modules",
1528
1528
  details: allowedText,
1529
1529
  suggestions: [
1530
- `Pindahkan isi file ke luar ${toRelative(projectRoot, routesDir)}/, atau`,
1531
- "Hapus `export *` tersebut",
1530
+ `Move the file contents outside ${toRelative(projectRoot, routesDir)}/, or`,
1531
+ "Remove the `export *`",
1532
1532
  ],
1533
1533
  });
1534
1534
  }
@@ -1564,11 +1564,11 @@ export function checkRouteModuleExports(context: RouteExportCheckContext): void
1564
1564
  code: "E_ROUTE_EXPORT_INVALID",
1565
1565
  file: relativeFile,
1566
1566
  line: entry.line,
1567
- message: `export \`${entry.name}\` tidak diizinkan di modul route`,
1567
+ message: `export \`${entry.name}\` is not allowed in route modules`,
1568
1568
  details: allowedText,
1569
1569
  suggestions: [
1570
- `Pindahkan \`${entry.name}\` ke file di luar ${toRelative(projectRoot, routesDir)}/, atau`,
1571
- "Hapus export tersebut",
1570
+ `Move \`${entry.name}\` to a file outside ${toRelative(projectRoot, routesDir)}/, or`,
1571
+ "Remove the export",
1572
1572
  ],
1573
1573
  });
1574
1574
  }
@@ -1578,9 +1578,9 @@ export function checkRouteModuleExports(context: RouteExportCheckContext): void
1578
1578
  throw new MoonsError({
1579
1579
  code: "E_ROUTE_EXPORT_INVALID",
1580
1580
  file: relativeFile,
1581
- message: "modul route wajib mengekspor `default`",
1582
- details: "Setiap file route harus punya `export default` berupa komponen React.",
1583
- suggestions: ["Tambahkan `export default function Page() { ... }`"],
1581
+ message: "route module must export `default`",
1582
+ details: "Every route file needs an `export default` React component.",
1583
+ suggestions: ["Add `export default function Page() { ... }`"],
1584
1584
  });
1585
1585
  }
1586
1586
  }