@lukoweb/apitogo 0.1.10 → 0.1.12

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/dist/cli/cli.js CHANGED
@@ -3529,10 +3529,12 @@ async function loadZudokuConfig(configEnv, rootDir) {
3529
3529
  try {
3530
3530
  const loadedConfig = await loadZudokuConfigWithMeta(rootDir);
3531
3531
  config = await runPluginTransformConfig(loadedConfig);
3532
- logger.info(
3533
- colors2.cyan(`loaded config file `) + colors2.dim(config.__meta.configPath),
3534
- { timestamp: true }
3535
- );
3532
+ if (!process.env.APITOGO_JSON_ONLY) {
3533
+ logger.info(
3534
+ colors2.cyan(`loaded config file `) + colors2.dim(config.__meta.configPath),
3535
+ { timestamp: true }
3536
+ );
3537
+ }
3536
3538
  return { config, envPrefix, publicEnv };
3537
3539
  } catch (error) {
3538
3540
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -3624,7 +3626,9 @@ async function generateLlmsTxtFiles({
3624
3626
  }
3625
3627
  const llmsTxt2 = llmsTxtParts.join("\n");
3626
3628
  await writeFile4(path20.join(baseOutputDir, "llms.txt"), llmsTxt2, "utf-8");
3627
- console.log(colors6.blue("\u2713 generated llms.txt"));
3629
+ if (process.env.APITOGO_JSON_ONLY !== "1") {
3630
+ console.log(colors6.blue("\u2713 generated llms.txt"));
3631
+ }
3628
3632
  }
3629
3633
  if (llmsTxtFull) {
3630
3634
  const llmsFullParts = [];
@@ -3653,7 +3657,9 @@ ${info.content}
3653
3657
  llmsFull,
3654
3658
  "utf-8"
3655
3659
  );
3656
- console.log(colors6.blue("\u2713 generated llms-full.txt"));
3660
+ if (process.env.APITOGO_JSON_ONLY !== "1") {
3661
+ console.log(colors6.blue("\u2713 generated llms-full.txt"));
3662
+ }
3657
3663
  }
3658
3664
  }
3659
3665
  var init_llms = __esm({
@@ -3674,7 +3680,7 @@ import path24 from "node:path";
3674
3680
  import { mkdir as mkdir5, readFile as readFile3, rename, rm as rm2, writeFile as writeFile5 } from "node:fs/promises";
3675
3681
  import path22 from "node:path";
3676
3682
  import { build as esbuild } from "esbuild";
3677
- import { build as viteBuild } from "vite";
3683
+ import { build as viteBuild, mergeConfig as mergeConfig3 } from "vite";
3678
3684
 
3679
3685
  // src/app/env.ts
3680
3686
  import { z as z2 } from "zod/mini";
@@ -3816,7 +3822,7 @@ import {
3816
3822
  // package.json
3817
3823
  var package_default = {
3818
3824
  name: "@lukoweb/apitogo",
3819
- version: "0.1.9",
3825
+ version: "0.1.11",
3820
3826
  type: "module",
3821
3827
  sideEffects: [
3822
3828
  "**/*.css",
@@ -7923,12 +7929,14 @@ var prerender = async ({
7923
7929
  const start = performance.now();
7924
7930
  const LOG_INTERVAL_MS = 3e4;
7925
7931
  let lastLogTime = start;
7932
+ const quietDeployJson = process.env.APITOGO_JSON_ONLY === "1";
7926
7933
  const writeProgress = throttle(
7927
7934
  (count, total, urlPath) => {
7935
+ if (quietDeployJson) return;
7928
7936
  writeLine(`prerendering (${count}/${total}) ${colors7.dim(urlPath)}`);
7929
7937
  }
7930
7938
  );
7931
- if (!isTTY()) {
7939
+ if (!isTTY() && !quietDeployJson) {
7932
7940
  logger.info(
7933
7941
  colors7.dim(
7934
7942
  `prerendering ${paths.length} routes using ${maxThreads} workers...`
@@ -7967,7 +7975,8 @@ var prerender = async ({
7967
7975
  });
7968
7976
  }
7969
7977
  completedCount++;
7970
- if (isTTY()) {
7978
+ if (quietDeployJson) {
7979
+ } else if (isTTY()) {
7971
7980
  writeProgress(completedCount, paths.length, urlPath);
7972
7981
  } else {
7973
7982
  const now = performance.now();
@@ -7988,16 +7997,18 @@ var prerender = async ({
7988
7997
  });
7989
7998
  const seconds = ((performance.now() - start) / 1e3).toFixed(1);
7990
7999
  const message = `\u2713 finished prerendering ${paths.length} routes in ${seconds} seconds using ${maxThreads} workers`;
7991
- if (isTTY()) {
7992
- writeLine(colors7.blue(`${message}
8000
+ if (!quietDeployJson) {
8001
+ if (isTTY()) {
8002
+ writeLine(colors7.blue(`${message}
7993
8003
  `));
7994
- } else {
7995
- logger.info(colors7.blue(message));
7996
- }
7997
- if (pagefindWriteResult?.outputPath) {
7998
- logger.info(
7999
- colors7.blue(`\u2713 pagefind index built: ${pagefindWriteResult.outputPath}`)
8000
- );
8004
+ } else {
8005
+ logger.info(colors7.blue(message));
8006
+ }
8007
+ if (pagefindWriteResult?.outputPath) {
8008
+ logger.info(
8009
+ colors7.blue(`\u2713 pagefind index built: ${pagefindWriteResult.outputPath}`)
8010
+ );
8011
+ }
8001
8012
  }
8002
8013
  const redirectUrls = getRedirectUrls(workerResults, config2.basePath);
8003
8014
  await generateSitemap({
@@ -8056,7 +8067,7 @@ var extractAssets = (result) => {
8056
8067
  return { jsEntry, cssEntries };
8057
8068
  };
8058
8069
  async function runBuild(options) {
8059
- const { dir, ssr, adapter = "node" } = options;
8070
+ const { dir, ssr, adapter = "node", jsonOnly = false } = options;
8060
8071
  const viteClientConfig = await getViteConfig(dir, {
8061
8072
  mode: "production",
8062
8073
  command: "build"
@@ -8066,7 +8077,9 @@ async function runBuild(options) {
8066
8077
  command: "build",
8067
8078
  isSsrBuild: true
8068
8079
  });
8069
- const clientResult = await viteBuild(viteClientConfig);
8080
+ const clientResult = await viteBuild(
8081
+ jsonOnly ? mergeConfig3(viteClientConfig, { logLevel: "silent" }) : viteClientConfig
8082
+ );
8070
8083
  const serverResult = await viteBuild({
8071
8084
  ...viteServerConfig,
8072
8085
  logLevel: "silent"
@@ -8220,6 +8233,10 @@ async function printCriticalFailureToConsoleAndExit(message) {
8220
8233
  process.exit(1);
8221
8234
  });
8222
8235
  }
8236
+ function printJsonOnlyErrorAndExit(message) {
8237
+ console.log(JSON.stringify({ error: message }));
8238
+ process.exit(1);
8239
+ }
8223
8240
  function printResultToConsole(message) {
8224
8241
  console.log(colors8.bold(colors8.green(message)));
8225
8242
  }
@@ -8274,19 +8291,27 @@ async function preview(argv) {
8274
8291
  // src/cli/build/handler.ts
8275
8292
  async function build(argv) {
8276
8293
  const packageJson2 = getZudokuPackageJson();
8277
- printDiagnosticsToConsole(`Starting APIToGo build v${packageJson2.version}`);
8278
- printDiagnosticsToConsole("");
8279
- printDiagnosticsToConsole("");
8294
+ const jsonOnly = argv.jsonOnly === true || process.env.APITOGO_JSON_ONLY === "1";
8295
+ if (!jsonOnly) {
8296
+ printDiagnosticsToConsole(`Starting APIToGo build v${packageJson2.version}`);
8297
+ printDiagnosticsToConsole("");
8298
+ printDiagnosticsToConsole("");
8299
+ }
8280
8300
  const dir = path24.resolve(process.cwd(), argv.dir);
8281
8301
  try {
8282
8302
  await runBuild({
8283
8303
  dir,
8284
8304
  ssr: argv.experimentalSsr,
8285
- adapter: argv.adapter
8305
+ adapter: argv.adapter,
8306
+ jsonOnly
8286
8307
  });
8287
8308
  } catch (error) {
8309
+ const message = error instanceof Error ? error.message : String(error);
8310
+ if (jsonOnly) {
8311
+ printJsonOnlyErrorAndExit(`Build failed: ${message}`);
8312
+ }
8288
8313
  logger.error("\u274C Build failed");
8289
- logger.error(error instanceof Error ? error.message : String(error));
8314
+ logger.error(message);
8290
8315
  process.exit(1);
8291
8316
  }
8292
8317
  if (argv.preview) {
@@ -8429,6 +8454,30 @@ var build_default = {
8429
8454
  }
8430
8455
  };
8431
8456
 
8457
+ // src/cli/common/json-only-deploy.ts
8458
+ init_logger();
8459
+ function isDeployJsonOnlyArgv() {
8460
+ const args = process.argv;
8461
+ const deployIdx = args.indexOf("deploy");
8462
+ if (deployIdx === -1) {
8463
+ return false;
8464
+ }
8465
+ return args.slice(deployIdx).some(
8466
+ (a) => a === "--json-only" || a.startsWith("--json-only=")
8467
+ );
8468
+ }
8469
+ function isJsonOnlyDeployEnv() {
8470
+ return process.env.APITOGO_JSON_ONLY === "1";
8471
+ }
8472
+ function applyJsonOnlyDeployQuietMode() {
8473
+ process.env.APITOGO_JSON_ONLY = "1";
8474
+ const noop = () => {
8475
+ };
8476
+ logger.info = noop;
8477
+ logger.warn = noop;
8478
+ logger.warnOnce = noop;
8479
+ }
8480
+
8432
8481
  // src/cli/deploy/handler.ts
8433
8482
  import { access, readFile as readFile4 } from "node:fs/promises";
8434
8483
  import path25 from "node:path";
@@ -8460,11 +8509,15 @@ async function deploy(argv) {
8460
8509
  if (!deploymentToken) {
8461
8510
  throw new Error("A deployment token is required.");
8462
8511
  }
8463
- printDiagnosticsToConsole("Creating deployment archive...");
8512
+ if (!isJsonOnlyDeployEnv()) {
8513
+ printDiagnosticsToConsole("Creating deployment archive...");
8514
+ }
8464
8515
  const archivePath = await createDeploymentArchive(dir);
8465
- printDiagnosticsToConsole(
8466
- `Uploading ${path25.basename(archivePath)} to ${env}...`
8467
- );
8516
+ if (!isJsonOnlyDeployEnv()) {
8517
+ printDiagnosticsToConsole(
8518
+ `Uploading ${path25.basename(archivePath)} to ${env}...`
8519
+ );
8520
+ }
8468
8521
  const archiveBuffer = await readFile4(archivePath);
8469
8522
  const formData = new FormData();
8470
8523
  formData.append(
@@ -8474,7 +8527,11 @@ async function deploy(argv) {
8474
8527
  );
8475
8528
  formData.append("deploymentToken", deploymentToken);
8476
8529
  formData.append("env", env);
8477
- const response = await fetch(DEPLOY_ENDPOINT, {
8530
+ const deployUrl = new URL(DEPLOY_ENDPOINT);
8531
+ if (argv.jsonOnly) {
8532
+ deployUrl.searchParams.set("jsonOnly", "true");
8533
+ }
8534
+ const response = await fetch(deployUrl, {
8478
8535
  method: "POST",
8479
8536
  headers: {
8480
8537
  "x-api-key": DEPLOY_API_KEY
@@ -8487,16 +8544,24 @@ async function deploy(argv) {
8487
8544
  `Deploy failed with ${response.status}: ${JSON.stringify(textOrJson(responseText))}`
8488
8545
  );
8489
8546
  }
8490
- printResultToConsole(`Deployment uploaded to ${DEPLOY_ENDPOINT}`);
8547
+ if (isJsonOnlyDeployEnv()) {
8548
+ const parsed = responseText.trim() ? textOrJson(responseText) : {};
8549
+ console.log(JSON.stringify(parsed));
8550
+ return;
8551
+ }
8552
+ printResultToConsole(`Deployment uploaded to ${deployUrl.href}`);
8491
8553
  if (responseText.trim()) {
8492
8554
  printDiagnosticsToConsole(
8493
8555
  JSON.stringify(textOrJson(responseText), null, 2)
8494
8556
  );
8495
8557
  }
8496
8558
  } catch (error) {
8497
- await printCriticalFailureToConsoleAndExit(
8498
- error instanceof Error ? error.message : String(error)
8499
- );
8559
+ const message = error instanceof Error ? error.message : String(error);
8560
+ if (isJsonOnlyDeployEnv()) {
8561
+ printJsonOnlyErrorAndExit(message);
8562
+ } else {
8563
+ await printCriticalFailureToConsoleAndExit(message);
8564
+ }
8500
8565
  }
8501
8566
  }
8502
8567
 
@@ -8526,9 +8591,16 @@ var deploy_default = {
8526
8591
  describe: "SSR adapter (node, cloudflare, vercel)",
8527
8592
  choices: ["node", "cloudflare", "vercel"],
8528
8593
  default: "node"
8594
+ }).option("json-only", {
8595
+ type: "boolean",
8596
+ describe: "JSON-only output on stdout; adds ?jsonOnly=true to the deploy request",
8597
+ default: false
8529
8598
  }),
8530
8599
  handler: async (argv) => {
8531
8600
  process.env.NODE_ENV = "production";
8601
+ if (argv.jsonOnly) {
8602
+ applyJsonOnlyDeployQuietMode();
8603
+ }
8532
8604
  await captureEvent({ argv, event: "apitogo deploy" });
8533
8605
  await deploy(argv);
8534
8606
  }
@@ -8548,7 +8620,7 @@ import { createHttpTerminator } from "http-terminator";
8548
8620
  import {
8549
8621
  createServer as createViteServer,
8550
8622
  isRunnableDevEnvironment as isRunnableDevEnvironment2,
8551
- mergeConfig as mergeConfig3
8623
+ mergeConfig as mergeConfig4
8552
8624
  } from "vite";
8553
8625
 
8554
8626
  // src/cli/common/utils/ports.ts
@@ -8666,7 +8738,7 @@ var DevServer = class {
8666
8738
  this.options.argPort ?? config2.port ?? DEFAULT_DEV_PORT
8667
8739
  );
8668
8740
  const server = await this.createNodeServer(config2);
8669
- const mergedViteConfig = mergeConfig3(viteConfig, {
8741
+ const mergedViteConfig = mergeConfig4(viteConfig, {
8670
8742
  server: {
8671
8743
  hmr: { server }
8672
8744
  },
@@ -9310,6 +9382,9 @@ var ZUDOKU_XDG_STATE_HOME = path30.join(
9310
9382
 
9311
9383
  // src/cli/common/outdated.ts
9312
9384
  async function warnIfOutdatedVersion(currentVersion) {
9385
+ if (isDeployJsonOnlyArgv()) {
9386
+ return false;
9387
+ }
9313
9388
  if (!process.env.ZUDOKU_OVERRIDE_CI_TO_TEST && (process.env.CI || process.env.ZUDOKU_DISABLE_UPDATE_CHECK)) {
9314
9389
  return false;
9315
9390
  }
@@ -9416,9 +9491,11 @@ var warnPackageVersionMismatch = () => {
9416
9491
  "react-dom": getPackageJson(reactDomPath).version
9417
9492
  };
9418
9493
  if (!installed.react || !installed["react-dom"] || !required?.react || !required?.["react-dom"]) {
9419
- printWarningToConsole(
9420
- "Could not verify React version. Ensure react and react-dom are installed."
9421
- );
9494
+ const msg = "Could not verify React version. Ensure react and react-dom are installed.";
9495
+ if (isDeployJsonOnlyArgv()) {
9496
+ printJsonOnlyErrorAndExit(msg);
9497
+ }
9498
+ printWarningToConsole(msg);
9422
9499
  return;
9423
9500
  }
9424
9501
  if (satisfies(installed.react, required.react) && satisfies(installed["react-dom"], required["react-dom"])) {
@@ -9435,6 +9512,11 @@ Required: ${colors11.green(`react@${required.react}, react-dom@${required["reac
9435
9512
 
9436
9513
  To fix, run:
9437
9514
  ${colors11.cyan(`${pkgManager} install react@${minVersion(required.react)} react-dom@${minVersion(required["react-dom"])}`)}`;
9515
+ if (isDeployJsonOnlyArgv()) {
9516
+ printJsonOnlyErrorAndExit(
9517
+ `React version mismatch. Installed react@${installed.react}, react-dom@${installed["react-dom"]}; required react@${required.react}, react-dom@${required["react-dom"]}. Run: ${pkgManager} install react@${minVersion(required.react)} react-dom@${minVersion(required["react-dom"])}`
9518
+ );
9519
+ }
9438
9520
  printWarningToConsole(box(message));
9439
9521
  process.exit(1);
9440
9522
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lukoweb/apitogo",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "type": "module",
5
5
  "sideEffects": [
6
6
  "**/*.css",
@@ -212,10 +212,13 @@ export async function loadZudokuConfig(
212
212
  const loadedConfig = await loadZudokuConfigWithMeta(rootDir);
213
213
  config = await runPluginTransformConfig(loadedConfig);
214
214
 
215
- logger.info(
216
- colors.cyan(`loaded config file `) + colors.dim(config.__meta.configPath),
217
- { timestamp: true },
218
- );
215
+ if (!process.env.APITOGO_JSON_ONLY) {
216
+ logger.info(
217
+ colors.cyan(`loaded config file `) +
218
+ colors.dim(config.__meta.configPath),
219
+ { timestamp: true },
220
+ );
221
+ }
219
222
 
220
223
  return { config, envPrefix, publicEnv };
221
224
  } catch (error) {
package/src/vite/build.ts CHANGED
@@ -2,7 +2,7 @@ import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { build as esbuild } from "esbuild";
4
4
  import type { Rollup } from "vite";
5
- import { build as viteBuild } from "vite";
5
+ import { build as viteBuild, mergeConfig } from "vite";
6
6
  import { ZuploEnv } from "../app/env.js";
7
7
  import { getZudokuRootDir } from "../cli/common/package-json.js";
8
8
  import {
@@ -38,10 +38,12 @@ export type BuildOptions = {
38
38
  dir: string;
39
39
  ssr?: boolean;
40
40
  adapter?: "node" | "cloudflare" | "vercel";
41
+ /** Suppress Vite build table and most build logs (used with `apitogo deploy --json-only`). */
42
+ jsonOnly?: boolean;
41
43
  };
42
44
 
43
45
  export async function runBuild(options: BuildOptions) {
44
- const { dir, ssr, adapter = "node" } = options;
46
+ const { dir, ssr, adapter = "node", jsonOnly = false } = options;
45
47
 
46
48
  // Build client and server bundles
47
49
  const viteClientConfig = await getViteConfig(dir, {
@@ -54,7 +56,11 @@ export async function runBuild(options: BuildOptions) {
54
56
  isSsrBuild: true,
55
57
  });
56
58
 
57
- const clientResult = await viteBuild(viteClientConfig);
59
+ const clientResult = await viteBuild(
60
+ jsonOnly
61
+ ? mergeConfig(viteClientConfig, { logLevel: "silent" as const })
62
+ : viteClientConfig,
63
+ );
58
64
  const serverResult = await viteBuild({
59
65
  ...viteServerConfig,
60
66
  logLevel: "silent",
package/src/vite/llms.ts CHANGED
@@ -60,8 +60,10 @@ export async function generateLlmsTxtFiles({
60
60
  const llmsTxt = llmsTxtParts.join("\n");
61
61
  await writeFile(path.join(baseOutputDir, "llms.txt"), llmsTxt, "utf-8");
62
62
 
63
- // biome-ignore lint/suspicious/noConsole: Logging allowed here
64
- console.log(colors.blue("✓ generated llms.txt"));
63
+ if (process.env.APITOGO_JSON_ONLY !== "1") {
64
+ // biome-ignore lint/suspicious/noConsole: Logging allowed here
65
+ console.log(colors.blue("✓ generated llms.txt"));
66
+ }
65
67
  }
66
68
 
67
69
  // Generate llms-full.txt (full content of all markdown documents)
@@ -89,7 +91,9 @@ export async function generateLlmsTxtFiles({
89
91
  "utf-8",
90
92
  );
91
93
 
92
- // biome-ignore lint/suspicious/noConsole: Allowed here
93
- console.log(colors.blue("✓ generated llms-full.txt"));
94
+ if (process.env.APITOGO_JSON_ONLY !== "1") {
95
+ // biome-ignore lint/suspicious/noConsole: Allowed here
96
+ console.log(colors.blue("✓ generated llms-full.txt"));
97
+ }
94
98
  }
95
99
  }
@@ -91,13 +91,16 @@ export const prerender = async ({
91
91
  const LOG_INTERVAL_MS = 30_000; // Log every 30 seconds
92
92
  let lastLogTime = start;
93
93
 
94
+ const quietDeployJson = process.env.APITOGO_JSON_ONLY === "1";
95
+
94
96
  const writeProgress = throttle(
95
97
  (count: number, total: number, urlPath: string) => {
98
+ if (quietDeployJson) return;
96
99
  writeLine(`prerendering (${count}/${total}) ${colors.dim(urlPath)}`);
97
100
  },
98
101
  );
99
102
 
100
- if (!isTTY()) {
103
+ if (!isTTY() && !quietDeployJson) {
101
104
  logger.info(
102
105
  colors.dim(
103
106
  `prerendering ${paths.length} routes using ${maxThreads} workers...`,
@@ -143,7 +146,9 @@ export const prerender = async ({
143
146
 
144
147
  completedCount++;
145
148
 
146
- if (isTTY()) {
149
+ if (quietDeployJson) {
150
+ // no progress output
151
+ } else if (isTTY()) {
147
152
  writeProgress(completedCount, paths.length, urlPath);
148
153
  } else {
149
154
  const now = performance.now();
@@ -168,15 +173,17 @@ export const prerender = async ({
168
173
 
169
174
  const message = `✓ finished prerendering ${paths.length} routes in ${seconds} seconds using ${maxThreads} workers`;
170
175
 
171
- if (isTTY()) {
172
- writeLine(colors.blue(`${message}\n`));
173
- } else {
174
- logger.info(colors.blue(message));
175
- }
176
- if (pagefindWriteResult?.outputPath) {
177
- logger.info(
178
- colors.blue(`✓ pagefind index built: ${pagefindWriteResult.outputPath}`),
179
- );
176
+ if (!quietDeployJson) {
177
+ if (isTTY()) {
178
+ writeLine(colors.blue(`${message}\n`));
179
+ } else {
180
+ logger.info(colors.blue(message));
181
+ }
182
+ if (pagefindWriteResult?.outputPath) {
183
+ logger.info(
184
+ colors.blue(`✓ pagefind index built: ${pagefindWriteResult.outputPath}`),
185
+ );
186
+ }
180
187
  }
181
188
 
182
189
  const redirectUrls = getRedirectUrls(workerResults, config.basePath);