@lukoweb/apitogo 0.1.78 → 0.1.79
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 +398 -195
- package/docs/cli/commands.md +80 -0
- package/docs/cli/go-live.md +122 -0
- package/docs/cli/overview.md +89 -0
- package/docs/cli/setup.md +112 -0
- package/docs/cli/shape.md +121 -0
- package/docs/configuration/authentication.md +4 -3
- package/docs/configuration/make-config.mdx +57 -17
- package/docs/configuration/manifest.md +3 -2
- package/docs/configuration/overview.md +3 -1
- package/docs/configuration/plans.md +113 -0
- package/docs/deploy/apitogo.md +9 -43
- package/docs/deployment.md +1 -1
- package/docs/guides/custom-pages.md +8 -0
- package/docs/guides/environment-variables.md +4 -3
- package/docs/mcp/go-live.md +1 -1
- package/docs/mcp/overview.md +1 -1
- package/docs/quickstart.md +2 -10
- package/package.json +1 -1
package/dist/cli/cli.js
CHANGED
|
@@ -744,7 +744,7 @@ import { stat } from "node:fs/promises";
|
|
|
744
744
|
var fileExists;
|
|
745
745
|
var init_file_exists = __esm({
|
|
746
746
|
"src/config/file-exists.ts"() {
|
|
747
|
-
fileExists = (
|
|
747
|
+
fileExists = (path45) => stat(path45).then(() => true).catch(() => false);
|
|
748
748
|
}
|
|
749
749
|
});
|
|
750
750
|
|
|
@@ -5633,7 +5633,7 @@ import {
|
|
|
5633
5633
|
// package.json
|
|
5634
5634
|
var package_default = {
|
|
5635
5635
|
name: "@lukoweb/apitogo",
|
|
5636
|
-
version: "0.1.
|
|
5636
|
+
version: "0.1.79",
|
|
5637
5637
|
type: "module",
|
|
5638
5638
|
sideEffects: [
|
|
5639
5639
|
"**/*.css",
|
|
@@ -6402,14 +6402,14 @@ var flattenAllOf = (schema2) => {
|
|
|
6402
6402
|
};
|
|
6403
6403
|
|
|
6404
6404
|
// src/lib/util/traverse.ts
|
|
6405
|
-
var traverse = (specification, transform,
|
|
6406
|
-
const transformed = transform(specification,
|
|
6405
|
+
var traverse = (specification, transform, path45 = []) => {
|
|
6406
|
+
const transformed = transform(specification, path45);
|
|
6407
6407
|
if (typeof transformed !== "object" || transformed === null) {
|
|
6408
6408
|
return transformed;
|
|
6409
6409
|
}
|
|
6410
6410
|
const result = Array.isArray(transformed) ? [] : {};
|
|
6411
6411
|
for (const [key, value] of Object.entries(transformed)) {
|
|
6412
|
-
const currentPath = [...
|
|
6412
|
+
const currentPath = [...path45, key];
|
|
6413
6413
|
if (Array.isArray(value)) {
|
|
6414
6414
|
result[key] = value.map(
|
|
6415
6415
|
(item, index) => typeof item === "object" && item != null ? traverse(item, transform, [...currentPath, index.toString()]) : item
|
|
@@ -6437,9 +6437,9 @@ var resolveLocalRef = (schema2, ref) => {
|
|
|
6437
6437
|
if (schemaCache?.has(ref)) {
|
|
6438
6438
|
return schemaCache.get(ref);
|
|
6439
6439
|
}
|
|
6440
|
-
const
|
|
6440
|
+
const path45 = ref.split("/").slice(1);
|
|
6441
6441
|
let current = schema2;
|
|
6442
|
-
for (const segment of
|
|
6442
|
+
for (const segment of path45) {
|
|
6443
6443
|
if (!current || typeof current !== "object") {
|
|
6444
6444
|
current = null;
|
|
6445
6445
|
}
|
|
@@ -6458,7 +6458,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
6458
6458
|
}
|
|
6459
6459
|
const cloned = structuredClone(schema2);
|
|
6460
6460
|
const visited = /* @__PURE__ */ new Set();
|
|
6461
|
-
const resolve = async (current,
|
|
6461
|
+
const resolve = async (current, path45) => {
|
|
6462
6462
|
if (isIndexableObject(current)) {
|
|
6463
6463
|
if (visited.has(current)) {
|
|
6464
6464
|
return CIRCULAR_REF;
|
|
@@ -6466,7 +6466,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
6466
6466
|
visited.add(current);
|
|
6467
6467
|
if (Array.isArray(current)) {
|
|
6468
6468
|
for (let index = 0; index < current.length; index++) {
|
|
6469
|
-
current[index] = await resolve(current[index], `${
|
|
6469
|
+
current[index] = await resolve(current[index], `${path45}/${index}`);
|
|
6470
6470
|
}
|
|
6471
6471
|
} else {
|
|
6472
6472
|
if ("$ref" in current && typeof current.$ref === "string") {
|
|
@@ -6477,13 +6477,13 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
6477
6477
|
for (const resolver of resolvers) {
|
|
6478
6478
|
const resolved = await resolver($ref);
|
|
6479
6479
|
if (resolved) {
|
|
6480
|
-
result2 = await resolve(resolved,
|
|
6480
|
+
result2 = await resolve(resolved, path45);
|
|
6481
6481
|
break;
|
|
6482
6482
|
}
|
|
6483
6483
|
}
|
|
6484
6484
|
if (result2 === void 0) {
|
|
6485
6485
|
const resolved = await resolveLocalRef(cloned, $ref);
|
|
6486
|
-
result2 = await resolve(resolved,
|
|
6486
|
+
result2 = await resolve(resolved, path45);
|
|
6487
6487
|
}
|
|
6488
6488
|
if (hasSiblings) {
|
|
6489
6489
|
if (result2 === CIRCULAR_REF) {
|
|
@@ -6496,7 +6496,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
6496
6496
|
return result2;
|
|
6497
6497
|
}
|
|
6498
6498
|
for (const key in current) {
|
|
6499
|
-
current[key] = await resolve(current[key], `${
|
|
6499
|
+
current[key] = await resolve(current[key], `${path45}/${key}`);
|
|
6500
6500
|
}
|
|
6501
6501
|
}
|
|
6502
6502
|
visited.delete(current);
|
|
@@ -6535,9 +6535,9 @@ var upgradeSchema = (schema2) => {
|
|
|
6535
6535
|
}
|
|
6536
6536
|
return sub;
|
|
6537
6537
|
});
|
|
6538
|
-
schema2 = traverse(schema2, (sub,
|
|
6538
|
+
schema2 = traverse(schema2, (sub, path45) => {
|
|
6539
6539
|
if (sub.example !== void 0) {
|
|
6540
|
-
if (isSchemaPath(
|
|
6540
|
+
if (isSchemaPath(path45 ?? [])) {
|
|
6541
6541
|
sub.examples = [sub.example];
|
|
6542
6542
|
} else {
|
|
6543
6543
|
sub.examples = {
|
|
@@ -6550,11 +6550,11 @@ var upgradeSchema = (schema2) => {
|
|
|
6550
6550
|
}
|
|
6551
6551
|
return sub;
|
|
6552
6552
|
});
|
|
6553
|
-
schema2 = traverse(schema2, (schema3,
|
|
6553
|
+
schema2 = traverse(schema2, (schema3, path45) => {
|
|
6554
6554
|
if (schema3.type === "object" && schema3.properties !== void 0) {
|
|
6555
|
-
const parentPath =
|
|
6555
|
+
const parentPath = path45?.slice(0, -1);
|
|
6556
6556
|
const isMultipart = parentPath?.some((segment, index) => {
|
|
6557
|
-
return segment === "content" &&
|
|
6557
|
+
return segment === "content" && path45?.[index + 1] === "multipart/form-data";
|
|
6558
6558
|
});
|
|
6559
6559
|
if (isMultipart) {
|
|
6560
6560
|
const entries = Object.entries(schema3.properties);
|
|
@@ -6568,8 +6568,8 @@ var upgradeSchema = (schema2) => {
|
|
|
6568
6568
|
}
|
|
6569
6569
|
return schema3;
|
|
6570
6570
|
});
|
|
6571
|
-
schema2 = traverse(schema2, (schema3,
|
|
6572
|
-
if (
|
|
6571
|
+
schema2 = traverse(schema2, (schema3, path45) => {
|
|
6572
|
+
if (path45?.includes("content") && path45.includes("application/octet-stream")) {
|
|
6573
6573
|
return {};
|
|
6574
6574
|
}
|
|
6575
6575
|
if (schema3.type === "string" && schema3.format === "binary") {
|
|
@@ -6595,11 +6595,11 @@ var upgradeSchema = (schema2) => {
|
|
|
6595
6595
|
}
|
|
6596
6596
|
return sub;
|
|
6597
6597
|
});
|
|
6598
|
-
schema2 = traverse(schema2, (schema3,
|
|
6598
|
+
schema2 = traverse(schema2, (schema3, path45) => {
|
|
6599
6599
|
if (schema3.type === "string" && schema3.format === "byte") {
|
|
6600
|
-
const parentPath =
|
|
6600
|
+
const parentPath = path45?.slice(0, -1);
|
|
6601
6601
|
const contentMediaType = parentPath?.find(
|
|
6602
|
-
(_, index) =>
|
|
6602
|
+
(_, index) => path45?.[index - 1] === "content"
|
|
6603
6603
|
);
|
|
6604
6604
|
return {
|
|
6605
6605
|
type: "string",
|
|
@@ -6611,7 +6611,7 @@ var upgradeSchema = (schema2) => {
|
|
|
6611
6611
|
});
|
|
6612
6612
|
return schema2;
|
|
6613
6613
|
};
|
|
6614
|
-
function isSchemaPath(
|
|
6614
|
+
function isSchemaPath(path45) {
|
|
6615
6615
|
const schemaLocations = [
|
|
6616
6616
|
["components", "schemas"],
|
|
6617
6617
|
"properties",
|
|
@@ -6624,10 +6624,10 @@ function isSchemaPath(path43) {
|
|
|
6624
6624
|
];
|
|
6625
6625
|
return schemaLocations.some((location) => {
|
|
6626
6626
|
if (Array.isArray(location)) {
|
|
6627
|
-
return location.every((segment, index) =>
|
|
6627
|
+
return location.every((segment, index) => path45[index] === segment);
|
|
6628
6628
|
}
|
|
6629
|
-
return
|
|
6630
|
-
}) ||
|
|
6629
|
+
return path45.includes(location);
|
|
6630
|
+
}) || path45.includes("schema") || path45.some((segment) => segment.endsWith("Schema"));
|
|
6631
6631
|
}
|
|
6632
6632
|
|
|
6633
6633
|
// src/lib/oas/parser/index.ts
|
|
@@ -6709,13 +6709,13 @@ var OPENAPI_PROPS = /* @__PURE__ */ new Set([
|
|
|
6709
6709
|
"anyOf",
|
|
6710
6710
|
"oneOf"
|
|
6711
6711
|
]);
|
|
6712
|
-
var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(),
|
|
6712
|
+
var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path45 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
|
|
6713
6713
|
if (obj === null || typeof obj !== "object") return obj;
|
|
6714
6714
|
const refPath = obj.__$ref;
|
|
6715
6715
|
const isCircular = currentPath.has(obj) || typeof refPath === "string" && currentRefPaths.has(refPath);
|
|
6716
6716
|
if (isCircular) {
|
|
6717
6717
|
if (typeof refPath === "string") return SCHEMA_REF_PREFIX + refPath;
|
|
6718
|
-
const circularProp =
|
|
6718
|
+
const circularProp = path45.find((p) => !OPENAPI_PROPS.has(p)) || path45[0];
|
|
6719
6719
|
return [CIRCULAR_REF, circularProp].filter(Boolean).join(":");
|
|
6720
6720
|
}
|
|
6721
6721
|
if (refs.has(obj)) return refs.get(obj);
|
|
@@ -6725,7 +6725,7 @@ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs
|
|
|
6725
6725
|
value,
|
|
6726
6726
|
currentPath,
|
|
6727
6727
|
refs,
|
|
6728
|
-
[...
|
|
6728
|
+
[...path45, key],
|
|
6729
6729
|
currentRefPaths
|
|
6730
6730
|
);
|
|
6731
6731
|
const result = Array.isArray(obj) ? obj.map((item, i) => recurse(item, i.toString())) : Object.fromEntries(
|
|
@@ -6760,7 +6760,7 @@ var resolveExtensions = (obj) => Object.fromEntries(
|
|
|
6760
6760
|
var getAllTags = (schema2) => {
|
|
6761
6761
|
const rootTags = schema2.tags ?? [];
|
|
6762
6762
|
const operations = Object.values(schema2.paths ?? {}).flatMap(
|
|
6763
|
-
(
|
|
6763
|
+
(path45) => HttpMethods.map((k) => path45?.[k]).filter((op) => op != null)
|
|
6764
6764
|
);
|
|
6765
6765
|
const operationTags = new Set(operations.flatMap((op) => op.tags ?? []));
|
|
6766
6766
|
const hasUntaggedOperations = operations.some(
|
|
@@ -6815,7 +6815,7 @@ var getAllSlugs = (ops, schemaTags = []) => {
|
|
|
6815
6815
|
var getOperationSlugKey = (op) => [op.path, op.method, op.operationId, op.summary].filter(Boolean).join("-");
|
|
6816
6816
|
var getAllOperations = (paths) => {
|
|
6817
6817
|
const operations = Object.entries(paths ?? {}).flatMap(
|
|
6818
|
-
([
|
|
6818
|
+
([path45, value]) => HttpMethods.flatMap((method) => {
|
|
6819
6819
|
if (!value?.[method]) return [];
|
|
6820
6820
|
const operation = value[method];
|
|
6821
6821
|
const pathParameters = value.parameters ?? [];
|
|
@@ -6835,7 +6835,7 @@ var getAllOperations = (paths) => {
|
|
|
6835
6835
|
return {
|
|
6836
6836
|
...operation,
|
|
6837
6837
|
method,
|
|
6838
|
-
path:
|
|
6838
|
+
path: path45,
|
|
6839
6839
|
parameters,
|
|
6840
6840
|
servers,
|
|
6841
6841
|
tags: operation.tags ?? []
|
|
@@ -7193,8 +7193,8 @@ var Schema = builder.objectRef("Schema").implement({
|
|
|
7193
7193
|
}),
|
|
7194
7194
|
paths: t.field({
|
|
7195
7195
|
type: [PathItem],
|
|
7196
|
-
resolve: (root) => Object.entries(root.paths ?? {}).map(([
|
|
7197
|
-
path:
|
|
7196
|
+
resolve: (root) => Object.entries(root.paths ?? {}).map(([path45, value]) => ({
|
|
7197
|
+
path: path45,
|
|
7198
7198
|
// biome-ignore lint/style/noNonNullAssertion: value is guaranteed to be defined
|
|
7199
7199
|
methods: Object.keys(value)
|
|
7200
7200
|
}))
|
|
@@ -7359,7 +7359,7 @@ init_joinUrl();
|
|
|
7359
7359
|
|
|
7360
7360
|
// src/vite/api/schema-codegen.ts
|
|
7361
7361
|
var unescapeJsonPointer = (uri) => decodeURIComponent(uri.replace(/~1/g, "/").replace(/~0/g, "~"));
|
|
7362
|
-
var getSegmentsFromPath = (
|
|
7362
|
+
var getSegmentsFromPath = (path45) => path45.split("/").slice(1).map(unescapeJsonPointer);
|
|
7363
7363
|
var createLocalRefMap = (obj) => {
|
|
7364
7364
|
const refMap = /* @__PURE__ */ new Map();
|
|
7365
7365
|
const siblingsMap = /* @__PURE__ */ new Map();
|
|
@@ -7390,16 +7390,16 @@ var replaceMarkers = (code, mergedRefs) => code.replace(/"__refMap:(.*?)"/g, '__
|
|
|
7390
7390
|
/"__refMap\+Siblings:(.*?)"/g,
|
|
7391
7391
|
(_, key) => mergedRefs.get(key) ?? `__refMap["${key}"]`
|
|
7392
7392
|
);
|
|
7393
|
-
var lookup = (schema2,
|
|
7394
|
-
const parts = getSegmentsFromPath(
|
|
7393
|
+
var lookup = (schema2, path45, filePath) => {
|
|
7394
|
+
const parts = getSegmentsFromPath(path45);
|
|
7395
7395
|
let val = schema2;
|
|
7396
7396
|
for (const part of parts) {
|
|
7397
7397
|
while (val.$ref?.startsWith("#/")) {
|
|
7398
|
-
val = val.$ref ===
|
|
7398
|
+
val = val.$ref === path45 ? val : lookup(schema2, val.$ref, filePath);
|
|
7399
7399
|
}
|
|
7400
7400
|
if (val[part] === void 0) {
|
|
7401
7401
|
throw new Error(
|
|
7402
|
-
`Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${
|
|
7402
|
+
`Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path45}`
|
|
7403
7403
|
);
|
|
7404
7404
|
}
|
|
7405
7405
|
val = val[part];
|
|
@@ -7644,8 +7644,8 @@ var SchemaManager = class {
|
|
|
7644
7644
|
}
|
|
7645
7645
|
}
|
|
7646
7646
|
};
|
|
7647
|
-
getLatestSchema = (
|
|
7648
|
-
getSchemasForPath = (
|
|
7647
|
+
getLatestSchema = (path45) => this.processedSchemas[path45]?.at(0);
|
|
7648
|
+
getSchemasForPath = (path45) => this.processedSchemas[path45];
|
|
7649
7649
|
getSchemaImports = () => Object.values(this.processedSchemas).flat().filter((s) => s.importKey);
|
|
7650
7650
|
getUrlToFilePathMap = () => {
|
|
7651
7651
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -10046,14 +10046,14 @@ async function generateSitemap({
|
|
|
10046
10046
|
|
|
10047
10047
|
// src/vite/prerender/utils.ts
|
|
10048
10048
|
init_joinUrl();
|
|
10049
|
-
var resolveRoutePath = (
|
|
10050
|
-
const segments =
|
|
10049
|
+
var resolveRoutePath = (path45) => {
|
|
10050
|
+
const segments = path45.split("/");
|
|
10051
10051
|
if (segments.some((s) => s.startsWith(":") && !s.endsWith("?"))) {
|
|
10052
10052
|
return void 0;
|
|
10053
10053
|
}
|
|
10054
10054
|
return segments.filter((s) => !s.startsWith(":")).join("/") || void 0;
|
|
10055
10055
|
};
|
|
10056
|
-
var isSkipped = (
|
|
10056
|
+
var isSkipped = (path45) => path45.includes("*") || /^\d+$/.test(path45);
|
|
10057
10057
|
var resolveRoutes = (routes, parentPath = "") => routes.flatMap((route) => {
|
|
10058
10058
|
if (route.path && isSkipped(route.path)) return [];
|
|
10059
10059
|
const routePath = route.path ? resolveRoutePath(route.path) : void 0;
|
|
@@ -10518,103 +10518,17 @@ var build_default = {
|
|
|
10518
10518
|
|
|
10519
10519
|
// src/cli/make-config/handler.ts
|
|
10520
10520
|
import { constants as constants2 } from "node:fs";
|
|
10521
|
-
import { access as access3, readFile as readFile5, writeFile as writeFile7 } from "node:fs/promises";
|
|
10522
|
-
import
|
|
10521
|
+
import { access as access3, mkdir as mkdir7, readFile as readFile5, writeFile as writeFile7 } from "node:fs/promises";
|
|
10522
|
+
import path36 from "node:path";
|
|
10523
10523
|
import { glob as glob5 } from "glob";
|
|
10524
10524
|
|
|
10525
10525
|
// src/cli/make-config/interactive.ts
|
|
10526
10526
|
import { createInterface } from "node:readline/promises";
|
|
10527
10527
|
import { stdin as input, stdout as output } from "node:process";
|
|
10528
|
-
|
|
10529
|
-
const suffix = defaultValue ? ` [${defaultValue}]` : "";
|
|
10530
|
-
const answer = (await rl.question(`${question}${suffix}: `)).trim();
|
|
10531
|
-
return answer || defaultValue || "";
|
|
10532
|
-
};
|
|
10533
|
-
var askYesNo = async (rl, question, defaultYes) => {
|
|
10534
|
-
const hint = defaultYes ? "Y/n" : "y/N";
|
|
10535
|
-
const answer = (await rl.question(`${question} (${hint}): `)).trim().toLowerCase();
|
|
10536
|
-
if (!answer) {
|
|
10537
|
-
return defaultYes;
|
|
10538
|
-
}
|
|
10539
|
-
return answer === "y" || answer === "yes";
|
|
10540
|
-
};
|
|
10541
|
-
async function promptMakeConfigInteractive(defaults) {
|
|
10542
|
-
const rl = createInterface({ input, output });
|
|
10543
|
-
try {
|
|
10544
|
-
const title = await ask(rl, "Site title", defaults.title);
|
|
10545
|
-
const logoAlt = await ask(rl, "Logo alt text", defaults.logoAlt);
|
|
10546
|
-
const authEnabled = await askYesNo(
|
|
10547
|
-
rl,
|
|
10548
|
-
"Enable authentication",
|
|
10549
|
-
defaults.authEnabled
|
|
10550
|
-
);
|
|
10551
|
-
let apiBaseUrl = defaults.apiBaseUrl ?? "";
|
|
10552
|
-
if (authEnabled) {
|
|
10553
|
-
apiBaseUrl = await ask(
|
|
10554
|
-
rl,
|
|
10555
|
-
"Auth API base URL (optional; secrets stay in .env)",
|
|
10556
|
-
apiBaseUrl
|
|
10557
|
-
);
|
|
10558
|
-
}
|
|
10559
|
-
const sans = await ask(rl, "Sans font", defaults.sans ?? "IBM Plex Sans");
|
|
10560
|
-
const mono = await ask(
|
|
10561
|
-
rl,
|
|
10562
|
-
"Mono font",
|
|
10563
|
-
defaults.mono ?? "JetBrains Mono"
|
|
10564
|
-
);
|
|
10565
|
-
const lightPrimary = await ask(
|
|
10566
|
-
rl,
|
|
10567
|
-
"Light primary color",
|
|
10568
|
-
defaults.lightPrimary ?? "#E11D2A"
|
|
10569
|
-
);
|
|
10570
|
-
const darkPrimary = await ask(
|
|
10571
|
-
rl,
|
|
10572
|
-
"Dark primary color",
|
|
10573
|
-
defaults.darkPrimary ?? "#F23645"
|
|
10574
|
-
);
|
|
10575
|
-
let openApiPath;
|
|
10576
|
-
if (defaults.discoveredOpenApi) {
|
|
10577
|
-
const useDiscovered = await askYesNo(
|
|
10578
|
-
rl,
|
|
10579
|
-
`Wire OpenAPI at ${defaults.discoveredOpenApi}`,
|
|
10580
|
-
true
|
|
10581
|
-
);
|
|
10582
|
-
openApiPath = useDiscovered ? defaults.discoveredOpenApi : null;
|
|
10583
|
-
} else {
|
|
10584
|
-
const entered = await ask(
|
|
10585
|
-
rl,
|
|
10586
|
-
"OpenAPI file path (leave empty to skip)",
|
|
10587
|
-
""
|
|
10588
|
-
);
|
|
10589
|
-
openApiPath = entered || null;
|
|
10590
|
-
}
|
|
10591
|
-
const authentication = {
|
|
10592
|
-
enabled: authEnabled,
|
|
10593
|
-
type: "dev-portal"
|
|
10594
|
-
};
|
|
10595
|
-
if (apiBaseUrl) {
|
|
10596
|
-
authentication.apiBaseUrl = apiBaseUrl;
|
|
10597
|
-
}
|
|
10598
|
-
return {
|
|
10599
|
-
title,
|
|
10600
|
-
site: {
|
|
10601
|
-
title,
|
|
10602
|
-
logo: { alt: logoAlt }
|
|
10603
|
-
},
|
|
10604
|
-
theme: {
|
|
10605
|
-
fonts: { sans, mono },
|
|
10606
|
-
light: { primary: lightPrimary },
|
|
10607
|
-
dark: { primary: darkPrimary }
|
|
10608
|
-
},
|
|
10609
|
-
authentication,
|
|
10610
|
-
openApiPath
|
|
10611
|
-
};
|
|
10612
|
-
} finally {
|
|
10613
|
-
rl.close();
|
|
10614
|
-
}
|
|
10615
|
-
}
|
|
10528
|
+
import path34 from "node:path";
|
|
10616
10529
|
|
|
10617
10530
|
// src/cli/make-config/json-config.ts
|
|
10531
|
+
import path33 from "node:path";
|
|
10618
10532
|
var APITOGO_JSON_FILENAME = "apitogo.config.json";
|
|
10619
10533
|
var DOCUMENTATION_NAV_LABEL = "Documentation";
|
|
10620
10534
|
var API_REFERENCE_PATH = "/api";
|
|
@@ -10665,7 +10579,7 @@ function createDefaultApitogoJsonConfig(options) {
|
|
|
10665
10579
|
}
|
|
10666
10580
|
},
|
|
10667
10581
|
authentication: {
|
|
10668
|
-
enabled:
|
|
10582
|
+
enabled: true,
|
|
10669
10583
|
type: "dev-portal",
|
|
10670
10584
|
redirectToAfterSignIn: "/account/dashboard",
|
|
10671
10585
|
redirectToAfterSignUp: "/account/dashboard"
|
|
@@ -10895,6 +10809,67 @@ function openapiInputForConfig(specRelativePosix) {
|
|
|
10895
10809
|
}
|
|
10896
10810
|
return `./${specRelativePosix}`;
|
|
10897
10811
|
}
|
|
10812
|
+
function toRelativeOpenApiInput(projectDir, inputPath) {
|
|
10813
|
+
const resolved = path33.isAbsolute(inputPath) ? inputPath : path33.resolve(projectDir, inputPath);
|
|
10814
|
+
const relative = path33.relative(projectDir, resolved);
|
|
10815
|
+
const posix = relative.split(path33.sep).join(path33.posix.sep);
|
|
10816
|
+
if (!posix) {
|
|
10817
|
+
throw new Error("OpenAPI path must point to a file.");
|
|
10818
|
+
}
|
|
10819
|
+
return openapiInputForConfig(posix);
|
|
10820
|
+
}
|
|
10821
|
+
function normalizePageSlug(pathOrSlug) {
|
|
10822
|
+
return pathOrSlug.replace(/^\/+/, "").replace(/\/+$/, "").replace(/\.(mdx?|tsx|jsx)$/i, "");
|
|
10823
|
+
}
|
|
10824
|
+
function slugifyPlanSku(displayName) {
|
|
10825
|
+
const sku = displayName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
10826
|
+
return sku || "plan";
|
|
10827
|
+
}
|
|
10828
|
+
function buildLimitsJson(rateLimitCalls, monthlyQuota) {
|
|
10829
|
+
return JSON.stringify({
|
|
10830
|
+
rateLimit: { calls: rateLimitCalls, renewalPeriodSeconds: 60 },
|
|
10831
|
+
quota: { calls: monthlyQuota, renewalPeriodDays: 30 }
|
|
10832
|
+
});
|
|
10833
|
+
}
|
|
10834
|
+
function buildPlanItemFromWizard(input2) {
|
|
10835
|
+
const sku = input2.sku ?? slugifyPlanSku(input2.displayName);
|
|
10836
|
+
const item = {
|
|
10837
|
+
sku,
|
|
10838
|
+
displayName: input2.displayName,
|
|
10839
|
+
priceAmount: input2.priceAmount,
|
|
10840
|
+
limitsJson: buildLimitsJson(input2.rateLimitCalls, input2.monthlyQuota)
|
|
10841
|
+
};
|
|
10842
|
+
if (input2.priceAmount > 0) {
|
|
10843
|
+
item.priceCurrency = "usd";
|
|
10844
|
+
item.billingPeriod = "month";
|
|
10845
|
+
}
|
|
10846
|
+
return item;
|
|
10847
|
+
}
|
|
10848
|
+
function applyPlansToJsonConfig(config2, planItems) {
|
|
10849
|
+
if (planItems.length === 0) {
|
|
10850
|
+
return config2;
|
|
10851
|
+
}
|
|
10852
|
+
const modules = isPlainObject2(config2.modules) ? { ...config2.modules } : {};
|
|
10853
|
+
const userPanel = isPlainObject2(modules.userPanel) ? { ...modules.userPanel } : {};
|
|
10854
|
+
const plans = isPlainObject2(userPanel.plans) ? { ...userPanel.plans } : {};
|
|
10855
|
+
const existing = Array.isArray(plans.items) ? [...plans.items] : [];
|
|
10856
|
+
for (const item of planItems) {
|
|
10857
|
+
const sku = item.sku;
|
|
10858
|
+
const index = typeof sku === "string" ? existing.findIndex((plan) => plan.sku === sku) : -1;
|
|
10859
|
+
if (index >= 0) {
|
|
10860
|
+
existing[index] = { ...existing[index], ...item };
|
|
10861
|
+
} else {
|
|
10862
|
+
existing.push(item);
|
|
10863
|
+
}
|
|
10864
|
+
}
|
|
10865
|
+
userPanel.plans = {
|
|
10866
|
+
...plans,
|
|
10867
|
+
enabled: true,
|
|
10868
|
+
items: existing
|
|
10869
|
+
};
|
|
10870
|
+
modules.userPanel = userPanel;
|
|
10871
|
+
return { ...config2, modules };
|
|
10872
|
+
}
|
|
10898
10873
|
function toRoutePath(relativeFile, pagesDir) {
|
|
10899
10874
|
const relativeNoExt = relativeFile.replace(/\.(mdx?|tsx|jsx)$/i, "");
|
|
10900
10875
|
const escaped = pagesDir.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -10981,11 +10956,238 @@ ${customPages}
|
|
|
10981
10956
|
`;
|
|
10982
10957
|
}
|
|
10983
10958
|
|
|
10959
|
+
// src/cli/make-config/wrap-up.ts
|
|
10960
|
+
var DOCS = "https://docs.apitogo.com";
|
|
10961
|
+
function printPageAddedHint(relativePath, routePath) {
|
|
10962
|
+
printDiagnosticsToConsole(`Page created: ${relativePath} (route ${routePath})`);
|
|
10963
|
+
printDiagnosticsToConsole("Edit that file to change the content.");
|
|
10964
|
+
printDiagnosticsToConsole(
|
|
10965
|
+
`Predefined components: ${DOCS}/docs/guides/custom-pages and ${DOCS}/docs/components/callout`
|
|
10966
|
+
);
|
|
10967
|
+
}
|
|
10968
|
+
function printPlanAddedHint(displayName) {
|
|
10969
|
+
printDiagnosticsToConsole(
|
|
10970
|
+
`Plan "${displayName}" added to modules.userPanel.plans.items in apitogo.config.json.`
|
|
10971
|
+
);
|
|
10972
|
+
printDiagnosticsToConsole(
|
|
10973
|
+
"Configure includedActionKeys, billing, and Stripe in the manifest before publish."
|
|
10974
|
+
);
|
|
10975
|
+
printDiagnosticsToConsole(`Docs: ${DOCS}/docs/configuration/plans`);
|
|
10976
|
+
}
|
|
10977
|
+
function printPaidPlanPlatformWarning() {
|
|
10978
|
+
printDiagnosticsToConsole(
|
|
10979
|
+
"Paid API plans require Starter or Professional platform hosting. Free cannot publish paid gateway plans or custom domains."
|
|
10980
|
+
);
|
|
10981
|
+
}
|
|
10982
|
+
function printInteractiveWrapUp(hasPaidPlans) {
|
|
10983
|
+
printDiagnosticsToConsole("");
|
|
10984
|
+
printDiagnosticsToConsole("Configuration saved. Next steps:");
|
|
10985
|
+
printDiagnosticsToConsole("- Preview locally: npm run dev");
|
|
10986
|
+
printDiagnosticsToConsole(
|
|
10987
|
+
"- Auth API URL is written automatically when you run apitogo apply"
|
|
10988
|
+
);
|
|
10989
|
+
if (hasPaidPlans) {
|
|
10990
|
+
printPaidPlanPlatformWarning();
|
|
10991
|
+
} else {
|
|
10992
|
+
printDiagnosticsToConsole(
|
|
10993
|
+
"Platform note: Free hosting does not support paid API plans or custom domains \u2014 use Starter or Professional for those."
|
|
10994
|
+
);
|
|
10995
|
+
}
|
|
10996
|
+
printDiagnosticsToConsole("");
|
|
10997
|
+
printDiagnosticsToConsole("Configure more:");
|
|
10998
|
+
printDiagnosticsToConsole(`- Overview: ${DOCS}/docs/configuration/overview`);
|
|
10999
|
+
printDiagnosticsToConsole(`- Manifest: ${DOCS}/docs/configuration/manifest`);
|
|
11000
|
+
printDiagnosticsToConsole(`- Gateway plans: ${DOCS}/docs/configuration/plans`);
|
|
11001
|
+
printDiagnosticsToConsole(`- Custom pages: ${DOCS}/docs/guides/custom-pages`);
|
|
11002
|
+
printDiagnosticsToConsole(`- API reference: ${DOCS}/docs/configuration/api-reference`);
|
|
11003
|
+
printDiagnosticsToConsole(`- Theme: ${DOCS}/docs/customization/colors-theme`);
|
|
11004
|
+
printDiagnosticsToConsole(`- Fonts: ${DOCS}/docs/customization/fonts`);
|
|
11005
|
+
printDiagnosticsToConsole(`- CLI shape: ${DOCS}/docs/cli/shape`);
|
|
11006
|
+
printDiagnosticsToConsole(`- apitogo config: ${DOCS}/docs/configuration/make-config`);
|
|
11007
|
+
}
|
|
11008
|
+
|
|
11009
|
+
// src/cli/make-config/interactive.ts
|
|
11010
|
+
var ask = async (rl, question, defaultValue) => {
|
|
11011
|
+
const suffix = defaultValue ? ` [${defaultValue}]` : "";
|
|
11012
|
+
const answer = (await rl.question(`${question}${suffix}: `)).trim();
|
|
11013
|
+
return answer || defaultValue || "";
|
|
11014
|
+
};
|
|
11015
|
+
var askNonNegativeNumber = async (rl, question, defaultValue) => {
|
|
11016
|
+
while (true) {
|
|
11017
|
+
const answer = await ask(rl, question, String(defaultValue));
|
|
11018
|
+
const parsed = Number.parseFloat(answer);
|
|
11019
|
+
if (!Number.isNaN(parsed) && parsed >= 0) {
|
|
11020
|
+
return parsed;
|
|
11021
|
+
}
|
|
11022
|
+
printDiagnosticsToConsole("Enter a non-negative number.");
|
|
11023
|
+
}
|
|
11024
|
+
};
|
|
11025
|
+
var parseLoopChoice = (raw) => {
|
|
11026
|
+
const value = raw.trim().toLowerCase();
|
|
11027
|
+
if (!value || value === "done") {
|
|
11028
|
+
return "done";
|
|
11029
|
+
}
|
|
11030
|
+
if (value === "openapi" || value === "page" || value === "plan") {
|
|
11031
|
+
return value;
|
|
11032
|
+
}
|
|
11033
|
+
return null;
|
|
11034
|
+
};
|
|
11035
|
+
async function promptMakeConfigInteractive(defaults) {
|
|
11036
|
+
const rl = createInterface({ input, output });
|
|
11037
|
+
const customPages = [];
|
|
11038
|
+
const planItems = [];
|
|
11039
|
+
let hasPaidPlans = false;
|
|
11040
|
+
let openApiPath;
|
|
11041
|
+
try {
|
|
11042
|
+
const title = await ask(rl, "Site title", defaults.title);
|
|
11043
|
+
while (true) {
|
|
11044
|
+
const choiceRaw = await ask(
|
|
11045
|
+
rl,
|
|
11046
|
+
"Add OpenAPI, a custom page, or a plan? (openapi / page / plan / done)",
|
|
11047
|
+
"done"
|
|
11048
|
+
);
|
|
11049
|
+
const choice = parseLoopChoice(choiceRaw);
|
|
11050
|
+
if (!choice) {
|
|
11051
|
+
printDiagnosticsToConsole("Choose openapi, page, plan, or done.");
|
|
11052
|
+
continue;
|
|
11053
|
+
}
|
|
11054
|
+
if (choice === "done") {
|
|
11055
|
+
break;
|
|
11056
|
+
}
|
|
11057
|
+
if (choice === "openapi") {
|
|
11058
|
+
const entered = await ask(
|
|
11059
|
+
rl,
|
|
11060
|
+
"OpenAPI file path (leave empty to skip)",
|
|
11061
|
+
defaults.discoveredOpenApi ?? ""
|
|
11062
|
+
);
|
|
11063
|
+
openApiPath = entered ? entered : null;
|
|
11064
|
+
if (openApiPath) {
|
|
11065
|
+
printDiagnosticsToConsole(
|
|
11066
|
+
`OpenAPI will be linked as a relative path in apitogo.config.json.`
|
|
11067
|
+
);
|
|
11068
|
+
}
|
|
11069
|
+
continue;
|
|
11070
|
+
}
|
|
11071
|
+
if (choice === "page") {
|
|
11072
|
+
const pageTitle = await ask(rl, "Page title");
|
|
11073
|
+
if (!pageTitle.trim()) {
|
|
11074
|
+
printDiagnosticsToConsole("Page title is required.");
|
|
11075
|
+
continue;
|
|
11076
|
+
}
|
|
11077
|
+
const address = await ask(
|
|
11078
|
+
rl,
|
|
11079
|
+
"Page URL path (e.g. /guides/getting-started)"
|
|
11080
|
+
);
|
|
11081
|
+
const slug = normalizePageSlug(address);
|
|
11082
|
+
if (!slug) {
|
|
11083
|
+
printDiagnosticsToConsole("Page URL path is required.");
|
|
11084
|
+
continue;
|
|
11085
|
+
}
|
|
11086
|
+
const routePath = `/${slug}`;
|
|
11087
|
+
const relativePath = path34.posix.join(defaults.pagesDir, `${slug}.tsx`);
|
|
11088
|
+
const page = {
|
|
11089
|
+
slug,
|
|
11090
|
+
title: pageTitle.trim(),
|
|
11091
|
+
routePath,
|
|
11092
|
+
relativePath
|
|
11093
|
+
};
|
|
11094
|
+
customPages.push(page);
|
|
11095
|
+
printPageAddedHint(relativePath, routePath);
|
|
11096
|
+
continue;
|
|
11097
|
+
}
|
|
11098
|
+
const displayName = await ask(rl, "Plan title");
|
|
11099
|
+
if (!displayName.trim()) {
|
|
11100
|
+
printDiagnosticsToConsole("Plan title is required.");
|
|
11101
|
+
continue;
|
|
11102
|
+
}
|
|
11103
|
+
const priceAmount = await askNonNegativeNumber(
|
|
11104
|
+
rl,
|
|
11105
|
+
"Price (USD/month, 0 for free)",
|
|
11106
|
+
0
|
|
11107
|
+
);
|
|
11108
|
+
const rateLimitCalls = await askNonNegativeNumber(
|
|
11109
|
+
rl,
|
|
11110
|
+
"Rate limit (calls per minute)",
|
|
11111
|
+
100
|
|
11112
|
+
);
|
|
11113
|
+
const monthlyQuota = await askNonNegativeNumber(
|
|
11114
|
+
rl,
|
|
11115
|
+
"Monthly quota (calls per 30 days)",
|
|
11116
|
+
5e4
|
|
11117
|
+
);
|
|
11118
|
+
const planItem = buildPlanItemFromWizard({
|
|
11119
|
+
displayName: displayName.trim(),
|
|
11120
|
+
priceAmount,
|
|
11121
|
+
rateLimitCalls,
|
|
11122
|
+
monthlyQuota
|
|
11123
|
+
});
|
|
11124
|
+
planItems.push(planItem);
|
|
11125
|
+
if (priceAmount > 0) {
|
|
11126
|
+
hasPaidPlans = true;
|
|
11127
|
+
printPaidPlanPlatformWarning();
|
|
11128
|
+
}
|
|
11129
|
+
printPlanAddedHint(displayName.trim());
|
|
11130
|
+
}
|
|
11131
|
+
return {
|
|
11132
|
+
title,
|
|
11133
|
+
site: { title },
|
|
11134
|
+
authentication: {
|
|
11135
|
+
enabled: true,
|
|
11136
|
+
type: "dev-portal"
|
|
11137
|
+
},
|
|
11138
|
+
openApiPath,
|
|
11139
|
+
customPages,
|
|
11140
|
+
planItems,
|
|
11141
|
+
hasPaidPlans
|
|
11142
|
+
};
|
|
11143
|
+
} finally {
|
|
11144
|
+
rl.close();
|
|
11145
|
+
}
|
|
11146
|
+
}
|
|
11147
|
+
|
|
11148
|
+
// src/cli/make-config/page-scaffold.ts
|
|
11149
|
+
function buildStarterDocsPageTsx(slug, title) {
|
|
11150
|
+
const componentName = pageComponentName(slug);
|
|
11151
|
+
const safeTitle = title.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
11152
|
+
return `import { Callout, Heading, Typography } from "@lukoweb/apitogo/components";
|
|
11153
|
+
|
|
11154
|
+
export default function ${componentName}() {
|
|
11155
|
+
return (
|
|
11156
|
+
<section className="mx-auto max-w-screen-xl px-4 py-12 pt-(--padding-content-top)">
|
|
11157
|
+
<Typography>
|
|
11158
|
+
<Heading level={1}>${safeTitle}</Heading>
|
|
11159
|
+
<p className="mt-4 text-muted-foreground">
|
|
11160
|
+
Edit this page in <code>pages/${slug}.tsx</code>.
|
|
11161
|
+
</p>
|
|
11162
|
+
<Callout type="info" title="Components">
|
|
11163
|
+
APIToGo ships predefined UI components for docs pages. See{" "}
|
|
11164
|
+
<a
|
|
11165
|
+
href="https://docs.apitogo.com/docs/guides/custom-pages"
|
|
11166
|
+
className="text-primary underline"
|
|
11167
|
+
>
|
|
11168
|
+
custom pages
|
|
11169
|
+
</a>{" "}
|
|
11170
|
+
and the{" "}
|
|
11171
|
+
<a
|
|
11172
|
+
href="https://docs.apitogo.com/docs/components/callout"
|
|
11173
|
+
className="text-primary underline"
|
|
11174
|
+
>
|
|
11175
|
+
component catalog
|
|
11176
|
+
</a>
|
|
11177
|
+
.
|
|
11178
|
+
</Callout>
|
|
11179
|
+
</Typography>
|
|
11180
|
+
</section>
|
|
11181
|
+
);
|
|
11182
|
+
}
|
|
11183
|
+
`;
|
|
11184
|
+
}
|
|
11185
|
+
|
|
10984
11186
|
// src/cli/make-config/scaffold-project.ts
|
|
10985
11187
|
init_package_json();
|
|
10986
11188
|
import { constants } from "node:fs";
|
|
10987
11189
|
import { access as access2, mkdir as mkdir6, readFile as readFile4, writeFile as writeFile6 } from "node:fs/promises";
|
|
10988
|
-
import
|
|
11190
|
+
import path35 from "node:path";
|
|
10989
11191
|
import { glob as glob4 } from "glob";
|
|
10990
11192
|
var OPENAPI_GLOBS = [
|
|
10991
11193
|
"apis/openapi.json",
|
|
@@ -10995,9 +11197,9 @@ var OPENAPI_GLOBS = [
|
|
|
10995
11197
|
"openapi.yaml",
|
|
10996
11198
|
"openapi.yml"
|
|
10997
11199
|
];
|
|
10998
|
-
var toPosix = (p) => p.split(
|
|
11200
|
+
var toPosix = (p) => p.split(path35.sep).join("/");
|
|
10999
11201
|
var sanitizePackageName = (dir) => {
|
|
11000
|
-
const base =
|
|
11202
|
+
const base = path35.basename(path35.resolve(dir));
|
|
11001
11203
|
const s = base.toLowerCase().replace(/[^a-z0-9-_.]/g, "-").replace(/^-+|-+$/g, "");
|
|
11002
11204
|
return s || "apitogo-site";
|
|
11003
11205
|
};
|
|
@@ -11007,7 +11209,7 @@ var apitogoVersionRange = () => {
|
|
|
11007
11209
|
};
|
|
11008
11210
|
async function findOpenApiSpecPath(dir) {
|
|
11009
11211
|
for (const rel of OPENAPI_GLOBS) {
|
|
11010
|
-
const full =
|
|
11212
|
+
const full = path35.join(dir, rel);
|
|
11011
11213
|
try {
|
|
11012
11214
|
await access2(full, constants.R_OK);
|
|
11013
11215
|
return toPosix(rel);
|
|
@@ -11022,7 +11224,7 @@ async function findOpenApiSpecPath(dir) {
|
|
|
11022
11224
|
return extra[0] ? toPosix(extra[0]) : null;
|
|
11023
11225
|
}
|
|
11024
11226
|
async function ensurePackageJson(dir) {
|
|
11025
|
-
const pkgPath =
|
|
11227
|
+
const pkgPath = path35.join(dir, "package.json");
|
|
11026
11228
|
const apitogoVer = apitogoVersionRange();
|
|
11027
11229
|
const baseDeps = {
|
|
11028
11230
|
react: ">=19.0.0",
|
|
@@ -11089,7 +11291,7 @@ async function ensurePackageJson(dir) {
|
|
|
11089
11291
|
return false;
|
|
11090
11292
|
}
|
|
11091
11293
|
async function ensureTsconfigJson(dir) {
|
|
11092
|
-
const tsPath =
|
|
11294
|
+
const tsPath = path35.join(dir, "tsconfig.json");
|
|
11093
11295
|
try {
|
|
11094
11296
|
await access2(tsPath, constants.R_OK);
|
|
11095
11297
|
return false;
|
|
@@ -11179,19 +11381,19 @@ var fileExists2 = async (filePath) => {
|
|
|
11179
11381
|
}
|
|
11180
11382
|
};
|
|
11181
11383
|
async function ensurePortalStubFiles(dir) {
|
|
11182
|
-
const landingPath =
|
|
11384
|
+
const landingPath = path35.join(dir, "landing", "LandingPage.tsx");
|
|
11183
11385
|
if (!await fileExists2(landingPath)) {
|
|
11184
|
-
await mkdir6(
|
|
11386
|
+
await mkdir6(path35.join(dir, "landing"), { recursive: true });
|
|
11185
11387
|
await writeFile6(landingPath, LANDING_PAGE_SOURCE, "utf8");
|
|
11186
11388
|
}
|
|
11187
|
-
const plansPath =
|
|
11389
|
+
const plansPath = path35.join(dir, "user-panel", "AccountPlansPage.tsx");
|
|
11188
11390
|
if (!await fileExists2(plansPath)) {
|
|
11189
|
-
await mkdir6(
|
|
11391
|
+
await mkdir6(path35.join(dir, "user-panel"), { recursive: true });
|
|
11190
11392
|
await writeFile6(plansPath, ACCOUNT_PLANS_PAGE_SOURCE, "utf8");
|
|
11191
11393
|
}
|
|
11192
11394
|
}
|
|
11193
11395
|
async function ensureThinConfigTsx(dir) {
|
|
11194
|
-
const tsxPath =
|
|
11396
|
+
const tsxPath = path35.join(dir, "apitogo.config.tsx");
|
|
11195
11397
|
if (await fileExists2(tsxPath)) {
|
|
11196
11398
|
return false;
|
|
11197
11399
|
}
|
|
@@ -11200,7 +11402,7 @@ async function ensureThinConfigTsx(dir) {
|
|
|
11200
11402
|
}
|
|
11201
11403
|
|
|
11202
11404
|
// src/cli/make-config/handler.ts
|
|
11203
|
-
var toPosixPath2 = (value) => value.split(
|
|
11405
|
+
var toPosixPath2 = (value) => value.split(path36.sep).join(path36.posix.sep);
|
|
11204
11406
|
var fileExists3 = async (filePath) => {
|
|
11205
11407
|
try {
|
|
11206
11408
|
await access3(filePath, constants2.F_OK);
|
|
@@ -11218,7 +11420,7 @@ var readJsonConfig = async (filePath) => {
|
|
|
11218
11420
|
return parsed;
|
|
11219
11421
|
};
|
|
11220
11422
|
async function makeConfig(argv) {
|
|
11221
|
-
const dir =
|
|
11423
|
+
const dir = path36.resolve(process.cwd(), argv.dir);
|
|
11222
11424
|
const pagesDir = toPosixPath2(
|
|
11223
11425
|
argv.pagesDir.replace(/^[./]+/, "").replace(/\/+$/, "")
|
|
11224
11426
|
);
|
|
@@ -11235,14 +11437,14 @@ async function makeConfig(argv) {
|
|
|
11235
11437
|
printDiagnosticsToConsole("Created tsconfig.json.");
|
|
11236
11438
|
}
|
|
11237
11439
|
await ensurePortalStubFiles(dir);
|
|
11238
|
-
const jsonPath =
|
|
11440
|
+
const jsonPath = path36.join(dir, APITOGO_JSON_FILENAME);
|
|
11239
11441
|
let createdJson = false;
|
|
11240
11442
|
let config2;
|
|
11241
11443
|
if (await fileExists3(jsonPath)) {
|
|
11242
11444
|
config2 = await readJsonConfig(jsonPath);
|
|
11243
11445
|
} else {
|
|
11244
11446
|
config2 = createDefaultApitogoJsonConfig({
|
|
11245
|
-
title: titleFromDirectoryName(
|
|
11447
|
+
title: titleFromDirectoryName(path36.basename(dir)),
|
|
11246
11448
|
pagesDir
|
|
11247
11449
|
});
|
|
11248
11450
|
createdJson = true;
|
|
@@ -11259,27 +11461,27 @@ async function makeConfig(argv) {
|
|
|
11259
11461
|
title: argv.title
|
|
11260
11462
|
};
|
|
11261
11463
|
let openApiOverride;
|
|
11464
|
+
let interactiveHasPaidPlans = false;
|
|
11262
11465
|
if (argv.interactive) {
|
|
11263
11466
|
const site = isPlainObject2(config2.site) ? config2.site : {};
|
|
11264
|
-
const logo = isPlainObject2(site.logo) ? site.logo : {};
|
|
11265
|
-
const theme = isPlainObject2(config2.theme) ? config2.theme : {};
|
|
11266
|
-
const fonts = isPlainObject2(theme.fonts) ? theme.fonts : {};
|
|
11267
|
-
const light = isPlainObject2(theme.light) ? theme.light : {};
|
|
11268
|
-
const dark = isPlainObject2(theme.dark) ? theme.dark : {};
|
|
11269
|
-
const authentication = isPlainObject2(config2.authentication) ? config2.authentication : {};
|
|
11270
11467
|
const prompted = await promptMakeConfigInteractive({
|
|
11271
|
-
title: flagPatches.title ?? (typeof site.title === "string" ? site.title : titleFromDirectoryName(
|
|
11272
|
-
|
|
11273
|
-
|
|
11274
|
-
apiBaseUrl: typeof authentication.apiBaseUrl === "string" ? authentication.apiBaseUrl : void 0,
|
|
11275
|
-
sans: typeof fonts.sans === "string" ? fonts.sans : void 0,
|
|
11276
|
-
mono: typeof fonts.mono === "string" ? fonts.mono : void 0,
|
|
11277
|
-
lightPrimary: typeof light.primary === "string" ? light.primary : void 0,
|
|
11278
|
-
darkPrimary: typeof dark.primary === "string" ? dark.primary : void 0,
|
|
11279
|
-
discoveredOpenApi
|
|
11468
|
+
title: flagPatches.title ?? (typeof site.title === "string" ? site.title : titleFromDirectoryName(path36.basename(dir))),
|
|
11469
|
+
discoveredOpenApi,
|
|
11470
|
+
pagesDir
|
|
11280
11471
|
});
|
|
11281
11472
|
openApiOverride = prompted.openApiPath;
|
|
11473
|
+
interactiveHasPaidPlans = prompted.hasPaidPlans;
|
|
11282
11474
|
config2 = applyConfigPatches(config2, prompted);
|
|
11475
|
+
config2 = applyPlansToJsonConfig(config2, prompted.planItems);
|
|
11476
|
+
for (const page of prompted.customPages) {
|
|
11477
|
+
const pagePath = path36.join(dir, page.relativePath);
|
|
11478
|
+
await mkdir7(path36.dirname(pagePath), { recursive: true });
|
|
11479
|
+
await writeFile7(
|
|
11480
|
+
pagePath,
|
|
11481
|
+
buildStarterDocsPageTsx(page.slug, page.title),
|
|
11482
|
+
"utf8"
|
|
11483
|
+
);
|
|
11484
|
+
}
|
|
11283
11485
|
}
|
|
11284
11486
|
config2 = applyConfigPatches(config2, flagPatches);
|
|
11285
11487
|
const pageFiles = await glob5(`${pagesDir}/**/*.{md,mdx,tsx,jsx}`, {
|
|
@@ -11305,14 +11507,12 @@ async function makeConfig(argv) {
|
|
|
11305
11507
|
);
|
|
11306
11508
|
const openApiRel = openApiOverride === void 0 ? discoveredOpenApi : openApiOverride;
|
|
11307
11509
|
if (openApiRel) {
|
|
11308
|
-
|
|
11309
|
-
|
|
11310
|
-
openapiInputForConfig(openApiRel)
|
|
11311
|
-
);
|
|
11510
|
+
const openApiInput = argv.interactive ? toRelativeOpenApiInput(dir, openApiRel) : openapiInputForConfig(openApiRel);
|
|
11511
|
+
config2 = applyOpenApiToJsonConfig(config2, openApiInput);
|
|
11312
11512
|
}
|
|
11313
11513
|
await writeFile7(jsonPath, `${JSON.stringify(config2, null, 2)}
|
|
11314
11514
|
`, "utf8");
|
|
11315
|
-
const tsxPath =
|
|
11515
|
+
const tsxPath = path36.join(dir, "apitogo.config.tsx");
|
|
11316
11516
|
if (await fileExists3(tsxPath) && tsxRoutes.length > 0) {
|
|
11317
11517
|
const tsxSource = await readFile5(tsxPath, "utf8");
|
|
11318
11518
|
if (isThinConfigWrapper(tsxSource)) {
|
|
@@ -11325,13 +11525,16 @@ async function makeConfig(argv) {
|
|
|
11325
11525
|
}
|
|
11326
11526
|
const action = createdJson ? "Initialized" : "Updated";
|
|
11327
11527
|
printResultToConsole(
|
|
11328
|
-
`${action} ${APITOGO_JSON_FILENAME} (site/
|
|
11528
|
+
`${action} ${APITOGO_JSON_FILENAME} (site/auth/navigation/OpenAPI/plans as applicable; redirects unchanged).`
|
|
11329
11529
|
);
|
|
11330
11530
|
if (createdPackageJson) {
|
|
11331
11531
|
printDiagnosticsToConsole(
|
|
11332
11532
|
"Next: run npm install (or pnpm install / yarn) in this directory, then npm run dev."
|
|
11333
11533
|
);
|
|
11334
11534
|
}
|
|
11535
|
+
if (argv.interactive) {
|
|
11536
|
+
printInteractiveWrapUp(interactiveHasPaidPlans);
|
|
11537
|
+
}
|
|
11335
11538
|
} catch (error) {
|
|
11336
11539
|
await printCriticalFailureToConsoleAndExit(
|
|
11337
11540
|
error instanceof Error ? error.message : String(error)
|
|
@@ -11357,7 +11560,7 @@ var config_default = {
|
|
|
11357
11560
|
}).option("interactive", {
|
|
11358
11561
|
alias: "i",
|
|
11359
11562
|
type: "boolean",
|
|
11360
|
-
describe: "
|
|
11563
|
+
describe: "Interactive wizard: site title, OpenAPI path, custom pages, and gateway plans",
|
|
11361
11564
|
default: false
|
|
11362
11565
|
}).option("site", {
|
|
11363
11566
|
type: "string",
|
|
@@ -11411,14 +11614,14 @@ var deploy_default = {
|
|
|
11411
11614
|
|
|
11412
11615
|
// src/cli/dev/handler.ts
|
|
11413
11616
|
init_joinUrl();
|
|
11414
|
-
import
|
|
11617
|
+
import path39 from "node:path";
|
|
11415
11618
|
|
|
11416
11619
|
// src/vite/dev-server.ts
|
|
11417
11620
|
init_logger();
|
|
11418
11621
|
import fs4 from "node:fs/promises";
|
|
11419
11622
|
import http from "node:http";
|
|
11420
11623
|
import https from "node:https";
|
|
11421
|
-
import
|
|
11624
|
+
import path38 from "node:path";
|
|
11422
11625
|
import { createHttpTerminator } from "http-terminator";
|
|
11423
11626
|
import {
|
|
11424
11627
|
createServer as createViteServer,
|
|
@@ -11451,7 +11654,7 @@ init_loader();
|
|
|
11451
11654
|
// src/vite/pagefind-dev-index.ts
|
|
11452
11655
|
init_invariant();
|
|
11453
11656
|
init_joinUrl();
|
|
11454
|
-
import
|
|
11657
|
+
import path37 from "node:path";
|
|
11455
11658
|
import { createIndex as createIndex2 } from "pagefind";
|
|
11456
11659
|
import { isRunnableDevEnvironment } from "vite";
|
|
11457
11660
|
async function* buildPagefindDevIndex(vite, config2) {
|
|
@@ -11504,7 +11707,7 @@ async function* buildPagefindDevIndex(vite, config2) {
|
|
|
11504
11707
|
path: urlPath
|
|
11505
11708
|
};
|
|
11506
11709
|
}
|
|
11507
|
-
const outputPath =
|
|
11710
|
+
const outputPath = path37.join(vite.config.publicDir, "pagefind");
|
|
11508
11711
|
await pagefindIndex.writeFiles({ outputPath });
|
|
11509
11712
|
yield { type: "complete", success: true, indexed };
|
|
11510
11713
|
}
|
|
@@ -11523,9 +11726,9 @@ var DevServer = class {
|
|
|
11523
11726
|
this.protocol = "https";
|
|
11524
11727
|
const { dir } = this.options;
|
|
11525
11728
|
const [key, cert, ca] = await Promise.all([
|
|
11526
|
-
fs4.readFile(
|
|
11527
|
-
fs4.readFile(
|
|
11528
|
-
config2.https.ca ? fs4.readFile(
|
|
11729
|
+
fs4.readFile(path38.resolve(dir, config2.https.key)),
|
|
11730
|
+
fs4.readFile(path38.resolve(dir, config2.https.cert)),
|
|
11731
|
+
config2.https.ca ? fs4.readFile(path38.resolve(dir, config2.https.ca)) : void 0
|
|
11529
11732
|
]);
|
|
11530
11733
|
return https.createServer({ key, cert, ca });
|
|
11531
11734
|
}
|
|
@@ -11542,7 +11745,7 @@ var DevServer = class {
|
|
|
11542
11745
|
);
|
|
11543
11746
|
const server = await this.createNodeServer(config2);
|
|
11544
11747
|
if (config2.search?.type === "pagefind" && viteConfig.publicDir !== false) {
|
|
11545
|
-
const publicRoot =
|
|
11748
|
+
const publicRoot = path38.resolve(
|
|
11546
11749
|
this.options.dir,
|
|
11547
11750
|
typeof viteConfig.publicDir === "string" ? viteConfig.publicDir : "public"
|
|
11548
11751
|
);
|
|
@@ -11559,7 +11762,7 @@ var DevServer = class {
|
|
|
11559
11762
|
// built-in transform middleware which would treat the path as a static asset.
|
|
11560
11763
|
name: "apitogo:entry-client",
|
|
11561
11764
|
configureServer(server2) {
|
|
11562
|
-
const entryPath =
|
|
11765
|
+
const entryPath = path38.posix.join(
|
|
11563
11766
|
server2.config.base,
|
|
11564
11767
|
"/__z/entry.client.tsx"
|
|
11565
11768
|
);
|
|
@@ -11724,7 +11927,7 @@ init_package_json();
|
|
|
11724
11927
|
async function dev(argv) {
|
|
11725
11928
|
const packageJson2 = getZudokuPackageJson();
|
|
11726
11929
|
process.env.NODE_ENV = "development";
|
|
11727
|
-
const dir =
|
|
11930
|
+
const dir = path39.resolve(process.cwd(), argv.dir);
|
|
11728
11931
|
const server = new DevServer({
|
|
11729
11932
|
dir,
|
|
11730
11933
|
argPort: argv.port,
|
|
@@ -11807,9 +12010,9 @@ var dev_default = {
|
|
|
11807
12010
|
};
|
|
11808
12011
|
|
|
11809
12012
|
// src/cli/init/handler.ts
|
|
11810
|
-
import
|
|
12013
|
+
import path40 from "node:path";
|
|
11811
12014
|
async function init2(argv) {
|
|
11812
|
-
const dir =
|
|
12015
|
+
const dir = path40.resolve(process.cwd(), argv.dir ?? ".");
|
|
11813
12016
|
try {
|
|
11814
12017
|
const createdPackageJson = await ensurePackageJson(dir);
|
|
11815
12018
|
const createdTsconfig = await ensureTsconfigJson(dir);
|
|
@@ -11881,12 +12084,12 @@ var remove_default = {
|
|
|
11881
12084
|
};
|
|
11882
12085
|
|
|
11883
12086
|
// src/cli/status/handler.ts
|
|
11884
|
-
import
|
|
12087
|
+
import path42 from "node:path";
|
|
11885
12088
|
|
|
11886
12089
|
// src/cli/common/mcp-cli.ts
|
|
11887
12090
|
import { access as access4 } from "node:fs/promises";
|
|
11888
12091
|
import { spawn as spawn2 } from "node:child_process";
|
|
11889
|
-
import
|
|
12092
|
+
import path41 from "node:path";
|
|
11890
12093
|
async function pathExists2(candidate) {
|
|
11891
12094
|
try {
|
|
11892
12095
|
await access4(candidate);
|
|
@@ -11899,7 +12102,7 @@ async function resolveApitogoMcpCliCommand(binary) {
|
|
|
11899
12102
|
const binName = `apitogo-${binary}`;
|
|
11900
12103
|
const mcpPath = process.env.APITOGO_MCP_PATH?.trim();
|
|
11901
12104
|
if (mcpPath) {
|
|
11902
|
-
const scriptJs =
|
|
12105
|
+
const scriptJs = path41.join(mcpPath, "dist", "cli", `${binary}.js`);
|
|
11903
12106
|
if (await pathExists2(scriptJs)) {
|
|
11904
12107
|
return {
|
|
11905
12108
|
command: process.execPath,
|
|
@@ -11957,7 +12160,7 @@ async function runApitogoMcpCli(binary, childArgs, options = {}) {
|
|
|
11957
12160
|
|
|
11958
12161
|
// src/cli/status/handler.ts
|
|
11959
12162
|
async function status(argv) {
|
|
11960
|
-
const dir =
|
|
12163
|
+
const dir = path42.resolve(process.cwd(), argv.dir);
|
|
11961
12164
|
const args = [dir];
|
|
11962
12165
|
if (argv.projectId?.trim()) {
|
|
11963
12166
|
args.push("--project-id", argv.projectId.trim());
|
|
@@ -11999,7 +12202,7 @@ var status_default = {
|
|
|
11999
12202
|
};
|
|
12000
12203
|
|
|
12001
12204
|
// src/cli/teardown/handler.ts
|
|
12002
|
-
import
|
|
12205
|
+
import path43 from "node:path";
|
|
12003
12206
|
async function teardown(argv) {
|
|
12004
12207
|
if (!argv.yes) {
|
|
12005
12208
|
await printCriticalFailureToConsoleAndExit(
|
|
@@ -12007,7 +12210,7 @@ async function teardown(argv) {
|
|
|
12007
12210
|
);
|
|
12008
12211
|
return;
|
|
12009
12212
|
}
|
|
12010
|
-
const dir =
|
|
12213
|
+
const dir = path43.resolve(process.cwd(), argv.dir);
|
|
12011
12214
|
const args = [dir, "--yes"];
|
|
12012
12215
|
if (argv.projectId?.trim()) {
|
|
12013
12216
|
args.push("--project-id", argv.projectId.trim());
|
|
@@ -12122,12 +12325,12 @@ function box(message, {
|
|
|
12122
12325
|
|
|
12123
12326
|
// src/cli/common/xdg/lib.ts
|
|
12124
12327
|
import { homedir } from "node:os";
|
|
12125
|
-
import
|
|
12328
|
+
import path44 from "node:path";
|
|
12126
12329
|
function defineDirectoryWithFallback(xdgName, fallback) {
|
|
12127
12330
|
if (process.env[xdgName]) {
|
|
12128
12331
|
return process.env[xdgName];
|
|
12129
12332
|
} else {
|
|
12130
|
-
return
|
|
12333
|
+
return path44.join(homedir(), fallback);
|
|
12131
12334
|
}
|
|
12132
12335
|
}
|
|
12133
12336
|
var XDG_CONFIG_HOME = defineDirectoryWithFallback(
|
|
@@ -12142,15 +12345,15 @@ var XDG_STATE_HOME = defineDirectoryWithFallback(
|
|
|
12142
12345
|
"XDG_DATA_HOME",
|
|
12143
12346
|
".local/state"
|
|
12144
12347
|
);
|
|
12145
|
-
var ZUDOKU_XDG_CONFIG_HOME =
|
|
12348
|
+
var ZUDOKU_XDG_CONFIG_HOME = path44.join(
|
|
12146
12349
|
XDG_CONFIG_HOME,
|
|
12147
12350
|
CLI_XDG_FOLDER_NAME
|
|
12148
12351
|
);
|
|
12149
|
-
var ZUDOKU_XDG_DATA_HOME =
|
|
12352
|
+
var ZUDOKU_XDG_DATA_HOME = path44.join(
|
|
12150
12353
|
XDG_DATA_HOME,
|
|
12151
12354
|
CLI_XDG_FOLDER_NAME
|
|
12152
12355
|
);
|
|
12153
|
-
var ZUDOKU_XDG_STATE_HOME =
|
|
12356
|
+
var ZUDOKU_XDG_STATE_HOME = path44.join(
|
|
12154
12357
|
XDG_STATE_HOME,
|
|
12155
12358
|
CLI_XDG_FOLDER_NAME
|
|
12156
12359
|
);
|