@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.
@@ -13,7 +13,7 @@ import {
13
13
  DEFAULT_SECURITY_HEADERS,
14
14
  sendNodeResponse2,
15
15
  installDevMiddleware2
16
- } from "../index-v5sbd3az.js";
16
+ } from "../index-1ksjfvnz.js";
17
17
 
18
18
  // src/server/handler.ts
19
19
  import {
@@ -93,9 +93,9 @@ function createRequestHandler(options) {
93
93
  return apiErrorResponse(new MoonsError({
94
94
  code: "E_API_HANDLER_INVALID",
95
95
  file: route.file,
96
- message: `modul API \`${route.path}\` tidak bisa dimuat`,
97
- details: "Peta `loadApi` tidak memuat route ini (build/dev tidak sinkron).",
98
- suggestions: ["Jalankan ulang build / restart dev server"]
96
+ message: `API module \`${route.path}\` could not be loaded`,
97
+ details: "The `loadApi` map does not contain this route (build/dev out of sync).",
98
+ suggestions: ["Rebuild / restart the dev server"]
99
99
  }), route);
100
100
  }
101
101
  let mod;
@@ -108,9 +108,9 @@ function createRequestHandler(options) {
108
108
  return apiErrorResponse(new MoonsError({
109
109
  code: "E_API_HANDLER_INVALID",
110
110
  file: route.file,
111
- message: "modul API tidak mengekspor objek handler",
112
- details: `Modul \`${route.path}\` harus mengekspor handler method.`,
113
- suggestions: ["Export `GET`/`POST`/… sebagai fungsi `(args) => Response`"]
111
+ message: "API module does not export a handler object",
112
+ details: `Module \`${route.path}\` must export method handlers.`,
113
+ suggestions: ["Export `GET`/`POST`/… as `(args) => Response` functions"]
114
114
  }), route);
115
115
  }
116
116
  const record = mod;
@@ -137,9 +137,9 @@ function createRequestHandler(options) {
137
137
  return apiErrorResponse(new MoonsError({
138
138
  code: "E_API_HANDLER_INVALID",
139
139
  file: route.file,
140
- message: `handler \`${requestMethod}\` tidak mengembalikan \`Response\``,
141
- details: "Handler API wajib mengembalikan `new Response(...)`.",
142
- suggestions: ["Kembalikan `new Response(body, { status, headers })`"]
140
+ message: `handler \`${requestMethod}\` did not return a \`Response\``,
141
+ details: "API handlers must return `new Response(...)`.",
142
+ suggestions: ["Return `new Response(body, { status, headers })`"]
143
143
  }), route);
144
144
  }
145
145
  if (stripBody) {
@@ -159,11 +159,11 @@ function createRequestHandler(options) {
159
159
  const markup = renderToMarkup({ page: key, layouts: [] }, { page: module, layouts: [] }, {}, {});
160
160
  return htmlResponse(await shell(markup, payload, request.url), 404);
161
161
  } catch (error) {
162
- console.error("[moons] gagal merender _404 kustom:", error);
162
+ console.error("[moons] failed to render custom _404:", error);
163
163
  }
164
164
  }
165
165
  const payload = encodeSsrPayload({ key: "", params: {}, data: {} });
166
- const html = await shell("<h1>404</h1><p>Halaman tidak ditemukan.</p>", payload, request.url);
166
+ const html = await shell("<h1>404</h1><p>Page not found.</p>", payload, request.url);
167
167
  return htmlResponse(html, 404);
168
168
  }
169
169
  async function routeErrorResponse(error, request, resolved) {
@@ -184,7 +184,7 @@ function createRequestHandler(options) {
184
184
  const markup = renderToMarkup({ page: key, layouts: [] }, { page: module, layouts: [] }, {}, {}, {}, serialized === undefined ? undefined : reviveError(serialized));
185
185
  return htmlResponse(await shell(markup, payload, request.url), 500);
186
186
  } catch (renderError) {
187
- console.error("[moons] gagal merender _error kustom:", renderError);
187
+ console.error("[moons] failed to render custom _error:", renderError);
188
188
  }
189
189
  }
190
190
  return internalErrorResponse(error, { log: false });
@@ -198,9 +198,9 @@ function createRequestHandler(options) {
198
198
  throw new MoonsError({
199
199
  code: "E_MIDDLEWARE_INVALID",
200
200
  file: definition.file,
201
- message: "middleware direktori tidak bisa dimuat",
202
- details: "Peta `loadRoute` tidak memuat `_middleware.ts` ini.",
203
- suggestions: ["Restart dev server / jalankan ulang build"]
201
+ message: "directory middleware could not be loaded",
202
+ details: "The `loadRoute` map does not contain this `_middleware.ts`.",
203
+ suggestions: ["Restart the dev server / rebuild"]
204
204
  });
205
205
  }
206
206
  const module = await load();
@@ -209,8 +209,8 @@ function createRequestHandler(options) {
209
209
  throw new MoonsError({
210
210
  code: "E_MIDDLEWARE_INVALID",
211
211
  file: definition.file,
212
- message: "`_middleware.ts` tidak meng-export default fungsi",
213
- details: "Middleware direktori mengikuti bentuk `(args) => Promise<Response>`.",
212
+ message: "`_middleware.ts` does not default-export a function",
213
+ details: "Directory middleware follows the `(args) => Promise<Response>` shape.",
214
214
  suggestions: ["Export default `async ({ req, ctx, next }) => await next()`"]
215
215
  });
216
216
  }
@@ -226,9 +226,9 @@ function createRequestHandler(options) {
226
226
  throw new MoonsError({
227
227
  code: "E_MIDDLEWARE_INVALID",
228
228
  file: definition.file,
229
- message: "middleware API tidak bisa dimuat",
230
- details: "Peta `loadApiMiddleware` tidak memuat `_middleware.ts` ini.",
231
- suggestions: ["Restart dev server / jalankan ulang build"]
229
+ message: "API middleware could not be loaded",
230
+ details: "The `loadApiMiddleware` map does not contain this `_middleware.ts`.",
231
+ suggestions: ["Restart the dev server / rebuild"]
232
232
  });
233
233
  }
234
234
  const module = await load();
@@ -236,8 +236,8 @@ function createRequestHandler(options) {
236
236
  throw new MoonsError({
237
237
  code: "E_MIDDLEWARE_INVALID",
238
238
  file: definition.file,
239
- message: "`_middleware.ts` tidak meng-export default fungsi",
240
- details: "Middleware direktori mengikuti bentuk `(args) => Promise<Response>`.",
239
+ message: "`_middleware.ts` does not default-export a function",
240
+ details: "Directory middleware follows the `(args) => Promise<Response>` shape.",
241
241
  suggestions: ["Export default `async ({ req, ctx, next }) => await next()`"]
242
242
  });
243
243
  }
@@ -268,7 +268,7 @@ function createRequestHandler(options) {
268
268
  return await handleApiRequest(apiMatch.route, apiMatch.params, request, ctx);
269
269
  }
270
270
  const middlewares = await loadApiDirMiddlewares(apiChain);
271
- return await composeMiddleware(middlewares, ctx, () => handleApiRequest(apiMatch.route, apiMatch.params, request, ctx), { code: "E_MIDDLEWARE_INVALID", label: "middleware API" })(request);
271
+ return await composeMiddleware(middlewares, ctx, () => handleApiRequest(apiMatch.route, apiMatch.params, request, ctx), { code: "E_MIDDLEWARE_INVALID", label: "API middleware" })(request);
272
272
  }
273
273
  }
274
274
  const resolved = resolveRoute(url.pathname, routes);
@@ -281,7 +281,7 @@ function createRequestHandler(options) {
281
281
  return await renderRoute(resolved, request, ctx);
282
282
  }
283
283
  const middlewares = await loadDirMiddlewares(dirChain);
284
- return await composeMiddleware(middlewares, ctx, () => renderRoute(resolved, request, ctx), { code: "E_MIDDLEWARE_INVALID", label: "middleware direktori" })(request);
284
+ return await composeMiddleware(middlewares, ctx, () => renderRoute(resolved, request, ctx), { code: "E_MIDDLEWARE_INVALID", label: "directory middleware" })(request);
285
285
  } catch (error) {
286
286
  if (isRedirectSignal(error)) {
287
287
  return new Response(null, {
@@ -386,9 +386,9 @@ async function loadModules(keys, loadRoute) {
386
386
  if (load === undefined) {
387
387
  throw new MoonsError({
388
388
  code: "E_INTERNAL",
389
- message: `modul route \`${key}\` tidak terdaftar`,
390
- details: "Registry route tidak sinkron dengan hasil scan.",
391
- suggestions: ["Jalankan ulang `bun run build`, atau restart dev server"]
389
+ message: `route module \`${key}\` is not registered`,
390
+ details: "The route registry is out of sync with the scan result.",
391
+ suggestions: ["Run `bun run build` again, or restart the dev server"]
392
392
  });
393
393
  }
394
394
  return await load();
@@ -403,11 +403,11 @@ async function runRouteMeta(pageModule, pageData, file) {
403
403
  throw new MoonsError({
404
404
  code: "E_INTERNAL",
405
405
  file,
406
- message: "export `meta` harus berupa fungsi `({ data }) => RouteMeta`",
407
- details: "Bentuk `meta` mengikuti ",
406
+ message: "export `meta` must be a function `({ data }) => RouteMeta`",
407
+ details: "The `meta` shape follows `RouteMeta`.",
408
408
  suggestions: [
409
- 'Ubah menjadi `export const meta = ({ data }) => ({ title: "..." })`',
410
- "Atau hapus export `meta`"
409
+ 'Change it to `export const meta = ({ data }) => ({ title: "..." })`',
410
+ "Or remove the `meta` export"
411
411
  ]
412
412
  });
413
413
  }
@@ -416,9 +416,9 @@ async function runRouteMeta(pageModule, pageData, file) {
416
416
  throw new MoonsError({
417
417
  code: "E_INTERNAL",
418
418
  file,
419
- message: "`meta()` harus mengembalikan objek RouteMeta",
420
- details: "Nilai yang dikembalikan dipakai untuk <title>/description/og.",
421
- suggestions: ['Kembalikan objek, mis. `({ title: "Halaman" })`']
419
+ message: "`meta()` must return a RouteMeta object",
420
+ details: "The returned value is used for <title>/description/og.",
421
+ suggestions: ['Return an object, e.g. `({ title: "Home" })`']
422
422
  });
423
423
  }
424
424
  return result;
@@ -427,13 +427,13 @@ function apiErrorResponse(error, route) {
427
427
  const isProduction = process.env["NODE_ENV"] === "production";
428
428
  if (error instanceof MoonsError) {
429
429
  console.error(`[moons] API ${route.path}: ${error.format()}`);
430
- return new Response(isProduction ? "Terjadi kesalahan internal." : error.format(), {
430
+ return new Response(isProduction ? "Internal server error." : error.format(), {
431
431
  status: 500,
432
432
  headers: { "content-type": "text/plain; charset=utf-8" }
433
433
  });
434
434
  }
435
435
  console.error(`[moons] API ${route.path}:`, error);
436
- return new Response(isProduction ? "Terjadi kesalahan internal." : String(error), {
436
+ return new Response(isProduction ? "Internal server error." : String(error), {
437
437
  status: 500,
438
438
  headers: { "content-type": "text/plain; charset=utf-8" }
439
439
  });
@@ -442,8 +442,8 @@ function internalErrorResponse(error, options = {}) {
442
442
  if (options.log !== false) {
443
443
  console.error("[moons] request error:", error);
444
444
  }
445
- const detail = process.env["NODE_ENV"] !== "production" && error instanceof MoonsError ? `<pre>${escapeHtml(error.format())}</pre>` : "<p>Terjadi kesalahan internal.</p>";
446
- return htmlResponse(`<!doctype html><html lang="id"><head><meta charset="utf-8"><title>500</title></head><body><h1>500</h1>${detail}</body></html>`, 500);
445
+ const detail = process.env["NODE_ENV"] !== "production" && error instanceof MoonsError ? `<pre>${escapeHtml(error.format())}</pre>` : "<p>Internal server error.</p>";
446
+ return htmlResponse(`<!doctype html><html lang="en"><head><meta charset="utf-8"><title>500</title></head><body><h1>500</h1>${detail}</body></html>`, 500);
447
447
  }
448
448
  function htmlResponse(html, status) {
449
449
  return new Response(html, {
@@ -477,7 +477,7 @@ function warnPayloadFindings(payload, scan, warned) {
477
477
  continue;
478
478
  }
479
479
  warned.add(label);
480
- console.warn(`[moons] peringatan dev: payload SSR memuat ${label} — jangan mengembalikan rahasia dari loader.`);
480
+ console.warn(`[moons] dev warning: SSR payload contains ${label} — do not return secrets from loaders.`);
481
481
  }
482
482
  }
483
483
  // src/server/node-server.ts
@@ -517,7 +517,7 @@ async function runRevalidate(options) {
517
517
  headers: { "x-moons-prerender": "1" }
518
518
  }));
519
519
  if (response.status !== 200) {
520
- log(`[moons] isr: lewati ${options.pathname} (status ${response.status})`);
520
+ log(`[moons] isr: skipped ${options.pathname} (status ${response.status})`);
521
521
  return;
522
522
  }
523
523
  const html = await response.text();
@@ -527,7 +527,7 @@ async function runRevalidate(options) {
527
527
  });
528
528
  if (findings.length > 0) {
529
529
  const labels = findings.map((finding) => finding.kind === "canary" ? "canary" : `env(${finding.label})`).join(", ");
530
- log(`[moons] isr: TIDAK menulis ${options.pathname} — memuat ${labels}`);
530
+ log(`[moons] isr: NOT writing ${options.pathname} — contains ${labels}`);
531
531
  return;
532
532
  }
533
533
  if (options.storage !== undefined) {
@@ -535,14 +535,14 @@ async function runRevalidate(options) {
535
535
  return;
536
536
  }
537
537
  if (options.file === undefined) {
538
- log(`[moons] isr: lewati ${options.pathname} — tanpa file/storage tujuan`);
538
+ log(`[moons] isr: skipped ${options.pathname} — no destination file/storage`);
539
539
  return;
540
540
  }
541
541
  const tmp = `${options.file}.tmp-${process.pid}`;
542
542
  writeFileSync(tmp, html);
543
543
  renameSync(tmp, options.file);
544
544
  } catch (error) {
545
- log(`[moons] isr: gagal regenerasi ${options.pathname}: ${String(error)}`);
545
+ log(`[moons] isr: failed to regenerate ${options.pathname}: ${String(error)}`);
546
546
  }
547
547
  }
548
548
 
@@ -562,7 +562,7 @@ function createFileStorage(clientDir) {
562
562
  async write(pathname, body) {
563
563
  const target = staticFileTarget(clientDir, pathname);
564
564
  if (target === null) {
565
- throw new Error(`[moons] isr: path tidak valid untuk ditulis: ${pathname}`);
565
+ throw new Error(`[moons] isr: invalid path to write: ${pathname}`);
566
566
  }
567
567
  mkdirSync(dirname(target), { recursive: true });
568
568
  const tmp = `${target}.tmp-${process.pid}`;
@@ -645,9 +645,9 @@ function installGracefulShutdown(server, options = {}) {
645
645
  return;
646
646
  }
647
647
  shuttingDown = true;
648
- log(`[moons] menerima ${signal} — berhenti menerima koneksi, drain...`);
648
+ log(`[moons] received ${signal} — no longer accepting connections, draining...`);
649
649
  const timer = setTimeout(() => {
650
- log(`[moons] drain melewati ${timeoutMs}ms — keluar paksa`);
650
+ log(`[moons] drain exceeded ${timeoutMs}ms — forcing exit`);
651
651
  const closeAll = server.closeAllConnections;
652
652
  try {
653
653
  closeAll?.call(server);
@@ -661,7 +661,7 @@ function installGracefulShutdown(server, options = {}) {
661
661
  server.close(async (error) => {
662
662
  if (error !== undefined) {
663
663
  clearTimeout(timer);
664
- log(`[moons] penutupan server gagal: ${error.message}`);
664
+ log(`[moons] server close failed: ${error.message}`);
665
665
  exit(1);
666
666
  return;
667
667
  }
@@ -670,11 +670,11 @@ function installGracefulShutdown(server, options = {}) {
670
670
  try {
671
671
  await options.onShutdown();
672
672
  } catch (hookError) {
673
- log(`[moons] onShutdown gagal: ${String(hookError)}`);
673
+ log(`[moons] onShutdown failed: ${String(hookError)}`);
674
674
  }
675
675
  }
676
676
  clearTimeout(timer);
677
- log("[moons] shutdown selesai (drain penuh)");
677
+ log("[moons] shutdown complete (full drain)");
678
678
  exit(0);
679
679
  });
680
680
  };
@@ -921,11 +921,11 @@ function rpcBodyTooLargeText(limit, size) {
921
921
  const megabytes = (bytes) => (bytes / 1e6).toFixed(1);
922
922
  return new MoonsError2({
923
923
  code: "E_RPC_BODY_TOO_LARGE",
924
- message: size === null ? `body melebihi limit ${megabytes(limit)} MB` : `body ${megabytes(size)} MB melebihi limit ${megabytes(limit)} MB`,
925
- details: "Body melebihi `security.bodyLimitBytes`; pembacaan dihentikan di transport sebelum penuh.",
924
+ message: size === null ? `body exceeds the ${megabytes(limit)} MB limit` : `body ${megabytes(size)} MB exceeds the ${megabytes(limit)} MB limit`,
925
+ details: "Body exceeds `security.bodyLimitBytes`; reading stops at the transport before the body is fully buffered.",
926
926
  suggestions: [
927
- "Kurangi ukuran payload, atau",
928
- "Naikkan security.bodyLimitBytes jika memang perlu"
927
+ "Reduce the payload size, or",
928
+ "Increase security.bodyLimitBytes if you really need to"
929
929
  ]
930
930
  }).format();
931
931
  }
@@ -1030,7 +1030,7 @@ function scheduleRevalidation(input) {
1030
1030
  if (logger !== null) {
1031
1031
  logger({ msg: "isr:revalidate-failed", level: "warn", path: normalized, error: message });
1032
1032
  } else {
1033
- console.error(`[moons] isr regenerasi gagal (${normalized}): ${message}`);
1033
+ console.error(`[moons] isr regeneration failed (${normalized}): ${message}`);
1034
1034
  }
1035
1035
  });
1036
1036
  }
@@ -1091,7 +1091,7 @@ function createPluginRuntime(options) {
1091
1091
  try {
1092
1092
  await plugin.onShutdown?.(app);
1093
1093
  } catch (error) {
1094
- log(`[moons] plugin \`${plugin.name}\` gagal saat onShutdown: ${String(error)}`);
1094
+ log(`[moons] plugin \`${plugin.name}\` failed during onShutdown: ${String(error)}`);
1095
1095
  }
1096
1096
  }
1097
1097
  },
@@ -1133,18 +1133,18 @@ async function runPrerender(options) {
1133
1133
  throw new MoonsError3({
1134
1134
  code: "E_ISR_INVALID",
1135
1135
  file: route.file,
1136
- message: "`revalidate` tidak valid atau dipakai tanpa `prerender = true`",
1137
- details: "ISR berbasis file: `revalidate` (detik, number >= 0) + `prerender`.",
1136
+ message: "`revalidate` is invalid or used without `prerender = true`",
1137
+ details: "File-based ISR: `revalidate` (seconds, number >= 0) + `prerender`.",
1138
1138
  suggestions: [
1139
- "Gunakan angka detik, mis. `export const revalidate = 60`",
1140
- "Tambahkan `export const prerender = true` pada page yang sama"
1139
+ "Use a number of seconds, e.g. `export const revalidate = 60`",
1140
+ "Add `export const prerender = true` to the same page"
1141
1141
  ]
1142
1142
  });
1143
1143
  }
1144
1144
  }
1145
1145
  if (prerender !== true) {
1146
1146
  if (prerender !== undefined && prerender !== false) {
1147
- throw prerenderError(route, "`prerender` harus boolean (`true`/`false`)");
1147
+ throw prerenderError(route, "`prerender` must be a boolean (`true`/`false`)");
1148
1148
  }
1149
1149
  continue;
1150
1150
  }
@@ -1155,15 +1155,15 @@ async function runPrerender(options) {
1155
1155
  headers: { "x-moons-prerender": "1" }
1156
1156
  }));
1157
1157
  if (response.status === 404) {
1158
- log(`[moons] prerender: lewati ${pathname} (notFound)`);
1158
+ log(`[moons] prerender: skipped ${pathname} (notFound)`);
1159
1159
  skipped += 1;
1160
1160
  continue;
1161
1161
  }
1162
1162
  if (response.status >= 300 && response.status < 400) {
1163
- throw prerenderError(route, `\`redirect()\` tidak didukung saat prerender (${pathname})`);
1163
+ throw prerenderError(route, `\`redirect()\` is not supported during prerender (${pathname})`);
1164
1164
  }
1165
1165
  if (response.status !== 200) {
1166
- throw prerenderError(route, `status ${response.status} saat merender ${pathname}`);
1166
+ throw prerenderError(route, `status ${response.status} while rendering ${pathname}`);
1167
1167
  }
1168
1168
  const html = await response.text();
1169
1169
  assertNoLeak(html, pathname, route.file, options, env);
@@ -1184,7 +1184,7 @@ async function runPrerender(options) {
1184
1184
  `);
1185
1185
  const emitted = emitStaticFiles(options.clientDir, options.staticConfig, entries);
1186
1186
  const extras = [...wrote404 ? [NOT_FOUND_FILE] : [], ...emitted];
1187
- log(`[moons] prerender selesai: ${written} file${extras.length > 0 ? ` + ${extras.join(" + ")}` : ""} (${skipped} dilewati)`);
1187
+ log(`[moons] prerender done: ${written} file${extras.length > 0 ? ` + ${extras.join(" + ")}` : ""} (${skipped} skipped)`);
1188
1188
  return { written, skipped };
1189
1189
  }
1190
1190
  function emitStaticFiles(clientDir, staticConfig, entries) {
@@ -1249,7 +1249,7 @@ async function renderStaticNotFound(options, env, log) {
1249
1249
  headers: { "x-moons-prerender": "1" }
1250
1250
  }));
1251
1251
  if (response.status !== 404) {
1252
- log(`[moons] prerender: ${NOT_FOUND_FILE} dilewati (sentinel \`${NOT_FOUND_SENTINEL}\` → ${response.status})`);
1252
+ log(`[moons] prerender: ${NOT_FOUND_FILE} skipped (sentinel \`${NOT_FOUND_SENTINEL}\` → ${response.status})`);
1253
1253
  return null;
1254
1254
  }
1255
1255
  const html = await response.text();
@@ -1268,11 +1268,11 @@ function assertNoLeak(html, pathname, file, options, env) {
1268
1268
  throw new MoonsError3({
1269
1269
  code: "E_PRERENDER_LEAK",
1270
1270
  file,
1271
- message: `hasil prerender \`${pathname}\` memuat ${labels}`,
1272
- details: "HTML statis permanen — rahasia yang ter-prerender tidak bisa ditarik kembali.",
1271
+ message: `prerender output \`${pathname}\` contains ${labels}`,
1272
+ details: "Static HTML is permanent — a prerendered secret cannot be retracted.",
1273
1273
  suggestions: [
1274
- "Jangan mengembalikan nilai env rahasia dari loader yang di-prerender",
1275
- "Matikan `prerender` untuk route ini atau pindahkan datanya ke serverFn request-time"
1274
+ "Do not return secret env values from a loader that runs at prerender time",
1275
+ "Turn off `prerender` for this route or move the data to a request-time serverFn"
1276
1276
  ]
1277
1277
  });
1278
1278
  }
@@ -1290,35 +1290,35 @@ async function resolvePathnames(route, module) {
1290
1290
  throw new MoonsError3({
1291
1291
  code: "E_PRERENDER_NO_PATHS",
1292
1292
  file: route.file,
1293
- message: "route dynamic ber-`prerender = true` tanpa `export const paths`",
1294
- details: "Prerender butuh daftar param untuk merender tiap path.",
1293
+ message: "dynamic route with `prerender = true` without `export const paths`",
1294
+ details: "Prerendering needs a param list to render each path.",
1295
1295
  suggestions: [
1296
- 'Tambahkan `export const paths = () => [{ id: "…" }]`',
1297
- "Atau hapus `prerender` agar dirender SSR saat request"
1296
+ 'Add `export const paths = () => [{ id: "…" }]`',
1297
+ "Or remove `prerender` so the route renders at request time (SSR)"
1298
1298
  ]
1299
1299
  });
1300
1300
  }
1301
1301
  const raw = await paths();
1302
1302
  if (!Array.isArray(raw)) {
1303
- throw prerenderError(route, "`paths()` harus mengembalikan array");
1303
+ throw prerenderError(route, "`paths()` must return an array");
1304
1304
  }
1305
1305
  const expected = new Set(route.params);
1306
1306
  const result = [];
1307
1307
  for (const item of raw) {
1308
1308
  if (item === null || typeof item !== "object" || Array.isArray(item)) {
1309
- throw prerenderError(route, "item `paths()` harus objek param string");
1309
+ throw prerenderError(route, "`paths()` items must be objects with string params");
1310
1310
  }
1311
1311
  const record = item;
1312
1312
  const keys = Object.keys(record);
1313
1313
  for (const name of expected) {
1314
1314
  const value = record[name];
1315
1315
  if (typeof value !== "string" || value.length === 0) {
1316
- throw prerenderError(route, `param \`${name}\` wajib string non-kosong`);
1316
+ throw prerenderError(route, `param \`${name}\` must be a non-empty string`);
1317
1317
  }
1318
1318
  }
1319
1319
  for (const key of keys) {
1320
1320
  if (!expected.has(key)) {
1321
- throw prerenderError(route, `param \`${key}\` tidak ada di pola route`);
1321
+ throw prerenderError(route, `param \`${key}\` is not in the route pattern`);
1322
1322
  }
1323
1323
  }
1324
1324
  result.push(buildPathname(route, record));
@@ -1351,7 +1351,7 @@ function buildPathname(route, params) {
1351
1351
  }
1352
1352
  function encodeSegment(route, value) {
1353
1353
  if (value.length === 0 || /^\.+$/.test(value)) {
1354
- throw prerenderError(route, `nilai param \`${value}\` tidak valid untuk path file`);
1354
+ throw prerenderError(route, `param value \`${value}\` is not valid for a file path`);
1355
1355
  }
1356
1356
  return encodeURIComponent(value);
1357
1357
  }
@@ -1362,9 +1362,9 @@ function outputFile(clientDir, pathname) {
1362
1362
  if (file !== base && !file.startsWith(base + sep2)) {
1363
1363
  throw new MoonsError3({
1364
1364
  code: "E_PRERENDER_INVALID",
1365
- message: `path prerender keluar dari direktori client (\`${pathname}\`)`,
1366
- details: "Nama file harus berada di dalam `dist/client`.",
1367
- suggestions: ["Periksa nilai param `paths` — jangan memakai `..`"]
1365
+ message: `prerender path escapes the client directory (\`${pathname}\`)`,
1366
+ details: "The file name must stay inside `dist/client`.",
1367
+ suggestions: ["Check the `paths` param values — do not use `..`"]
1368
1368
  });
1369
1369
  }
1370
1370
  return file;
@@ -1374,10 +1374,10 @@ function prerenderError(route, message) {
1374
1374
  code: "E_PRERENDER_INVALID",
1375
1375
  file: route.file,
1376
1376
  message,
1377
- details: "Kontrak prerender mengikuti.",
1377
+ details: "The prerender contract is enforced.",
1378
1378
  suggestions: [
1379
- "Perbaiki bentuk `paths`/param agar cocok dengan pola route",
1380
- "Jangan memakai `redirect()` pada route yang di-prerender"
1379
+ "Fix the `paths`/params shape so it matches the route pattern",
1380
+ "Do not use `redirect()` on a prerendered route"
1381
1381
  ]
1382
1382
  });
1383
1383
  }
@@ -1401,4 +1401,4 @@ export {
1401
1401
  toWebRequest2 as toWebRequest
1402
1402
  };
1403
1403
 
1404
- //# debugId=49CA3636C1DE25F564756E2164756E21
1404
+ //# debugId=01666BCB63B6268E64756E2164756E21