@lukoweb/apitogo 0.1.144 → 0.1.146

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
@@ -836,7 +836,7 @@ import { stat } from "node:fs/promises";
836
836
  var fileExists;
837
837
  var init_file_exists = __esm({
838
838
  "src/config/file-exists.ts"() {
839
- fileExists = (path73) => stat(path73).then(() => true).catch(() => false);
839
+ fileExists = (path74) => stat(path74).then(() => true).catch(() => false);
840
840
  }
841
841
  });
842
842
 
@@ -5845,7 +5845,7 @@ import {
5845
5845
  // package.json
5846
5846
  var package_default = {
5847
5847
  name: "@lukoweb/apitogo",
5848
- version: "0.1.144",
5848
+ version: "0.1.146",
5849
5849
  type: "module",
5850
5850
  sideEffects: [
5851
5851
  "**/*.css",
@@ -6624,14 +6624,14 @@ var flattenAllOf = (schema2) => {
6624
6624
  };
6625
6625
 
6626
6626
  // src/lib/util/traverse.ts
6627
- var traverse = (specification, transform, path73 = []) => {
6628
- const transformed = transform(specification, path73);
6627
+ var traverse = (specification, transform, path74 = []) => {
6628
+ const transformed = transform(specification, path74);
6629
6629
  if (typeof transformed !== "object" || transformed === null) {
6630
6630
  return transformed;
6631
6631
  }
6632
6632
  const result = Array.isArray(transformed) ? [] : {};
6633
6633
  for (const [key, value] of Object.entries(transformed)) {
6634
- const currentPath = [...path73, key];
6634
+ const currentPath = [...path74, key];
6635
6635
  if (Array.isArray(value)) {
6636
6636
  result[key] = value.map(
6637
6637
  (item, index) => typeof item === "object" && item != null ? traverse(item, transform, [...currentPath, index.toString()]) : item
@@ -6659,9 +6659,9 @@ var resolveLocalRef = (schema2, ref) => {
6659
6659
  if (schemaCache?.has(ref)) {
6660
6660
  return schemaCache.get(ref);
6661
6661
  }
6662
- const path73 = ref.split("/").slice(1);
6662
+ const path74 = ref.split("/").slice(1);
6663
6663
  let current = schema2;
6664
- for (const segment of path73) {
6664
+ for (const segment of path74) {
6665
6665
  if (!current || typeof current !== "object") {
6666
6666
  current = null;
6667
6667
  }
@@ -6680,7 +6680,7 @@ var dereference = async (schema2, resolvers = []) => {
6680
6680
  }
6681
6681
  const cloned = structuredClone(schema2);
6682
6682
  const visited = /* @__PURE__ */ new Set();
6683
- const resolve = async (current, path73) => {
6683
+ const resolve = async (current, path74) => {
6684
6684
  if (isIndexableObject(current)) {
6685
6685
  if (visited.has(current)) {
6686
6686
  return CIRCULAR_REF;
@@ -6688,7 +6688,7 @@ var dereference = async (schema2, resolvers = []) => {
6688
6688
  visited.add(current);
6689
6689
  if (Array.isArray(current)) {
6690
6690
  for (let index = 0; index < current.length; index++) {
6691
- current[index] = await resolve(current[index], `${path73}/${index}`);
6691
+ current[index] = await resolve(current[index], `${path74}/${index}`);
6692
6692
  }
6693
6693
  } else {
6694
6694
  if ("$ref" in current && typeof current.$ref === "string") {
@@ -6699,13 +6699,13 @@ var dereference = async (schema2, resolvers = []) => {
6699
6699
  for (const resolver of resolvers) {
6700
6700
  const resolved = await resolver($ref);
6701
6701
  if (resolved) {
6702
- result2 = await resolve(resolved, path73);
6702
+ result2 = await resolve(resolved, path74);
6703
6703
  break;
6704
6704
  }
6705
6705
  }
6706
6706
  if (result2 === void 0) {
6707
6707
  const resolved = await resolveLocalRef(cloned, $ref);
6708
- result2 = await resolve(resolved, path73);
6708
+ result2 = await resolve(resolved, path74);
6709
6709
  }
6710
6710
  if (hasSiblings) {
6711
6711
  if (result2 === CIRCULAR_REF) {
@@ -6718,7 +6718,7 @@ var dereference = async (schema2, resolvers = []) => {
6718
6718
  return result2;
6719
6719
  }
6720
6720
  for (const key in current) {
6721
- current[key] = await resolve(current[key], `${path73}/${key}`);
6721
+ current[key] = await resolve(current[key], `${path74}/${key}`);
6722
6722
  }
6723
6723
  }
6724
6724
  visited.delete(current);
@@ -6757,9 +6757,9 @@ var upgradeSchema = (schema2) => {
6757
6757
  }
6758
6758
  return sub;
6759
6759
  });
6760
- schema2 = traverse(schema2, (sub, path73) => {
6760
+ schema2 = traverse(schema2, (sub, path74) => {
6761
6761
  if (sub.example !== void 0) {
6762
- if (isSchemaPath(path73 ?? [])) {
6762
+ if (isSchemaPath(path74 ?? [])) {
6763
6763
  sub.examples = [sub.example];
6764
6764
  } else {
6765
6765
  sub.examples = {
@@ -6772,11 +6772,11 @@ var upgradeSchema = (schema2) => {
6772
6772
  }
6773
6773
  return sub;
6774
6774
  });
6775
- schema2 = traverse(schema2, (schema3, path73) => {
6775
+ schema2 = traverse(schema2, (schema3, path74) => {
6776
6776
  if (schema3.type === "object" && schema3.properties !== void 0) {
6777
- const parentPath = path73?.slice(0, -1);
6777
+ const parentPath = path74?.slice(0, -1);
6778
6778
  const isMultipart = parentPath?.some((segment, index) => {
6779
- return segment === "content" && path73?.[index + 1] === "multipart/form-data";
6779
+ return segment === "content" && path74?.[index + 1] === "multipart/form-data";
6780
6780
  });
6781
6781
  if (isMultipart) {
6782
6782
  const entries = Object.entries(schema3.properties);
@@ -6790,8 +6790,8 @@ var upgradeSchema = (schema2) => {
6790
6790
  }
6791
6791
  return schema3;
6792
6792
  });
6793
- schema2 = traverse(schema2, (schema3, path73) => {
6794
- if (path73?.includes("content") && path73.includes("application/octet-stream")) {
6793
+ schema2 = traverse(schema2, (schema3, path74) => {
6794
+ if (path74?.includes("content") && path74.includes("application/octet-stream")) {
6795
6795
  return {};
6796
6796
  }
6797
6797
  if (schema3.type === "string" && schema3.format === "binary") {
@@ -6817,11 +6817,11 @@ var upgradeSchema = (schema2) => {
6817
6817
  }
6818
6818
  return sub;
6819
6819
  });
6820
- schema2 = traverse(schema2, (schema3, path73) => {
6820
+ schema2 = traverse(schema2, (schema3, path74) => {
6821
6821
  if (schema3.type === "string" && schema3.format === "byte") {
6822
- const parentPath = path73?.slice(0, -1);
6822
+ const parentPath = path74?.slice(0, -1);
6823
6823
  const contentMediaType = parentPath?.find(
6824
- (_, index) => path73?.[index - 1] === "content"
6824
+ (_, index) => path74?.[index - 1] === "content"
6825
6825
  );
6826
6826
  return {
6827
6827
  type: "string",
@@ -6833,7 +6833,7 @@ var upgradeSchema = (schema2) => {
6833
6833
  });
6834
6834
  return schema2;
6835
6835
  };
6836
- function isSchemaPath(path73) {
6836
+ function isSchemaPath(path74) {
6837
6837
  const schemaLocations = [
6838
6838
  ["components", "schemas"],
6839
6839
  "properties",
@@ -6846,10 +6846,10 @@ function isSchemaPath(path73) {
6846
6846
  ];
6847
6847
  return schemaLocations.some((location) => {
6848
6848
  if (Array.isArray(location)) {
6849
- return location.every((segment, index) => path73[index] === segment);
6849
+ return location.every((segment, index) => path74[index] === segment);
6850
6850
  }
6851
- return path73.includes(location);
6852
- }) || path73.includes("schema") || path73.some((segment) => segment.endsWith("Schema"));
6851
+ return path74.includes(location);
6852
+ }) || path74.includes("schema") || path74.some((segment) => segment.endsWith("Schema"));
6853
6853
  }
6854
6854
 
6855
6855
  // src/lib/oas/parser/index.ts
@@ -6931,13 +6931,13 @@ var OPENAPI_PROPS = /* @__PURE__ */ new Set([
6931
6931
  "anyOf",
6932
6932
  "oneOf"
6933
6933
  ]);
6934
- var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path73 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
6934
+ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path74 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
6935
6935
  if (obj === null || typeof obj !== "object") return obj;
6936
6936
  const refPath = obj.__$ref;
6937
6937
  const isCircular = currentPath.has(obj) || typeof refPath === "string" && currentRefPaths.has(refPath);
6938
6938
  if (isCircular) {
6939
6939
  if (typeof refPath === "string") return SCHEMA_REF_PREFIX + refPath;
6940
- const circularProp = path73.find((p) => !OPENAPI_PROPS.has(p)) || path73[0];
6940
+ const circularProp = path74.find((p) => !OPENAPI_PROPS.has(p)) || path74[0];
6941
6941
  return [CIRCULAR_REF, circularProp].filter(Boolean).join(":");
6942
6942
  }
6943
6943
  if (refs.has(obj)) return refs.get(obj);
@@ -6947,7 +6947,7 @@ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs
6947
6947
  value,
6948
6948
  currentPath,
6949
6949
  refs,
6950
- [...path73, key],
6950
+ [...path74, key],
6951
6951
  currentRefPaths
6952
6952
  );
6953
6953
  const result = Array.isArray(obj) ? obj.map((item, i) => recurse(item, i.toString())) : Object.fromEntries(
@@ -6982,7 +6982,7 @@ var resolveExtensions = (obj) => Object.fromEntries(
6982
6982
  var getAllTags = (schema2) => {
6983
6983
  const rootTags = schema2.tags ?? [];
6984
6984
  const operations = Object.values(schema2.paths ?? {}).flatMap(
6985
- (path73) => HttpMethods.map((k) => path73?.[k]).filter((op) => op != null)
6985
+ (path74) => HttpMethods.map((k) => path74?.[k]).filter((op) => op != null)
6986
6986
  );
6987
6987
  const operationTags = new Set(operations.flatMap((op) => op.tags ?? []));
6988
6988
  const hasUntaggedOperations = operations.some(
@@ -7037,7 +7037,7 @@ var getAllSlugs = (ops, schemaTags = []) => {
7037
7037
  var getOperationSlugKey = (op) => [op.path, op.method, op.operationId, op.summary].filter(Boolean).join("-");
7038
7038
  var getAllOperations = (paths) => {
7039
7039
  const operations = Object.entries(paths ?? {}).flatMap(
7040
- ([path73, value]) => HttpMethods.flatMap((method) => {
7040
+ ([path74, value]) => HttpMethods.flatMap((method) => {
7041
7041
  if (!value?.[method]) return [];
7042
7042
  const operation = value[method];
7043
7043
  const pathParameters = value.parameters ?? [];
@@ -7057,7 +7057,7 @@ var getAllOperations = (paths) => {
7057
7057
  return {
7058
7058
  ...operation,
7059
7059
  method,
7060
- path: path73,
7060
+ path: path74,
7061
7061
  parameters,
7062
7062
  servers,
7063
7063
  tags: operation.tags ?? []
@@ -7415,8 +7415,8 @@ var Schema = builder.objectRef("Schema").implement({
7415
7415
  }),
7416
7416
  paths: t.field({
7417
7417
  type: [PathItem],
7418
- resolve: (root) => Object.entries(root.paths ?? {}).map(([path73, value]) => ({
7419
- path: path73,
7418
+ resolve: (root) => Object.entries(root.paths ?? {}).map(([path74, value]) => ({
7419
+ path: path74,
7420
7420
  // biome-ignore lint/style/noNonNullAssertion: value is guaranteed to be defined
7421
7421
  methods: Object.keys(value)
7422
7422
  }))
@@ -7581,7 +7581,7 @@ init_joinUrl();
7581
7581
 
7582
7582
  // src/vite/api/schema-codegen.ts
7583
7583
  var unescapeJsonPointer = (uri) => decodeURIComponent(uri.replace(/~1/g, "/").replace(/~0/g, "~"));
7584
- var getSegmentsFromPath = (path73) => path73.split("/").slice(1).map(unescapeJsonPointer);
7584
+ var getSegmentsFromPath = (path74) => path74.split("/").slice(1).map(unescapeJsonPointer);
7585
7585
  var createLocalRefMap = (obj) => {
7586
7586
  const refMap = /* @__PURE__ */ new Map();
7587
7587
  const siblingsMap = /* @__PURE__ */ new Map();
@@ -7612,16 +7612,16 @@ var replaceMarkers = (code, mergedRefs) => code.replace(/"__refMap:(.*?)"/g, '__
7612
7612
  /"__refMap\+Siblings:(.*?)"/g,
7613
7613
  (_, key) => mergedRefs.get(key) ?? `__refMap["${key}"]`
7614
7614
  );
7615
- var lookup = (schema2, path73, filePath) => {
7616
- const parts = getSegmentsFromPath(path73);
7615
+ var lookup = (schema2, path74, filePath) => {
7616
+ const parts = getSegmentsFromPath(path74);
7617
7617
  let val = schema2;
7618
7618
  for (const part of parts) {
7619
7619
  while (val.$ref?.startsWith("#/")) {
7620
- val = val.$ref === path73 ? val : lookup(schema2, val.$ref, filePath);
7620
+ val = val.$ref === path74 ? val : lookup(schema2, val.$ref, filePath);
7621
7621
  }
7622
7622
  if (val[part] === void 0) {
7623
7623
  throw new Error(
7624
- `Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path73}`
7624
+ `Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path74}`
7625
7625
  );
7626
7626
  }
7627
7627
  val = val[part];
@@ -7866,8 +7866,8 @@ var SchemaManager = class {
7866
7866
  }
7867
7867
  }
7868
7868
  };
7869
- getLatestSchema = (path73) => this.processedSchemas[path73]?.at(0);
7870
- getSchemasForPath = (path73) => this.processedSchemas[path73];
7869
+ getLatestSchema = (path74) => this.processedSchemas[path74]?.at(0);
7870
+ getSchemasForPath = (path74) => this.processedSchemas[path74];
7871
7871
  getSchemaImports = () => Object.values(this.processedSchemas).flat().filter((s) => s.importKey);
7872
7872
  getUrlToFilePathMap = () => {
7873
7873
  const map = /* @__PURE__ */ new Map();
@@ -10305,14 +10305,14 @@ async function generateSitemap({
10305
10305
 
10306
10306
  // src/vite/prerender/utils.ts
10307
10307
  init_joinUrl();
10308
- var resolveRoutePath = (path73) => {
10309
- const segments = path73.split("/");
10308
+ var resolveRoutePath = (path74) => {
10309
+ const segments = path74.split("/");
10310
10310
  if (segments.some((s) => s.startsWith(":") && !s.endsWith("?"))) {
10311
10311
  return void 0;
10312
10312
  }
10313
10313
  return segments.filter((s) => !s.startsWith(":")).join("/") || void 0;
10314
10314
  };
10315
- var isSkipped = (path73) => path73.includes("*") || /^\d+$/.test(path73);
10315
+ var isSkipped = (path74) => path74.includes("*") || /^\d+$/.test(path74);
10316
10316
  var resolveRoutes = (routes, parentPath = "") => routes.flatMap((route) => {
10317
10317
  if (route.path && isSkipped(route.path)) return [];
10318
10318
  const routePath = route.path ? resolveRoutePath(route.path) : void 0;
@@ -10944,8 +10944,8 @@ var PlatformApiClient = class {
10944
10944
  constructor(config2) {
10945
10945
  this.config = config2;
10946
10946
  }
10947
- url(path73) {
10948
- return `${this.config.apiUrl}${path73.startsWith("/") ? path73 : `/${path73}`}`;
10947
+ url(path74) {
10948
+ return `${this.config.apiUrl}${path74.startsWith("/") ? path74 : `/${path74}`}`;
10949
10949
  }
10950
10950
  headers(extra) {
10951
10951
  return {
@@ -10955,9 +10955,9 @@ var PlatformApiClient = class {
10955
10955
  ...extra
10956
10956
  };
10957
10957
  }
10958
- async request(method, path73, init4) {
10958
+ async request(method, path74, init4) {
10959
10959
  const response = await fetchWithRetry(
10960
- this.url(path73),
10960
+ this.url(path74),
10961
10961
  {
10962
10962
  method,
10963
10963
  ...init4,
@@ -11169,15 +11169,15 @@ var PlatformApiClient = class {
11169
11169
  }
11170
11170
  );
11171
11171
  }
11172
- deleteDevPortalPage(projectId, path73) {
11173
- const query = new URLSearchParams({ path: path73 });
11172
+ deleteDevPortalPage(projectId, path74) {
11173
+ const query = new URLSearchParams({ path: path74 });
11174
11174
  return this.request(
11175
11175
  "DELETE",
11176
11176
  `/api/v1/projects/${projectId}/dev-portal/pages/files?${query.toString()}`
11177
11177
  );
11178
11178
  }
11179
- renameDevPortalPage(projectId, path73, newName) {
11180
- const query = new URLSearchParams({ path: path73 });
11179
+ renameDevPortalPage(projectId, path74, newName) {
11180
+ const query = new URLSearchParams({ path: path74 });
11181
11181
  return this.request(
11182
11182
  "POST",
11183
11183
  `/api/v1/projects/${projectId}/dev-portal/pages/files/rename?${query.toString()}`,
@@ -11293,8 +11293,8 @@ var PlatformApiClient = class {
11293
11293
  * the project-less endpoint is used; `planTier` overrides the tier used for paid-plan checks.
11294
11294
  */
11295
11295
  validateGatewayPlans(plans, options = {}) {
11296
- const path73 = options.projectId ? `/api/v1/projects/${options.projectId}/gateway/plans/validate` : "/api/v1/gateway/plans/validate";
11297
- return this.request("POST", path73, {
11296
+ const path74 = options.projectId ? `/api/v1/projects/${options.projectId}/gateway/plans/validate` : "/api/v1/gateway/plans/validate";
11297
+ return this.request("POST", path74, {
11298
11298
  headers: { "Content-Type": "application/json" },
11299
11299
  body: JSON.stringify({ plans, planTier: options.planTier })
11300
11300
  });
@@ -11395,8 +11395,8 @@ var PlatformApiClient = class {
11395
11395
  }
11396
11396
  };
11397
11397
  async function readFileBytes(filePath) {
11398
- const { readFile: readFile20 } = await import("node:fs/promises");
11399
- const buffer = await readFile20(filePath);
11398
+ const { readFile: readFile21 } = await import("node:fs/promises");
11399
+ const buffer = await readFile21(filePath);
11400
11400
  const arrayBuffer = new ArrayBuffer(buffer.byteLength);
11401
11401
  new Uint8Array(arrayBuffer).set(buffer);
11402
11402
  return arrayBuffer;
@@ -12818,6 +12818,13 @@ function mergePlansBySku2(existing, patch) {
12818
12818
  }
12819
12819
  return Array.from(bySku.values());
12820
12820
  }
12821
+ function resolveBackendSourceDirectory(siteDirectory, sourceDirectory) {
12822
+ const trimmed = sourceDirectory?.trim();
12823
+ if (!trimmed) {
12824
+ return void 0;
12825
+ }
12826
+ return path37.resolve(siteDirectory, trimmed);
12827
+ }
12821
12828
  function resolveBackendOpenApiPath(openApiPath, options) {
12822
12829
  const trimmed = openApiPath?.trim();
12823
12830
  if (!trimmed) {
@@ -15370,8 +15377,8 @@ async function pathExists3(filePath) {
15370
15377
  }
15371
15378
  async function directoryHasEntries(dir) {
15372
15379
  try {
15373
- const { readdir: readdir4 } = await import("node:fs/promises");
15374
- const entries = await readdir4(dir);
15380
+ const { readdir: readdir5 } = await import("node:fs/promises");
15381
+ const entries = await readdir5(dir);
15375
15382
  return entries.length > 0;
15376
15383
  } catch {
15377
15384
  return false;
@@ -17356,8 +17363,8 @@ function normalizeActionKey(actionKey) {
17356
17363
  const trimmed = actionKey.trim();
17357
17364
  if (trimmed.includes(":")) {
17358
17365
  const [method2, ...pathParts] = trimmed.split(":");
17359
- const path74 = pathParts.join(":").trim();
17360
- return `${method2?.toLowerCase()}:${path74.startsWith("/") ? path74 : `/${path74}`}`;
17366
+ const path75 = pathParts.join(":").trim();
17367
+ return `${method2?.toLowerCase()}:${path75.startsWith("/") ? path75 : `/${path75}`}`;
17361
17368
  }
17362
17369
  const spaceIndex = trimmed.indexOf(" ");
17363
17370
  if (spaceIndex <= 0) {
@@ -17366,8 +17373,8 @@ function normalizeActionKey(actionKey) {
17366
17373
  );
17367
17374
  }
17368
17375
  const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
17369
- const path73 = trimmed.slice(spaceIndex + 1).trim();
17370
- return `${method}:${path73.startsWith("/") ? path73 : `/${path73}`}`;
17376
+ const path74 = trimmed.slice(spaceIndex + 1).trim();
17377
+ return `${method}:${path74.startsWith("/") ? path74 : `/${path74}`}`;
17371
17378
  }
17372
17379
  async function applyGatewayPublicRoutes(client, projectId, routes, options) {
17373
17380
  const applied = [];
@@ -17950,7 +17957,10 @@ async function prepareOpenApiServersForGatewayBuild(options) {
17950
17957
  options.manifest?.backend?.openApiPath,
17951
17958
  {
17952
17959
  siteDirectory,
17953
- backendSourceDirectory: options.manifest?.backend?.sourceDirectory
17960
+ backendSourceDirectory: resolveBackendSourceDirectory(
17961
+ siteDirectory,
17962
+ options.manifest?.backend?.sourceDirectory
17963
+ )
17954
17964
  }
17955
17965
  );
17956
17966
  if (!openApiPath) {
@@ -17985,8 +17995,8 @@ function normalizeActionKeyFormat(actionKey) {
17985
17995
  const trimmed = actionKey.trim();
17986
17996
  if (trimmed.includes(":")) {
17987
17997
  const [method2, ...pathParts] = trimmed.split(":");
17988
- const path74 = pathParts.join(":").trim();
17989
- return `${method2.toLowerCase()}:${path74.startsWith("/") ? path74 : `/${path74}`}`;
17998
+ const path75 = pathParts.join(":").trim();
17999
+ return `${method2.toLowerCase()}:${path75.startsWith("/") ? path75 : `/${path75}`}`;
17990
18000
  }
17991
18001
  const spaceIndex = trimmed.indexOf(" ");
17992
18002
  if (spaceIndex <= 0) {
@@ -17995,8 +18005,8 @@ function normalizeActionKeyFormat(actionKey) {
17995
18005
  );
17996
18006
  }
17997
18007
  const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
17998
- const path73 = trimmed.slice(spaceIndex + 1).trim();
17999
- return `${method}:${path73.startsWith("/") ? path73 : `/${path73}`}`;
18008
+ const path74 = trimmed.slice(spaceIndex + 1).trim();
18009
+ return `${method}:${path74.startsWith("/") ? path74 : `/${path74}`}`;
18000
18010
  }
18001
18011
  function normalizePublicRoute(route) {
18002
18012
  const trimmed = route.trim();
@@ -21448,7 +21458,10 @@ async function runApplyFromSiteDirectory(client, config2, args, progress) {
21448
21458
  );
21449
21459
  const skipBackend = skipBackendDecision.skip;
21450
21460
  const backendConfig = manifest.backend;
21451
- const backendSourceDirectory = backendConfig?.sourceDirectory?.trim();
21461
+ const backendSourceDirectory = resolveBackendSourceDirectory(
21462
+ args.sourceDirectory,
21463
+ backendConfig?.sourceDirectory
21464
+ );
21452
21465
  const hasBackendSource = Boolean(backendSourceDirectory);
21453
21466
  let backendDeploySucceeded = false;
21454
21467
  let backendDeployFailed = false;
@@ -22511,24 +22524,123 @@ var deploy_default = {
22511
22524
  };
22512
22525
 
22513
22526
  // src/cli/init/handler.ts
22514
- import path66 from "node:path";
22527
+ import path67 from "node:path";
22515
22528
 
22516
22529
  // src/cli/scaffold/run-scaffold-discovery.ts
22517
- import { access as access10, readFile as readFile19, writeFile as writeFile18 } from "node:fs/promises";
22518
- import path65 from "node:path";
22530
+ import { access as access10, readFile as readFile20, writeFile as writeFile18 } from "node:fs/promises";
22531
+ import path66 from "node:path";
22532
+
22533
+ // src/cli/scaffold/detect-backend.ts
22534
+ import { readdir as readdir3, readFile as readFile18 } from "node:fs/promises";
22535
+ import path64 from "node:path";
22536
+ var DEFAULT_RUNTIME_VERSION = {
22537
+ dotnet: "DOTNET_10",
22538
+ nodejs: "NODE_22_LTS",
22539
+ python: "PYTHON_312"
22540
+ };
22541
+ var PYTHON_MARKERS = ["pyproject.toml", "requirements.txt", "Pipfile"];
22542
+ async function listFiles(directory) {
22543
+ try {
22544
+ const entries = await readdir3(directory, { withFileTypes: true });
22545
+ return entries.filter((e) => e.isFile()).map((e) => e.name);
22546
+ } catch {
22547
+ return [];
22548
+ }
22549
+ }
22550
+ async function readText(filePath) {
22551
+ try {
22552
+ return await readFile18(filePath, "utf8");
22553
+ } catch {
22554
+ return void 0;
22555
+ }
22556
+ }
22557
+ function dotnetVersionFromCsproj(content) {
22558
+ const match = content?.match(/<TargetFrameworks?>\s*net(\d+)\.\d/i);
22559
+ const major = match?.[1];
22560
+ if (major === "8" || major === "9" || major === "10") {
22561
+ return `DOTNET_${major}`;
22562
+ }
22563
+ return DEFAULT_RUNTIME_VERSION.dotnet;
22564
+ }
22565
+ function nodeVersionFromEngines(engines) {
22566
+ const range = engines && typeof engines === "object" && !Array.isArray(engines) ? engines.node : void 0;
22567
+ if (typeof range === "string" && /(^|[^\d])24/.test(range)) {
22568
+ return "NODE_24_LTS";
22569
+ }
22570
+ return DEFAULT_RUNTIME_VERSION.nodejs;
22571
+ }
22572
+ function pythonVersionFromText(content) {
22573
+ const match = content?.match(/3\.(1[0-4])/);
22574
+ return match ? `PYTHON_3${match[1]}` : DEFAULT_RUNTIME_VERSION.python;
22575
+ }
22576
+ function isRunnableNodePackage(pkg) {
22577
+ const scripts = pkg.scripts && typeof pkg.scripts === "object" ? pkg.scripts : {};
22578
+ return typeof scripts.start === "string" || typeof pkg.main === "string";
22579
+ }
22580
+ async function detectParentBackend(siteDirectory) {
22581
+ const site = path64.resolve(siteDirectory);
22582
+ const directory = path64.dirname(site);
22583
+ if (directory === site) {
22584
+ return void 0;
22585
+ }
22586
+ const files = await listFiles(directory);
22587
+ const toResult = (runtime, runtimeVersion, marker) => ({
22588
+ directory,
22589
+ sourceDirectory: path64.relative(site, directory).split(path64.sep).join("/") || ".",
22590
+ runtime,
22591
+ runtimeVersion,
22592
+ marker
22593
+ });
22594
+ const csproj = files.find((f) => f.endsWith(".csproj"));
22595
+ const solution = files.find((f) => /\.slnx?$/.test(f));
22596
+ if (csproj || solution) {
22597
+ const content = csproj ? await readText(path64.join(directory, csproj)) : void 0;
22598
+ return toResult(
22599
+ "dotnet",
22600
+ dotnetVersionFromCsproj(content),
22601
+ csproj ?? solution
22602
+ );
22603
+ }
22604
+ if (files.includes("package.json")) {
22605
+ const raw = await readText(path64.join(directory, "package.json"));
22606
+ try {
22607
+ const pkg = JSON.parse(raw ?? "");
22608
+ if (isRunnableNodePackage(pkg)) {
22609
+ return toResult(
22610
+ "nodejs",
22611
+ nodeVersionFromEngines(pkg.engines),
22612
+ "package.json"
22613
+ );
22614
+ }
22615
+ } catch {
22616
+ }
22617
+ }
22618
+ const pythonMarker = PYTHON_MARKERS.find((m) => files.includes(m));
22619
+ if (pythonMarker) {
22620
+ const versionSource = await readText(path64.join(directory, ".python-version")) ?? (pythonMarker === "pyproject.toml" ? (await readText(path64.join(directory, pythonMarker)))?.match(
22621
+ /requires-python\s*=\s*"([^"]+)"/
22622
+ )?.[1] : void 0);
22623
+ return toResult(
22624
+ "python",
22625
+ pythonVersionFromText(versionSource),
22626
+ pythonMarker
22627
+ );
22628
+ }
22629
+ return void 0;
22630
+ }
22519
22631
 
22520
22632
  // src/cli/scaffold/wire-docs.ts
22521
22633
  import {
22522
22634
  access as access9,
22523
22635
  lstat,
22524
22636
  mkdir as mkdir13,
22525
- readdir as readdir3,
22526
- readFile as readFile18,
22637
+ readdir as readdir4,
22638
+ readFile as readFile19,
22527
22639
  readlink,
22528
22640
  symlink,
22529
22641
  writeFile as writeFile17
22530
22642
  } from "node:fs/promises";
22531
- import path64 from "node:path";
22643
+ import path65 from "node:path";
22532
22644
  var DOCS_DIR_WHITELIST = [
22533
22645
  "docs",
22534
22646
  "documents",
@@ -22565,20 +22677,20 @@ async function isDirectory(filePath) {
22565
22677
  }
22566
22678
  }
22567
22679
  function toPosix2(value) {
22568
- return value.split(path64.sep).join(path64.posix.sep);
22680
+ return value.split(path65.sep).join(path65.posix.sep);
22569
22681
  }
22570
22682
  function isWhitelistedDirName(name) {
22571
22683
  return DOCS_DIR_WHITELIST.includes(name.toLowerCase());
22572
22684
  }
22573
22685
  function isInside2(parent, child) {
22574
- const relative = path64.relative(parent, child);
22575
- return relative === "" || !relative.startsWith("..") && !path64.isAbsolute(relative);
22686
+ const relative = path65.relative(parent, child);
22687
+ return relative === "" || !relative.startsWith("..") && !path65.isAbsolute(relative);
22576
22688
  }
22577
22689
  async function collectMarkdownFiles(dir, excludeDir) {
22578
22690
  const files = [];
22579
22691
  let entries;
22580
22692
  try {
22581
- entries = await readdir3(dir, { withFileTypes: true });
22693
+ entries = await readdir4(dir, { withFileTypes: true });
22582
22694
  } catch {
22583
22695
  return files;
22584
22696
  }
@@ -22586,9 +22698,9 @@ async function collectMarkdownFiles(dir, excludeDir) {
22586
22698
  if (entry.name.startsWith(".")) {
22587
22699
  continue;
22588
22700
  }
22589
- const full = path64.join(dir, entry.name);
22701
+ const full = path65.join(dir, entry.name);
22590
22702
  if (entry.isDirectory()) {
22591
- if (SKIP_SEARCH_DIRS.has(entry.name) || entry.isSymbolicLink() || excludeDir && path64.resolve(full) === excludeDir) {
22703
+ if (SKIP_SEARCH_DIRS.has(entry.name) || entry.isSymbolicLink() || excludeDir && path65.resolve(full) === excludeDir) {
22592
22704
  continue;
22593
22705
  }
22594
22706
  files.push(...await collectMarkdownFiles(full, excludeDir));
@@ -22601,11 +22713,11 @@ async function collectMarkdownFiles(dir, excludeDir) {
22601
22713
  return files;
22602
22714
  }
22603
22715
  async function collectSearchRoots(siteDirectory) {
22604
- const site = path64.resolve(siteDirectory);
22605
- const parent = path64.dirname(site);
22716
+ const site = path65.resolve(siteDirectory);
22717
+ const parent = path65.dirname(site);
22606
22718
  const roots = [];
22607
22719
  const add = (dir) => {
22608
- const resolved = path64.resolve(dir);
22720
+ const resolved = path65.resolve(dir);
22609
22721
  if (!roots.includes(resolved)) {
22610
22722
  roots.push(resolved);
22611
22723
  }
@@ -22613,12 +22725,12 @@ async function collectSearchRoots(siteDirectory) {
22613
22725
  if (parent && parent !== site) {
22614
22726
  add(parent);
22615
22727
  try {
22616
- const entries = await readdir3(parent, { withFileTypes: true });
22728
+ const entries = await readdir4(parent, { withFileTypes: true });
22617
22729
  for (const entry of entries) {
22618
22730
  if (!entry.isDirectory() || SKIP_SEARCH_DIRS.has(entry.name)) {
22619
22731
  continue;
22620
22732
  }
22621
- add(path64.join(parent, entry.name));
22733
+ add(path65.join(parent, entry.name));
22622
22734
  }
22623
22735
  } catch {
22624
22736
  }
@@ -22627,13 +22739,13 @@ async function collectSearchRoots(siteDirectory) {
22627
22739
  return roots;
22628
22740
  }
22629
22741
  async function discoverNearbyDocsDirectories(siteDirectory) {
22630
- const site = path64.resolve(siteDirectory);
22631
- const sitePages = path64.join(site, PAGES_DIR);
22742
+ const site = path65.resolve(siteDirectory);
22743
+ const sitePages = path65.join(site, PAGES_DIR);
22632
22744
  const searchedDirectories = await collectSearchRoots(site);
22633
22745
  const directories = [];
22634
22746
  const seen = /* @__PURE__ */ new Set();
22635
22747
  const consider = async (dir) => {
22636
- const resolved = path64.resolve(dir);
22748
+ const resolved = path65.resolve(dir);
22637
22749
  if (resolved === site || seen.has(resolved) || isInside2(sitePages, resolved)) {
22638
22750
  return;
22639
22751
  }
@@ -22650,11 +22762,11 @@ async function discoverNearbyDocsDirectories(siteDirectory) {
22650
22762
  directories.push({ sourceDirectory: resolved, files });
22651
22763
  };
22652
22764
  for (const root of searchedDirectories) {
22653
- if (isWhitelistedDirName(path64.basename(root))) {
22765
+ if (isWhitelistedDirName(path65.basename(root))) {
22654
22766
  await consider(root);
22655
22767
  }
22656
22768
  try {
22657
- const entries = await readdir3(root, { withFileTypes: true });
22769
+ const entries = await readdir4(root, { withFileTypes: true });
22658
22770
  for (const entry of entries) {
22659
22771
  if (!entry.isDirectory() || SKIP_SEARCH_DIRS.has(entry.name)) {
22660
22772
  continue;
@@ -22662,7 +22774,7 @@ async function discoverNearbyDocsDirectories(siteDirectory) {
22662
22774
  if (!isWhitelistedDirName(entry.name)) {
22663
22775
  continue;
22664
22776
  }
22665
- await consider(path64.join(root, entry.name));
22777
+ await consider(path65.join(root, entry.name));
22666
22778
  }
22667
22779
  } catch {
22668
22780
  }
@@ -22681,8 +22793,8 @@ function slugifyDirName(name) {
22681
22793
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "docs";
22682
22794
  }
22683
22795
  async function allocateLinkName(pagesDir, sourceDirectory, used) {
22684
- const base = slugifyDirName(path64.basename(sourceDirectory));
22685
- const parent = slugifyDirName(path64.basename(path64.dirname(sourceDirectory)));
22796
+ const base = slugifyDirName(path65.basename(sourceDirectory));
22797
+ const parent = slugifyDirName(path65.basename(path65.dirname(sourceDirectory)));
22686
22798
  const candidates = [base, `${parent}-${base}`];
22687
22799
  let index = 2;
22688
22800
  while (true) {
@@ -22690,7 +22802,7 @@ async function allocateLinkName(pagesDir, sourceDirectory, used) {
22690
22802
  if (used.has(name)) {
22691
22803
  continue;
22692
22804
  }
22693
- const target = path64.join(pagesDir, name);
22805
+ const target = path65.join(pagesDir, name);
22694
22806
  if (await pathExists5(target)) {
22695
22807
  const stat4 = await lstat(target);
22696
22808
  if (!stat4.isDirectory() || !await isManagedLinkDir(target)) {
@@ -22703,7 +22815,7 @@ async function allocateLinkName(pagesDir, sourceDirectory, used) {
22703
22815
  }
22704
22816
  async function isManagedLinkDir(dir) {
22705
22817
  try {
22706
- const entries = await readdir3(dir, { withFileTypes: true });
22818
+ const entries = await readdir4(dir, { withFileTypes: true });
22707
22819
  if (entries.length === 0) {
22708
22820
  return true;
22709
22821
  }
@@ -22721,8 +22833,8 @@ async function alreadyLinked(linkPath, sourcePath) {
22721
22833
  return false;
22722
22834
  }
22723
22835
  const current = await readlink(linkPath);
22724
- const resolved = path64.resolve(path64.dirname(linkPath), current);
22725
- return resolved === path64.resolve(sourcePath);
22836
+ const resolved = path65.resolve(path65.dirname(linkPath), current);
22837
+ return resolved === path65.resolve(sourcePath);
22726
22838
  } catch {
22727
22839
  return false;
22728
22840
  }
@@ -22734,8 +22846,8 @@ async function linkMarkdownFile(sourcePath, linkPath) {
22734
22846
  if (await pathExists5(linkPath)) {
22735
22847
  return "skipped";
22736
22848
  }
22737
- await mkdir13(path64.dirname(linkPath), { recursive: true });
22738
- const relativeTarget = path64.relative(path64.dirname(linkPath), sourcePath);
22849
+ await mkdir13(path65.dirname(linkPath), { recursive: true });
22850
+ const relativeTarget = path65.relative(path65.dirname(linkPath), sourcePath);
22739
22851
  await symlink(
22740
22852
  relativeTarget,
22741
22853
  linkPath,
@@ -22750,11 +22862,11 @@ async function applyDocsNavigation(siteDirectory, routes) {
22750
22862
  if (routes.length === 0) {
22751
22863
  return;
22752
22864
  }
22753
- const configPath = path64.join(siteDirectory, CONFIG_FILENAME);
22865
+ const configPath = path65.join(siteDirectory, CONFIG_FILENAME);
22754
22866
  if (!await pathExists5(configPath)) {
22755
22867
  return;
22756
22868
  }
22757
- const raw = await readFile18(configPath, "utf8");
22869
+ const raw = await readFile19(configPath, "utf8");
22758
22870
  const parsed = JSON.parse(raw);
22759
22871
  if (!isPlainObject5(parsed)) {
22760
22872
  return;
@@ -22767,8 +22879,8 @@ async function applyDocsNavigation(siteDirectory, routes) {
22767
22879
  `, "utf8");
22768
22880
  }
22769
22881
  async function discoverAndWireDocs(siteDirectory) {
22770
- const site = path64.resolve(siteDirectory);
22771
- const pagesDir = path64.join(site, PAGES_DIR);
22882
+ const site = path65.resolve(siteDirectory);
22883
+ const pagesDir = path65.join(site, PAGES_DIR);
22772
22884
  const { directories, searchedDirectories } = await discoverNearbyDocsDirectories(site);
22773
22885
  if (directories.length === 0) {
22774
22886
  return {
@@ -22790,15 +22902,15 @@ async function discoverAndWireDocs(siteDirectory) {
22790
22902
  directory.sourceDirectory,
22791
22903
  usedNames
22792
22904
  );
22793
- const linkDirectory = path64.join(pagesDir, linkName);
22905
+ const linkDirectory = path65.join(pagesDir, linkName);
22794
22906
  const linked = [];
22795
22907
  const skipped = [];
22796
22908
  for (const sourcePath of directory.files) {
22797
22909
  const relativeSource = toPosix2(
22798
- path64.relative(directory.sourceDirectory, sourcePath)
22910
+ path65.relative(directory.sourceDirectory, sourcePath)
22799
22911
  );
22800
- const linkPath = path64.join(linkDirectory, relativeSource);
22801
- const relativeLink = toPosix2(path64.relative(site, linkPath));
22912
+ const linkPath = path65.join(linkDirectory, relativeSource);
22913
+ const relativeLink = toPosix2(path65.relative(site, linkPath));
22802
22914
  const route = toRoutePath(relativeLink, PAGES_DIR);
22803
22915
  if (routes.includes(route)) {
22804
22916
  skipped.push({
@@ -22846,11 +22958,11 @@ async function discoverAndWireDocs(siteDirectory) {
22846
22958
  };
22847
22959
  }
22848
22960
  function siteRelative(siteDirectory, filePath) {
22849
- const relative = toPosix2(path64.relative(siteDirectory, filePath));
22961
+ const relative = toPosix2(path65.relative(siteDirectory, filePath));
22850
22962
  if (!relative) {
22851
22963
  return ".";
22852
22964
  }
22853
- if (path64.isAbsolute(relative)) {
22965
+ if (path65.isAbsolute(relative)) {
22854
22966
  return toPosix2(filePath);
22855
22967
  }
22856
22968
  if (relative.startsWith("..")) {
@@ -22899,10 +23011,31 @@ function formatDocsDiscoveryLines(siteDirectory, docsDiscovery) {
22899
23011
  }
22900
23012
  return lines;
22901
23013
  }
22902
- function formatInitDiscoveryReport(siteDirectory, openApiDiscovery, docsDiscovery) {
23014
+ function formatBackendDiscoveryLines(backendDiscovery) {
23015
+ const status2 = String(backendDiscovery?.status ?? "unknown");
23016
+ if (status2 === "wired" || status2 === "already_configured") {
23017
+ const runtime = backendDiscovery?.runtime ?? "unknown runtime";
23018
+ const version = backendDiscovery?.runtimeVersion ?? "";
23019
+ const source = backendDiscovery?.sourceDirectory ?? "";
23020
+ const verb = status2 === "wired" ? "detected" : "kept";
23021
+ return [`Backend: ${verb} ${runtime} ${version} at ${source}`.trimEnd()];
23022
+ }
23023
+ if (status2 === "wire_failed") {
23024
+ const error = typeof backendDiscovery?.error === "string" ? `: ${backendDiscovery.error}` : "";
23025
+ return [`Backend: found a project but did not wire it${error}`];
23026
+ }
23027
+ if (status2 === "skipped") {
23028
+ return ["Backend: search skipped"];
23029
+ }
23030
+ return [
23031
+ "Backend: none detected in the parent folder (set one with apitogo config)"
23032
+ ];
23033
+ }
23034
+ function formatInitDiscoveryReport(siteDirectory, openApiDiscovery, docsDiscovery, backendDiscovery) {
22903
23035
  return [
22904
23036
  ...formatOpenApiDiscoveryLines(siteDirectory, openApiDiscovery),
22905
- ...formatDocsDiscoveryLines(siteDirectory, docsDiscovery)
23037
+ ...formatDocsDiscoveryLines(siteDirectory, docsDiscovery),
23038
+ ...backendDiscovery ? formatBackendDiscoveryLines(backendDiscovery) : []
22906
23039
  ];
22907
23040
  }
22908
23041
 
@@ -22917,8 +23050,8 @@ async function pathExists6(filePath) {
22917
23050
  }
22918
23051
  async function wireOpenApiIntoJsonConfig(siteDirectory, openApiPath) {
22919
23052
  const input5 = toSiteRelativeOpenApiInput(siteDirectory, openApiPath);
22920
- const jsonConfigPath = path65.join(siteDirectory, "apitogo.config.json");
22921
- const raw = await readFile19(jsonConfigPath, "utf8");
23053
+ const jsonConfigPath = path66.join(siteDirectory, "apitogo.config.json");
23054
+ const raw = await readFile20(jsonConfigPath, "utf8");
22922
23055
  const siteConfig = JSON.parse(raw);
22923
23056
  const updated = applyOpenApiToSiteConfig(siteConfig, {
22924
23057
  input: input5,
@@ -22945,7 +23078,7 @@ async function discoverAndWireOpenApiLite(siteDirectory, mode) {
22945
23078
  const invalidCandidates = [];
22946
23079
  let selected;
22947
23080
  for (const candidate of search.candidates) {
22948
- const content = await readFile19(candidate, "utf8");
23081
+ const content = await readFile20(candidate, "utf8");
22949
23082
  const parsed = liteParseOpenApi(content, candidate);
22950
23083
  if (parsed.valid) {
22951
23084
  selected = {
@@ -22969,7 +23102,7 @@ async function discoverAndWireOpenApiLite(siteDirectory, mode) {
22969
23102
  wired: false
22970
23103
  };
22971
23104
  }
22972
- const jsonConfigPath = path65.join(siteDirectory, "apitogo.config.json");
23105
+ const jsonConfigPath = path66.join(siteDirectory, "apitogo.config.json");
22973
23106
  if (!await pathExists6(jsonConfigPath)) {
22974
23107
  return {
22975
23108
  openApiDiscovery: {
@@ -23015,6 +23148,58 @@ async function discoverAndWireOpenApiLite(siteDirectory, mode) {
23015
23148
  };
23016
23149
  }
23017
23150
  }
23151
+ async function discoverAndWireBackend(siteDirectory, mode) {
23152
+ if (mode !== "nearby") {
23153
+ return { status: "skipped", mode };
23154
+ }
23155
+ const jsonConfigPath = path66.join(siteDirectory, "apitogo.config.json");
23156
+ if (!await pathExists6(jsonConfigPath)) {
23157
+ return { status: "not_found" };
23158
+ }
23159
+ try {
23160
+ const siteConfig = JSON.parse(
23161
+ await readFile20(jsonConfigPath, "utf8")
23162
+ );
23163
+ const existing = siteConfig.backend && typeof siteConfig.backend === "object" && !Array.isArray(siteConfig.backend) ? siteConfig.backend : {};
23164
+ if (typeof existing.sourceDirectory === "string" && existing.sourceDirectory.trim()) {
23165
+ return {
23166
+ status: "already_configured",
23167
+ sourceDirectory: existing.sourceDirectory,
23168
+ runtime: existing.runtime ?? null,
23169
+ runtimeVersion: existing.runtimeVersion ?? null
23170
+ };
23171
+ }
23172
+ const detected = await detectParentBackend(siteDirectory);
23173
+ if (!detected) {
23174
+ return { status: "not_found" };
23175
+ }
23176
+ siteConfig.backend = {
23177
+ ...existing,
23178
+ sourceDirectory: detected.sourceDirectory,
23179
+ runtime: detected.runtime,
23180
+ runtimeVersion: detected.runtimeVersion
23181
+ };
23182
+ await writeFile18(
23183
+ jsonConfigPath,
23184
+ `${JSON.stringify(siteConfig, null, 2)}
23185
+ `,
23186
+ "utf8"
23187
+ );
23188
+ return {
23189
+ status: "wired",
23190
+ directory: detected.directory,
23191
+ sourceDirectory: detected.sourceDirectory,
23192
+ runtime: detected.runtime,
23193
+ runtimeVersion: detected.runtimeVersion,
23194
+ marker: detected.marker
23195
+ };
23196
+ } catch (error) {
23197
+ return {
23198
+ status: "wire_failed",
23199
+ error: error instanceof Error ? error.message : String(error)
23200
+ };
23201
+ }
23202
+ }
23018
23203
  async function runScaffoldDiscovery(siteDirectory, options) {
23019
23204
  const openapiSearch = options?.openapiSearch ?? "nearby";
23020
23205
  const { openApiDiscovery } = await discoverAndWireOpenApiLite(
@@ -23022,7 +23207,11 @@ async function runScaffoldDiscovery(siteDirectory, options) {
23022
23207
  openapiSearch
23023
23208
  );
23024
23209
  const docsDiscovery = await discoverAndWireDocs(siteDirectory);
23025
- return { openApiDiscovery, docsDiscovery };
23210
+ const backendDiscovery = await discoverAndWireBackend(
23211
+ siteDirectory,
23212
+ openapiSearch
23213
+ );
23214
+ return { openApiDiscovery, docsDiscovery, backendDiscovery };
23026
23215
  }
23027
23216
 
23028
23217
  // src/cli/init/handler.ts
@@ -23030,8 +23219,8 @@ function slugifyName2(name) {
23030
23219
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "dev-portal-site";
23031
23220
  }
23032
23221
  function resolveInitOutputDirectory(dirArg, name) {
23033
- const resolved = path66.resolve(process.cwd(), dirArg);
23034
- const base = path66.basename(resolved);
23222
+ const resolved = path67.resolve(process.cwd(), dirArg);
23223
+ const base = path67.basename(resolved);
23035
23224
  const isDot = dirArg === "." || dirArg === "./" || base === "." || resolved === process.cwd();
23036
23225
  if (isDot) {
23037
23226
  const fromName = name?.trim();
@@ -23041,7 +23230,7 @@ function resolveInitOutputDirectory(dirArg, name) {
23041
23230
  );
23042
23231
  }
23043
23232
  return {
23044
- outputDirectory: path66.resolve(process.cwd(), slugifyName2(fromName)),
23233
+ outputDirectory: path67.resolve(process.cwd(), slugifyName2(fromName)),
23045
23234
  siteName: fromName
23046
23235
  };
23047
23236
  }
@@ -23086,17 +23275,15 @@ async function init2(argv) {
23086
23275
  }
23087
23276
  npmInstall = await runNpmInstall(result.outputDirectory);
23088
23277
  }
23089
- const { openApiDiscovery, docsDiscovery } = await runScaffoldDiscovery(
23090
- result.outputDirectory,
23091
- { openapiSearch }
23092
- );
23278
+ const { openApiDiscovery, docsDiscovery, backendDiscovery } = await runScaffoldDiscovery(result.outputDirectory, { openapiSearch });
23093
23279
  const siteValidation = await validateDevPortalSiteConfig(
23094
23280
  result.outputDirectory
23095
23281
  );
23096
23282
  const discoveryReport = formatInitDiscoveryReport(
23097
23283
  result.outputDirectory,
23098
23284
  openApiDiscovery,
23099
- docsDiscovery
23285
+ docsDiscovery,
23286
+ backendDiscovery
23100
23287
  );
23101
23288
  const devCommand = "npm run dev";
23102
23289
  const response = {
@@ -23116,6 +23303,7 @@ async function init2(argv) {
23116
23303
  npmInstallDurationMs: npmInstall?.durationMs ?? null,
23117
23304
  openApiDiscovery,
23118
23305
  docsDiscovery,
23306
+ backendDiscovery,
23119
23307
  openapiSearch,
23120
23308
  previewStarted: false,
23121
23309
  devCommand,
@@ -23194,8 +23382,8 @@ import open2 from "open";
23194
23382
  import colors13 from "picocolors";
23195
23383
 
23196
23384
  // src/cli/platform/device-auth.ts
23197
- function url(apiUrl, path73) {
23198
- return `${apiUrl}${path73.startsWith("/") ? path73 : `/${path73}`}`;
23385
+ function url(apiUrl, path74) {
23386
+ return `${apiUrl}${path74.startsWith("/") ? path74 : `/${path74}`}`;
23199
23387
  }
23200
23388
  async function requestDeviceCode(apiUrl) {
23201
23389
  const response = await fetchWithRetry(
@@ -23458,14 +23646,14 @@ var project_create_default = {
23458
23646
 
23459
23647
  // src/cli/dev/handler.ts
23460
23648
  init_joinUrl();
23461
- import path69 from "node:path";
23649
+ import path70 from "node:path";
23462
23650
 
23463
23651
  // src/vite/dev-server.ts
23464
23652
  init_logger();
23465
23653
  import fs12 from "node:fs/promises";
23466
23654
  import http from "node:http";
23467
23655
  import https from "node:https";
23468
- import path68 from "node:path";
23656
+ import path69 from "node:path";
23469
23657
  import { createHttpTerminator } from "http-terminator";
23470
23658
  import {
23471
23659
  createServer as createViteServer,
@@ -23498,7 +23686,7 @@ init_loader();
23498
23686
  // src/vite/pagefind-dev-index.ts
23499
23687
  init_invariant();
23500
23688
  init_joinUrl();
23501
- import path67 from "node:path";
23689
+ import path68 from "node:path";
23502
23690
  import { createIndex as createIndex2 } from "pagefind";
23503
23691
  import { isRunnableDevEnvironment } from "vite";
23504
23692
  async function* buildPagefindDevIndex(vite, config2) {
@@ -23551,7 +23739,7 @@ async function* buildPagefindDevIndex(vite, config2) {
23551
23739
  path: urlPath
23552
23740
  };
23553
23741
  }
23554
- const outputPath = path67.join(vite.config.publicDir, "pagefind");
23742
+ const outputPath = path68.join(vite.config.publicDir, "pagefind");
23555
23743
  await pagefindIndex.writeFiles({ outputPath });
23556
23744
  yield { type: "complete", success: true, indexed };
23557
23745
  }
@@ -23570,9 +23758,9 @@ var DevServer = class {
23570
23758
  this.protocol = "https";
23571
23759
  const { dir } = this.options;
23572
23760
  const [key, cert, ca] = await Promise.all([
23573
- fs12.readFile(path68.resolve(dir, config2.https.key)),
23574
- fs12.readFile(path68.resolve(dir, config2.https.cert)),
23575
- config2.https.ca ? fs12.readFile(path68.resolve(dir, config2.https.ca)) : void 0
23761
+ fs12.readFile(path69.resolve(dir, config2.https.key)),
23762
+ fs12.readFile(path69.resolve(dir, config2.https.cert)),
23763
+ config2.https.ca ? fs12.readFile(path69.resolve(dir, config2.https.ca)) : void 0
23576
23764
  ]);
23577
23765
  return https.createServer({ key, cert, ca });
23578
23766
  }
@@ -23589,7 +23777,7 @@ var DevServer = class {
23589
23777
  );
23590
23778
  const server = await this.createNodeServer(config2);
23591
23779
  if (config2.search?.type === "pagefind" && viteConfig.publicDir !== false) {
23592
- const publicRoot = path68.resolve(
23780
+ const publicRoot = path69.resolve(
23593
23781
  this.options.dir,
23594
23782
  typeof viteConfig.publicDir === "string" ? viteConfig.publicDir : "public"
23595
23783
  );
@@ -23606,7 +23794,7 @@ var DevServer = class {
23606
23794
  // built-in transform middleware which would treat the path as a static asset.
23607
23795
  name: "apitogo:entry-client",
23608
23796
  configureServer(server2) {
23609
- const entryPath = path68.posix.join(
23797
+ const entryPath = path69.posix.join(
23610
23798
  server2.config.base,
23611
23799
  "/__z/entry.client.tsx"
23612
23800
  );
@@ -23771,7 +23959,7 @@ init_package_json();
23771
23959
  async function dev(argv) {
23772
23960
  const packageJson3 = getZudokuPackageJson();
23773
23961
  process.env.NODE_ENV = "development";
23774
- const dir = path69.resolve(process.cwd(), argv.dir);
23962
+ const dir = path70.resolve(process.cwd(), argv.dir);
23775
23963
  const server = new DevServer({
23776
23964
  dir,
23777
23965
  argPort: argv.port,
@@ -23860,9 +24048,9 @@ var run_default = {
23860
24048
  };
23861
24049
 
23862
24050
  // src/cli/status/handler.ts
23863
- import path70 from "node:path";
24051
+ import path71 from "node:path";
23864
24052
  async function status(argv) {
23865
- const sourceDirectory = path70.resolve(process.cwd(), argv.dir);
24053
+ const sourceDirectory = path71.resolve(process.cwd(), argv.dir);
23866
24054
  let config2;
23867
24055
  try {
23868
24056
  config2 = loadConfig();
@@ -23950,7 +24138,7 @@ var status_default = {
23950
24138
  };
23951
24139
 
23952
24140
  // src/cli/teardown/handler.ts
23953
- import path71 from "node:path";
24141
+ import path72 from "node:path";
23954
24142
  function resultLooksFailed3(payload) {
23955
24143
  try {
23956
24144
  const parsed = JSON.parse(payload);
@@ -23966,7 +24154,7 @@ async function teardown(argv) {
23966
24154
  );
23967
24155
  return;
23968
24156
  }
23969
- const sourceDirectory = path71.resolve(process.cwd(), argv.dir);
24157
+ const sourceDirectory = path72.resolve(process.cwd(), argv.dir);
23970
24158
  let config2;
23971
24159
  try {
23972
24160
  config2 = loadConfig();
@@ -24123,36 +24311,36 @@ function createApitogoCli(argv) {
24123
24311
  // src/cli/local-handoff.ts
24124
24312
  import { spawn as spawn4 } from "node:child_process";
24125
24313
  import { existsSync as existsSync6, realpathSync } from "node:fs";
24126
- import path72 from "node:path";
24314
+ import path73 from "node:path";
24127
24315
  var LOCAL_HANDOFF_ENV = "APITOGO_LOCAL_CLI";
24128
24316
  var PACKAGE_NAME = "@lukoweb/apitogo";
24129
24317
  var resolveProjectDir = (argv, cwd) => {
24130
24318
  for (let i = 0; i < argv.length; i++) {
24131
24319
  const arg = argv[i];
24132
24320
  const next = argv[i + 1];
24133
- if (arg === "--dir" && next) return path72.resolve(cwd, next);
24321
+ if (arg === "--dir" && next) return path73.resolve(cwd, next);
24134
24322
  if (arg?.startsWith("--dir=")) {
24135
- return path72.resolve(cwd, arg.slice("--dir=".length));
24323
+ return path73.resolve(cwd, arg.slice("--dir=".length));
24136
24324
  }
24137
24325
  }
24138
24326
  return cwd;
24139
24327
  };
24140
24328
  var findLocalCli = (projectDir, runningRoot) => {
24141
- let dir = path72.resolve(projectDir);
24329
+ let dir = path73.resolve(projectDir);
24142
24330
  let localPackageRoot;
24143
24331
  while (!localPackageRoot) {
24144
- const candidate = path72.join(dir, "node_modules", PACKAGE_NAME);
24145
- if (existsSync6(path72.join(candidate, "package.json"))) {
24332
+ const candidate = path73.join(dir, "node_modules", PACKAGE_NAME);
24333
+ if (existsSync6(path73.join(candidate, "package.json"))) {
24146
24334
  localPackageRoot = candidate;
24147
- } else if (dir === path72.dirname(dir)) {
24335
+ } else if (dir === path73.dirname(dir)) {
24148
24336
  return void 0;
24149
24337
  } else {
24150
- dir = path72.dirname(dir);
24338
+ dir = path73.dirname(dir);
24151
24339
  }
24152
24340
  }
24153
24341
  const localRoot = realpathSync(localPackageRoot);
24154
24342
  if (localRoot === realpathSync(runningRoot)) return void 0;
24155
- return path72.join(localRoot, "cli.js");
24343
+ return path73.join(localRoot, "cli.js");
24156
24344
  };
24157
24345
  var handoffToLocalCli = async (argv, runningRoot) => {
24158
24346
  if (process.env[LOCAL_HANDOFF_ENV] || process.env.ZUDOKU_ENV === "internal") {
@@ -24164,7 +24352,7 @@ var handoffToLocalCli = async (argv, runningRoot) => {
24164
24352
  );
24165
24353
  if (!localCli) return void 0;
24166
24354
  printDiagnosticsToConsole(
24167
- `Using the project's local ${PACKAGE_NAME} (${path72.dirname(localCli)})`
24355
+ `Using the project's local ${PACKAGE_NAME} (${path73.dirname(localCli)})`
24168
24356
  );
24169
24357
  const child = spawn4(process.execPath, [localCli, ...argv], {
24170
24358
  stdio: "inherit",
@@ -151,6 +151,7 @@ export declare function applyScaffoldManifestPolicy(manifest: DevPortalLocalMani
151
151
  includeDefaultPlans?: boolean;
152
152
  }): DevPortalLocalManifest;
153
153
  export declare function mergePlansBySku(existing: ManifestPlanInput[] | undefined, patch: ManifestPlanInput[]): ManifestPlanInput[];
154
+ export declare function resolveBackendSourceDirectory(siteDirectory: string, sourceDirectory: string | undefined): string | undefined;
154
155
  export declare function resolveBackendOpenApiPath(openApiPath: string | undefined, options: {
155
156
  siteDirectory: string;
156
157
  backendSourceDirectory?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lukoweb/apitogo",
3
- "version": "0.1.144",
3
+ "version": "0.1.146",
4
4
  "type": "module",
5
5
  "sideEffects": [
6
6
  "**/*.css",