@lukoweb/apitogo 0.1.4 → 0.1.6

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
@@ -131,7 +131,7 @@ import { stat } from "node:fs/promises";
131
131
  var fileExists;
132
132
  var init_file_exists = __esm({
133
133
  "src/config/file-exists.ts"() {
134
- fileExists = (path30) => stat(path30).then(() => true).catch(() => false);
134
+ fileExists = (path31) => stat(path31).then(() => true).catch(() => false);
135
135
  }
136
136
  });
137
137
 
@@ -3816,7 +3816,7 @@ import {
3816
3816
  // package.json
3817
3817
  var package_default = {
3818
3818
  name: "@lukoweb/apitogo",
3819
- version: "0.1.3",
3819
+ version: "0.1.5",
3820
3820
  type: "module",
3821
3821
  sideEffects: [
3822
3822
  "**/*.css",
@@ -4066,6 +4066,127 @@ var package_default = {
4066
4066
  mermaid: {
4067
4067
  optional: true
4068
4068
  }
4069
+ },
4070
+ publishConfig: {
4071
+ exports: {
4072
+ ".": {
4073
+ types: "./dist/declarations/index.d.ts",
4074
+ default: "./src/index.ts"
4075
+ },
4076
+ "./package.json": "./package.json",
4077
+ "./ui/*": {
4078
+ types: "./dist/declarations/lib/ui/*.d.ts",
4079
+ default: "./src/lib/ui/*.tsx"
4080
+ },
4081
+ "./ui/*.js": {
4082
+ types: "./dist/declarations/lib/ui/*.d.ts",
4083
+ default: "./src/lib/ui/*.tsx"
4084
+ },
4085
+ "./client": {
4086
+ types: "./client.d.ts"
4087
+ },
4088
+ "./auth/clerk": {
4089
+ types: "./dist/declarations/lib/authentication/providers/clerk.d.ts",
4090
+ default: "./src/lib/authentication/providers/clerk.tsx"
4091
+ },
4092
+ "./auth/auth0": {
4093
+ types: "./dist/declarations/lib/authentication/providers/auth0.d.ts",
4094
+ default: "./src/lib/authentication/providers/auth0.tsx"
4095
+ },
4096
+ "./auth/openid": {
4097
+ types: "./dist/declarations/lib/authentication/providers/openid.d.ts",
4098
+ default: "./src/lib/authentication/providers/openid.tsx"
4099
+ },
4100
+ "./auth/supabase": {
4101
+ types: "./dist/declarations/lib/authentication/providers/supabase.d.ts",
4102
+ default: "./src/lib/authentication/providers/supabase.tsx"
4103
+ },
4104
+ "./auth/azureb2c": {
4105
+ types: "./dist/declarations/lib/authentication/providers/azureb2c.d.ts",
4106
+ default: "./src/lib/authentication/providers/azureb2c.tsx"
4107
+ },
4108
+ "./auth/firebase": {
4109
+ types: "./dist/declarations/lib/authentication/providers/firebase.d.ts",
4110
+ default: "./src/lib/authentication/providers/firebase.tsx"
4111
+ },
4112
+ "./plugins": {
4113
+ types: "./dist/declarations/lib/core/plugins.d.ts",
4114
+ default: "./src/lib/core/plugins.ts"
4115
+ },
4116
+ "./plugins/api-keys": {
4117
+ types: "./dist/declarations/lib/plugins/api-keys/index.d.ts",
4118
+ default: "./src/lib/plugins/api-keys/index.tsx"
4119
+ },
4120
+ "./plugins/markdown": {
4121
+ types: "./dist/declarations/lib/plugins/markdown/index.d.ts",
4122
+ default: "./src/lib/plugins/markdown/index.tsx"
4123
+ },
4124
+ "./plugins/openapi": {
4125
+ types: "./dist/declarations/lib/plugins/openapi/index.d.ts",
4126
+ default: "./src/lib/plugins/openapi/index.tsx"
4127
+ },
4128
+ "./plugins/custom-pages": {
4129
+ types: "./dist/declarations/lib/plugins/custom-pages/index.d.ts",
4130
+ default: "./src/lib/plugins/custom-pages/index.tsx"
4131
+ },
4132
+ "./plugins/search-inkeep": {
4133
+ types: "./dist/declarations/lib/plugins/search-inkeep/index.d.ts",
4134
+ default: "./src/lib/plugins/search-inkeep/index.tsx"
4135
+ },
4136
+ "./plugins/search-pagefind": {
4137
+ types: "./dist/declarations/lib/plugins/search-pagefind/index.d.ts",
4138
+ default: "./src/lib/plugins/search-pagefind/index.tsx"
4139
+ },
4140
+ "./plugins/api-catalog": {
4141
+ types: "./dist/declarations/lib/plugins/api-catalog/index.d.ts",
4142
+ default: "./src/lib/plugins/api-catalog/index.tsx"
4143
+ },
4144
+ "./components": {
4145
+ types: "./dist/declarations/lib/components/index.d.ts",
4146
+ default: "./src/lib/components/index.ts"
4147
+ },
4148
+ "./mermaid": {
4149
+ types: "./dist/declarations/lib/components/Mermaid.d.ts",
4150
+ default: "./src/lib/components/Mermaid.tsx"
4151
+ },
4152
+ "./router": {
4153
+ types: "./dist/declarations/lib/core/router.d.ts",
4154
+ default: "./src/lib/core/router.ts"
4155
+ },
4156
+ "./react-query": {
4157
+ types: "./dist/declarations/lib/core/react-query.d.ts",
4158
+ default: "./src/lib/core/react-query.ts"
4159
+ },
4160
+ "./icons": {
4161
+ types: "./dist/declarations/lib/icons.d.ts",
4162
+ default: "./src/lib/icons.ts"
4163
+ },
4164
+ "./vite": {
4165
+ types: "./dist/declarations/vite/index.d.ts",
4166
+ default: "./src/vite/index.ts"
4167
+ },
4168
+ "./app/*": {
4169
+ types: "./dist/declarations/app/*.d.ts",
4170
+ default: "./src/app/*"
4171
+ },
4172
+ "./hooks": {
4173
+ types: "./dist/declarations/lib/hooks/index.d.ts",
4174
+ default: "./src/lib/hooks/index.ts"
4175
+ },
4176
+ "./main.css": "./src/app/main.css",
4177
+ "./processors/*": {
4178
+ types: "./dist/declarations/lib/plugins/openapi/processors/*.d.ts",
4179
+ default: "./src/lib/plugins/openapi/processors/*.ts"
4180
+ },
4181
+ "./with-zuplo": {
4182
+ types: "./dist/declarations/zuplo/with-zuplo.d.ts",
4183
+ default: "./src/zuplo/with-zuplo.ts"
4184
+ },
4185
+ "./testing": {
4186
+ types: "./dist/declarations/lib/testing/index.d.ts",
4187
+ default: "./src/lib/testing/index.tsx"
4188
+ }
4189
+ }
4069
4190
  }
4070
4191
  };
4071
4192
 
@@ -4406,14 +4527,14 @@ var flattenAllOf = (schema2) => {
4406
4527
  };
4407
4528
 
4408
4529
  // src/lib/util/traverse.ts
4409
- var traverse = (specification, transform, path30 = []) => {
4410
- const transformed = transform(specification, path30);
4530
+ var traverse = (specification, transform, path31 = []) => {
4531
+ const transformed = transform(specification, path31);
4411
4532
  if (typeof transformed !== "object" || transformed === null) {
4412
4533
  return transformed;
4413
4534
  }
4414
4535
  const result = Array.isArray(transformed) ? [] : {};
4415
4536
  for (const [key, value] of Object.entries(transformed)) {
4416
- const currentPath = [...path30, key];
4537
+ const currentPath = [...path31, key];
4417
4538
  if (Array.isArray(value)) {
4418
4539
  result[key] = value.map(
4419
4540
  (item, index) => typeof item === "object" && item != null ? traverse(item, transform, [...currentPath, index.toString()]) : item
@@ -4441,9 +4562,9 @@ var resolveLocalRef = (schema2, ref) => {
4441
4562
  if (schemaCache?.has(ref)) {
4442
4563
  return schemaCache.get(ref);
4443
4564
  }
4444
- const path30 = ref.split("/").slice(1);
4565
+ const path31 = ref.split("/").slice(1);
4445
4566
  let current = schema2;
4446
- for (const segment of path30) {
4567
+ for (const segment of path31) {
4447
4568
  if (!current || typeof current !== "object") {
4448
4569
  current = null;
4449
4570
  }
@@ -4462,7 +4583,7 @@ var dereference = async (schema2, resolvers = []) => {
4462
4583
  }
4463
4584
  const cloned = structuredClone(schema2);
4464
4585
  const visited = /* @__PURE__ */ new Set();
4465
- const resolve = async (current, path30) => {
4586
+ const resolve = async (current, path31) => {
4466
4587
  if (isIndexableObject(current)) {
4467
4588
  if (visited.has(current)) {
4468
4589
  return CIRCULAR_REF;
@@ -4470,7 +4591,7 @@ var dereference = async (schema2, resolvers = []) => {
4470
4591
  visited.add(current);
4471
4592
  if (Array.isArray(current)) {
4472
4593
  for (let index = 0; index < current.length; index++) {
4473
- current[index] = await resolve(current[index], `${path30}/${index}`);
4594
+ current[index] = await resolve(current[index], `${path31}/${index}`);
4474
4595
  }
4475
4596
  } else {
4476
4597
  if ("$ref" in current && typeof current.$ref === "string") {
@@ -4481,13 +4602,13 @@ var dereference = async (schema2, resolvers = []) => {
4481
4602
  for (const resolver of resolvers) {
4482
4603
  const resolved = await resolver($ref);
4483
4604
  if (resolved) {
4484
- result2 = await resolve(resolved, path30);
4605
+ result2 = await resolve(resolved, path31);
4485
4606
  break;
4486
4607
  }
4487
4608
  }
4488
4609
  if (result2 === void 0) {
4489
4610
  const resolved = await resolveLocalRef(cloned, $ref);
4490
- result2 = await resolve(resolved, path30);
4611
+ result2 = await resolve(resolved, path31);
4491
4612
  }
4492
4613
  if (hasSiblings) {
4493
4614
  if (result2 === CIRCULAR_REF) {
@@ -4500,7 +4621,7 @@ var dereference = async (schema2, resolvers = []) => {
4500
4621
  return result2;
4501
4622
  }
4502
4623
  for (const key in current) {
4503
- current[key] = await resolve(current[key], `${path30}/${key}`);
4624
+ current[key] = await resolve(current[key], `${path31}/${key}`);
4504
4625
  }
4505
4626
  }
4506
4627
  visited.delete(current);
@@ -4539,9 +4660,9 @@ var upgradeSchema = (schema2) => {
4539
4660
  }
4540
4661
  return sub;
4541
4662
  });
4542
- schema2 = traverse(schema2, (sub, path30) => {
4663
+ schema2 = traverse(schema2, (sub, path31) => {
4543
4664
  if (sub.example !== void 0) {
4544
- if (isSchemaPath(path30 ?? [])) {
4665
+ if (isSchemaPath(path31 ?? [])) {
4545
4666
  sub.examples = [sub.example];
4546
4667
  } else {
4547
4668
  sub.examples = {
@@ -4554,11 +4675,11 @@ var upgradeSchema = (schema2) => {
4554
4675
  }
4555
4676
  return sub;
4556
4677
  });
4557
- schema2 = traverse(schema2, (schema3, path30) => {
4678
+ schema2 = traverse(schema2, (schema3, path31) => {
4558
4679
  if (schema3.type === "object" && schema3.properties !== void 0) {
4559
- const parentPath = path30?.slice(0, -1);
4680
+ const parentPath = path31?.slice(0, -1);
4560
4681
  const isMultipart = parentPath?.some((segment, index) => {
4561
- return segment === "content" && path30?.[index + 1] === "multipart/form-data";
4682
+ return segment === "content" && path31?.[index + 1] === "multipart/form-data";
4562
4683
  });
4563
4684
  if (isMultipart) {
4564
4685
  const entries = Object.entries(schema3.properties);
@@ -4572,8 +4693,8 @@ var upgradeSchema = (schema2) => {
4572
4693
  }
4573
4694
  return schema3;
4574
4695
  });
4575
- schema2 = traverse(schema2, (schema3, path30) => {
4576
- if (path30?.includes("content") && path30.includes("application/octet-stream")) {
4696
+ schema2 = traverse(schema2, (schema3, path31) => {
4697
+ if (path31?.includes("content") && path31.includes("application/octet-stream")) {
4577
4698
  return {};
4578
4699
  }
4579
4700
  if (schema3.type === "string" && schema3.format === "binary") {
@@ -4599,11 +4720,11 @@ var upgradeSchema = (schema2) => {
4599
4720
  }
4600
4721
  return sub;
4601
4722
  });
4602
- schema2 = traverse(schema2, (schema3, path30) => {
4723
+ schema2 = traverse(schema2, (schema3, path31) => {
4603
4724
  if (schema3.type === "string" && schema3.format === "byte") {
4604
- const parentPath = path30?.slice(0, -1);
4725
+ const parentPath = path31?.slice(0, -1);
4605
4726
  const contentMediaType = parentPath?.find(
4606
- (_, index) => path30?.[index - 1] === "content"
4727
+ (_, index) => path31?.[index - 1] === "content"
4607
4728
  );
4608
4729
  return {
4609
4730
  type: "string",
@@ -4615,7 +4736,7 @@ var upgradeSchema = (schema2) => {
4615
4736
  });
4616
4737
  return schema2;
4617
4738
  };
4618
- function isSchemaPath(path30) {
4739
+ function isSchemaPath(path31) {
4619
4740
  const schemaLocations = [
4620
4741
  ["components", "schemas"],
4621
4742
  "properties",
@@ -4628,10 +4749,10 @@ function isSchemaPath(path30) {
4628
4749
  ];
4629
4750
  return schemaLocations.some((location) => {
4630
4751
  if (Array.isArray(location)) {
4631
- return location.every((segment, index) => path30[index] === segment);
4752
+ return location.every((segment, index) => path31[index] === segment);
4632
4753
  }
4633
- return path30.includes(location);
4634
- }) || path30.includes("schema") || path30.some((segment) => segment.endsWith("Schema"));
4754
+ return path31.includes(location);
4755
+ }) || path31.includes("schema") || path31.some((segment) => segment.endsWith("Schema"));
4635
4756
  }
4636
4757
 
4637
4758
  // src/lib/oas/parser/index.ts
@@ -4713,13 +4834,13 @@ var OPENAPI_PROPS = /* @__PURE__ */ new Set([
4713
4834
  "anyOf",
4714
4835
  "oneOf"
4715
4836
  ]);
4716
- var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path30 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
4837
+ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path31 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
4717
4838
  if (obj === null || typeof obj !== "object") return obj;
4718
4839
  const refPath = obj.__$ref;
4719
4840
  const isCircular = currentPath.has(obj) || typeof refPath === "string" && currentRefPaths.has(refPath);
4720
4841
  if (isCircular) {
4721
4842
  if (typeof refPath === "string") return SCHEMA_REF_PREFIX + refPath;
4722
- const circularProp = path30.find((p) => !OPENAPI_PROPS.has(p)) || path30[0];
4843
+ const circularProp = path31.find((p) => !OPENAPI_PROPS.has(p)) || path31[0];
4723
4844
  return [CIRCULAR_REF, circularProp].filter(Boolean).join(":");
4724
4845
  }
4725
4846
  if (refs.has(obj)) return refs.get(obj);
@@ -4729,7 +4850,7 @@ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs
4729
4850
  value,
4730
4851
  currentPath,
4731
4852
  refs,
4732
- [...path30, key],
4853
+ [...path31, key],
4733
4854
  currentRefPaths
4734
4855
  );
4735
4856
  const result = Array.isArray(obj) ? obj.map((item, i) => recurse(item, i.toString())) : Object.fromEntries(
@@ -4764,7 +4885,7 @@ var resolveExtensions = (obj) => Object.fromEntries(
4764
4885
  var getAllTags = (schema2) => {
4765
4886
  const rootTags = schema2.tags ?? [];
4766
4887
  const operations = Object.values(schema2.paths ?? {}).flatMap(
4767
- (path30) => HttpMethods.map((k) => path30?.[k]).filter((op) => op != null)
4888
+ (path31) => HttpMethods.map((k) => path31?.[k]).filter((op) => op != null)
4768
4889
  );
4769
4890
  const operationTags = new Set(operations.flatMap((op) => op.tags ?? []));
4770
4891
  const hasUntaggedOperations = operations.some(
@@ -4819,7 +4940,7 @@ var getAllSlugs = (ops, schemaTags = []) => {
4819
4940
  var getOperationSlugKey = (op) => [op.path, op.method, op.operationId, op.summary].filter(Boolean).join("-");
4820
4941
  var getAllOperations = (paths) => {
4821
4942
  const operations = Object.entries(paths ?? {}).flatMap(
4822
- ([path30, value]) => HttpMethods.flatMap((method) => {
4943
+ ([path31, value]) => HttpMethods.flatMap((method) => {
4823
4944
  if (!value?.[method]) return [];
4824
4945
  const operation = value[method];
4825
4946
  const pathParameters = value.parameters ?? [];
@@ -4839,7 +4960,7 @@ var getAllOperations = (paths) => {
4839
4960
  return {
4840
4961
  ...operation,
4841
4962
  method,
4842
- path: path30,
4963
+ path: path31,
4843
4964
  parameters,
4844
4965
  servers,
4845
4966
  tags: operation.tags ?? []
@@ -5197,8 +5318,8 @@ var Schema = builder.objectRef("Schema").implement({
5197
5318
  }),
5198
5319
  paths: t.field({
5199
5320
  type: [PathItem],
5200
- resolve: (root) => Object.entries(root.paths ?? {}).map(([path30, value]) => ({
5201
- path: path30,
5321
+ resolve: (root) => Object.entries(root.paths ?? {}).map(([path31, value]) => ({
5322
+ path: path31,
5202
5323
  // biome-ignore lint/style/noNonNullAssertion: value is guaranteed to be defined
5203
5324
  methods: Object.keys(value)
5204
5325
  }))
@@ -5345,7 +5466,7 @@ init_joinUrl();
5345
5466
 
5346
5467
  // src/vite/api/schema-codegen.ts
5347
5468
  var unescapeJsonPointer = (uri) => decodeURIComponent(uri.replace(/~1/g, "/").replace(/~0/g, "~"));
5348
- var getSegmentsFromPath = (path30) => path30.split("/").slice(1).map(unescapeJsonPointer);
5469
+ var getSegmentsFromPath = (path31) => path31.split("/").slice(1).map(unescapeJsonPointer);
5349
5470
  var createLocalRefMap = (obj) => {
5350
5471
  const refMap = /* @__PURE__ */ new Map();
5351
5472
  const siblingsMap = /* @__PURE__ */ new Map();
@@ -5376,16 +5497,16 @@ var replaceMarkers = (code, mergedRefs) => code.replace(/"__refMap:(.*?)"/g, '__
5376
5497
  /"__refMap\+Siblings:(.*?)"/g,
5377
5498
  (_, key) => mergedRefs.get(key) ?? `__refMap["${key}"]`
5378
5499
  );
5379
- var lookup = (schema2, path30, filePath) => {
5380
- const parts = getSegmentsFromPath(path30);
5500
+ var lookup = (schema2, path31, filePath) => {
5501
+ const parts = getSegmentsFromPath(path31);
5381
5502
  let val = schema2;
5382
5503
  for (const part of parts) {
5383
5504
  while (val.$ref?.startsWith("#/")) {
5384
- val = val.$ref === path30 ? val : lookup(schema2, val.$ref, filePath);
5505
+ val = val.$ref === path31 ? val : lookup(schema2, val.$ref, filePath);
5385
5506
  }
5386
5507
  if (val[part] === void 0) {
5387
5508
  throw new Error(
5388
- `Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path30}`
5509
+ `Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path31}`
5389
5510
  );
5390
5511
  }
5391
5512
  val = val[part];
@@ -5630,8 +5751,8 @@ var SchemaManager = class {
5630
5751
  }
5631
5752
  }
5632
5753
  };
5633
- getLatestSchema = (path30) => this.processedSchemas[path30]?.at(0);
5634
- getSchemasForPath = (path30) => this.processedSchemas[path30];
5754
+ getLatestSchema = (path31) => this.processedSchemas[path31]?.at(0);
5755
+ getSchemasForPath = (path31) => this.processedSchemas[path31];
5635
5756
  getSchemaImports = () => Object.values(this.processedSchemas).flat().filter((s) => s.importKey);
5636
5757
  getUrlToFilePathMap = () => {
5637
5758
  const map = /* @__PURE__ */ new Map();
@@ -7720,14 +7841,14 @@ async function generateSitemap({
7720
7841
 
7721
7842
  // src/vite/prerender/utils.ts
7722
7843
  init_joinUrl();
7723
- var resolveRoutePath = (path30) => {
7724
- const segments = path30.split("/");
7844
+ var resolveRoutePath = (path31) => {
7845
+ const segments = path31.split("/");
7725
7846
  if (segments.some((s) => s.startsWith(":") && !s.endsWith("?"))) {
7726
7847
  return void 0;
7727
7848
  }
7728
7849
  return segments.filter((s) => !s.startsWith(":")).join("/") || void 0;
7729
7850
  };
7730
- var isSkipped = (path30) => path30.includes("*") || /^\d+$/.test(path30);
7851
+ var isSkipped = (path31) => path31.includes("*") || /^\d+$/.test(path31);
7731
7852
  var resolveRoutes = (routes, parentPath = "") => routes.flatMap((route) => {
7732
7853
  if (route.path && isSkipped(route.path)) return [];
7733
7854
  const routePath = route.path ? resolveRoutePath(route.path) : void 0;
@@ -8308,16 +8429,109 @@ var build_default = {
8308
8429
  }
8309
8430
  };
8310
8431
 
8432
+ // src/cli/deploy/handler.ts
8433
+ import { access, readFile as readFile4 } from "node:fs/promises";
8434
+ import path25 from "node:path";
8435
+ import { create as createTar } from "tar";
8436
+ var DEPLOY_ENDPOINT = "http://localhost:3000/deploy";
8437
+ var ARCHIVE_NAME = "dist.tgz";
8438
+ var createDeploymentArchive = async (dir) => {
8439
+ const distDir = path25.join(dir, "dist");
8440
+ await access(distDir);
8441
+ const archivePath = path25.join(dir, ARCHIVE_NAME);
8442
+ await createTar(
8443
+ {
8444
+ cwd: dir,
8445
+ file: archivePath,
8446
+ gzip: true,
8447
+ portable: true
8448
+ },
8449
+ ["dist"]
8450
+ );
8451
+ return archivePath;
8452
+ };
8453
+ async function deploy(argv) {
8454
+ await build({ ...argv, preview: void 0 });
8455
+ const dir = path25.resolve(process.cwd(), argv.dir);
8456
+ const deploymentToken = argv.deploymentToken?.trim();
8457
+ try {
8458
+ if (!deploymentToken) {
8459
+ throw new Error("A deployment token is required.");
8460
+ }
8461
+ printDiagnosticsToConsole("Creating deployment archive...");
8462
+ const archivePath = await createDeploymentArchive(dir);
8463
+ printDiagnosticsToConsole(`Uploading ${path25.basename(archivePath)}...`);
8464
+ const archiveBuffer = await readFile4(archivePath);
8465
+ const formData = new FormData();
8466
+ formData.append(
8467
+ "file",
8468
+ new Blob([archiveBuffer], { type: "application/gzip" }),
8469
+ path25.basename(archivePath)
8470
+ );
8471
+ formData.append("deploymentToken", deploymentToken);
8472
+ const response = await fetch(DEPLOY_ENDPOINT, {
8473
+ method: "POST",
8474
+ body: formData
8475
+ });
8476
+ const responseText = await response.text();
8477
+ if (!response.ok) {
8478
+ throw new Error(
8479
+ `Deploy failed with ${response.status}: ${JSON.stringify(textOrJson(responseText))}`
8480
+ );
8481
+ }
8482
+ printResultToConsole(`Deployment uploaded to ${DEPLOY_ENDPOINT}`);
8483
+ if (responseText.trim()) {
8484
+ printDiagnosticsToConsole(
8485
+ JSON.stringify(textOrJson(responseText), null, 2)
8486
+ );
8487
+ }
8488
+ } catch (error) {
8489
+ await printCriticalFailureToConsoleAndExit(
8490
+ error instanceof Error ? error.message : String(error)
8491
+ );
8492
+ }
8493
+ }
8494
+
8495
+ // src/cli/cmds/deploy.ts
8496
+ var deploy_default = {
8497
+ desc: "Build, archive, and deploy",
8498
+ command: "deploy [deploymentToken]",
8499
+ builder: (yargs2) => yargs2.positional("deploymentToken", {
8500
+ type: "string",
8501
+ describe: "Deployment token sent to the deploy endpoint"
8502
+ }).option("dir", {
8503
+ type: "string",
8504
+ describe: "The directory containing your project",
8505
+ default: ".",
8506
+ normalize: true,
8507
+ hidden: true
8508
+ }).option("experimental-ssr", {
8509
+ type: "boolean",
8510
+ describe: "Build for server-side rendering (experimental)",
8511
+ default: false
8512
+ }).option("adapter", {
8513
+ type: "string",
8514
+ describe: "SSR adapter (node, cloudflare, vercel)",
8515
+ choices: ["node", "cloudflare", "vercel"],
8516
+ default: "node"
8517
+ }),
8518
+ handler: async (argv) => {
8519
+ process.env.NODE_ENV = "production";
8520
+ await captureEvent({ argv, event: "apitogo deploy" });
8521
+ await deploy(argv);
8522
+ }
8523
+ };
8524
+
8311
8525
  // src/cli/dev/handler.ts
8312
8526
  init_joinUrl();
8313
- import path27 from "node:path";
8527
+ import path28 from "node:path";
8314
8528
 
8315
8529
  // src/vite/dev-server.ts
8316
8530
  init_logger();
8317
8531
  import fs3 from "node:fs/promises";
8318
8532
  import http from "node:http";
8319
8533
  import https from "node:https";
8320
- import path26 from "node:path";
8534
+ import path27 from "node:path";
8321
8535
  import { createHttpTerminator } from "http-terminator";
8322
8536
  import {
8323
8537
  createServer as createViteServer,
@@ -8350,7 +8564,7 @@ init_loader();
8350
8564
  // src/vite/pagefind-dev-index.ts
8351
8565
  init_invariant();
8352
8566
  init_joinUrl();
8353
- import path25 from "node:path";
8567
+ import path26 from "node:path";
8354
8568
  import { createIndex as createIndex2 } from "pagefind";
8355
8569
  import { isRunnableDevEnvironment } from "vite";
8356
8570
  async function* buildPagefindDevIndex(vite, config2) {
@@ -8403,7 +8617,7 @@ async function* buildPagefindDevIndex(vite, config2) {
8403
8617
  path: urlPath
8404
8618
  };
8405
8619
  }
8406
- const outputPath = path25.join(vite.config.publicDir, "pagefind");
8620
+ const outputPath = path26.join(vite.config.publicDir, "pagefind");
8407
8621
  await pagefindIndex.writeFiles({ outputPath });
8408
8622
  yield { type: "complete", success: true, indexed };
8409
8623
  }
@@ -8422,9 +8636,9 @@ var DevServer = class {
8422
8636
  this.protocol = "https";
8423
8637
  const { dir } = this.options;
8424
8638
  const [key, cert, ca] = await Promise.all([
8425
- fs3.readFile(path26.resolve(dir, config2.https.key)),
8426
- fs3.readFile(path26.resolve(dir, config2.https.cert)),
8427
- config2.https.ca ? fs3.readFile(path26.resolve(dir, config2.https.ca)) : void 0
8639
+ fs3.readFile(path27.resolve(dir, config2.https.key)),
8640
+ fs3.readFile(path27.resolve(dir, config2.https.cert)),
8641
+ config2.https.ca ? fs3.readFile(path27.resolve(dir, config2.https.ca)) : void 0
8428
8642
  ]);
8429
8643
  return https.createServer({ key, cert, ca });
8430
8644
  }
@@ -8451,7 +8665,7 @@ var DevServer = class {
8451
8665
  // built-in transform middleware which would treat the path as a static asset.
8452
8666
  name: "apitogo:entry-client",
8453
8667
  configureServer(server2) {
8454
- const entryPath = path26.posix.join(
8668
+ const entryPath = path27.posix.join(
8455
8669
  server2.config.base,
8456
8670
  "/__z/entry.client.tsx"
8457
8671
  );
@@ -8524,13 +8738,13 @@ var DevServer = class {
8524
8738
  `Server-side rendering ${this.options.ssr ? "enabled" : "disabled"}`
8525
8739
  );
8526
8740
  if (config2.search?.type === "pagefind") {
8527
- const pagefindPath = path26.join(
8741
+ const pagefindPath = path27.join(
8528
8742
  vite.config.publicDir,
8529
8743
  "pagefind/pagefind.js"
8530
8744
  );
8531
8745
  const exists = await fs3.stat(pagefindPath).catch(() => false);
8532
8746
  if (!exists) {
8533
- await fs3.mkdir(path26.dirname(pagefindPath), { recursive: true });
8747
+ await fs3.mkdir(path27.dirname(pagefindPath), { recursive: true });
8534
8748
  await fs3.writeFile(pagefindPath, 'throw new Error("NOT_BUILT_YET");');
8535
8749
  }
8536
8750
  }
@@ -8624,7 +8838,7 @@ init_package_json();
8624
8838
  async function dev(argv) {
8625
8839
  const packageJson2 = getZudokuPackageJson();
8626
8840
  process.env.NODE_ENV = "development";
8627
- const dir = path27.resolve(process.cwd(), argv.dir);
8841
+ const dir = path28.resolve(process.cwd(), argv.dir);
8628
8842
  const server = new DevServer({
8629
8843
  dir,
8630
8844
  argPort: argv.port,
@@ -8706,60 +8920,261 @@ var dev_default = {
8706
8920
  }
8707
8921
  };
8708
8922
 
8709
- // src/cli/deploy/handler.ts
8710
- import { access, readFile as readFile4 } from "node:fs/promises";
8711
- import path28 from "node:path";
8712
- import { create as createTar } from "tar";
8713
- var DEPLOY_ENDPOINT = "http://localhost:3000/deploy";
8714
- var ARCHIVE_NAME = "dist.tgz";
8715
- var createDeploymentArchive = async (dir) => {
8716
- const distDir = path28.join(dir, "dist");
8717
- await access(distDir);
8718
- const archivePath = path28.join(dir, ARCHIVE_NAME);
8719
- await createTar(
8720
- {
8721
- cwd: dir,
8722
- file: archivePath,
8723
- gzip: true,
8724
- portable: true
8725
- },
8726
- ["dist"]
8923
+ // src/cli/cmds/preview.ts
8924
+ var previewCommand = {
8925
+ desc: "Preview production build",
8926
+ command: "preview",
8927
+ builder: (yargs2) => yargs2.option("dir", {
8928
+ type: "string",
8929
+ describe: "The directory containing your project",
8930
+ default: ".",
8931
+ normalize: true,
8932
+ hidden: true
8933
+ }).option("port", {
8934
+ type: "number",
8935
+ describe: "The port to run the local server on"
8936
+ }),
8937
+ handler: async (argv) => {
8938
+ process.env.NODE_ENV = "production";
8939
+ await captureEvent({ argv, event: "apitogo preview" });
8940
+ await preview(argv);
8941
+ }
8942
+ };
8943
+ var preview_default = previewCommand;
8944
+
8945
+ // src/cli/sync-config/handler.ts
8946
+ import { readFile as readFile5, writeFile as writeFile6 } from "node:fs/promises";
8947
+ import path29 from "node:path";
8948
+ import { glob as glob4 } from "glob";
8949
+ var CONFIG_FILENAMES = [
8950
+ "apitogo.config.tsx",
8951
+ "apitogo.config.ts",
8952
+ "apitogo.config.jsx",
8953
+ "apitogo.config.js",
8954
+ "apitogo.config.mjs",
8955
+ "zudoku.config.tsx",
8956
+ "zudoku.config.ts",
8957
+ "zudoku.config.jsx",
8958
+ "zudoku.config.js",
8959
+ "zudoku.config.mjs"
8960
+ ];
8961
+ var createTreeNode = () => ({ docs: [], children: /* @__PURE__ */ new Map() });
8962
+ var toPosixPath2 = (value) => value.split(path29.sep).join(path29.posix.sep);
8963
+ var toRoutePath = (relativeFile, pagesDir) => {
8964
+ const relativeNoExt = relativeFile.replace(/\.mdx?$/, "");
8965
+ const withoutPagesPrefix = relativeNoExt.replace(
8966
+ new RegExp(`^${pagesDir.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/?`),
8967
+ ""
8727
8968
  );
8728
- return archivePath;
8969
+ const normalized = withoutPagesPrefix.replace(/\/index$/, "");
8970
+ return `/${normalized || "index"}`;
8729
8971
  };
8730
- async function deploy(argv) {
8731
- await build({ ...argv, preview: void 0 });
8732
- const dir = path28.resolve(process.cwd(), argv.dir);
8733
- const deploymentToken = argv.deploymentToken?.trim();
8734
- try {
8735
- if (!deploymentToken) {
8736
- throw new Error("A deployment token is required.");
8972
+ var titleCase = (value) => value.split(/[-_\s]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
8973
+ var docSortRank = (docPath) => {
8974
+ const lastSegment = docPath.split("/").at(-1) ?? docPath;
8975
+ if (lastSegment === "introduction") return 0;
8976
+ if (lastSegment === "getting-started") return 1;
8977
+ if (lastSegment === "index") return 2;
8978
+ return 3;
8979
+ };
8980
+ var sortDocPaths = (docPaths) => [...docPaths].sort((a, b) => {
8981
+ const rankDiff = docSortRank(a) - docSortRank(b);
8982
+ if (rankDiff !== 0) return rankDiff;
8983
+ return a.localeCompare(b);
8984
+ });
8985
+ var sortDirectoryNames = (names) => [...names].sort((a, b) => a.localeCompare(b));
8986
+ var buildTree = (routePaths) => {
8987
+ const root = createTreeNode();
8988
+ for (const routePath of routePaths) {
8989
+ const segments = routePath.replace(/^\//, "").split("/").filter(Boolean);
8990
+ const directorySegments = segments.slice(0, -1);
8991
+ let current = root;
8992
+ for (const segment of directorySegments) {
8993
+ let child = current.children.get(segment);
8994
+ if (!child) {
8995
+ child = createTreeNode();
8996
+ current.children.set(segment, child);
8997
+ }
8998
+ current = child;
8737
8999
  }
8738
- printDiagnosticsToConsole("Creating deployment archive...");
8739
- const archivePath = await createDeploymentArchive(dir);
8740
- printDiagnosticsToConsole(`Uploading ${path28.basename(archivePath)}...`);
8741
- const archiveBuffer = await readFile4(archivePath);
8742
- const formData = new FormData();
8743
- formData.append(
8744
- "file",
8745
- new Blob([archiveBuffer], { type: "application/gzip" }),
8746
- path28.basename(archivePath)
8747
- );
8748
- formData.append("deploymentToken", deploymentToken);
8749
- const response = await fetch(DEPLOY_ENDPOINT, {
8750
- method: "POST",
8751
- body: formData
8752
- });
8753
- const responseText = await response.text();
8754
- if (!response.ok) {
8755
- throw new Error(
8756
- `Deploy failed with ${response.status}: ${JSON.stringify(textOrJson(responseText))}`
8757
- );
9000
+ current.docs.push(routePath);
9001
+ }
9002
+ return root;
9003
+ };
9004
+ var treeToNavigationItems = (node) => {
9005
+ const docs = sortDocPaths(node.docs);
9006
+ const categories = sortDirectoryNames([...node.children.keys()]).map((directoryName) => {
9007
+ const childNode = node.children.get(directoryName);
9008
+ if (!childNode) {
9009
+ throw new Error(`Missing child node for directory '${directoryName}'.`);
8758
9010
  }
8759
- printResultToConsole(`Deployment uploaded to ${DEPLOY_ENDPOINT}`);
8760
- if (responseText.trim()) {
8761
- printDiagnosticsToConsole(JSON.stringify(textOrJson(responseText), null, 2));
9011
+ return {
9012
+ type: "category",
9013
+ label: titleCase(directoryName),
9014
+ items: treeToNavigationItems(childNode)
9015
+ };
9016
+ });
9017
+ return [...docs, ...categories];
9018
+ };
9019
+ var formatNavigationItem = (item, indentLevel) => {
9020
+ const indent = " ".repeat(indentLevel);
9021
+ if (typeof item === "string") {
9022
+ return `${indent}"${item}"`;
9023
+ }
9024
+ const items = item.items.map((subItem) => formatNavigationItem(subItem, indentLevel + 2));
9025
+ return [
9026
+ `${indent}{`,
9027
+ `${indent} type: "category",`,
9028
+ `${indent} label: "${item.label}",`,
9029
+ `${indent} items: [`,
9030
+ items.join(",\n"),
9031
+ `${indent} ],`,
9032
+ `${indent}}`
9033
+ ].join("\n");
9034
+ };
9035
+ var buildNavigationCode = (items) => {
9036
+ const docsItems = items.map((item) => formatNavigationItem(item, 3));
9037
+ const documentationItems = [
9038
+ ...docsItems,
9039
+ [
9040
+ " {",
9041
+ ' type: "category",',
9042
+ ' label: "Useful Links",',
9043
+ " collapsible: false,",
9044
+ ' icon: "link",',
9045
+ " items: [",
9046
+ " {",
9047
+ ' type: "link",',
9048
+ ' icon: "book",',
9049
+ ' label: "APIToGo",',
9050
+ ' to: "https://apitogo.com",',
9051
+ " },",
9052
+ " ],",
9053
+ " },"
9054
+ ].join("\n")
9055
+ ];
9056
+ return [
9057
+ "[",
9058
+ " {",
9059
+ ' type: "category",',
9060
+ ' label: "Documentation",',
9061
+ " items: [",
9062
+ documentationItems.join(",\n"),
9063
+ " ],",
9064
+ " },",
9065
+ " {",
9066
+ ' type: "link",',
9067
+ ' to: "/api",',
9068
+ ' label: "API Reference",',
9069
+ " },",
9070
+ "]"
9071
+ ].join("\n");
9072
+ };
9073
+ var buildRedirectsCode = (firstDocPath) => `[{ from: "/", to: "${firstDocPath}" }]`;
9074
+ var findMatchingBracket = (source, startIndex) => {
9075
+ let depth = 0;
9076
+ let inSingleQuote = false;
9077
+ let inDoubleQuote = false;
9078
+ let inTemplate = false;
9079
+ let inLineComment = false;
9080
+ let inBlockComment = false;
9081
+ for (let index = startIndex; index < source.length; index++) {
9082
+ const char = source[index];
9083
+ const next = source[index + 1];
9084
+ const prev = source[index - 1];
9085
+ if (inLineComment) {
9086
+ if (char === "\n") inLineComment = false;
9087
+ continue;
9088
+ }
9089
+ if (inBlockComment) {
9090
+ if (prev === "*" && char === "/") inBlockComment = false;
9091
+ continue;
9092
+ }
9093
+ if (!inSingleQuote && !inDoubleQuote && !inTemplate) {
9094
+ if (char === "/" && next === "/") {
9095
+ inLineComment = true;
9096
+ index++;
9097
+ continue;
9098
+ }
9099
+ if (char === "/" && next === "*") {
9100
+ inBlockComment = true;
9101
+ index++;
9102
+ continue;
9103
+ }
9104
+ }
9105
+ if (!inDoubleQuote && !inTemplate && char === "'" && prev !== "\\") {
9106
+ inSingleQuote = !inSingleQuote;
9107
+ continue;
9108
+ }
9109
+ if (!inSingleQuote && !inTemplate && char === '"' && prev !== "\\") {
9110
+ inDoubleQuote = !inDoubleQuote;
9111
+ continue;
9112
+ }
9113
+ if (!inSingleQuote && !inDoubleQuote && char === "`" && prev !== "\\") {
9114
+ inTemplate = !inTemplate;
9115
+ continue;
9116
+ }
9117
+ if (inSingleQuote || inDoubleQuote || inTemplate) continue;
9118
+ if (char === "[") depth++;
9119
+ if (char === "]") depth--;
9120
+ if (depth === 0) return index;
9121
+ }
9122
+ throw new Error("Could not find matching closing bracket.");
9123
+ };
9124
+ var replaceArrayProperty = (source, propertyName, replacement) => {
9125
+ const propertyIndex = source.indexOf(`${propertyName}:`);
9126
+ if (propertyIndex === -1) {
9127
+ throw new Error(`Could not find '${propertyName}' in config file.`);
9128
+ }
9129
+ const arrayStart = source.indexOf("[", propertyIndex);
9130
+ if (arrayStart === -1) {
9131
+ throw new Error(`Could not find array start for '${propertyName}'.`);
9132
+ }
9133
+ const arrayEnd = findMatchingBracket(source, arrayStart);
9134
+ return `${source.slice(0, arrayStart)}${replacement}${source.slice(arrayEnd + 1)}`;
9135
+ };
9136
+ var findConfigPath = async (dir) => {
9137
+ for (const filename of CONFIG_FILENAMES) {
9138
+ const fullPath = path29.join(dir, filename);
9139
+ try {
9140
+ await readFile5(fullPath, "utf8");
9141
+ return fullPath;
9142
+ } catch {
9143
+ }
9144
+ }
9145
+ throw new Error("No APIToGo config file found in the project root.");
9146
+ };
9147
+ async function syncConfig(argv) {
9148
+ const dir = path29.resolve(process.cwd(), argv.dir);
9149
+ const pagesDir = toPosixPath2(argv.pagesDir.replace(/^[./]+/, "").replace(/\/+$/, ""));
9150
+ try {
9151
+ const configPath = await findConfigPath(dir);
9152
+ const pageFiles = await glob4(`${pagesDir}/**/*.{md,mdx}`, {
9153
+ cwd: dir,
9154
+ ignore: ["**/node_modules/**", "**/.git/**", "**/dist/**"],
9155
+ posix: true
9156
+ });
9157
+ const routePaths = sortDocPaths(
9158
+ pageFiles.map((file) => toRoutePath(file, pagesDir))
9159
+ );
9160
+ if (routePaths.length === 0) {
9161
+ throw new Error(`No .md or .mdx files found under '${pagesDir}'.`);
8762
9162
  }
9163
+ const tree = buildTree(routePaths);
9164
+ const navigationItems = treeToNavigationItems(tree);
9165
+ const originalConfig = await readFile5(configPath, "utf8");
9166
+ const withNavigation = replaceArrayProperty(
9167
+ originalConfig,
9168
+ "navigation",
9169
+ buildNavigationCode(navigationItems)
9170
+ );
9171
+ const withRedirects = replaceArrayProperty(
9172
+ withNavigation,
9173
+ "redirects",
9174
+ buildRedirectsCode(routePaths[0])
9175
+ );
9176
+ await writeFile6(configPath, withRedirects, "utf8");
9177
+ printResultToConsole(`Updated ${path29.basename(configPath)} from ${pagesDir}/`);
8763
9178
  } catch (error) {
8764
9179
  await printCriticalFailureToConsoleAndExit(
8765
9180
  error instanceof Error ? error.message : String(error)
@@ -8767,61 +9182,30 @@ async function deploy(argv) {
8767
9182
  }
8768
9183
  }
8769
9184
 
8770
- // src/cli/cmds/deploy.ts
8771
- var deploy_default = {
8772
- desc: "Build, archive, and deploy",
8773
- command: "deploy [deploymentToken]",
8774
- builder: (yargs2) => yargs2.positional("deploymentToken", {
8775
- type: "string",
8776
- describe: "Deployment token sent to the deploy endpoint"
8777
- }).option("dir", {
8778
- type: "string",
8779
- describe: "The directory containing your project",
8780
- default: ".",
8781
- normalize: true,
8782
- hidden: true
8783
- }).option("experimental-ssr", {
8784
- type: "boolean",
8785
- describe: "Build for server-side rendering (experimental)",
8786
- default: false
8787
- }).option("adapter", {
8788
- type: "string",
8789
- describe: "SSR adapter (node, cloudflare, vercel)",
8790
- choices: ["node", "cloudflare", "vercel"],
8791
- default: "node"
8792
- }),
8793
- handler: async (argv) => {
8794
- process.env.NODE_ENV = "production";
8795
- await captureEvent({ argv, event: "apitogo deploy" });
8796
- await deploy(argv);
8797
- }
8798
- };
8799
-
8800
- // src/cli/cmds/preview.ts
8801
- var previewCommand = {
8802
- desc: "Preview production build",
8803
- command: "preview",
9185
+ // src/cli/cmds/sync-config.ts
9186
+ var sync_config_default = {
9187
+ desc: "Regenerate navigation from the pages folder",
9188
+ command: "sync-config",
8804
9189
  builder: (yargs2) => yargs2.option("dir", {
8805
9190
  type: "string",
8806
9191
  describe: "The directory containing your project",
8807
9192
  default: ".",
8808
9193
  normalize: true,
8809
9194
  hidden: true
8810
- }).option("port", {
8811
- type: "number",
8812
- describe: "The port to run the local server on"
9195
+ }).option("pages-dir", {
9196
+ type: "string",
9197
+ describe: "Directory to scan for md/mdx pages",
9198
+ default: "pages"
8813
9199
  }),
8814
9200
  handler: async (argv) => {
8815
- process.env.NODE_ENV = "production";
8816
- await captureEvent({ argv, event: "apitogo preview" });
8817
- await preview(argv);
9201
+ await captureEvent({ argv, event: "apitogo sync-config" });
9202
+ await syncConfig(argv);
8818
9203
  }
8819
9204
  };
8820
- var preview_default = previewCommand;
8821
9205
 
8822
9206
  // src/cli/common/outdated.ts
8823
9207
  import { existsSync as existsSync2, mkdirSync } from "node:fs";
8824
- import { readFile as readFile5, writeFile as writeFile6 } from "node:fs/promises";
9208
+ import { readFile as readFile6, writeFile as writeFile7 } from "node:fs/promises";
8825
9209
  import { join } from "node:path";
8826
9210
  import colors10 from "picocolors";
8827
9211
  import { gt } from "semver";
@@ -8871,12 +9255,12 @@ function box(message, {
8871
9255
 
8872
9256
  // src/cli/common/xdg/lib.ts
8873
9257
  import { homedir } from "node:os";
8874
- import path29 from "node:path";
9258
+ import path30 from "node:path";
8875
9259
  function defineDirectoryWithFallback(xdgName, fallback) {
8876
9260
  if (process.env[xdgName]) {
8877
9261
  return process.env[xdgName];
8878
9262
  } else {
8879
- return path29.join(homedir(), fallback);
9263
+ return path30.join(homedir(), fallback);
8880
9264
  }
8881
9265
  }
8882
9266
  var XDG_CONFIG_HOME = defineDirectoryWithFallback(
@@ -8891,15 +9275,15 @@ var XDG_STATE_HOME = defineDirectoryWithFallback(
8891
9275
  "XDG_DATA_HOME",
8892
9276
  ".local/state"
8893
9277
  );
8894
- var ZUDOKU_XDG_CONFIG_HOME = path29.join(
9278
+ var ZUDOKU_XDG_CONFIG_HOME = path30.join(
8895
9279
  XDG_CONFIG_HOME,
8896
9280
  CLI_XDG_FOLDER_NAME
8897
9281
  );
8898
- var ZUDOKU_XDG_DATA_HOME = path29.join(
9282
+ var ZUDOKU_XDG_DATA_HOME = path30.join(
8899
9283
  XDG_DATA_HOME,
8900
9284
  CLI_XDG_FOLDER_NAME
8901
9285
  );
8902
- var ZUDOKU_XDG_STATE_HOME = path29.join(
9286
+ var ZUDOKU_XDG_STATE_HOME = path30.join(
8903
9287
  XDG_STATE_HOME,
8904
9288
  CLI_XDG_FOLDER_NAME
8905
9289
  );
@@ -8948,7 +9332,7 @@ async function getVersionCheckInfo() {
8948
9332
  let versionCheckInfo;
8949
9333
  if (existsSync2(versionCheckPath)) {
8950
9334
  try {
8951
- versionCheckInfo = await readFile5(versionCheckPath, "utf-8").then(
9335
+ versionCheckInfo = await readFile6(versionCheckPath, "utf-8").then(
8952
9336
  JSON.parse
8953
9337
  );
8954
9338
  } catch {
@@ -8973,7 +9357,7 @@ async function getVersionCheckInfo() {
8973
9357
  lastCheck: Date.now(),
8974
9358
  latestVersion
8975
9359
  };
8976
- await writeFile6(
9360
+ await writeFile7(
8977
9361
  versionCheckPath,
8978
9362
  JSON.stringify(versionCheckInfo),
8979
9363
  "utf-8"
@@ -9053,7 +9437,7 @@ var cli = yargs(hideBin(process.argv)).option("zuplo", {
9053
9437
  process.env.ZUPLO = "1";
9054
9438
  printDiagnosticsToConsole("Running in Zuplo mode");
9055
9439
  }
9056
- }).middleware(warnPackageVersionMismatch).command(build_default).command(dev_default).command(deploy_default).command(preview_default).demandCommand().strictCommands().version(packageJson?.version).fail(false).help();
9440
+ }).middleware(warnPackageVersionMismatch).command(build_default).command(dev_default).command(deploy_default).command(preview_default).command(sync_config_default).demandCommand().strictCommands().version(packageJson?.version).fail(false).help();
9057
9441
  try {
9058
9442
  void warnIfOutdatedVersion(packageJson?.version);
9059
9443
  await cli.argv;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lukoweb/apitogo",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "type": "module",
5
5
  "sideEffects": [
6
6
  "**/*.css",
package/src/app/main.tsx CHANGED
@@ -42,6 +42,9 @@ export const shikiReady: Promise<HighlighterCore> =
42
42
  export const convertZudokuConfigToOptions = (
43
43
  config: ZudokuConfig,
44
44
  ): ZudokuContextOptions => {
45
+ const siteTitle =
46
+ config.metadata?.applicationName ?? config.site?.title ?? "APIToGo";
47
+
45
48
  return {
46
49
  basePath: config.basePath,
47
50
  canonicalUrlOrigin: config.canonicalUrlOrigin,
@@ -57,7 +60,9 @@ export const convertZudokuConfigToOptions = (
57
60
  slots: config.slots,
58
61
  metadata: {
59
62
  favicon: "https://cdn.zudoku.dev/logos/favicon.svg",
60
- title: "%s - Zudoku",
63
+ applicationName: siteTitle,
64
+ defaultTitle: siteTitle,
65
+ title: `%s - ${siteTitle}`,
61
66
  ...config.metadata,
62
67
  },
63
68
  header: {