@lukoweb/apitogo 0.2.59 → 0.2.61
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 +897 -527
- package/docs/cli/commands.md +6 -6
- package/docs/cli/go-live.md +12 -12
- package/docs/cli/overview.md +26 -27
- package/docs/cli/setup.md +38 -46
- package/docs/cli/shape.md +32 -35
- package/docs/cli/walkthrough.md +19 -19
- package/docs/components/slot.mdx +116 -116
- package/docs/configuration/api-reference.md +1 -1
- package/docs/configuration/authentication.md +3 -3
- package/docs/configuration/footer.mdx +89 -89
- package/docs/configuration/gateway.md +8 -8
- package/docs/configuration/make-config.mdx +20 -10
- package/docs/configuration/overview.md +3 -3
- package/docs/configuration/plans.md +5 -5
- package/docs/configuration/portal.md +36 -0
- package/docs/customization/colors-theme.mdx +255 -255
- package/docs/customization/fonts.md +105 -105
- package/docs/customization/landing-page.md +1 -1
- package/docs/deploy/apitogo.md +3 -3
- package/docs/deployment.md +3 -3
- package/docs/guides/custom-pages.md +3 -3
- package/docs/guides/customer-account.md +1 -1
- package/docs/guides/stripe-setup.mdx +9 -9
- package/docs/markdown/frontmatter.md +2 -2
- package/docs/mcp/go-live.md +7 -7
- package/docs/mcp/overview.md +58 -58
- package/docs/mcp/setup.md +6 -6
- package/docs/mcp/shape.md +2 -2
- package/docs/mcp/tools.md +57 -57
- package/docs/quickstart.md +6 -4
- package/docs/writing.mdx +68 -68
- package/package.json +1 -1
- package/src/config/apitogo-config-core.ts +11 -1
- package/src/config/v2/resolve.ts +19 -0
- package/src/config/v2/rules.ts +88 -0
- package/src/config/v2/schema.ts +28 -0
- package/src/config/v2/wrapper.ts +85 -13
- package/src/vite/config.ts +278 -273
- package/src/vite/markdown-output-path.ts +48 -0
- package/src/vite/plugin-markdown-export.ts +210 -214
- package/src/vite/prerender/prerender.ts +4 -4
- package/src/vite/watch-ignore.ts +19 -0
package/dist/cli/cli.js
CHANGED
|
@@ -457,8 +457,12 @@ function syncAuthentication(normalized) {
|
|
|
457
457
|
if (!userPanelEnabled && !authentication) {
|
|
458
458
|
return;
|
|
459
459
|
}
|
|
460
|
+
if (!userPanelEnabled && authentication?.enabled === false) {
|
|
461
|
+
delete normalized.authentication;
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
460
464
|
const auth = authentication ?? {};
|
|
461
|
-
auth.enabled =
|
|
465
|
+
if (userPanelEnabled) auth.enabled = true;
|
|
462
466
|
const keepsOpenId = auth.type === "openid";
|
|
463
467
|
if (!keepsOpenId) auth.type = "dev-portal";
|
|
464
468
|
if (userPanelEnabled && !keepsOpenId) {
|
|
@@ -837,7 +841,7 @@ import { stat as stat4 } from "node:fs/promises";
|
|
|
837
841
|
var fileExists;
|
|
838
842
|
var init_file_exists = __esm({
|
|
839
843
|
"src/config/file-exists.ts"() {
|
|
840
|
-
fileExists = (
|
|
844
|
+
fileExists = (path100) => stat4(path100).then(() => true).catch(() => false);
|
|
841
845
|
}
|
|
842
846
|
});
|
|
843
847
|
|
|
@@ -5270,7 +5274,7 @@ __export(llms_exports, {
|
|
|
5270
5274
|
generateLlmsTxtFiles: () => generateLlmsTxtFiles
|
|
5271
5275
|
});
|
|
5272
5276
|
import { writeFile as writeFile12 } from "node:fs/promises";
|
|
5273
|
-
import
|
|
5277
|
+
import path47 from "node:path";
|
|
5274
5278
|
import colors10 from "picocolors";
|
|
5275
5279
|
async function generateLlmsTxtFiles({
|
|
5276
5280
|
markdownFileInfos,
|
|
@@ -5305,7 +5309,7 @@ async function generateLlmsTxtFiles({
|
|
|
5305
5309
|
}
|
|
5306
5310
|
}
|
|
5307
5311
|
const llmsTxt2 = llmsTxtParts.join("\n");
|
|
5308
|
-
await writeFile12(
|
|
5312
|
+
await writeFile12(path47.join(baseOutputDir, "llms.txt"), llmsTxt2, "utf-8");
|
|
5309
5313
|
if (process.env.APITOGO_JSON_ONLY !== "1") {
|
|
5310
5314
|
console.log(colors10.blue("\u2713 generated llms.txt"));
|
|
5311
5315
|
}
|
|
@@ -5333,7 +5337,7 @@ ${info.content}
|
|
|
5333
5337
|
}
|
|
5334
5338
|
const llmsFull = llmsFullParts.join("\n");
|
|
5335
5339
|
await writeFile12(
|
|
5336
|
-
|
|
5340
|
+
path47.join(baseOutputDir, "llms-full.txt"),
|
|
5337
5341
|
llmsFull,
|
|
5338
5342
|
"utf-8"
|
|
5339
5343
|
);
|
|
@@ -5836,7 +5840,7 @@ Run the command with --help to see its options.`;
|
|
|
5836
5840
|
import yargs from "yargs/yargs";
|
|
5837
5841
|
|
|
5838
5842
|
// src/cli/services/handler.ts
|
|
5839
|
-
import
|
|
5843
|
+
import path55 from "node:path";
|
|
5840
5844
|
|
|
5841
5845
|
// src/config/v2/billing.ts
|
|
5842
5846
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
@@ -5915,6 +5919,21 @@ var nonEmpty = z.string().min(1, { error: "must not be empty" });
|
|
|
5915
5919
|
var path3 = nonEmpty;
|
|
5916
5920
|
var pathList = z.array(nonEmpty);
|
|
5917
5921
|
var enabled = z.boolean().optional();
|
|
5922
|
+
var headerLabel = z.string().trim().min(1, { error: "must not be empty" }).max(40, { error: "must be 40 characters or fewer" });
|
|
5923
|
+
var HeaderLinkSchema = z.union(
|
|
5924
|
+
[
|
|
5925
|
+
z.strictObject({ label: headerLabel, page: path3 }),
|
|
5926
|
+
z.strictObject({
|
|
5927
|
+
label: headerLabel,
|
|
5928
|
+
to: z.string().regex(/^(\/(?!\/)|https:\/\/)/, {
|
|
5929
|
+
error: 'must start with "/" or "https://"'
|
|
5930
|
+
})
|
|
5931
|
+
})
|
|
5932
|
+
],
|
|
5933
|
+
{
|
|
5934
|
+
error: 'must be { "label": "...", "page": "path/to/page.tsx" } or { "label": "...", "to": "/path or https://..." }'
|
|
5935
|
+
}
|
|
5936
|
+
);
|
|
5918
5937
|
var PortalSchema = z.strictObject({
|
|
5919
5938
|
enabled,
|
|
5920
5939
|
dir: path3.optional(),
|
|
@@ -5931,6 +5950,8 @@ var PortalSchema = z.strictObject({
|
|
|
5931
5950
|
landing: path3.optional(),
|
|
5932
5951
|
/** The footer: a React component file shown under every page except the console's (API-129). */
|
|
5933
5952
|
footer: path3.optional(),
|
|
5953
|
+
/** Links of the header's top menu, after the built-in ones (Documentation, API Reference; the plans add Pricing). */
|
|
5954
|
+
header: z.strictObject({ links: z.array(HeaderLinkSchema) }).optional(),
|
|
5934
5955
|
/**
|
|
5935
5956
|
* The logo in the portal header: one image, or one per color scheme (API-129). `dark` is optional; without it the
|
|
5936
5957
|
* light image is used in both.
|
|
@@ -6094,8 +6115,8 @@ var ConfigV2Schema = z.strictObject({
|
|
|
6094
6115
|
var REMOVED_KEYS = {
|
|
6095
6116
|
"plans.provider": "plans.provider was removed. Only plans.billing.provider (stripe or none) is selectable."
|
|
6096
6117
|
};
|
|
6097
|
-
function pathToString(
|
|
6098
|
-
return
|
|
6118
|
+
function pathToString(path100) {
|
|
6119
|
+
return path100.reduce(
|
|
6099
6120
|
(acc, segment) => typeof segment === "number" ? `${acc}[${segment}]` : acc === "" ? String(segment) : `${acc}.${String(segment)}`,
|
|
6100
6121
|
""
|
|
6101
6122
|
);
|
|
@@ -6115,9 +6136,9 @@ function step(schema2, segment) {
|
|
|
6115
6136
|
}
|
|
6116
6137
|
return void 0;
|
|
6117
6138
|
}
|
|
6118
|
-
function knownKeysAt(
|
|
6139
|
+
function knownKeysAt(path100) {
|
|
6119
6140
|
let current = ConfigV2Schema;
|
|
6120
|
-
for (const segment of
|
|
6141
|
+
for (const segment of path100) {
|
|
6121
6142
|
if (!current) return [];
|
|
6122
6143
|
current = step(current, segment);
|
|
6123
6144
|
}
|
|
@@ -6153,7 +6174,7 @@ function unknownKeyHint(fullPath, key, known) {
|
|
|
6153
6174
|
return known.length > 0 ? `Allowed keys: ${known.join(", ")}.` : void 0;
|
|
6154
6175
|
}
|
|
6155
6176
|
function mapIssue(issue4) {
|
|
6156
|
-
const
|
|
6177
|
+
const path100 = pathToString(issue4.path);
|
|
6157
6178
|
switch (issue4.code) {
|
|
6158
6179
|
case "unrecognized_keys":
|
|
6159
6180
|
return issue4.keys.map((key) => {
|
|
@@ -6169,20 +6190,20 @@ function mapIssue(issue4) {
|
|
|
6169
6190
|
return [
|
|
6170
6191
|
{
|
|
6171
6192
|
code: "CONFIG_INVALID_VALUE",
|
|
6172
|
-
path:
|
|
6193
|
+
path: path100,
|
|
6173
6194
|
message: `must be one of: ${issue4.values.map((v) => JSON.stringify(v)).join(", ")}.`
|
|
6174
6195
|
}
|
|
6175
6196
|
];
|
|
6176
6197
|
case "custom": {
|
|
6177
6198
|
const code = typeof issue4.params?.code === "string" ? issue4.params.code : "CONFIG_INVALID_VALUE";
|
|
6178
|
-
return [{ code, path:
|
|
6199
|
+
return [{ code, path: path100, message: issue4.message ?? "is invalid." }];
|
|
6179
6200
|
}
|
|
6180
6201
|
case "invalid_type":
|
|
6181
6202
|
return [
|
|
6182
|
-
/received undefined/.test(issue4.message) ? { code: "CONFIG_MISSING_FIELD", path:
|
|
6203
|
+
/received undefined/.test(issue4.message) ? { code: "CONFIG_MISSING_FIELD", path: path100, message: "is required." } : { code: "CONFIG_INVALID_VALUE", path: path100, message: issue4.message }
|
|
6183
6204
|
];
|
|
6184
6205
|
default:
|
|
6185
|
-
return [{ code: "CONFIG_INVALID_VALUE", path:
|
|
6206
|
+
return [{ code: "CONFIG_INVALID_VALUE", path: path100, message: issue4.message }];
|
|
6186
6207
|
}
|
|
6187
6208
|
}
|
|
6188
6209
|
function isRecord(value) {
|
|
@@ -6478,6 +6499,7 @@ function toGlobPath(value) {
|
|
|
6478
6499
|
function fromConfig(configDir, value) {
|
|
6479
6500
|
return value.startsWith("!") ? `!${toGlobPath(path7.resolve(configDir, value.slice(1)))}` : toGlobPath(path7.resolve(configDir, value));
|
|
6480
6501
|
}
|
|
6502
|
+
var headerPageRoute = (file) => `/${path7.basename(file).replace(/\.(mdx?|tsx)$/i, "")}`;
|
|
6481
6503
|
var isLogoUrl = (value) => value.toLowerCase().startsWith("https://");
|
|
6482
6504
|
var logoSource = (configDir, value) => isLogoUrl(value) ? value : path7.resolve(configDir, value);
|
|
6483
6505
|
function resolveConfigV2(config2, configPath) {
|
|
@@ -6513,6 +6535,13 @@ function resolveConfigV2(config2, configPath) {
|
|
|
6513
6535
|
theme: portal.theme ? path7.resolve(configDir, portal.theme) : path7.join(dir, "theme.json"),
|
|
6514
6536
|
...portal.landing ? { landing: path7.resolve(configDir, portal.landing) } : {},
|
|
6515
6537
|
...portal.footer ? { footer: path7.resolve(configDir, portal.footer) } : {},
|
|
6538
|
+
headerLinks: (portal.header?.links ?? []).map(
|
|
6539
|
+
(link) => {
|
|
6540
|
+
if ("to" in link) return { label: link.label, to: link.to };
|
|
6541
|
+
const page = path7.resolve(configDir, link.page);
|
|
6542
|
+
return { label: link.label, to: headerPageRoute(page), page };
|
|
6543
|
+
}
|
|
6544
|
+
),
|
|
6516
6545
|
...portal.logo ? {
|
|
6517
6546
|
logo: typeof portal.logo === "string" ? {
|
|
6518
6547
|
light: logoSource(configDir, portal.logo),
|
|
@@ -6644,17 +6673,30 @@ function loadConfigV2(pathOrDir) {
|
|
|
6644
6673
|
}
|
|
6645
6674
|
|
|
6646
6675
|
// src/config/v2/rules.ts
|
|
6647
|
-
import { readdir as readdir2, readFile as
|
|
6648
|
-
import
|
|
6649
|
-
import { glob as
|
|
6676
|
+
import { readdir as readdir2, readFile as readFile5, stat as stat2 } from "node:fs/promises";
|
|
6677
|
+
import path11 from "node:path";
|
|
6678
|
+
import { glob as glob3 } from "glob";
|
|
6650
6679
|
import { parse as parseYaml } from "yaml";
|
|
6651
6680
|
|
|
6652
|
-
// src/config/v2/
|
|
6653
|
-
import { readFile as readFile3 } from "node:fs/promises";
|
|
6681
|
+
// src/config/v2/home-redirect.ts
|
|
6654
6682
|
import path9 from "node:path";
|
|
6655
6683
|
import { glob } from "glob";
|
|
6656
6684
|
import globParent from "glob-parent";
|
|
6657
6685
|
|
|
6686
|
+
// src/lib/util/readFrontmatter.ts
|
|
6687
|
+
import { readFile as readFile3 } from "node:fs/promises";
|
|
6688
|
+
import matter from "gray-matter";
|
|
6689
|
+
import { parse, stringify } from "yaml";
|
|
6690
|
+
var yaml = {
|
|
6691
|
+
parse: (input5) => parse(input5) ?? {},
|
|
6692
|
+
stringify: (obj) => stringify(obj)
|
|
6693
|
+
};
|
|
6694
|
+
var readFrontmatter = async (filePath) => {
|
|
6695
|
+
const content = await readFile3(filePath, "utf-8");
|
|
6696
|
+
const normalizedContent = content.replace(/\r\n/g, "\n");
|
|
6697
|
+
return matter(normalizedContent, { engines: { yaml } });
|
|
6698
|
+
};
|
|
6699
|
+
|
|
6658
6700
|
// src/config/v2/page-order.ts
|
|
6659
6701
|
var FIRST_PAGE_NAMES = [
|
|
6660
6702
|
"introduction",
|
|
@@ -6696,6 +6738,79 @@ function tsxPageOrder(source) {
|
|
|
6696
6738
|
return match?.[1] ? Number(match[1]) : void 0;
|
|
6697
6739
|
}
|
|
6698
6740
|
|
|
6741
|
+
// src/config/v2/home-redirect.ts
|
|
6742
|
+
var IGNORED = ["**/node_modules/**", "**/dist/**", "**/.git/**"];
|
|
6743
|
+
async function docRoutes(patterns, options = {}) {
|
|
6744
|
+
const globs = patterns.map(toGlobPath);
|
|
6745
|
+
const excluded = globs.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1));
|
|
6746
|
+
const included = globs.filter((pattern) => !pattern.startsWith("!"));
|
|
6747
|
+
const routes = await Promise.all(
|
|
6748
|
+
included.map(async (pattern) => {
|
|
6749
|
+
const files = await glob(pattern, {
|
|
6750
|
+
absolute: true,
|
|
6751
|
+
posix: true,
|
|
6752
|
+
ignore: [...IGNORED, ...excluded]
|
|
6753
|
+
});
|
|
6754
|
+
const parent = globParent(pattern);
|
|
6755
|
+
const published = options.includeDrafts ? files : (await Promise.all(
|
|
6756
|
+
files.map(async (file) => ({
|
|
6757
|
+
file,
|
|
6758
|
+
draft: (await readFrontmatter(file)).data.draft === true
|
|
6759
|
+
}))
|
|
6760
|
+
)).filter(({ draft }) => !draft).map(({ file }) => file);
|
|
6761
|
+
return published.map(
|
|
6762
|
+
(file) => `/${path9.posix.relative(parent, file.replace(/^\/\/\?\//, "")).replace(/\.mdx?$/, "")}`
|
|
6763
|
+
);
|
|
6764
|
+
})
|
|
6765
|
+
);
|
|
6766
|
+
return [...new Set(routes.flat())].sort();
|
|
6767
|
+
}
|
|
6768
|
+
function pickLandingRoute(routes, orders) {
|
|
6769
|
+
return firstPage(routes, orders);
|
|
6770
|
+
}
|
|
6771
|
+
async function docPageOrders(patterns) {
|
|
6772
|
+
const globs = patterns.map(toGlobPath);
|
|
6773
|
+
const excluded = globs.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1));
|
|
6774
|
+
const orders = /* @__PURE__ */ new Map();
|
|
6775
|
+
for (const pattern of globs.filter((p) => !p.startsWith("!"))) {
|
|
6776
|
+
const parent = globParent(pattern);
|
|
6777
|
+
const files = await glob(pattern, {
|
|
6778
|
+
absolute: true,
|
|
6779
|
+
posix: true,
|
|
6780
|
+
ignore: [...IGNORED, ...excluded]
|
|
6781
|
+
});
|
|
6782
|
+
for (const raw of files) {
|
|
6783
|
+
const order = orderValue((await readFrontmatter(raw)).data.order);
|
|
6784
|
+
if (order === void 0) continue;
|
|
6785
|
+
const route = `/${path9.posix.relative(parent, raw.replace(/^\/\/\?\//, "")).replace(/\.mdx?$/, "")}`;
|
|
6786
|
+
if (!orders.has(route)) orders.set(route, order);
|
|
6787
|
+
}
|
|
6788
|
+
}
|
|
6789
|
+
return orders;
|
|
6790
|
+
}
|
|
6791
|
+
function homeRedirect(input5) {
|
|
6792
|
+
if (input5.hostsDocs) {
|
|
6793
|
+
if (input5.docRoutes.some((route) => route === "/" || route === "/index"))
|
|
6794
|
+
return void 0;
|
|
6795
|
+
const landing = pickLandingRoute(input5.docRoutes, input5.pageOrders);
|
|
6796
|
+
if (landing) return { from: "/", to: landing };
|
|
6797
|
+
return input5.apiReferencePath ? { from: "/", to: input5.apiReferencePath } : void 0;
|
|
6798
|
+
}
|
|
6799
|
+
if (input5.externalDocsUrl && !input5.userPanel) {
|
|
6800
|
+
return { from: "/", to: input5.externalDocsUrl };
|
|
6801
|
+
}
|
|
6802
|
+
if (input5.userPanel) {
|
|
6803
|
+
return { from: "/", to: input5.pricingPath ?? "/account" };
|
|
6804
|
+
}
|
|
6805
|
+
return void 0;
|
|
6806
|
+
}
|
|
6807
|
+
|
|
6808
|
+
// src/config/v2/tsx-pages.ts
|
|
6809
|
+
import { readFile as readFile4 } from "node:fs/promises";
|
|
6810
|
+
import path10 from "node:path";
|
|
6811
|
+
import { glob as glob2 } from "glob";
|
|
6812
|
+
import globParent2 from "glob-parent";
|
|
6813
|
+
|
|
6699
6814
|
// src/config/v2/docs-navigation.ts
|
|
6700
6815
|
var DOCS_NAVIGATION_LABEL = "Documentation";
|
|
6701
6816
|
var emptyBranch = () => ({ pages: /* @__PURE__ */ new Map(), folders: /* @__PURE__ */ new Map() });
|
|
@@ -6766,7 +6881,7 @@ function docsNavigation(routes, customPages = [], orders = /* @__PURE__ */ new M
|
|
|
6766
6881
|
}
|
|
6767
6882
|
|
|
6768
6883
|
// src/config/v2/tsx-pages.ts
|
|
6769
|
-
var
|
|
6884
|
+
var IGNORED2 = ["**/node_modules/**", "**/dist/**", "**/.git/**"];
|
|
6770
6885
|
function isTsxHelper(relative) {
|
|
6771
6886
|
return relative.split("/").some((part) => part.startsWith("_")) || /\.(test|spec|stories)\.tsx$/.test(relative) || relative.split("/").includes("node_modules");
|
|
6772
6887
|
}
|
|
@@ -6777,7 +6892,7 @@ function tsxPagePatterns(contentGlobs) {
|
|
|
6777
6892
|
return [
|
|
6778
6893
|
...new Set(
|
|
6779
6894
|
included.map(
|
|
6780
|
-
(pattern) =>
|
|
6895
|
+
(pattern) => path10.posix.join(globParent2(pattern), "**", "*.tsx")
|
|
6781
6896
|
)
|
|
6782
6897
|
),
|
|
6783
6898
|
...excluded
|
|
@@ -6787,21 +6902,21 @@ var TITLE = /export\s+const\s+title\s*(?::\s*string\s*)?=\s*(["'`])((?:\\.|(?!\1
|
|
|
6787
6902
|
function tsxPageLabel(source, file) {
|
|
6788
6903
|
const match = TITLE.exec(source);
|
|
6789
6904
|
if (match?.[2]) return match[2].replace(/\\(.)/g, "$1");
|
|
6790
|
-
const name =
|
|
6905
|
+
const name = path10.basename(file, ".tsx");
|
|
6791
6906
|
return folderLabel(
|
|
6792
|
-
name === "index" ?
|
|
6907
|
+
name === "index" ? path10.basename(path10.dirname(file)) : name
|
|
6793
6908
|
);
|
|
6794
6909
|
}
|
|
6795
6910
|
async function findTsxPages(contentGlobs) {
|
|
6796
6911
|
const patterns = tsxPagePatterns(contentGlobs);
|
|
6797
6912
|
const ignore2 = [
|
|
6798
|
-
...
|
|
6913
|
+
...IGNORED2,
|
|
6799
6914
|
...patterns.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1))
|
|
6800
6915
|
];
|
|
6801
6916
|
const found = /* @__PURE__ */ new Map();
|
|
6802
6917
|
for (const pattern of patterns.filter((p) => !p.startsWith("!"))) {
|
|
6803
|
-
const parent =
|
|
6804
|
-
const files = await
|
|
6918
|
+
const parent = globParent2(pattern);
|
|
6919
|
+
const files = await glob2(pattern, {
|
|
6805
6920
|
absolute: true,
|
|
6806
6921
|
posix: true,
|
|
6807
6922
|
nodir: true,
|
|
@@ -6809,11 +6924,11 @@ async function findTsxPages(contentGlobs) {
|
|
|
6809
6924
|
});
|
|
6810
6925
|
for (const raw of files.sort()) {
|
|
6811
6926
|
const file = raw.replace(/^\/\/\?\//, "");
|
|
6812
|
-
const relative =
|
|
6927
|
+
const relative = path10.posix.relative(parent, file);
|
|
6813
6928
|
if (isTsxHelper(relative)) continue;
|
|
6814
6929
|
const route = `/${relative.replace(/\.tsx$/, "")}`;
|
|
6815
6930
|
if (found.has(route)) continue;
|
|
6816
|
-
const source = await
|
|
6931
|
+
const source = await readFile4(file, "utf8").catch(() => "");
|
|
6817
6932
|
const order = tsxPageOrder(source);
|
|
6818
6933
|
found.set(route, {
|
|
6819
6934
|
route,
|
|
@@ -6978,40 +7093,41 @@ async function portalRules(config2, resolved, out) {
|
|
|
6978
7093
|
out.error({
|
|
6979
7094
|
code: "PORTAL_FILE_MISSING",
|
|
6980
7095
|
path: "portal.footer",
|
|
6981
|
-
message: `the file ${
|
|
7096
|
+
message: `the file ${path11.relative(resolved.configDir, portal.footer)} does not exist.`,
|
|
6982
7097
|
hint: "Create it, or remove portal.footer."
|
|
6983
7098
|
});
|
|
6984
|
-
|
|
7099
|
+
await headerLinksRule(portal, resolved, out);
|
|
7100
|
+
const publicDir = path11.join(portal.dir, "public");
|
|
6985
7101
|
for (const file of new Set(
|
|
6986
7102
|
[portal.logo?.light, portal.logo?.dark].filter(
|
|
6987
7103
|
(value) => !!value && !isLogoUrl(value)
|
|
6988
7104
|
)
|
|
6989
7105
|
)) {
|
|
6990
|
-
const inside =
|
|
6991
|
-
if (inside.startsWith("..") ||
|
|
7106
|
+
const inside = path11.relative(publicDir, file);
|
|
7107
|
+
if (inside.startsWith("..") || path11.isAbsolute(inside))
|
|
6992
7108
|
out.error({
|
|
6993
7109
|
code: "PORTAL_LOGO_OUTSIDE_PUBLIC",
|
|
6994
7110
|
path: "portal.logo",
|
|
6995
|
-
message: `the logo ${
|
|
6996
|
-
hint: `Move it into ${
|
|
7111
|
+
message: `the logo ${path11.relative(resolved.configDir, file)} is not in the portal's public folder, which is what the site serves.`,
|
|
7112
|
+
hint: `Move it into ${path11.relative(resolved.configDir, publicDir)}/, or use an https:// address.`
|
|
6997
7113
|
});
|
|
6998
7114
|
else if (!await isFile(file))
|
|
6999
7115
|
out.error({
|
|
7000
7116
|
code: "PORTAL_FILE_MISSING",
|
|
7001
7117
|
path: "portal.logo",
|
|
7002
|
-
message: `the file ${
|
|
7118
|
+
message: `the file ${path11.relative(resolved.configDir, file)} does not exist.`,
|
|
7003
7119
|
hint: "Create it, or remove portal.logo."
|
|
7004
7120
|
});
|
|
7005
7121
|
}
|
|
7006
7122
|
if (await isFile(portal.theme)) {
|
|
7007
7123
|
try {
|
|
7008
|
-
JSON.parse(await
|
|
7124
|
+
JSON.parse(await readFile5(portal.theme, "utf8"));
|
|
7009
7125
|
} catch (error) {
|
|
7010
7126
|
out.error({
|
|
7011
7127
|
code: "PORTAL_THEME_INVALID",
|
|
7012
7128
|
path: "portal.theme",
|
|
7013
7129
|
message: `the theme file is not valid JSON (${error instanceof Error ? error.message : String(error)}).`,
|
|
7014
|
-
hint:
|
|
7130
|
+
hint: path11.relative(resolved.configDir, portal.theme)
|
|
7015
7131
|
});
|
|
7016
7132
|
}
|
|
7017
7133
|
}
|
|
@@ -7020,11 +7136,11 @@ async function docsContentRule(config2, patterns, resolved, out) {
|
|
|
7020
7136
|
const globs = patterns.map(toGlobPath);
|
|
7021
7137
|
const include = globs.filter((pattern) => !pattern.startsWith("!"));
|
|
7022
7138
|
const ignore2 = globs.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1));
|
|
7023
|
-
const matches = include.length > 0 ? await
|
|
7139
|
+
const matches = include.length > 0 ? await glob3(include, { nodir: true, ignore: ignore2, absolute: true }) : [];
|
|
7024
7140
|
if (matches.length > 0) return;
|
|
7025
7141
|
if ((await findTsxPages(patterns)).length > 0) return;
|
|
7026
7142
|
const shown = config2.portal?.docs?.content ?? [
|
|
7027
|
-
|
|
7143
|
+
path11.relative(resolved.configDir, patterns[0] ?? "")
|
|
7028
7144
|
];
|
|
7029
7145
|
out.warn({
|
|
7030
7146
|
code: "PORTAL_DOCS_EMPTY",
|
|
@@ -7033,6 +7149,77 @@ async function docsContentRule(config2, patterns, resolved, out) {
|
|
|
7033
7149
|
hint: "Add .md, .mdx or .tsx pages, or point docs.content at your existing docs."
|
|
7034
7150
|
});
|
|
7035
7151
|
}
|
|
7152
|
+
var RESERVED_HEADER_ROUTES = [
|
|
7153
|
+
"/",
|
|
7154
|
+
"/index",
|
|
7155
|
+
"/api",
|
|
7156
|
+
"/pricing",
|
|
7157
|
+
"/account",
|
|
7158
|
+
"/login",
|
|
7159
|
+
"/signup"
|
|
7160
|
+
];
|
|
7161
|
+
async function headerLinksRule(portal, resolved, out) {
|
|
7162
|
+
const pages = portal.headerLinks.map((link, index) => ({ link, index })).filter(({ link }) => link.page !== void 0);
|
|
7163
|
+
if (pages.length === 0) return;
|
|
7164
|
+
const hostsDocs = portal.docs.enabled && portal.docs.provider === "apitogo";
|
|
7165
|
+
const docs = hostsDocs ? [
|
|
7166
|
+
...await docRoutes(portal.docs.content, { includeDrafts: true }),
|
|
7167
|
+
...(await findTsxPages(portal.docs.content)).map((page) => page.route)
|
|
7168
|
+
] : [];
|
|
7169
|
+
const seen = /* @__PURE__ */ new Set();
|
|
7170
|
+
for (const { link, index } of pages) {
|
|
7171
|
+
const file = link.page;
|
|
7172
|
+
const at = `portal.header.links[${index}].page`;
|
|
7173
|
+
const shown = path11.relative(resolved.configDir, file);
|
|
7174
|
+
if (!hostsDocs) {
|
|
7175
|
+
out.error({
|
|
7176
|
+
code: "PORTAL_HEADER_PAGE_NO_DOCS",
|
|
7177
|
+
path: at,
|
|
7178
|
+
message: `the header page ${shown} needs hosted docs, which this portal does not have.`,
|
|
7179
|
+
hint: 'Header pages are served with the docs pages: set portal.docs.provider to "apitogo", or link an address with "to" instead.'
|
|
7180
|
+
});
|
|
7181
|
+
continue;
|
|
7182
|
+
}
|
|
7183
|
+
if (!/\.(mdx?|tsx)$/i.test(file)) {
|
|
7184
|
+
out.error({
|
|
7185
|
+
code: "PORTAL_HEADER_PAGE_INVALID",
|
|
7186
|
+
path: at,
|
|
7187
|
+
message: `the header page ${shown} is neither a React page nor a Markdown page.`,
|
|
7188
|
+
hint: "Use a .tsx file (its default export is the page) or a .md / .mdx file."
|
|
7189
|
+
});
|
|
7190
|
+
continue;
|
|
7191
|
+
}
|
|
7192
|
+
if (!await isFile(file)) {
|
|
7193
|
+
out.error({
|
|
7194
|
+
code: "PORTAL_FILE_MISSING",
|
|
7195
|
+
path: at,
|
|
7196
|
+
message: `the file ${shown} does not exist.`,
|
|
7197
|
+
hint: "Create it (`apitogo config --page-slug <name> --page-title <title> --page-header`), or remove the link."
|
|
7198
|
+
});
|
|
7199
|
+
continue;
|
|
7200
|
+
}
|
|
7201
|
+
const route = link.to;
|
|
7202
|
+
if (RESERVED_HEADER_ROUTES.includes(route.toLowerCase())) {
|
|
7203
|
+
out.error({
|
|
7204
|
+
code: "PORTAL_HEADER_PAGE_ROUTE_TAKEN",
|
|
7205
|
+
path: at,
|
|
7206
|
+
message: `the header page ${shown} would be served at ${route}, which the portal uses itself.`,
|
|
7207
|
+
hint: "Rename the file: its name is the page's address."
|
|
7208
|
+
});
|
|
7209
|
+
continue;
|
|
7210
|
+
}
|
|
7211
|
+
if (docs.includes(route) || seen.has(route)) {
|
|
7212
|
+
out.error({
|
|
7213
|
+
code: "PORTAL_HEADER_PAGE_ROUTE_TAKEN",
|
|
7214
|
+
path: at,
|
|
7215
|
+
message: `the header page ${shown} would be served at ${route}, which another page already has.`,
|
|
7216
|
+
hint: `Rename the file: its name is the page's address. A docs page that should be in the header too can be linked with "to" instead.`
|
|
7217
|
+
});
|
|
7218
|
+
continue;
|
|
7219
|
+
}
|
|
7220
|
+
seen.add(route);
|
|
7221
|
+
}
|
|
7222
|
+
}
|
|
7036
7223
|
function isIpLiteral(hostname) {
|
|
7037
7224
|
return /^\d{1,3}(\.\d{1,3}){3}$/.test(hostname) || hostname.startsWith("[");
|
|
7038
7225
|
}
|
|
@@ -7097,8 +7284,8 @@ async function gatewayRules(resolved, out) {
|
|
|
7097
7284
|
}
|
|
7098
7285
|
}
|
|
7099
7286
|
if (origin.source) {
|
|
7100
|
-
const inside =
|
|
7101
|
-
if (inside.startsWith("..") ||
|
|
7287
|
+
const inside = path11.relative(resolved.configDir, origin.source);
|
|
7288
|
+
if (inside.startsWith("..") || path11.isAbsolute(inside)) {
|
|
7102
7289
|
out.error({
|
|
7103
7290
|
code: "GATEWAY_ORIGIN_INVALID",
|
|
7104
7291
|
path: "gateway.origin.source",
|
|
@@ -7183,7 +7370,7 @@ async function gatewayRules(resolved, out) {
|
|
|
7183
7370
|
}
|
|
7184
7371
|
async function specRule(spec, index, resolved, out) {
|
|
7185
7372
|
const at = `gateway.specs[${index}]`;
|
|
7186
|
-
const shown =
|
|
7373
|
+
const shown = path11.relative(resolved.configDir, spec);
|
|
7187
7374
|
const info = await stat2(spec).catch(() => void 0);
|
|
7188
7375
|
if (!info?.isFile()) {
|
|
7189
7376
|
out.error({
|
|
@@ -7203,7 +7390,7 @@ async function specRule(spec, index, resolved, out) {
|
|
|
7203
7390
|
}
|
|
7204
7391
|
let document;
|
|
7205
7392
|
try {
|
|
7206
|
-
const text2 = await
|
|
7393
|
+
const text2 = await readFile5(spec, "utf8");
|
|
7207
7394
|
document = spec.toLowerCase().endsWith(".json") ? JSON.parse(text2) : parseYaml(text2);
|
|
7208
7395
|
} catch (error) {
|
|
7209
7396
|
out.error({
|
|
@@ -7352,12 +7539,12 @@ async function plansRules(resolved, out, paid) {
|
|
|
7352
7539
|
out.error({
|
|
7353
7540
|
code: "PLANS_FILE_INVALID",
|
|
7354
7541
|
path: "plans.file",
|
|
7355
|
-
message: `the plan catalog was not found: ${
|
|
7542
|
+
message: `the plan catalog was not found: ${path11.relative(resolved.configDir, plans.file)}.`,
|
|
7356
7543
|
hint: "Create it with `apitogo add plans`."
|
|
7357
7544
|
});
|
|
7358
7545
|
} else {
|
|
7359
7546
|
try {
|
|
7360
|
-
JSON.parse(await
|
|
7547
|
+
JSON.parse(await readFile5(plans.file, "utf8"));
|
|
7361
7548
|
} catch (error) {
|
|
7362
7549
|
out.error({
|
|
7363
7550
|
code: "PLANS_FILE_INVALID",
|
|
@@ -7473,8 +7660,8 @@ function portalProfile(resolved) {
|
|
|
7473
7660
|
}
|
|
7474
7661
|
|
|
7475
7662
|
// src/config/v2/manifest.ts
|
|
7476
|
-
import { mkdir as mkdir3, readFile as
|
|
7477
|
-
import
|
|
7663
|
+
import { mkdir as mkdir3, readFile as readFile6, rename, rm, writeFile as writeFile4 } from "node:fs/promises";
|
|
7664
|
+
import path12 from "node:path";
|
|
7478
7665
|
import { z as z3 } from "zod";
|
|
7479
7666
|
var SUPPORTED_MANIFEST_SCHEMA = 1;
|
|
7480
7667
|
var Capabilities = z3.record(z3.string(), z3.boolean()).default({});
|
|
@@ -7525,7 +7712,7 @@ var ServiceManifestSchema = z3.looseObject({
|
|
|
7525
7712
|
}).optional()
|
|
7526
7713
|
}).default({})
|
|
7527
7714
|
});
|
|
7528
|
-
var issue = (code,
|
|
7715
|
+
var issue = (code, path100, message, hint) => ({ code, path: path100, message, hint });
|
|
7529
7716
|
function parseManifest(raw, file = "services.json") {
|
|
7530
7717
|
const version = typeof raw === "object" && raw !== null && "schemaVersion" in raw ? raw.schemaVersion : void 0;
|
|
7531
7718
|
if (typeof version === "number" && version > SUPPORTED_MANIFEST_SCHEMA) {
|
|
@@ -7558,7 +7745,7 @@ async function readManifest(state) {
|
|
|
7558
7745
|
const file = manifestPathFor(state);
|
|
7559
7746
|
let text2;
|
|
7560
7747
|
try {
|
|
7561
|
-
text2 = await
|
|
7748
|
+
text2 = await readFile6(file, "utf8");
|
|
7562
7749
|
} catch (error) {
|
|
7563
7750
|
if (error.code === "ENOENT") return void 0;
|
|
7564
7751
|
throw error;
|
|
@@ -7756,7 +7943,7 @@ function withPlansEntry(existing, info) {
|
|
|
7756
7943
|
}
|
|
7757
7944
|
async function writeManifest(state, manifest) {
|
|
7758
7945
|
const file = manifestPathFor(state);
|
|
7759
|
-
await mkdir3(
|
|
7946
|
+
await mkdir3(path12.dirname(file), { recursive: true });
|
|
7760
7947
|
const temporary = `${file}.${process.pid}.tmp`;
|
|
7761
7948
|
try {
|
|
7762
7949
|
await writeFile4(
|
|
@@ -7787,8 +7974,8 @@ async function removeServicesFromManifest(state, names) {
|
|
|
7787
7974
|
}
|
|
7788
7975
|
|
|
7789
7976
|
// src/config/v2/gateway-reference.ts
|
|
7790
|
-
import { readFile as
|
|
7791
|
-
import { parse } from "yaml";
|
|
7977
|
+
import { readFile as readFile7 } from "node:fs/promises";
|
|
7978
|
+
import { parse as parse2 } from "yaml";
|
|
7792
7979
|
var DEFAULT_KEY_HEADER = "X-API-Key";
|
|
7793
7980
|
var KEY_HEADER_EXTENSION = "x-apitogo-key-header";
|
|
7794
7981
|
var METHODS = [
|
|
@@ -7802,8 +7989,8 @@ var METHODS = [
|
|
|
7802
7989
|
"trace"
|
|
7803
7990
|
];
|
|
7804
7991
|
var isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7805
|
-
function actionKey(method,
|
|
7806
|
-
const trimmed =
|
|
7992
|
+
function actionKey(method, path100) {
|
|
7993
|
+
const trimmed = path100.trim();
|
|
7807
7994
|
const withSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
7808
7995
|
const normalized = withSlash.length > 1 ? withSlash.replace(/\/+$/, "") || "/" : withSlash;
|
|
7809
7996
|
return `${method.trim().toLowerCase()}:${normalized}`;
|
|
@@ -7840,15 +8027,15 @@ var ReferenceSpecError = class extends Error {
|
|
|
7840
8027
|
};
|
|
7841
8028
|
function operationsOf(paths) {
|
|
7842
8029
|
return Object.entries(paths).flatMap(
|
|
7843
|
-
([
|
|
7844
|
-
(method) => [
|
|
8030
|
+
([path100, item]) => isObject(item) ? METHODS.filter((method) => isObject(item[method])).map(
|
|
8031
|
+
(method) => [path100, item, method]
|
|
7845
8032
|
) : []
|
|
7846
8033
|
);
|
|
7847
8034
|
}
|
|
7848
8035
|
function buildReferenceSpec(specText, options) {
|
|
7849
8036
|
let root;
|
|
7850
8037
|
try {
|
|
7851
|
-
root =
|
|
8038
|
+
root = parse2(specText);
|
|
7852
8039
|
} catch {
|
|
7853
8040
|
throw new ReferenceSpecError("The OpenAPI file could not be read.");
|
|
7854
8041
|
}
|
|
@@ -7856,14 +8043,14 @@ function buildReferenceSpec(specText, options) {
|
|
|
7856
8043
|
throw new ReferenceSpecError("The OpenAPI file could not be read.");
|
|
7857
8044
|
const doc = structuredClone(root);
|
|
7858
8045
|
const paths = isObject(doc.paths) ? doc.paths : {};
|
|
7859
|
-
for (const [
|
|
7860
|
-
if (options.deniedOperations.has(actionKey(method,
|
|
8046
|
+
for (const [path100, item, method] of operationsOf(paths))
|
|
8047
|
+
if (options.deniedOperations.has(actionKey(method, path100)))
|
|
7861
8048
|
delete item[method];
|
|
7862
|
-
for (const [
|
|
8049
|
+
for (const [path100, item] of Object.entries(paths))
|
|
7863
8050
|
if (!isObject(item) || !METHODS.some((method) => method in item))
|
|
7864
|
-
delete paths[
|
|
7865
|
-
for (const [
|
|
7866
|
-
if (options.publicOperations.has(actionKey(method,
|
|
8051
|
+
delete paths[path100];
|
|
8052
|
+
for (const [path100, item, method] of operationsOf(paths))
|
|
8053
|
+
if (options.publicOperations.has(actionKey(method, path100)))
|
|
7867
8054
|
item[method].security = [];
|
|
7868
8055
|
doc.servers = [{ url: options.gatewayBaseUrl.replace(/\/+$/, "") }];
|
|
7869
8056
|
for (const item of Object.values(paths)) {
|
|
@@ -7903,11 +8090,11 @@ function buildReferenceSpec(specText, options) {
|
|
|
7903
8090
|
if (Object.keys(components).length > 0) doc.components = components;
|
|
7904
8091
|
else delete doc.components;
|
|
7905
8092
|
doc.security = Object.keys(requirement).length > 0 ? [requirement] : [];
|
|
7906
|
-
for (const [
|
|
8093
|
+
for (const [path100, item, method] of operationsOf(paths)) {
|
|
7907
8094
|
const operation = item[method];
|
|
7908
8095
|
if (Array.isArray(operation.security) && operation.security.length > 0)
|
|
7909
8096
|
delete operation.security;
|
|
7910
|
-
if (options.apiKeyRequired && !options.publicOperations.has(actionKey(method,
|
|
8097
|
+
if (options.apiKeyRequired && !options.publicOperations.has(actionKey(method, path100)))
|
|
7911
8098
|
operation[KEY_HEADER_EXTENSION] = options.apiKeyHeader;
|
|
7912
8099
|
else delete operation[KEY_HEADER_EXTENSION];
|
|
7913
8100
|
}
|
|
@@ -7929,7 +8116,7 @@ async function renderReferenceSpec(gateway, gatewayBaseUrl, keyHeaderName) {
|
|
|
7929
8116
|
throw new ReferenceSpecError("gateway.specs lists no OpenAPI file.");
|
|
7930
8117
|
let text2;
|
|
7931
8118
|
try {
|
|
7932
|
-
text2 = await
|
|
8119
|
+
text2 = await readFile7(file, "utf8");
|
|
7933
8120
|
} catch {
|
|
7934
8121
|
throw new ReferenceSpecError(`Cannot read the OpenAPI file ${file}.`);
|
|
7935
8122
|
}
|
|
@@ -8006,7 +8193,7 @@ import path14 from "node:path";
|
|
|
8006
8193
|
|
|
8007
8194
|
// src/cli/platform/helpers/openapi-action-keys.ts
|
|
8008
8195
|
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
|
|
8009
|
-
import
|
|
8196
|
+
import path13 from "node:path";
|
|
8010
8197
|
import YAML from "yaml";
|
|
8011
8198
|
var HTTP_METHODS = [
|
|
8012
8199
|
"get",
|
|
@@ -8075,7 +8262,7 @@ function extractGatewayActionKeysFromOpenApiDocument(document) {
|
|
|
8075
8262
|
function extractGatewayActionKeysFromOpenApiFile(filePath) {
|
|
8076
8263
|
try {
|
|
8077
8264
|
const raw = readFileSync3(filePath, "utf8");
|
|
8078
|
-
const ext =
|
|
8265
|
+
const ext = path13.extname(filePath).toLowerCase();
|
|
8079
8266
|
const parsed = ext === ".json" ? JSON.parse(raw) : YAML.parse(raw);
|
|
8080
8267
|
return extractGatewayActionKeysFromOpenApiDocument(parsed);
|
|
8081
8268
|
} catch {
|
|
@@ -8083,92 +8270,6 @@ function extractGatewayActionKeysFromOpenApiFile(filePath) {
|
|
|
8083
8270
|
}
|
|
8084
8271
|
}
|
|
8085
8272
|
|
|
8086
|
-
// src/config/v2/home-redirect.ts
|
|
8087
|
-
import path13 from "node:path";
|
|
8088
|
-
import { glob as glob3 } from "glob";
|
|
8089
|
-
import globParent2 from "glob-parent";
|
|
8090
|
-
|
|
8091
|
-
// src/lib/util/readFrontmatter.ts
|
|
8092
|
-
import { readFile as readFile7 } from "node:fs/promises";
|
|
8093
|
-
import matter from "gray-matter";
|
|
8094
|
-
import { parse as parse2, stringify } from "yaml";
|
|
8095
|
-
var yaml = {
|
|
8096
|
-
parse: (input5) => parse2(input5) ?? {},
|
|
8097
|
-
stringify: (obj) => stringify(obj)
|
|
8098
|
-
};
|
|
8099
|
-
var readFrontmatter = async (filePath) => {
|
|
8100
|
-
const content = await readFile7(filePath, "utf-8");
|
|
8101
|
-
const normalizedContent = content.replace(/\r\n/g, "\n");
|
|
8102
|
-
return matter(normalizedContent, { engines: { yaml } });
|
|
8103
|
-
};
|
|
8104
|
-
|
|
8105
|
-
// src/config/v2/home-redirect.ts
|
|
8106
|
-
var IGNORED2 = ["**/node_modules/**", "**/dist/**", "**/.git/**"];
|
|
8107
|
-
async function docRoutes(patterns, options = {}) {
|
|
8108
|
-
const globs = patterns.map(toGlobPath);
|
|
8109
|
-
const excluded = globs.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1));
|
|
8110
|
-
const included = globs.filter((pattern) => !pattern.startsWith("!"));
|
|
8111
|
-
const routes = await Promise.all(
|
|
8112
|
-
included.map(async (pattern) => {
|
|
8113
|
-
const files = await glob3(pattern, {
|
|
8114
|
-
absolute: true,
|
|
8115
|
-
posix: true,
|
|
8116
|
-
ignore: [...IGNORED2, ...excluded]
|
|
8117
|
-
});
|
|
8118
|
-
const parent = globParent2(pattern);
|
|
8119
|
-
const published = options.includeDrafts ? files : (await Promise.all(
|
|
8120
|
-
files.map(async (file) => ({
|
|
8121
|
-
file,
|
|
8122
|
-
draft: (await readFrontmatter(file)).data.draft === true
|
|
8123
|
-
}))
|
|
8124
|
-
)).filter(({ draft }) => !draft).map(({ file }) => file);
|
|
8125
|
-
return published.map(
|
|
8126
|
-
(file) => `/${path13.posix.relative(parent, file.replace(/^\/\/\?\//, "")).replace(/\.mdx?$/, "")}`
|
|
8127
|
-
);
|
|
8128
|
-
})
|
|
8129
|
-
);
|
|
8130
|
-
return [...new Set(routes.flat())].sort();
|
|
8131
|
-
}
|
|
8132
|
-
function pickLandingRoute(routes, orders) {
|
|
8133
|
-
return firstPage(routes, orders);
|
|
8134
|
-
}
|
|
8135
|
-
async function docPageOrders(patterns) {
|
|
8136
|
-
const globs = patterns.map(toGlobPath);
|
|
8137
|
-
const excluded = globs.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1));
|
|
8138
|
-
const orders = /* @__PURE__ */ new Map();
|
|
8139
|
-
for (const pattern of globs.filter((p) => !p.startsWith("!"))) {
|
|
8140
|
-
const parent = globParent2(pattern);
|
|
8141
|
-
const files = await glob3(pattern, {
|
|
8142
|
-
absolute: true,
|
|
8143
|
-
posix: true,
|
|
8144
|
-
ignore: [...IGNORED2, ...excluded]
|
|
8145
|
-
});
|
|
8146
|
-
for (const raw of files) {
|
|
8147
|
-
const order = orderValue((await readFrontmatter(raw)).data.order);
|
|
8148
|
-
if (order === void 0) continue;
|
|
8149
|
-
const route = `/${path13.posix.relative(parent, raw.replace(/^\/\/\?\//, "")).replace(/\.mdx?$/, "")}`;
|
|
8150
|
-
if (!orders.has(route)) orders.set(route, order);
|
|
8151
|
-
}
|
|
8152
|
-
}
|
|
8153
|
-
return orders;
|
|
8154
|
-
}
|
|
8155
|
-
function homeRedirect(input5) {
|
|
8156
|
-
if (input5.hostsDocs) {
|
|
8157
|
-
if (input5.docRoutes.some((route) => route === "/" || route === "/index"))
|
|
8158
|
-
return void 0;
|
|
8159
|
-
const landing = pickLandingRoute(input5.docRoutes, input5.pageOrders);
|
|
8160
|
-
if (landing) return { from: "/", to: landing };
|
|
8161
|
-
return input5.apiReferencePath ? { from: "/", to: input5.apiReferencePath } : void 0;
|
|
8162
|
-
}
|
|
8163
|
-
if (input5.externalDocsUrl && !input5.userPanel) {
|
|
8164
|
-
return { from: "/", to: input5.externalDocsUrl };
|
|
8165
|
-
}
|
|
8166
|
-
if (input5.userPanel) {
|
|
8167
|
-
return { from: "/", to: input5.pricingPath ?? "/account" };
|
|
8168
|
-
}
|
|
8169
|
-
return void 0;
|
|
8170
|
-
}
|
|
8171
|
-
|
|
8172
8273
|
// src/config/v2/protected-routes.ts
|
|
8173
8274
|
function protectedRoutesFor(input5) {
|
|
8174
8275
|
const { requireAuth } = input5;
|
|
@@ -8267,6 +8368,9 @@ function planPortal(profile, manifest) {
|
|
|
8267
8368
|
preview: manifest.preview === true
|
|
8268
8369
|
};
|
|
8269
8370
|
if (!profile.enabled) return plan2;
|
|
8371
|
+
if (profile.pipelines.search === "pagefind") plan2.search = "pagefind";
|
|
8372
|
+
else if (profile.pipelines.search === "inkeep")
|
|
8373
|
+
skip("search", "inkeep needs keys that portal.search cannot hold yet");
|
|
8270
8374
|
if (profile.pipelines.openapi) {
|
|
8271
8375
|
if (!gateway) skip("api reference", "services.json has no gateway entry");
|
|
8272
8376
|
else if (!serviceReady(gateway))
|
|
@@ -8343,11 +8447,38 @@ function planPortal(profile, manifest) {
|
|
|
8343
8447
|
var SITE_CONFIG_FILE = "apitogo.config.json";
|
|
8344
8448
|
var REFERENCE_SPEC_FILE = "openapi/gateway.json";
|
|
8345
8449
|
var API_REFERENCE_PATH = "api";
|
|
8450
|
+
var MARKDOWN_PAGE = /\.mdx?$/i;
|
|
8451
|
+
var HEADER_PAGE_ELEMENT_PREFIX = "apitogo:header-page:";
|
|
8452
|
+
function headerTsxPages(resolved, plan2) {
|
|
8453
|
+
if (!plan2.docs) return [];
|
|
8454
|
+
return (resolved.portal?.headerLinks ?? []).flatMap(
|
|
8455
|
+
(link) => link.page && /\.tsx$/i.test(link.page) ? [{ route: link.to, label: link.label, file: link.page }] : []
|
|
8456
|
+
).map((page, index) => ({
|
|
8457
|
+
...page,
|
|
8458
|
+
id: `${HEADER_PAGE_ELEMENT_PREFIX}${index}`
|
|
8459
|
+
}));
|
|
8460
|
+
}
|
|
8346
8461
|
function buildSiteConfig(resolved, plan2, theme, extras = {}) {
|
|
8347
8462
|
const portal = resolved.portal;
|
|
8348
8463
|
const redirects = extras.redirects ?? [];
|
|
8464
|
+
const headerLinks = portal?.headerLinks ?? [];
|
|
8465
|
+
const headerPages = plan2.docs ? headerLinks.flatMap(
|
|
8466
|
+
(link) => link.page && MARKDOWN_PAGE.test(link.page) ? [link.page] : []
|
|
8467
|
+
) : [];
|
|
8468
|
+
const shownHeaderLinks = headerLinks.filter((link) => !link.page || plan2.docs).map((link) => ({
|
|
8469
|
+
label: link.label,
|
|
8470
|
+
to: link.to,
|
|
8471
|
+
...link.to.startsWith("https://") ? { target: "_blank" } : {}
|
|
8472
|
+
}));
|
|
8349
8473
|
const navigation = [
|
|
8350
8474
|
...extras.docsNavigation ?? [],
|
|
8475
|
+
...headerTsxPages(resolved, plan2).map((page) => ({
|
|
8476
|
+
type: "custom-page",
|
|
8477
|
+
path: page.route,
|
|
8478
|
+
label: page.label,
|
|
8479
|
+
element: page.id,
|
|
8480
|
+
display: "hide"
|
|
8481
|
+
})),
|
|
8351
8482
|
...plan2.apiReference ? [
|
|
8352
8483
|
{
|
|
8353
8484
|
type: "link",
|
|
@@ -8386,11 +8517,13 @@ function buildSiteConfig(resolved, plan2, theme, extras = {}) {
|
|
|
8386
8517
|
},
|
|
8387
8518
|
...plan2.docs ? {
|
|
8388
8519
|
docs: {
|
|
8389
|
-
files:
|
|
8390
|
-
|
|
8391
|
-
|
|
8520
|
+
files: [
|
|
8521
|
+
...portal?.docs.content ?? [],
|
|
8522
|
+
...headerPages.map(toGlobPath)
|
|
8523
|
+
].map((glob9) => contentGlob(resolved.configDir, glob9))
|
|
8392
8524
|
}
|
|
8393
8525
|
} : {},
|
|
8526
|
+
...plan2.search ? { search: { type: plan2.search } } : {},
|
|
8394
8527
|
...plan2.apiReference ? {
|
|
8395
8528
|
apis: [
|
|
8396
8529
|
{
|
|
@@ -8402,12 +8535,13 @@ function buildSiteConfig(resolved, plan2, theme, extras = {}) {
|
|
|
8402
8535
|
} : {},
|
|
8403
8536
|
...navigation.length > 0 ? { navigation } : {},
|
|
8404
8537
|
// The sidebar link above is only seen inside the docs; the header is what every page shows. A header navigation
|
|
8405
|
-
// replaces the docs tab, so the docs get a header link of their own.
|
|
8406
|
-
...plan2.apiReference ? {
|
|
8538
|
+
// replaces the docs tab, so the docs get a header link of their own. The tenant's own links (portal.header) follow.
|
|
8539
|
+
...plan2.apiReference || shownHeaderLinks.length > 0 ? {
|
|
8407
8540
|
header: {
|
|
8408
8541
|
navigation: [
|
|
8409
8542
|
...plan2.docs && extras.docsPath ? [{ label: "Documentation", to: extras.docsPath }] : [],
|
|
8410
|
-
{ label: "API Reference", to: `/${API_REFERENCE_PATH}` }
|
|
8543
|
+
...plan2.apiReference ? [{ label: "API Reference", to: `/${API_REFERENCE_PATH}` }] : [],
|
|
8544
|
+
...shownHeaderLinks
|
|
8411
8545
|
]
|
|
8412
8546
|
}
|
|
8413
8547
|
} : {},
|
|
@@ -8613,10 +8747,14 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
|
|
|
8613
8747
|
const tsxPages = plan2.docs ? (await findTsxPages(profile.docs.content)).filter(
|
|
8614
8748
|
(page) => !markdownRoutes.includes(page.route)
|
|
8615
8749
|
) : [];
|
|
8750
|
+
const importPathOf = (file) => `./${CONTENT_LINK}/${path14.relative(resolved.configDir, file).split(path14.sep).join("/")}`;
|
|
8616
8751
|
const wrapperPages = tsxPages.map((page, index) => ({
|
|
8617
8752
|
id: `${TSX_PAGE_ELEMENT_PREFIX}${index}`,
|
|
8618
|
-
importPath:
|
|
8753
|
+
importPath: importPathOf(page.file)
|
|
8619
8754
|
}));
|
|
8755
|
+
const headerWrapperPages = headerTsxPages(resolved, plan2).map(
|
|
8756
|
+
(page) => ({ id: page.id, importPath: importPathOf(page.file) })
|
|
8757
|
+
);
|
|
8620
8758
|
const hostedDocRoutes = [
|
|
8621
8759
|
.../* @__PURE__ */ new Set([...markdownRoutes, ...tsxPages.map((page) => page.route)])
|
|
8622
8760
|
].sort();
|
|
@@ -8687,14 +8825,20 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
|
|
|
8687
8825
|
protectedRoutes: protectedRoutesFor({
|
|
8688
8826
|
requireAuth: resolved.portal?.requireAuth,
|
|
8689
8827
|
hasAuth: !!plan2.auth,
|
|
8690
|
-
|
|
8828
|
+
// A header page is a docs page too, so a portal behind login keeps it behind login.
|
|
8829
|
+
docRoutes: plan2.docs ? [
|
|
8830
|
+
...hostedDocRoutes,
|
|
8831
|
+
...(resolved.portal?.headerLinks ?? []).flatMap(
|
|
8832
|
+
(link) => link.page ? [link.to] : []
|
|
8833
|
+
)
|
|
8834
|
+
] : hostedDocRoutes,
|
|
8691
8835
|
apiReferencePath: plan2.apiReference ? `/${API_REFERENCE_PATH}` : void 0
|
|
8692
8836
|
})
|
|
8693
8837
|
}
|
|
8694
8838
|
);
|
|
8695
8839
|
const wrapper = renderWrapper(
|
|
8696
8840
|
plan2,
|
|
8697
|
-
wrapperPages,
|
|
8841
|
+
[...wrapperPages, ...headerWrapperPages],
|
|
8698
8842
|
resolved.portal?.footer ? wrapperImport(contentFile(resolved.configDir, resolved.portal.footer)) : void 0
|
|
8699
8843
|
);
|
|
8700
8844
|
const wrapperPath = path14.join(resolved.state.generatedDir, WRAPPER_FILE);
|
|
@@ -10101,7 +10245,7 @@ init_invariant();
|
|
|
10101
10245
|
// src/cli/check/v2.ts
|
|
10102
10246
|
init_apitogo_config_core();
|
|
10103
10247
|
import { readFile as readFile18 } from "node:fs/promises";
|
|
10104
|
-
import
|
|
10248
|
+
import path52 from "node:path";
|
|
10105
10249
|
|
|
10106
10250
|
// src/cli/platform/client/platform-api.ts
|
|
10107
10251
|
import { basename } from "node:path";
|
|
@@ -10214,8 +10358,8 @@ var PlatformApiClient = class {
|
|
|
10214
10358
|
constructor(config2) {
|
|
10215
10359
|
this.config = config2;
|
|
10216
10360
|
}
|
|
10217
|
-
url(
|
|
10218
|
-
return `${this.config.apiUrl}${
|
|
10361
|
+
url(path100) {
|
|
10362
|
+
return `${this.config.apiUrl}${path100.startsWith("/") ? path100 : `/${path100}`}`;
|
|
10219
10363
|
}
|
|
10220
10364
|
headers(extra) {
|
|
10221
10365
|
return {
|
|
@@ -10225,9 +10369,9 @@ var PlatformApiClient = class {
|
|
|
10225
10369
|
...extra
|
|
10226
10370
|
};
|
|
10227
10371
|
}
|
|
10228
|
-
async request(method,
|
|
10372
|
+
async request(method, path100, init3) {
|
|
10229
10373
|
const response = await fetchWithRetry(
|
|
10230
|
-
this.url(
|
|
10374
|
+
this.url(path100),
|
|
10231
10375
|
{
|
|
10232
10376
|
method,
|
|
10233
10377
|
...init3,
|
|
@@ -10695,15 +10839,15 @@ var PlatformApiClient = class {
|
|
|
10695
10839
|
}
|
|
10696
10840
|
);
|
|
10697
10841
|
}
|
|
10698
|
-
deleteDevPortalPage(projectId,
|
|
10699
|
-
const query = new URLSearchParams({ path:
|
|
10842
|
+
deleteDevPortalPage(projectId, path100) {
|
|
10843
|
+
const query = new URLSearchParams({ path: path100 });
|
|
10700
10844
|
return this.request(
|
|
10701
10845
|
"DELETE",
|
|
10702
10846
|
`/api/v1/projects/${projectId}/dev-portal/pages/files?${query.toString()}`
|
|
10703
10847
|
);
|
|
10704
10848
|
}
|
|
10705
|
-
renameDevPortalPage(projectId,
|
|
10706
|
-
const query = new URLSearchParams({ path:
|
|
10849
|
+
renameDevPortalPage(projectId, path100, newName) {
|
|
10850
|
+
const query = new URLSearchParams({ path: path100 });
|
|
10707
10851
|
return this.request(
|
|
10708
10852
|
"POST",
|
|
10709
10853
|
`/api/v1/projects/${projectId}/dev-portal/pages/files/rename?${query.toString()}`,
|
|
@@ -10819,8 +10963,8 @@ var PlatformApiClient = class {
|
|
|
10819
10963
|
* the project-less endpoint is used; `planTier` overrides the tier used for paid-plan checks.
|
|
10820
10964
|
*/
|
|
10821
10965
|
validateGatewayPlans(plans, options = {}) {
|
|
10822
|
-
const
|
|
10823
|
-
return this.request("POST",
|
|
10966
|
+
const path100 = options.projectId ? `/api/v1/projects/${options.projectId}/gateway/plans/validate` : "/api/v1/gateway/plans/validate";
|
|
10967
|
+
return this.request("POST", path100, {
|
|
10824
10968
|
headers: { "Content-Type": "application/json" },
|
|
10825
10969
|
body: JSON.stringify({ plans, planTier: options.planTier })
|
|
10826
10970
|
});
|
|
@@ -11048,11 +11192,11 @@ import {
|
|
|
11048
11192
|
rm as rm8,
|
|
11049
11193
|
writeFile as writeFile15
|
|
11050
11194
|
} from "node:fs/promises";
|
|
11051
|
-
import
|
|
11195
|
+
import path51 from "node:path";
|
|
11052
11196
|
|
|
11053
11197
|
// src/vite/build.ts
|
|
11054
11198
|
import { mkdir as mkdir11, readFile as readFile13, rename as rename5, rm as rm7, writeFile as writeFile13 } from "node:fs/promises";
|
|
11055
|
-
import
|
|
11199
|
+
import path49 from "node:path";
|
|
11056
11200
|
import { build as esbuild } from "esbuild";
|
|
11057
11201
|
import { build as viteBuild, mergeConfig as mergeConfig3 } from "vite";
|
|
11058
11202
|
|
|
@@ -11188,7 +11332,7 @@ init_invariant();
|
|
|
11188
11332
|
init_joinUrl();
|
|
11189
11333
|
|
|
11190
11334
|
// src/vite/config.ts
|
|
11191
|
-
import
|
|
11335
|
+
import path44 from "node:path";
|
|
11192
11336
|
import dotenv from "dotenv";
|
|
11193
11337
|
import colors8 from "picocolors";
|
|
11194
11338
|
import {
|
|
@@ -11199,7 +11343,7 @@ import {
|
|
|
11199
11343
|
// package.json
|
|
11200
11344
|
var package_default = {
|
|
11201
11345
|
name: "@lukoweb/apitogo",
|
|
11202
|
-
version: "0.2.
|
|
11346
|
+
version: "0.2.61",
|
|
11203
11347
|
type: "module",
|
|
11204
11348
|
sideEffects: [
|
|
11205
11349
|
"**/*.css",
|
|
@@ -11984,14 +12128,14 @@ var flattenAllOf = (schema2) => {
|
|
|
11984
12128
|
};
|
|
11985
12129
|
|
|
11986
12130
|
// src/lib/util/traverse.ts
|
|
11987
|
-
var traverse = (specification, transform,
|
|
11988
|
-
const transformed = transform(specification,
|
|
12131
|
+
var traverse = (specification, transform, path100 = []) => {
|
|
12132
|
+
const transformed = transform(specification, path100);
|
|
11989
12133
|
if (typeof transformed !== "object" || transformed === null) {
|
|
11990
12134
|
return transformed;
|
|
11991
12135
|
}
|
|
11992
12136
|
const result = Array.isArray(transformed) ? [] : {};
|
|
11993
12137
|
for (const [key, value] of Object.entries(transformed)) {
|
|
11994
|
-
const currentPath = [...
|
|
12138
|
+
const currentPath = [...path100, key];
|
|
11995
12139
|
if (Array.isArray(value)) {
|
|
11996
12140
|
result[key] = value.map(
|
|
11997
12141
|
(item, index) => typeof item === "object" && item != null ? traverse(item, transform, [...currentPath, index.toString()]) : item
|
|
@@ -12019,9 +12163,9 @@ var resolveLocalRef = (schema2, ref) => {
|
|
|
12019
12163
|
if (schemaCache?.has(ref)) {
|
|
12020
12164
|
return schemaCache.get(ref);
|
|
12021
12165
|
}
|
|
12022
|
-
const
|
|
12166
|
+
const path100 = ref.split("/").slice(1);
|
|
12023
12167
|
let current = schema2;
|
|
12024
|
-
for (const segment of
|
|
12168
|
+
for (const segment of path100) {
|
|
12025
12169
|
if (!current || typeof current !== "object") {
|
|
12026
12170
|
current = null;
|
|
12027
12171
|
}
|
|
@@ -12040,7 +12184,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
12040
12184
|
}
|
|
12041
12185
|
const cloned = structuredClone(schema2);
|
|
12042
12186
|
const visited = /* @__PURE__ */ new Set();
|
|
12043
|
-
const resolve = async (current,
|
|
12187
|
+
const resolve = async (current, path100) => {
|
|
12044
12188
|
if (isIndexableObject(current)) {
|
|
12045
12189
|
if (visited.has(current)) {
|
|
12046
12190
|
return CIRCULAR_REF;
|
|
@@ -12048,7 +12192,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
12048
12192
|
visited.add(current);
|
|
12049
12193
|
if (Array.isArray(current)) {
|
|
12050
12194
|
for (let index = 0; index < current.length; index++) {
|
|
12051
|
-
current[index] = await resolve(current[index], `${
|
|
12195
|
+
current[index] = await resolve(current[index], `${path100}/${index}`);
|
|
12052
12196
|
}
|
|
12053
12197
|
} else {
|
|
12054
12198
|
if ("$ref" in current && typeof current.$ref === "string") {
|
|
@@ -12059,13 +12203,13 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
12059
12203
|
for (const resolver of resolvers) {
|
|
12060
12204
|
const resolved = await resolver($ref);
|
|
12061
12205
|
if (resolved) {
|
|
12062
|
-
result2 = await resolve(resolved,
|
|
12206
|
+
result2 = await resolve(resolved, path100);
|
|
12063
12207
|
break;
|
|
12064
12208
|
}
|
|
12065
12209
|
}
|
|
12066
12210
|
if (result2 === void 0) {
|
|
12067
12211
|
const resolved = await resolveLocalRef(cloned, $ref);
|
|
12068
|
-
result2 = await resolve(resolved,
|
|
12212
|
+
result2 = await resolve(resolved, path100);
|
|
12069
12213
|
}
|
|
12070
12214
|
if (hasSiblings) {
|
|
12071
12215
|
if (result2 === CIRCULAR_REF) {
|
|
@@ -12078,7 +12222,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
12078
12222
|
return result2;
|
|
12079
12223
|
}
|
|
12080
12224
|
for (const key in current) {
|
|
12081
|
-
current[key] = await resolve(current[key], `${
|
|
12225
|
+
current[key] = await resolve(current[key], `${path100}/${key}`);
|
|
12082
12226
|
}
|
|
12083
12227
|
}
|
|
12084
12228
|
visited.delete(current);
|
|
@@ -12117,9 +12261,9 @@ var upgradeSchema = (schema2) => {
|
|
|
12117
12261
|
}
|
|
12118
12262
|
return sub;
|
|
12119
12263
|
});
|
|
12120
|
-
schema2 = traverse(schema2, (sub,
|
|
12264
|
+
schema2 = traverse(schema2, (sub, path100) => {
|
|
12121
12265
|
if (sub.example !== void 0) {
|
|
12122
|
-
if (isSchemaPath(
|
|
12266
|
+
if (isSchemaPath(path100 ?? [])) {
|
|
12123
12267
|
sub.examples = [sub.example];
|
|
12124
12268
|
} else {
|
|
12125
12269
|
sub.examples = {
|
|
@@ -12132,11 +12276,11 @@ var upgradeSchema = (schema2) => {
|
|
|
12132
12276
|
}
|
|
12133
12277
|
return sub;
|
|
12134
12278
|
});
|
|
12135
|
-
schema2 = traverse(schema2, (schema3,
|
|
12279
|
+
schema2 = traverse(schema2, (schema3, path100) => {
|
|
12136
12280
|
if (schema3.type === "object" && schema3.properties !== void 0) {
|
|
12137
|
-
const parentPath =
|
|
12281
|
+
const parentPath = path100?.slice(0, -1);
|
|
12138
12282
|
const isMultipart = parentPath?.some((segment, index) => {
|
|
12139
|
-
return segment === "content" &&
|
|
12283
|
+
return segment === "content" && path100?.[index + 1] === "multipart/form-data";
|
|
12140
12284
|
});
|
|
12141
12285
|
if (isMultipart) {
|
|
12142
12286
|
const entries = Object.entries(schema3.properties);
|
|
@@ -12150,8 +12294,8 @@ var upgradeSchema = (schema2) => {
|
|
|
12150
12294
|
}
|
|
12151
12295
|
return schema3;
|
|
12152
12296
|
});
|
|
12153
|
-
schema2 = traverse(schema2, (schema3,
|
|
12154
|
-
if (
|
|
12297
|
+
schema2 = traverse(schema2, (schema3, path100) => {
|
|
12298
|
+
if (path100?.includes("content") && path100.includes("application/octet-stream")) {
|
|
12155
12299
|
return {};
|
|
12156
12300
|
}
|
|
12157
12301
|
if (schema3.type === "string" && schema3.format === "binary") {
|
|
@@ -12177,11 +12321,11 @@ var upgradeSchema = (schema2) => {
|
|
|
12177
12321
|
}
|
|
12178
12322
|
return sub;
|
|
12179
12323
|
});
|
|
12180
|
-
schema2 = traverse(schema2, (schema3,
|
|
12324
|
+
schema2 = traverse(schema2, (schema3, path100) => {
|
|
12181
12325
|
if (schema3.type === "string" && schema3.format === "byte") {
|
|
12182
|
-
const parentPath =
|
|
12326
|
+
const parentPath = path100?.slice(0, -1);
|
|
12183
12327
|
const contentMediaType = parentPath?.find(
|
|
12184
|
-
(_, index) =>
|
|
12328
|
+
(_, index) => path100?.[index - 1] === "content"
|
|
12185
12329
|
);
|
|
12186
12330
|
return {
|
|
12187
12331
|
type: "string",
|
|
@@ -12193,7 +12337,7 @@ var upgradeSchema = (schema2) => {
|
|
|
12193
12337
|
});
|
|
12194
12338
|
return schema2;
|
|
12195
12339
|
};
|
|
12196
|
-
function isSchemaPath(
|
|
12340
|
+
function isSchemaPath(path100) {
|
|
12197
12341
|
const schemaLocations = [
|
|
12198
12342
|
["components", "schemas"],
|
|
12199
12343
|
"properties",
|
|
@@ -12206,10 +12350,10 @@ function isSchemaPath(path99) {
|
|
|
12206
12350
|
];
|
|
12207
12351
|
return schemaLocations.some((location) => {
|
|
12208
12352
|
if (Array.isArray(location)) {
|
|
12209
|
-
return location.every((segment, index) =>
|
|
12353
|
+
return location.every((segment, index) => path100[index] === segment);
|
|
12210
12354
|
}
|
|
12211
|
-
return
|
|
12212
|
-
}) ||
|
|
12355
|
+
return path100.includes(location);
|
|
12356
|
+
}) || path100.includes("schema") || path100.some((segment) => segment.endsWith("Schema"));
|
|
12213
12357
|
}
|
|
12214
12358
|
|
|
12215
12359
|
// src/lib/oas/parser/index.ts
|
|
@@ -12291,13 +12435,13 @@ var OPENAPI_PROPS = /* @__PURE__ */ new Set([
|
|
|
12291
12435
|
"anyOf",
|
|
12292
12436
|
"oneOf"
|
|
12293
12437
|
]);
|
|
12294
|
-
var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(),
|
|
12438
|
+
var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path100 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
|
|
12295
12439
|
if (obj === null || typeof obj !== "object") return obj;
|
|
12296
12440
|
const refPath = obj.__$ref;
|
|
12297
12441
|
const isCircular = currentPath.has(obj) || typeof refPath === "string" && currentRefPaths.has(refPath);
|
|
12298
12442
|
if (isCircular) {
|
|
12299
12443
|
if (typeof refPath === "string") return SCHEMA_REF_PREFIX + refPath;
|
|
12300
|
-
const circularProp =
|
|
12444
|
+
const circularProp = path100.find((p) => !OPENAPI_PROPS.has(p)) || path100[0];
|
|
12301
12445
|
return [CIRCULAR_REF, circularProp].filter(Boolean).join(":");
|
|
12302
12446
|
}
|
|
12303
12447
|
if (refs.has(obj)) return refs.get(obj);
|
|
@@ -12307,7 +12451,7 @@ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs
|
|
|
12307
12451
|
value,
|
|
12308
12452
|
currentPath,
|
|
12309
12453
|
refs,
|
|
12310
|
-
[...
|
|
12454
|
+
[...path100, key],
|
|
12311
12455
|
currentRefPaths
|
|
12312
12456
|
);
|
|
12313
12457
|
const result = Array.isArray(obj) ? obj.map((item, i) => recurse(item, i.toString())) : Object.fromEntries(
|
|
@@ -12342,7 +12486,7 @@ var resolveExtensions = (obj) => Object.fromEntries(
|
|
|
12342
12486
|
var getAllTags = (schema2) => {
|
|
12343
12487
|
const rootTags = schema2.tags ?? [];
|
|
12344
12488
|
const operations = Object.values(schema2.paths ?? {}).flatMap(
|
|
12345
|
-
(
|
|
12489
|
+
(path100) => HttpMethods.map((k) => path100?.[k]).filter((op) => op != null)
|
|
12346
12490
|
);
|
|
12347
12491
|
const operationTags = new Set(operations.flatMap((op) => op.tags ?? []));
|
|
12348
12492
|
const hasUntaggedOperations = operations.some(
|
|
@@ -12397,7 +12541,7 @@ var getAllSlugs = (ops, schemaTags = []) => {
|
|
|
12397
12541
|
var getOperationSlugKey = (op) => [op.path, op.method, op.operationId, op.summary].filter(Boolean).join("-");
|
|
12398
12542
|
var getAllOperations = (paths) => {
|
|
12399
12543
|
const operations = Object.entries(paths ?? {}).flatMap(
|
|
12400
|
-
([
|
|
12544
|
+
([path100, value]) => HttpMethods.flatMap((method) => {
|
|
12401
12545
|
if (!value?.[method]) return [];
|
|
12402
12546
|
const operation = value[method];
|
|
12403
12547
|
const pathParameters = value.parameters ?? [];
|
|
@@ -12417,7 +12561,7 @@ var getAllOperations = (paths) => {
|
|
|
12417
12561
|
return {
|
|
12418
12562
|
...operation,
|
|
12419
12563
|
method,
|
|
12420
|
-
path:
|
|
12564
|
+
path: path100,
|
|
12421
12565
|
parameters,
|
|
12422
12566
|
servers,
|
|
12423
12567
|
tags: operation.tags ?? []
|
|
@@ -12775,8 +12919,8 @@ var Schema = builder.objectRef("Schema").implement({
|
|
|
12775
12919
|
}),
|
|
12776
12920
|
paths: t.field({
|
|
12777
12921
|
type: [PathItem],
|
|
12778
|
-
resolve: (root) => Object.entries(root.paths ?? {}).map(([
|
|
12779
|
-
path:
|
|
12922
|
+
resolve: (root) => Object.entries(root.paths ?? {}).map(([path100, value]) => ({
|
|
12923
|
+
path: path100,
|
|
12780
12924
|
// biome-ignore lint/style/noNonNullAssertion: value is guaranteed to be defined
|
|
12781
12925
|
methods: Object.keys(value)
|
|
12782
12926
|
}))
|
|
@@ -12941,7 +13085,7 @@ init_joinUrl();
|
|
|
12941
13085
|
|
|
12942
13086
|
// src/vite/api/schema-codegen.ts
|
|
12943
13087
|
var unescapeJsonPointer = (uri) => decodeURIComponent(uri.replace(/~1/g, "/").replace(/~0/g, "~"));
|
|
12944
|
-
var getSegmentsFromPath = (
|
|
13088
|
+
var getSegmentsFromPath = (path100) => path100.split("/").slice(1).map(unescapeJsonPointer);
|
|
12945
13089
|
var createLocalRefMap = (obj) => {
|
|
12946
13090
|
const refMap = /* @__PURE__ */ new Map();
|
|
12947
13091
|
const siblingsMap = /* @__PURE__ */ new Map();
|
|
@@ -12972,16 +13116,16 @@ var replaceMarkers = (code, mergedRefs) => code.replace(/"__refMap:(.*?)"/g, '__
|
|
|
12972
13116
|
/"__refMap\+Siblings:(.*?)"/g,
|
|
12973
13117
|
(_, key) => mergedRefs.get(key) ?? `__refMap["${key}"]`
|
|
12974
13118
|
);
|
|
12975
|
-
var lookup = (schema2,
|
|
12976
|
-
const parts = getSegmentsFromPath(
|
|
13119
|
+
var lookup = (schema2, path100, filePath) => {
|
|
13120
|
+
const parts = getSegmentsFromPath(path100);
|
|
12977
13121
|
let val = schema2;
|
|
12978
13122
|
for (const part of parts) {
|
|
12979
13123
|
while (val.$ref?.startsWith("#/")) {
|
|
12980
|
-
val = val.$ref ===
|
|
13124
|
+
val = val.$ref === path100 ? val : lookup(schema2, val.$ref, filePath);
|
|
12981
13125
|
}
|
|
12982
13126
|
if (val[part] === void 0) {
|
|
12983
13127
|
throw new Error(
|
|
12984
|
-
`Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${
|
|
13128
|
+
`Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path100}`
|
|
12985
13129
|
);
|
|
12986
13130
|
}
|
|
12987
13131
|
val = val[part];
|
|
@@ -13228,8 +13372,8 @@ var SchemaManager = class {
|
|
|
13228
13372
|
}
|
|
13229
13373
|
}
|
|
13230
13374
|
};
|
|
13231
|
-
getLatestSchema = (
|
|
13232
|
-
getSchemasForPath = (
|
|
13375
|
+
getLatestSchema = (path100) => this.processedSchemas[path100]?.at(0);
|
|
13376
|
+
getSchemasForPath = (path100) => this.processedSchemas[path100];
|
|
13233
13377
|
getSchemaImports = () => Object.values(this.processedSchemas).flat().filter((s) => s.importKey);
|
|
13234
13378
|
getUrlToFilePathMap = () => {
|
|
13235
13379
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -14353,8 +14497,32 @@ init_loader();
|
|
|
14353
14497
|
init_ProtectedRoutesSchema();
|
|
14354
14498
|
init_joinUrl();
|
|
14355
14499
|
import { mkdir as mkdir8, writeFile as writeFile10 } from "node:fs/promises";
|
|
14356
|
-
import
|
|
14500
|
+
import path37 from "node:path";
|
|
14357
14501
|
import { matchPath } from "react-router";
|
|
14502
|
+
|
|
14503
|
+
// src/vite/markdown-output-path.ts
|
|
14504
|
+
import { rm as rm6 } from "node:fs/promises";
|
|
14505
|
+
import path36 from "node:path";
|
|
14506
|
+
var markdownOutputPath = (distDir, routePath) => {
|
|
14507
|
+
const segments = routePath === "/" ? ["index"] : routePath.split("/").filter(Boolean);
|
|
14508
|
+
return `${path36.join(distDir, ...segments)}.md`;
|
|
14509
|
+
};
|
|
14510
|
+
var removableMarkdownOutput = (distDir, routePath) => {
|
|
14511
|
+
const output4 = path36.resolve(markdownOutputPath(distDir, routePath));
|
|
14512
|
+
const relative = path36.relative(path36.resolve(distDir), output4);
|
|
14513
|
+
if (!relative || relative.startsWith("..") || path36.isAbsolute(relative)) {
|
|
14514
|
+
return void 0;
|
|
14515
|
+
}
|
|
14516
|
+
return output4;
|
|
14517
|
+
};
|
|
14518
|
+
var removeExportedMarkdown = async (distDir, pages) => {
|
|
14519
|
+
await Promise.all(
|
|
14520
|
+
pages.map((page) => removableMarkdownOutput(distDir, page.routePath)).filter((output4) => output4 !== void 0).map((output4) => rm6(output4, { force: true }).catch(() => {
|
|
14521
|
+
}))
|
|
14522
|
+
);
|
|
14523
|
+
};
|
|
14524
|
+
|
|
14525
|
+
// src/vite/plugin-markdown-export.ts
|
|
14358
14526
|
var processMarkdownFile = async (filePath) => {
|
|
14359
14527
|
const { content: markdownContent, data: frontmatter } = await readFrontmatter(filePath);
|
|
14360
14528
|
let finalMarkdown = markdownContent;
|
|
@@ -14441,7 +14609,7 @@ var viteMarkdownExportPlugin = () => {
|
|
|
14441
14609
|
if (process.env.NODE_ENV !== "production" || Object.keys(markdownFiles).length === 0 || !needsMdFiles) {
|
|
14442
14610
|
return;
|
|
14443
14611
|
}
|
|
14444
|
-
const distDir =
|
|
14612
|
+
const distDir = path37.join(
|
|
14445
14613
|
config2.__meta.rootDir,
|
|
14446
14614
|
"dist",
|
|
14447
14615
|
config2.basePath ?? ""
|
|
@@ -14461,16 +14629,15 @@ var viteMarkdownExportPlugin = () => {
|
|
|
14461
14629
|
description,
|
|
14462
14630
|
content: finalMarkdown
|
|
14463
14631
|
});
|
|
14464
|
-
const
|
|
14465
|
-
|
|
14466
|
-
await mkdir8(path36.dirname(outputPath), { recursive: true });
|
|
14632
|
+
const outputPath = markdownOutputPath(distDir, routePath);
|
|
14633
|
+
await mkdir8(path37.dirname(outputPath), { recursive: true });
|
|
14467
14634
|
await writeFile10(outputPath, finalMarkdown, "utf-8");
|
|
14468
14635
|
} catch (error) {
|
|
14469
14636
|
console.warn(`Failed to export markdown for ${routePath}:`, error);
|
|
14470
14637
|
}
|
|
14471
14638
|
}
|
|
14472
14639
|
if (config2.docs?.llms?.llmsTxt || config2.docs?.llms?.llmsTxtFull) {
|
|
14473
|
-
const markdownInfoPath =
|
|
14640
|
+
const markdownInfoPath = path37.join(
|
|
14474
14641
|
config2.__meta.rootDir,
|
|
14475
14642
|
"node_modules/.apitogo/markdown-info.json"
|
|
14476
14643
|
);
|
|
@@ -14622,9 +14789,9 @@ var remarkCodeTabs = () => (tree) => {
|
|
|
14622
14789
|
};
|
|
14623
14790
|
|
|
14624
14791
|
// src/vite/mdx/remark-inject-filepath.ts
|
|
14625
|
-
import
|
|
14792
|
+
import path38 from "node:path";
|
|
14626
14793
|
var remarkInjectFilepath = (rootDir) => (tree, vfile) => {
|
|
14627
|
-
const relativePath =
|
|
14794
|
+
const relativePath = path38.relative(rootDir, vfile.path).split(path38.sep).join(path38.posix.sep);
|
|
14628
14795
|
tree.children.unshift(exportMdxjsConst("__filepath", relativePath));
|
|
14629
14796
|
};
|
|
14630
14797
|
|
|
@@ -14711,18 +14878,18 @@ var remarkLastModified = () => {
|
|
|
14711
14878
|
};
|
|
14712
14879
|
|
|
14713
14880
|
// src/vite/mdx/remark-link-rewrite.ts
|
|
14714
|
-
import
|
|
14881
|
+
import path39 from "node:path";
|
|
14715
14882
|
import { visit as visit5 } from "unist-util-visit";
|
|
14716
14883
|
var remarkLinkRewrite = (basePath = "") => (tree) => {
|
|
14717
14884
|
visit5(tree, "link", (node) => {
|
|
14718
14885
|
if (!node.url) return;
|
|
14719
14886
|
if (node.url.startsWith("http") || node.url.startsWith("mailto:")) return;
|
|
14720
14887
|
node.url = node.url.replace(/\\/g, "/");
|
|
14721
|
-
const base =
|
|
14888
|
+
const base = path39.posix.join(basePath);
|
|
14722
14889
|
if (basePath && node.url.startsWith(base)) {
|
|
14723
14890
|
node.url = node.url.slice(base.length);
|
|
14724
14891
|
} else if (!node.url.startsWith("/") && !node.url.startsWith("#")) {
|
|
14725
|
-
node.url =
|
|
14892
|
+
node.url = path39.posix.join("..", node.url);
|
|
14726
14893
|
}
|
|
14727
14894
|
node.url = node.url.replace(/\.mdx?(#.*)?$/, "$1");
|
|
14728
14895
|
});
|
|
@@ -14942,14 +15109,14 @@ var plugin_mdx_default = viteMdxPlugin;
|
|
|
14942
15109
|
|
|
14943
15110
|
// src/vite/plugin-modules.ts
|
|
14944
15111
|
init_loader();
|
|
14945
|
-
import
|
|
15112
|
+
import path40 from "node:path";
|
|
14946
15113
|
import { normalizePath as normalizePath2 } from "vite";
|
|
14947
|
-
var getLandingModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(
|
|
14948
|
-
var getUserPanelModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(
|
|
15114
|
+
var getLandingModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path40.join(moduleDir, "../module-landing/src/index.tsx")) : "@lukoweb/apitogo-module-landing";
|
|
15115
|
+
var getUserPanelModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path40.join(moduleDir, "../module-user-panel/src/index.tsx")) : "@lukoweb/apitogo-module-user-panel";
|
|
14949
15116
|
var getBillingPluginImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(
|
|
14950
|
-
|
|
15117
|
+
path40.join(moduleDir, "../plugin-dev-portal-billing/src/index.ts")
|
|
14951
15118
|
) : "@lukoweb/apitogo-plugin-dev-portal-billing";
|
|
14952
|
-
var resolveProjectPageImport = (rootDir, pagePath) => normalizePath2(
|
|
15119
|
+
var resolveProjectPageImport = (rootDir, pagePath) => normalizePath2(path40.resolve(rootDir, pagePath));
|
|
14953
15120
|
var viteModulesPlugin = () => {
|
|
14954
15121
|
const virtualModuleId4 = "virtual:zudoku-modules-plugin";
|
|
14955
15122
|
const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
|
|
@@ -15091,17 +15258,17 @@ var plugin_modules_default = viteModulesPlugin;
|
|
|
15091
15258
|
|
|
15092
15259
|
// src/vite/plugin-offroot-resolve.ts
|
|
15093
15260
|
init_loader();
|
|
15094
|
-
import
|
|
15261
|
+
import path41 from "node:path";
|
|
15095
15262
|
function stripQuery(id) {
|
|
15096
15263
|
const query = id.indexOf("?");
|
|
15097
15264
|
return query === -1 ? id : id.slice(0, query);
|
|
15098
15265
|
}
|
|
15099
15266
|
function isInside(parent, child) {
|
|
15100
|
-
const relative =
|
|
15101
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
15267
|
+
const relative = path41.relative(path41.resolve(parent), path41.resolve(child));
|
|
15268
|
+
return relative === "" || !relative.startsWith("..") && !path41.isAbsolute(relative);
|
|
15102
15269
|
}
|
|
15103
15270
|
function isBareSpecifier(source) {
|
|
15104
|
-
return !source.startsWith("\0") && !source.startsWith(".") && !source.startsWith("/") && !
|
|
15271
|
+
return !source.startsWith("\0") && !source.startsWith(".") && !source.startsWith("/") && !path41.isAbsolute(source);
|
|
15105
15272
|
}
|
|
15106
15273
|
function isInsideNodeModules(filePath) {
|
|
15107
15274
|
return filePath.split(/[\\/]/).includes("node_modules");
|
|
@@ -15125,7 +15292,7 @@ function viteOffrootResolvePlugin() {
|
|
|
15125
15292
|
if (!shouldResolveFromSiteRoot(source, importer, rootDir)) {
|
|
15126
15293
|
return;
|
|
15127
15294
|
}
|
|
15128
|
-
return this.resolve(source,
|
|
15295
|
+
return this.resolve(source, path41.join(rootDir, "package.json"), {
|
|
15129
15296
|
...options,
|
|
15130
15297
|
skipSelf: true
|
|
15131
15298
|
});
|
|
@@ -15135,7 +15302,7 @@ function viteOffrootResolvePlugin() {
|
|
|
15135
15302
|
|
|
15136
15303
|
// src/vite/plugin-search.ts
|
|
15137
15304
|
init_loader();
|
|
15138
|
-
import
|
|
15305
|
+
import path42 from "node:path";
|
|
15139
15306
|
var viteSearchPlugin = () => {
|
|
15140
15307
|
const virtualModuleId4 = "virtual:zudoku-search-plugin";
|
|
15141
15308
|
const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
|
|
@@ -15153,7 +15320,7 @@ var viteSearchPlugin = () => {
|
|
|
15153
15320
|
return resolvedVirtualModuleId5;
|
|
15154
15321
|
}
|
|
15155
15322
|
if (id === "/pagefind/pagefind.js" && resolvedViteConfig?.publicDir) {
|
|
15156
|
-
return
|
|
15323
|
+
return path42.join(resolvedViteConfig.publicDir, "pagefind/pagefind.js");
|
|
15157
15324
|
}
|
|
15158
15325
|
},
|
|
15159
15326
|
async load(id) {
|
|
@@ -15294,27 +15461,27 @@ function vitePlugin() {
|
|
|
15294
15461
|
|
|
15295
15462
|
// src/vite/watch-ignore.ts
|
|
15296
15463
|
import { lstatSync, realpathSync } from "node:fs";
|
|
15297
|
-
import
|
|
15464
|
+
import path43 from "node:path";
|
|
15298
15465
|
var STATE_INSIDE_CONTENT = /[\\/]content[\\/](?:\.apitogo|apitogo[\\/]\.state)(?:[\\/]|$)/;
|
|
15299
15466
|
var within = (base, file) => {
|
|
15300
|
-
const resolvedBase =
|
|
15301
|
-
const resolvedFile =
|
|
15302
|
-
return resolvedFile === resolvedBase || resolvedFile.startsWith(resolvedBase +
|
|
15467
|
+
const resolvedBase = path43.resolve(base);
|
|
15468
|
+
const resolvedFile = path43.resolve(file);
|
|
15469
|
+
return resolvedFile === resolvedBase || resolvedFile.startsWith(resolvedBase + path43.sep);
|
|
15303
15470
|
};
|
|
15304
15471
|
var unique = (paths) => [...new Set(paths)];
|
|
15305
15472
|
function isWorkspace(root) {
|
|
15306
15473
|
try {
|
|
15307
|
-
return
|
|
15474
|
+
return path43.basename(root) === "generated" && lstatSync(path43.join(root, "content")).isSymbolicLink();
|
|
15308
15475
|
} catch {
|
|
15309
15476
|
return false;
|
|
15310
15477
|
}
|
|
15311
15478
|
}
|
|
15312
15479
|
function tenantDir(root) {
|
|
15313
|
-
return isWorkspace(root) ? realpathSync(
|
|
15480
|
+
return isWorkspace(root) ? realpathSync(path43.join(root, "content")) : void 0;
|
|
15314
15481
|
}
|
|
15315
15482
|
function stateIgnore(root) {
|
|
15316
15483
|
if (!isWorkspace(root)) return void 0;
|
|
15317
|
-
const state =
|
|
15484
|
+
const state = path43.dirname(root);
|
|
15318
15485
|
const states = unique([state, realpathSync(state)]);
|
|
15319
15486
|
const roots = unique([root, realpathSync(root)]);
|
|
15320
15487
|
return (file) => {
|
|
@@ -15323,19 +15490,28 @@ function stateIgnore(root) {
|
|
|
15323
15490
|
return STATE_INSIDE_CONTENT.test(file);
|
|
15324
15491
|
};
|
|
15325
15492
|
}
|
|
15493
|
+
var STATE_FOLDER = /(?:^|[\\/])(?:\.apitogo|apitogo[\\/]\.state)(?:[\\/]|$)/;
|
|
15494
|
+
function nestedStateIgnore(root) {
|
|
15495
|
+
const resolvedRoot = path43.resolve(root);
|
|
15496
|
+
return (file) => {
|
|
15497
|
+
const relative = path43.relative(resolvedRoot, path43.resolve(file));
|
|
15498
|
+
if (relative.startsWith("..") || path43.isAbsolute(relative)) return false;
|
|
15499
|
+
return STATE_FOLDER.test(relative);
|
|
15500
|
+
};
|
|
15501
|
+
}
|
|
15326
15502
|
function devServerAllow(root, moduleDir) {
|
|
15327
15503
|
const tenant = tenantDir(root);
|
|
15328
|
-
return [root,
|
|
15504
|
+
return [root, path43.dirname(root), moduleDir, ...tenant ? [tenant] : []];
|
|
15329
15505
|
}
|
|
15330
15506
|
|
|
15331
15507
|
// src/vite/config.ts
|
|
15332
15508
|
var resolveMergedPublicDir = (rootDir, merged) => {
|
|
15333
15509
|
if (merged.publicDir === false) return void 0;
|
|
15334
15510
|
const rel2 = typeof merged.publicDir === "string" ? merged.publicDir : "public";
|
|
15335
|
-
return
|
|
15511
|
+
return path44.resolve(rootDir, rel2);
|
|
15336
15512
|
};
|
|
15337
|
-
var getAppClientEntryPath = () =>
|
|
15338
|
-
var getAppServerEntryPath = () =>
|
|
15513
|
+
var getAppClientEntryPath = () => path44.posix.join(getZudokuRootDir(), "src/app/entry.client.tsx");
|
|
15514
|
+
var getAppServerEntryPath = () => path44.posix.join(getZudokuRootDir(), "src/app/entry.server.tsx");
|
|
15339
15515
|
var hasLoggedCdnInfo = false;
|
|
15340
15516
|
var MEDIA_REGEX = /\.(a?png|jpe?g|gif|bmp|svg|webp|tiff|ico|webm|ogg|mp3|wav|m4a|avif|mp4)/i;
|
|
15341
15517
|
var defineEnvVars = (vars) => Object.fromEntries(
|
|
@@ -15366,7 +15542,7 @@ async function getViteConfig(dir, configEnv) {
|
|
|
15366
15542
|
const ignoreState = stateIgnore(dir);
|
|
15367
15543
|
if (ZuploEnv.isZuplo) {
|
|
15368
15544
|
dotenv.config({
|
|
15369
|
-
path:
|
|
15545
|
+
path: path44.resolve(config2.__meta.rootDir, "../.env.zuplo"),
|
|
15370
15546
|
quiet: true
|
|
15371
15547
|
});
|
|
15372
15548
|
}
|
|
@@ -15421,6 +15597,7 @@ async function getViteConfig(dir, configEnv) {
|
|
|
15421
15597
|
`${dir}/.git`,
|
|
15422
15598
|
`${config2.__meta.moduleDir}/src/vite`,
|
|
15423
15599
|
`${config2.__meta.moduleDir}/src/cli`,
|
|
15600
|
+
nestedStateIgnore(dir),
|
|
15424
15601
|
...ignoreState ? [ignoreState] : []
|
|
15425
15602
|
]
|
|
15426
15603
|
}
|
|
@@ -15429,8 +15606,8 @@ async function getViteConfig(dir, configEnv) {
|
|
|
15429
15606
|
ssr: configEnv.isSsrBuild,
|
|
15430
15607
|
sourcemap: true,
|
|
15431
15608
|
target: "es2022",
|
|
15432
|
-
outDir:
|
|
15433
|
-
|
|
15609
|
+
outDir: path44.resolve(
|
|
15610
|
+
path44.join(
|
|
15434
15611
|
dir,
|
|
15435
15612
|
"dist",
|
|
15436
15613
|
config2.basePath ?? "",
|
|
@@ -15449,7 +15626,7 @@ async function getViteConfig(dir, configEnv) {
|
|
|
15449
15626
|
},
|
|
15450
15627
|
experimental: {
|
|
15451
15628
|
renderBuiltUrl(filename) {
|
|
15452
|
-
if (cdnUrl?.base && [".js", ".css"].includes(
|
|
15629
|
+
if (cdnUrl?.base && [".js", ".css"].includes(path44.extname(filename))) {
|
|
15453
15630
|
return joinUrl(cdnUrl.base, filename);
|
|
15454
15631
|
}
|
|
15455
15632
|
if (cdnUrl?.media && MEDIA_REGEX.test(filename)) {
|
|
@@ -15462,7 +15639,7 @@ async function getViteConfig(dir, configEnv) {
|
|
|
15462
15639
|
esbuildOptions: {
|
|
15463
15640
|
target: "es2022"
|
|
15464
15641
|
},
|
|
15465
|
-
entries: [
|
|
15642
|
+
entries: [path44.posix.join(getZudokuRootDir(), "src/{app,lib}/**")],
|
|
15466
15643
|
exclude: [
|
|
15467
15644
|
"@lukoweb/apitogo",
|
|
15468
15645
|
"@lukoweb/apitogo-plugin-dev-portal-billing"
|
|
@@ -15566,7 +15743,7 @@ init_package_json();
|
|
|
15566
15743
|
init_joinUrl();
|
|
15567
15744
|
import assert from "node:assert";
|
|
15568
15745
|
import { cp, mkdir as mkdir9, writeFile as writeFile11 } from "node:fs/promises";
|
|
15569
|
-
import
|
|
15746
|
+
import path45 from "node:path";
|
|
15570
15747
|
var pkgJson = getZudokuPackageJson();
|
|
15571
15748
|
function generateOutput({
|
|
15572
15749
|
config: config2,
|
|
@@ -15623,9 +15800,9 @@ async function writeOutput(dir, {
|
|
|
15623
15800
|
rewrites
|
|
15624
15801
|
}) {
|
|
15625
15802
|
const output4 = generateOutput({ config: config2, redirects, rewrites });
|
|
15626
|
-
const outputDir = process.env.VERCEL ?
|
|
15803
|
+
const outputDir = process.env.VERCEL ? path45.join(dir, ".vercel/output") : path45.join(dir, "dist/.output");
|
|
15627
15804
|
await mkdir9(outputDir, { recursive: true });
|
|
15628
|
-
const outputFile =
|
|
15805
|
+
const outputFile = path45.join(outputDir, "config.json");
|
|
15629
15806
|
await writeFile11(outputFile, JSON.stringify(output4, null, 2), "utf-8");
|
|
15630
15807
|
if (process.env.VERCEL) {
|
|
15631
15808
|
console.log("Wrote Vercel output to", outputDir);
|
|
@@ -15635,9 +15812,9 @@ async function writeOutput(dir, {
|
|
|
15635
15812
|
// src/vite/prerender/prerender.ts
|
|
15636
15813
|
init_logger();
|
|
15637
15814
|
init_file_exists();
|
|
15638
|
-
import { readFile as readFile12
|
|
15815
|
+
import { readFile as readFile12 } from "node:fs/promises";
|
|
15639
15816
|
import os from "node:os";
|
|
15640
|
-
import
|
|
15817
|
+
import path48 from "node:path";
|
|
15641
15818
|
import { pathToFileURL } from "node:url";
|
|
15642
15819
|
import { createIndex } from "pagefind";
|
|
15643
15820
|
import colors11 from "picocolors";
|
|
@@ -15679,7 +15856,7 @@ function throttle(fn) {
|
|
|
15679
15856
|
init_joinUrl();
|
|
15680
15857
|
import { createWriteStream, existsSync as existsSync5 } from "node:fs";
|
|
15681
15858
|
import { mkdir as mkdir10 } from "node:fs/promises";
|
|
15682
|
-
import
|
|
15859
|
+
import path46 from "node:path";
|
|
15683
15860
|
import colors9 from "picocolors";
|
|
15684
15861
|
import { SitemapStream } from "sitemap";
|
|
15685
15862
|
async function generateSitemap({
|
|
@@ -15693,11 +15870,11 @@ async function generateSitemap({
|
|
|
15693
15870
|
return;
|
|
15694
15871
|
}
|
|
15695
15872
|
const sitemap = new SitemapStream({ hostname: config2.siteUrl });
|
|
15696
|
-
const outputDir =
|
|
15873
|
+
const outputDir = path46.resolve(baseOutputDir, config2.outDir ?? "");
|
|
15697
15874
|
if (!existsSync5(outputDir)) {
|
|
15698
15875
|
await mkdir10(outputDir, { recursive: true });
|
|
15699
15876
|
}
|
|
15700
|
-
const sitemapOutputPath =
|
|
15877
|
+
const sitemapOutputPath = path46.join(outputDir, "sitemap.xml");
|
|
15701
15878
|
const writeStream = createWriteStream(sitemapOutputPath);
|
|
15702
15879
|
sitemap.pipe(writeStream);
|
|
15703
15880
|
let lastmod;
|
|
@@ -15727,14 +15904,14 @@ async function generateSitemap({
|
|
|
15727
15904
|
|
|
15728
15905
|
// src/vite/prerender/utils.ts
|
|
15729
15906
|
init_joinUrl();
|
|
15730
|
-
var resolveRoutePath = (
|
|
15731
|
-
const segments =
|
|
15907
|
+
var resolveRoutePath = (path100) => {
|
|
15908
|
+
const segments = path100.split("/");
|
|
15732
15909
|
if (segments.some((s) => s.startsWith(":") && !s.endsWith("?"))) {
|
|
15733
15910
|
return void 0;
|
|
15734
15911
|
}
|
|
15735
15912
|
return segments.filter((s) => !s.startsWith(":")).join("/") || void 0;
|
|
15736
15913
|
};
|
|
15737
|
-
var isSkipped = (
|
|
15914
|
+
var isSkipped = (path100) => path100.includes("*") || /^\d+$/.test(path100);
|
|
15738
15915
|
var resolveRoutes = (routes, parentPath = "") => routes.flatMap((route) => {
|
|
15739
15916
|
if (route.path && isSkipped(route.path)) return [];
|
|
15740
15917
|
const routePath = route.path ? resolveRoutePath(route.path) : void 0;
|
|
@@ -15784,12 +15961,12 @@ var prerender = async ({
|
|
|
15784
15961
|
serverConfigFilename,
|
|
15785
15962
|
writeRedirects = true
|
|
15786
15963
|
}) => {
|
|
15787
|
-
const distDir =
|
|
15964
|
+
const distDir = path48.join(dir, "dist", basePath);
|
|
15788
15965
|
const serverConfigPath = pathToFileURL(
|
|
15789
|
-
|
|
15966
|
+
path48.join(distDir, "server", serverConfigFilename)
|
|
15790
15967
|
).href;
|
|
15791
15968
|
const entryServerPath = pathToFileURL(
|
|
15792
|
-
|
|
15969
|
+
path48.join(distDir, "server/entry.server.js")
|
|
15793
15970
|
).href;
|
|
15794
15971
|
const rawConfig = await import(serverConfigPath).then(
|
|
15795
15972
|
(m) => m.default
|
|
@@ -15874,7 +16051,7 @@ var prerender = async ({
|
|
|
15874
16051
|
})
|
|
15875
16052
|
);
|
|
15876
16053
|
const pagefindWriteResult = await pagefindIndex?.writeFiles({
|
|
15877
|
-
outputPath:
|
|
16054
|
+
outputPath: path48.join(distDir, "pagefind")
|
|
15878
16055
|
});
|
|
15879
16056
|
const seconds = ((performance.now() - start) / 1e3).toFixed(1);
|
|
15880
16057
|
const message = `\u2713 finished prerendering ${paths.length} routes in ${seconds} seconds using ${maxThreads} workers`;
|
|
@@ -15906,7 +16083,7 @@ var prerender = async ({
|
|
|
15906
16083
|
const { generateLlmsTxtFiles: generateLlmsTxtFiles2 } = await Promise.resolve().then(() => (init_llms(), llms_exports));
|
|
15907
16084
|
const docsConfig = DocsConfigSchema2.parse(config2.docs);
|
|
15908
16085
|
const llmsConfig = docsConfig.llms ?? {};
|
|
15909
|
-
const markdownInfoPath =
|
|
16086
|
+
const markdownInfoPath = path48.join(
|
|
15910
16087
|
dir,
|
|
15911
16088
|
"node_modules/.apitogo/markdown-info.json"
|
|
15912
16089
|
);
|
|
@@ -15928,10 +16105,7 @@ var prerender = async ({
|
|
|
15928
16105
|
});
|
|
15929
16106
|
}
|
|
15930
16107
|
if (!docsConfig.publishMarkdown) {
|
|
15931
|
-
await
|
|
15932
|
-
markdownFileInfos.map((info) => rm6(info.filePath).catch(() => {
|
|
15933
|
-
}))
|
|
15934
|
-
);
|
|
16108
|
+
await removeExportedMarkdown(distDir, markdownFileInfos);
|
|
15935
16109
|
}
|
|
15936
16110
|
}
|
|
15937
16111
|
return { workerResults, rewrites };
|
|
@@ -15997,7 +16171,7 @@ async function runBuild(options) {
|
|
|
15997
16171
|
html,
|
|
15998
16172
|
basePath: config2.basePath
|
|
15999
16173
|
});
|
|
16000
|
-
await rm7(
|
|
16174
|
+
await rm7(path49.join(clientOutDir, "index.html"), { force: true });
|
|
16001
16175
|
} else {
|
|
16002
16176
|
await runPrerender({
|
|
16003
16177
|
dir,
|
|
@@ -16021,7 +16195,7 @@ var runPrerender = async (options) => {
|
|
|
16021
16195
|
serverConfigFilename,
|
|
16022
16196
|
writeRedirects: process.env.VERCEL === void 0
|
|
16023
16197
|
});
|
|
16024
|
-
const indexHtml =
|
|
16198
|
+
const indexHtml = path49.join(clientOutDir, "index.html");
|
|
16025
16199
|
if (!workerResults.find((r) => r.outputPath === indexHtml)) {
|
|
16026
16200
|
await writeFile13(indexHtml, html, "utf-8");
|
|
16027
16201
|
}
|
|
@@ -16031,15 +16205,15 @@ var runPrerender = async (options) => {
|
|
|
16031
16205
|
for (const statusPage of statusPages) {
|
|
16032
16206
|
await rename5(
|
|
16033
16207
|
statusPage,
|
|
16034
|
-
|
|
16208
|
+
path49.join(dir, DIST_DIR, path49.basename(statusPage))
|
|
16035
16209
|
);
|
|
16036
16210
|
}
|
|
16037
16211
|
await rm7(serverOutDir, { recursive: true, force: true });
|
|
16038
16212
|
if (process.env.VERCEL) {
|
|
16039
|
-
await mkdir11(
|
|
16213
|
+
await mkdir11(path49.join(dir, ".vercel/output/static"), { recursive: true });
|
|
16040
16214
|
await rename5(
|
|
16041
|
-
|
|
16042
|
-
|
|
16215
|
+
path49.join(dir, DIST_DIR),
|
|
16216
|
+
path49.join(dir, ".vercel/output/static")
|
|
16043
16217
|
);
|
|
16044
16218
|
}
|
|
16045
16219
|
await writeOutput(dir, {
|
|
@@ -16049,7 +16223,7 @@ var runPrerender = async (options) => {
|
|
|
16049
16223
|
});
|
|
16050
16224
|
if (ZuploEnv.isZuplo && issuer) {
|
|
16051
16225
|
await writeFile13(
|
|
16052
|
-
|
|
16226
|
+
path49.join(dir, DIST_DIR, ".output/zuplo.json"),
|
|
16053
16227
|
JSON.stringify({ issuer }, null, 2),
|
|
16054
16228
|
"utf-8"
|
|
16055
16229
|
);
|
|
@@ -16061,10 +16235,10 @@ var runPrerender = async (options) => {
|
|
|
16061
16235
|
};
|
|
16062
16236
|
var bundleSSREntry = async (options) => {
|
|
16063
16237
|
const { dir, adapter, serverOutDir, serverConfigFilename, html, basePath } = options;
|
|
16064
|
-
const tempEntryPath =
|
|
16238
|
+
const tempEntryPath = path49.join(dir, "__ssr-entry.ts");
|
|
16065
16239
|
const packageRoot = getZudokuRootDir();
|
|
16066
16240
|
const templateContent = await readFile13(
|
|
16067
|
-
|
|
16241
|
+
path49.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
|
|
16068
16242
|
"utf-8"
|
|
16069
16243
|
);
|
|
16070
16244
|
const entryContent = templateContent.replace('"__TEMPLATE__"', JSON.stringify(html)).replace('"__CONFIG_FILE__"', JSON.stringify(`./${serverConfigFilename}`)).replace(
|
|
@@ -16079,9 +16253,9 @@ var bundleSSREntry = async (options) => {
|
|
|
16079
16253
|
platform: adapter === "node" ? "node" : "neutral",
|
|
16080
16254
|
target: "es2022",
|
|
16081
16255
|
format: "esm",
|
|
16082
|
-
outfile:
|
|
16256
|
+
outfile: path49.join(serverOutDir, "entry.js"),
|
|
16083
16257
|
external: ["./entry.server.js", `./${serverConfigFilename}`],
|
|
16084
|
-
nodePaths: [
|
|
16258
|
+
nodePaths: [path49.join(packageRoot, "node_modules")],
|
|
16085
16259
|
banner: { js: "// Bundled SSR entry" }
|
|
16086
16260
|
});
|
|
16087
16261
|
} finally {
|
|
@@ -16095,7 +16269,7 @@ init_package_json();
|
|
|
16095
16269
|
// src/cli/init/v2-packages.ts
|
|
16096
16270
|
import { existsSync as existsSync6 } from "node:fs";
|
|
16097
16271
|
import { readFile as readFile14, writeFile as writeFile14 } from "node:fs/promises";
|
|
16098
|
-
import
|
|
16272
|
+
import path50 from "node:path";
|
|
16099
16273
|
var CORE_PACKAGES = [
|
|
16100
16274
|
"@lukoweb/apitogo",
|
|
16101
16275
|
"react",
|
|
@@ -16112,7 +16286,7 @@ function packageNameFrom(name) {
|
|
|
16112
16286
|
return slug || "portal";
|
|
16113
16287
|
}
|
|
16114
16288
|
async function ensurePackageJson(dir, name) {
|
|
16115
|
-
const file =
|
|
16289
|
+
const file = path50.join(dir, "package.json");
|
|
16116
16290
|
if (existsSync6(file)) return false;
|
|
16117
16291
|
await writeFile14(
|
|
16118
16292
|
file,
|
|
@@ -16131,11 +16305,11 @@ async function ensurePackageJson(dir, name) {
|
|
|
16131
16305
|
return true;
|
|
16132
16306
|
}
|
|
16133
16307
|
function isPackageInstalled(startDir, name) {
|
|
16134
|
-
let dir =
|
|
16308
|
+
let dir = path50.resolve(startDir);
|
|
16135
16309
|
for (; ; ) {
|
|
16136
|
-
if (existsSync6(
|
|
16310
|
+
if (existsSync6(path50.join(dir, "node_modules", name, "package.json")))
|
|
16137
16311
|
return true;
|
|
16138
|
-
const parent =
|
|
16312
|
+
const parent = path50.dirname(dir);
|
|
16139
16313
|
if (parent === dir) return false;
|
|
16140
16314
|
dir = parent;
|
|
16141
16315
|
}
|
|
@@ -16192,7 +16366,7 @@ function portalBuildStep(context, options = {}, build2 = runBuild) {
|
|
|
16192
16366
|
return {
|
|
16193
16367
|
name: "build",
|
|
16194
16368
|
hash: () => hash2,
|
|
16195
|
-
stillValid: () => access4(
|
|
16369
|
+
stillValid: () => access4(path51.join(buildDir, "index.html")).then(
|
|
16196
16370
|
() => true,
|
|
16197
16371
|
() => false
|
|
16198
16372
|
),
|
|
@@ -16209,11 +16383,11 @@ function portalBuildStep(context, options = {}, build2 = runBuild) {
|
|
|
16209
16383
|
else process.env.NODE_ENV = originalNodeEnv;
|
|
16210
16384
|
}
|
|
16211
16385
|
await rm8(buildDir, { recursive: true, force: true });
|
|
16212
|
-
await mkdir12(
|
|
16213
|
-
await rename6(
|
|
16386
|
+
await mkdir12(path51.dirname(buildDir), { recursive: true });
|
|
16387
|
+
await rename6(path51.join(root, "dist"), buildDir);
|
|
16214
16388
|
if (prepared.publishedManifest) {
|
|
16215
16389
|
await writeFile15(
|
|
16216
|
-
|
|
16390
|
+
path51.join(buildDir, MANIFEST_FILE),
|
|
16217
16391
|
`${JSON.stringify(prepared.publishedManifest, null, 2)}
|
|
16218
16392
|
`
|
|
16219
16393
|
);
|
|
@@ -16244,15 +16418,15 @@ async function buildV2(options) {
|
|
|
16244
16418
|
// src/cli/check/gateway-online.ts
|
|
16245
16419
|
import { readFile as readFile16 } from "node:fs/promises";
|
|
16246
16420
|
var SPEC_SEND_LIMIT = 5 * 1024 * 1024 + 64 * 1024;
|
|
16247
|
-
var issue2 = (code,
|
|
16421
|
+
var issue2 = (code, path100, message, hint) => ({ code, path: path100, message, hint });
|
|
16248
16422
|
function capabilityIssues(gateway, answer) {
|
|
16249
16423
|
const can = answer.capabilities;
|
|
16250
16424
|
const plan2 = `your ${answer.tier} plan`;
|
|
16251
16425
|
const found = [];
|
|
16252
|
-
const unsupported = (
|
|
16426
|
+
const unsupported = (path100, what, hint) => found.push(
|
|
16253
16427
|
issue2(
|
|
16254
16428
|
"GATEWAY_CAPABILITY_UNSUPPORTED",
|
|
16255
|
-
|
|
16429
|
+
path100,
|
|
16256
16430
|
`${what} is not available on ${plan2}.`,
|
|
16257
16431
|
hint
|
|
16258
16432
|
)
|
|
@@ -16463,9 +16637,9 @@ function toPlatformPlans(plans, options = {}) {
|
|
|
16463
16637
|
}
|
|
16464
16638
|
|
|
16465
16639
|
// src/cli/check/services-online.ts
|
|
16466
|
-
var issue3 = (code,
|
|
16640
|
+
var issue3 = (code, path100, message, hint) => ({
|
|
16467
16641
|
code,
|
|
16468
|
-
path:
|
|
16642
|
+
path: path100,
|
|
16469
16643
|
message,
|
|
16470
16644
|
hint
|
|
16471
16645
|
});
|
|
@@ -16577,7 +16751,7 @@ var withPlanName = (message, sku) => !sku || message.toLowerCase().startsWith(`p
|
|
|
16577
16751
|
async function isConfigV2(dir) {
|
|
16578
16752
|
try {
|
|
16579
16753
|
return /"version"\s*:\s*2\b/.test(
|
|
16580
|
-
await readFile18(
|
|
16754
|
+
await readFile18(path52.join(dir, APITOGO_CONFIG_FILENAME), "utf8")
|
|
16581
16755
|
);
|
|
16582
16756
|
} catch {
|
|
16583
16757
|
return false;
|
|
@@ -16586,7 +16760,7 @@ async function isConfigV2(dir) {
|
|
|
16586
16760
|
async function isLegacyConfig(dir) {
|
|
16587
16761
|
let text2;
|
|
16588
16762
|
try {
|
|
16589
|
-
text2 = await readFile18(
|
|
16763
|
+
text2 = await readFile18(path52.join(dir, APITOGO_CONFIG_FILENAME), "utf8");
|
|
16590
16764
|
} catch {
|
|
16591
16765
|
return false;
|
|
16592
16766
|
}
|
|
@@ -16734,7 +16908,7 @@ async function validatePortalBuild(dir) {
|
|
|
16734
16908
|
}
|
|
16735
16909
|
}
|
|
16736
16910
|
async function runCheckV2(dir, args = {}, deps = {}) {
|
|
16737
|
-
const configPath =
|
|
16911
|
+
const configPath = path52.join(dir, APITOGO_CONFIG_FILENAME);
|
|
16738
16912
|
let report;
|
|
16739
16913
|
try {
|
|
16740
16914
|
const { config: config2, resolved } = loadConfigV2(dir);
|
|
@@ -16844,7 +17018,7 @@ async function checkV2(dir, args, deps = platformDependencies(args)) {
|
|
|
16844
17018
|
init_package_json();
|
|
16845
17019
|
|
|
16846
17020
|
// src/cli/init/v2-handler.ts
|
|
16847
|
-
import
|
|
17021
|
+
import path53 from "node:path";
|
|
16848
17022
|
import { createInterface } from "node:readline/promises";
|
|
16849
17023
|
function parseDocsFlag(value) {
|
|
16850
17024
|
if (value === void 0) return void 0;
|
|
@@ -16866,15 +17040,15 @@ async function ask(question) {
|
|
|
16866
17040
|
}
|
|
16867
17041
|
function describePlan(plan2) {
|
|
16868
17042
|
return {
|
|
16869
|
-
willCreate: plan2.entries.filter((entry) => !plan2.keep.includes(entry.path)).map((entry) =>
|
|
16870
|
-
willKeep: plan2.keep.map((target) =>
|
|
17043
|
+
willCreate: plan2.entries.filter((entry) => !plan2.keep.includes(entry.path)).map((entry) => path53.relative(plan2.dir, entry.path)),
|
|
17044
|
+
willKeep: plan2.keep.map((target) => path53.relative(plan2.dir, target)),
|
|
16871
17045
|
replacesConfig: plan2.replacesConfig
|
|
16872
17046
|
};
|
|
16873
17047
|
}
|
|
16874
17048
|
async function initV2(argv) {
|
|
16875
17049
|
const json = argv.json === true;
|
|
16876
17050
|
try {
|
|
16877
|
-
const dir =
|
|
17051
|
+
const dir = path53.resolve(process.cwd(), argv.dir ?? ".");
|
|
16878
17052
|
const plan2 = await planInit({
|
|
16879
17053
|
dir,
|
|
16880
17054
|
name: argv.name,
|
|
@@ -16915,8 +17089,8 @@ async function initV2(argv) {
|
|
|
16915
17089
|
status: "created",
|
|
16916
17090
|
dir,
|
|
16917
17091
|
...describePlan(plan2),
|
|
16918
|
-
created: result.created.map((p) =>
|
|
16919
|
-
kept: result.kept.map((p) =>
|
|
17092
|
+
created: result.created.map((p) => path53.relative(dir, p)),
|
|
17093
|
+
kept: result.kept.map((p) => path53.relative(dir, p))
|
|
16920
17094
|
},
|
|
16921
17095
|
null,
|
|
16922
17096
|
2
|
|
@@ -16925,7 +17099,7 @@ async function initV2(argv) {
|
|
|
16925
17099
|
return;
|
|
16926
17100
|
}
|
|
16927
17101
|
printResultToConsole(
|
|
16928
|
-
`Created ${
|
|
17102
|
+
`Created ${path53.basename(plan2.configPath)} (config version 2) in ${dir}.`
|
|
16929
17103
|
);
|
|
16930
17104
|
printHintToConsole(
|
|
16931
17105
|
"Next: add a service with `apitogo add <portal|gateway|identity|plans>`, or run `apitogo create` for a guided setup."
|
|
@@ -16952,7 +17126,7 @@ async function initV2(argv) {
|
|
|
16952
17126
|
|
|
16953
17127
|
// src/cli/services/packages.ts
|
|
16954
17128
|
import { existsSync as existsSync7 } from "node:fs";
|
|
16955
|
-
import
|
|
17129
|
+
import path54 from "node:path";
|
|
16956
17130
|
|
|
16957
17131
|
// src/cli/common/spawn-command.ts
|
|
16958
17132
|
import {
|
|
@@ -16985,18 +17159,18 @@ function packagesForConfig(config2) {
|
|
|
16985
17159
|
];
|
|
16986
17160
|
}
|
|
16987
17161
|
function isInstalled(dir, name) {
|
|
16988
|
-
for (let current =
|
|
16989
|
-
if (existsSync7(
|
|
17162
|
+
for (let current = path54.resolve(dir); ; current = path54.dirname(current)) {
|
|
17163
|
+
if (existsSync7(path54.join(current, "node_modules", name, "package.json")))
|
|
16990
17164
|
return true;
|
|
16991
|
-
if (
|
|
17165
|
+
if (path54.dirname(current) === current) return false;
|
|
16992
17166
|
}
|
|
16993
17167
|
}
|
|
16994
17168
|
function missingPackages(dir, names) {
|
|
16995
17169
|
return names.filter((name) => !isInstalled(dir, name));
|
|
16996
17170
|
}
|
|
16997
17171
|
function detectPackageManager(dir) {
|
|
16998
|
-
if (existsSync7(
|
|
16999
|
-
if (existsSync7(
|
|
17172
|
+
if (existsSync7(path54.join(dir, "pnpm-lock.yaml"))) return "pnpm";
|
|
17173
|
+
if (existsSync7(path54.join(dir, "yarn.lock"))) return "yarn";
|
|
17000
17174
|
return "npm";
|
|
17001
17175
|
}
|
|
17002
17176
|
function installSpecsCommand(manager, specs) {
|
|
@@ -17054,7 +17228,7 @@ async function installMissingPackages(dir, config2, version, options) {
|
|
|
17054
17228
|
reason: "--no-install was given",
|
|
17055
17229
|
command: shown
|
|
17056
17230
|
};
|
|
17057
|
-
await ensurePackageJson(dir, config2.project?.name ??
|
|
17231
|
+
await ensurePackageJson(dir, config2.project?.name ?? path54.basename(dir));
|
|
17058
17232
|
await (options.installer ?? runInstaller)(dir, command2);
|
|
17059
17233
|
return { status: "installed", packages: missing, command: shown };
|
|
17060
17234
|
}
|
|
@@ -17117,7 +17291,7 @@ var list = (value) => {
|
|
|
17117
17291
|
return items.length > 0 ? items : void 0;
|
|
17118
17292
|
};
|
|
17119
17293
|
function addOptionsFromArguments(service, argv) {
|
|
17120
|
-
const dir =
|
|
17294
|
+
const dir = path55.resolve(process.cwd(), argv.dir ?? ".");
|
|
17121
17295
|
const issuers = list(argv.issuer);
|
|
17122
17296
|
return {
|
|
17123
17297
|
dir,
|
|
@@ -17171,8 +17345,8 @@ function describe(edit, dir) {
|
|
|
17171
17345
|
return {
|
|
17172
17346
|
service: edit.service,
|
|
17173
17347
|
action: edit.action,
|
|
17174
|
-
willCreate: edit.files.map((file) =>
|
|
17175
|
-
keep: edit.keep.map((file) =>
|
|
17348
|
+
willCreate: edit.files.map((file) => path55.relative(dir, file.path)),
|
|
17349
|
+
keep: edit.keep.map((file) => path55.relative(dir, file)),
|
|
17176
17350
|
notes: edit.notes
|
|
17177
17351
|
};
|
|
17178
17352
|
}
|
|
@@ -17186,7 +17360,7 @@ async function run(action, argv, plan2, deps = {}) {
|
|
|
17186
17360
|
`Choose one of ${SERVICES.join(", ")}.`
|
|
17187
17361
|
);
|
|
17188
17362
|
}
|
|
17189
|
-
const dir =
|
|
17363
|
+
const dir = path55.resolve(process.cwd(), argv.dir ?? ".");
|
|
17190
17364
|
if (!await isConfigV2(dir)) {
|
|
17191
17365
|
throw new ServiceEditError(
|
|
17192
17366
|
`${action} works with a config version 2 project, and there is none in ${dir}.`,
|
|
@@ -17254,7 +17428,7 @@ async function run(action, argv, plan2, deps = {}) {
|
|
|
17254
17428
|
{
|
|
17255
17429
|
status: action === "add" ? "added" : "removed",
|
|
17256
17430
|
...describe(edit, dir),
|
|
17257
|
-
created: created.map((file) =>
|
|
17431
|
+
created: created.map((file) => path55.relative(dir, file)),
|
|
17258
17432
|
...install ? { packages: install } : {}
|
|
17259
17433
|
},
|
|
17260
17434
|
null,
|
|
@@ -17264,7 +17438,7 @@ async function run(action, argv, plan2, deps = {}) {
|
|
|
17264
17438
|
return;
|
|
17265
17439
|
}
|
|
17266
17440
|
printResultToConsole(
|
|
17267
|
-
`${action === "add" ? "Added" : "Removed"} ${edit.service} in ${
|
|
17441
|
+
`${action === "add" ? "Added" : "Removed"} ${edit.service} in ${path55.basename(edit.configPath)}.`
|
|
17268
17442
|
);
|
|
17269
17443
|
} catch (error) {
|
|
17270
17444
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -17325,7 +17499,7 @@ var removeService = (argv) => run(
|
|
|
17325
17499
|
"remove",
|
|
17326
17500
|
argv,
|
|
17327
17501
|
(service) => planRemoveService(service, {
|
|
17328
|
-
dir:
|
|
17502
|
+
dir: path55.resolve(process.cwd(), argv.dir ?? "."),
|
|
17329
17503
|
deleteFiles: argv.deleteFiles === true
|
|
17330
17504
|
})
|
|
17331
17505
|
);
|
|
@@ -17477,16 +17651,16 @@ var add_default = {
|
|
|
17477
17651
|
};
|
|
17478
17652
|
|
|
17479
17653
|
// src/cli/build/handler.ts
|
|
17480
|
-
import
|
|
17654
|
+
import path57 from "node:path";
|
|
17481
17655
|
init_logger();
|
|
17482
17656
|
init_package_json();
|
|
17483
17657
|
|
|
17484
17658
|
// src/cli/preview/handler.ts
|
|
17485
|
-
import
|
|
17659
|
+
import path56 from "node:path";
|
|
17486
17660
|
import { preview as vitePreview } from "vite";
|
|
17487
17661
|
var DEFAULT_PREVIEW_PORT = 4e3;
|
|
17488
17662
|
async function preview(argv) {
|
|
17489
|
-
const dir =
|
|
17663
|
+
const dir = path56.resolve(process.cwd(), argv.dir);
|
|
17490
17664
|
const viteConfig = await getViteConfig(dir, {
|
|
17491
17665
|
command: "serve",
|
|
17492
17666
|
mode: "production",
|
|
@@ -17529,7 +17703,7 @@ async function build(argv) {
|
|
|
17529
17703
|
printDiagnosticsToConsole("");
|
|
17530
17704
|
printDiagnosticsToConsole("");
|
|
17531
17705
|
}
|
|
17532
|
-
const dir =
|
|
17706
|
+
const dir = path57.resolve(process.cwd(), argv.dir);
|
|
17533
17707
|
try {
|
|
17534
17708
|
if (await isConfigV2(dir)) {
|
|
17535
17709
|
const result = await buildV2({ dir, jsonOnly });
|
|
@@ -17594,10 +17768,10 @@ var build_default = {
|
|
|
17594
17768
|
};
|
|
17595
17769
|
|
|
17596
17770
|
// src/cli/check/handler.ts
|
|
17597
|
-
import
|
|
17771
|
+
import path63 from "node:path";
|
|
17598
17772
|
|
|
17599
17773
|
// src/cli/platform/tools/check-publish-readiness.ts
|
|
17600
|
-
import
|
|
17774
|
+
import path62 from "node:path";
|
|
17601
17775
|
|
|
17602
17776
|
// src/cli/platform/helpers/dev-portal-backend.ts
|
|
17603
17777
|
function deriveProvisioningState(backend) {
|
|
@@ -17682,7 +17856,7 @@ function formatDevPortalBackendResponse(projectId, backend) {
|
|
|
17682
17856
|
init_gateway_limits();
|
|
17683
17857
|
import { existsSync as existsSync8 } from "node:fs";
|
|
17684
17858
|
import { access as access5, mkdir as mkdir13, readFile as readFile19, writeFile as writeFile16 } from "node:fs/promises";
|
|
17685
|
-
import
|
|
17859
|
+
import path58 from "node:path";
|
|
17686
17860
|
|
|
17687
17861
|
// src/cli/make-config/header-pricing-nav.ts
|
|
17688
17862
|
var HEADER_PRICING_PATH = "/pricing";
|
|
@@ -17804,7 +17978,7 @@ function isPlanFree(plan2) {
|
|
|
17804
17978
|
return (plan2.priceAmount ?? 0) <= 0;
|
|
17805
17979
|
}
|
|
17806
17980
|
function manifestFilePath(siteDirectory) {
|
|
17807
|
-
return
|
|
17981
|
+
return path58.join(path58.resolve(siteDirectory), APITOGO_CONFIG_FILENAME2);
|
|
17808
17982
|
}
|
|
17809
17983
|
var STORED_MANIFEST_KEYS = [
|
|
17810
17984
|
"authentication",
|
|
@@ -18228,23 +18402,23 @@ function resolveBackendSourceDirectory(siteDirectory, sourceDirectory) {
|
|
|
18228
18402
|
if (!trimmed) {
|
|
18229
18403
|
return void 0;
|
|
18230
18404
|
}
|
|
18231
|
-
return
|
|
18405
|
+
return path58.resolve(siteDirectory, trimmed);
|
|
18232
18406
|
}
|
|
18233
18407
|
function resolveBackendOpenApiPath(openApiPath, options) {
|
|
18234
18408
|
const trimmed = openApiPath?.trim();
|
|
18235
18409
|
if (!trimmed) {
|
|
18236
18410
|
return void 0;
|
|
18237
18411
|
}
|
|
18238
|
-
if (
|
|
18412
|
+
if (path58.isAbsolute(trimmed)) {
|
|
18239
18413
|
return trimmed;
|
|
18240
18414
|
}
|
|
18241
|
-
const siteResolved =
|
|
18415
|
+
const siteResolved = path58.resolve(options.siteDirectory, trimmed);
|
|
18242
18416
|
if (existsSync8(siteResolved)) {
|
|
18243
18417
|
return siteResolved;
|
|
18244
18418
|
}
|
|
18245
18419
|
const backendDir = options.backendSourceDirectory?.trim();
|
|
18246
18420
|
if (backendDir) {
|
|
18247
|
-
const backendResolved =
|
|
18421
|
+
const backendResolved = path58.resolve(backendDir, trimmed);
|
|
18248
18422
|
if (existsSync8(backendResolved)) {
|
|
18249
18423
|
return backendResolved;
|
|
18250
18424
|
}
|
|
@@ -18269,7 +18443,7 @@ async function readManifest2(siteDirectory) {
|
|
|
18269
18443
|
}
|
|
18270
18444
|
async function writeManifest2(siteDirectory, manifest) {
|
|
18271
18445
|
const filePath = manifestFilePath(siteDirectory);
|
|
18272
|
-
await mkdir13(
|
|
18446
|
+
await mkdir13(path58.dirname(filePath), { recursive: true });
|
|
18273
18447
|
let config2 = {};
|
|
18274
18448
|
if (await pathExists(filePath)) {
|
|
18275
18449
|
const raw = await readFile19(filePath, "utf8");
|
|
@@ -18295,7 +18469,7 @@ import {
|
|
|
18295
18469
|
unlink,
|
|
18296
18470
|
writeFile as writeFile17
|
|
18297
18471
|
} from "node:fs/promises";
|
|
18298
|
-
import
|
|
18472
|
+
import path59 from "node:path";
|
|
18299
18473
|
var ENV_FILENAME = ".env";
|
|
18300
18474
|
var COLLAPSED_UPPERCASE_ALIASES2 = {
|
|
18301
18475
|
SECRETKEY: "secretKey",
|
|
@@ -18414,12 +18588,12 @@ async function readEnvFile(filePath) {
|
|
|
18414
18588
|
}
|
|
18415
18589
|
}
|
|
18416
18590
|
async function loadSiteEnv(siteDirectory) {
|
|
18417
|
-
const resolvedDirectory =
|
|
18591
|
+
const resolvedDirectory = path59.resolve(siteDirectory);
|
|
18418
18592
|
const merged = { ...process.env };
|
|
18419
18593
|
for (const fileName of [ENV_FILENAME, ".env.local"]) {
|
|
18420
18594
|
Object.assign(
|
|
18421
18595
|
merged,
|
|
18422
|
-
await readEnvFile(
|
|
18596
|
+
await readEnvFile(path59.join(resolvedDirectory, fileName))
|
|
18423
18597
|
);
|
|
18424
18598
|
}
|
|
18425
18599
|
return merged;
|
|
@@ -18456,7 +18630,7 @@ function buildAuthSecretsJson(secrets2, options) {
|
|
|
18456
18630
|
return payload;
|
|
18457
18631
|
}
|
|
18458
18632
|
function envFilePath(siteDirectory) {
|
|
18459
|
-
return
|
|
18633
|
+
return path59.join(path59.resolve(siteDirectory), ENV_FILENAME);
|
|
18460
18634
|
}
|
|
18461
18635
|
function getSecretsStatus(siteDirectory, manifest, secrets2, envExists) {
|
|
18462
18636
|
const providerSecretStatus = {};
|
|
@@ -18492,7 +18666,7 @@ function validateSecretsForPublish(manifest, secrets2, emailOptions) {
|
|
|
18492
18666
|
}
|
|
18493
18667
|
async function siteEnvFileHasEntries(siteDirectory) {
|
|
18494
18668
|
for (const fileName of [ENV_FILENAME, ".env.local"]) {
|
|
18495
|
-
const loaded = await readEnvFile(
|
|
18669
|
+
const loaded = await readEnvFile(path59.join(siteDirectory, fileName));
|
|
18496
18670
|
if (Object.keys(loaded).length > 0) {
|
|
18497
18671
|
return true;
|
|
18498
18672
|
}
|
|
@@ -18500,7 +18674,7 @@ async function siteEnvFileHasEntries(siteDirectory) {
|
|
|
18500
18674
|
return false;
|
|
18501
18675
|
}
|
|
18502
18676
|
async function resolvePublishConfig(siteDirectory, emailOptions) {
|
|
18503
|
-
const resolvedDirectory =
|
|
18677
|
+
const resolvedDirectory = path59.resolve(siteDirectory);
|
|
18504
18678
|
const manifestRaw = await readManifest2(resolvedDirectory);
|
|
18505
18679
|
if (!manifestRaw) {
|
|
18506
18680
|
throw new Error("apitogo.config.json not found in sourceDirectory.");
|
|
@@ -18532,11 +18706,11 @@ var SECRETS_COLLECTION_INSTRUCTION = "For go-live, plans must already be in apit
|
|
|
18532
18706
|
init_gateway_limits();
|
|
18533
18707
|
import { readFile as readFile21 } from "node:fs/promises";
|
|
18534
18708
|
import { createRequire as createRequire2 } from "node:module";
|
|
18535
|
-
import
|
|
18709
|
+
import path60 from "node:path";
|
|
18536
18710
|
var cachedFallbackTs;
|
|
18537
18711
|
async function loadTypeScriptForSite(sourceDirectory) {
|
|
18538
18712
|
const require2 = createRequire2(
|
|
18539
|
-
|
|
18713
|
+
path60.join(path60.resolve(sourceDirectory), "package.json")
|
|
18540
18714
|
);
|
|
18541
18715
|
try {
|
|
18542
18716
|
return require2("typescript");
|
|
@@ -18583,7 +18757,7 @@ async function referencedFileExists(sourceDirectory, reference) {
|
|
|
18583
18757
|
return true;
|
|
18584
18758
|
}
|
|
18585
18759
|
return pathExists(
|
|
18586
|
-
|
|
18760
|
+
path60.resolve(sourceDirectory, reference.replace(/^\.\//, ""))
|
|
18587
18761
|
);
|
|
18588
18762
|
}
|
|
18589
18763
|
async function validateSiteConfigStructure(config2, sourceDirectory) {
|
|
@@ -18698,11 +18872,11 @@ var DEFAULT_TSX_CANDIDATES = [
|
|
|
18698
18872
|
"landing/LandingPage.tsx"
|
|
18699
18873
|
];
|
|
18700
18874
|
async function validateDevPortalSiteConfig(sourceDirectory, options) {
|
|
18701
|
-
const resolvedDir =
|
|
18875
|
+
const resolvedDir = path60.resolve(sourceDirectory);
|
|
18702
18876
|
const issues = [];
|
|
18703
18877
|
const checkedFiles = [];
|
|
18704
18878
|
const skippedChecks = [];
|
|
18705
|
-
const jsonPath =
|
|
18879
|
+
const jsonPath = path60.join(resolvedDir, APITOGO_CONFIG_FILENAME2);
|
|
18706
18880
|
if (await pathExists(jsonPath)) {
|
|
18707
18881
|
checkedFiles.push(APITOGO_CONFIG_FILENAME2);
|
|
18708
18882
|
let parsed;
|
|
@@ -18734,7 +18908,7 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
|
|
|
18734
18908
|
);
|
|
18735
18909
|
const existingTsxFiles = [];
|
|
18736
18910
|
for (const relativeFile of tsxFiles) {
|
|
18737
|
-
if (await pathExists(
|
|
18911
|
+
if (await pathExists(path60.join(resolvedDir, relativeFile))) {
|
|
18738
18912
|
existingTsxFiles.push(relativeFile);
|
|
18739
18913
|
}
|
|
18740
18914
|
}
|
|
@@ -18748,7 +18922,7 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
|
|
|
18748
18922
|
for (const relativeFile of existingTsxFiles) {
|
|
18749
18923
|
checkedFiles.push(relativeFile);
|
|
18750
18924
|
const content = await readFile21(
|
|
18751
|
-
|
|
18925
|
+
path60.join(resolvedDir, relativeFile),
|
|
18752
18926
|
"utf8"
|
|
18753
18927
|
);
|
|
18754
18928
|
issues.push(
|
|
@@ -18770,7 +18944,7 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
|
|
|
18770
18944
|
|
|
18771
18945
|
// src/cli/platform/helpers/npm-build.ts
|
|
18772
18946
|
import { access as access7, readFile as readFile22 } from "node:fs/promises";
|
|
18773
|
-
import
|
|
18947
|
+
import path61 from "node:path";
|
|
18774
18948
|
var BUILD_LOG_TAIL_BYTES = 8192;
|
|
18775
18949
|
var MIN_NODE_MAJOR = 20;
|
|
18776
18950
|
var NpmBuildError = class extends Error {
|
|
@@ -18836,13 +19010,13 @@ function runCommand(command2, args, cwd, env) {
|
|
|
18836
19010
|
}
|
|
18837
19011
|
async function runNpmInstall(sourceDirectory, options) {
|
|
18838
19012
|
assertNodeVersion(options?.nodeVersion);
|
|
18839
|
-
const cwd =
|
|
18840
|
-
const packageJsonPath =
|
|
19013
|
+
const cwd = path61.resolve(sourceDirectory);
|
|
19014
|
+
const packageJsonPath = path61.join(cwd, "package.json");
|
|
18841
19015
|
if (!await pathExists2(packageJsonPath)) {
|
|
18842
19016
|
throw new Error(`package.json not found in sourceDirectory: ${cwd}`);
|
|
18843
19017
|
}
|
|
18844
19018
|
const startedAt = Date.now();
|
|
18845
|
-
const lockPath =
|
|
19019
|
+
const lockPath = path61.join(cwd, "package-lock.json");
|
|
18846
19020
|
const installArgs = await pathExists2(lockPath) ? ["ci"] : ["install"];
|
|
18847
19021
|
const install = await runCommand("npm", installArgs, cwd);
|
|
18848
19022
|
const installLog = install.output;
|
|
@@ -18860,8 +19034,8 @@ async function runNpmInstall(sourceDirectory, options) {
|
|
|
18860
19034
|
}
|
|
18861
19035
|
async function runNpmBuild(sourceDirectory, options) {
|
|
18862
19036
|
assertNodeVersion(options?.nodeVersion);
|
|
18863
|
-
const cwd =
|
|
18864
|
-
const packageJsonPath =
|
|
19037
|
+
const cwd = path61.resolve(sourceDirectory);
|
|
19038
|
+
const packageJsonPath = path61.join(cwd, "package.json");
|
|
18865
19039
|
if (!await pathExists2(packageJsonPath)) {
|
|
18866
19040
|
throw new Error(`package.json not found in sourceDirectory: ${cwd}`);
|
|
18867
19041
|
}
|
|
@@ -18878,8 +19052,8 @@ async function runNpmBuild(sourceDirectory, options) {
|
|
|
18878
19052
|
build2.exitCode
|
|
18879
19053
|
);
|
|
18880
19054
|
}
|
|
18881
|
-
const distPath =
|
|
18882
|
-
const indexPath =
|
|
19055
|
+
const distPath = path61.join(cwd, "dist");
|
|
19056
|
+
const indexPath = path61.join(distPath, "index.html");
|
|
18883
19057
|
if (!await pathExists2(indexPath)) {
|
|
18884
19058
|
throw new NpmBuildError(
|
|
18885
19059
|
`Build completed but dist/index.html was not found at ${indexPath}`,
|
|
@@ -19263,7 +19437,7 @@ function validateManifestForPlatformPublish(manifest) {
|
|
|
19263
19437
|
|
|
19264
19438
|
// src/cli/platform/tools/check-publish-readiness.ts
|
|
19265
19439
|
async function checkPublishReadiness(client, _config, args) {
|
|
19266
|
-
const sourceDirectory =
|
|
19440
|
+
const sourceDirectory = path62.resolve(args.sourceDirectory);
|
|
19267
19441
|
const manifest = await readManifest2(sourceDirectory) ?? createScaffoldManifest();
|
|
19268
19442
|
const emailOptions = await resolveEmailOptionsForPublish(
|
|
19269
19443
|
client,
|
|
@@ -19341,7 +19515,7 @@ async function checkPublishReadiness(client, _config, args) {
|
|
|
19341
19515
|
|
|
19342
19516
|
// src/cli/check/handler.ts
|
|
19343
19517
|
async function check(argv) {
|
|
19344
|
-
const sourceDirectory =
|
|
19518
|
+
const sourceDirectory = path63.resolve(process.cwd(), argv.dir);
|
|
19345
19519
|
if (await isConfigV2(sourceDirectory)) {
|
|
19346
19520
|
await checkV2(sourceDirectory, argv);
|
|
19347
19521
|
return;
|
|
@@ -19405,7 +19579,7 @@ var check_default = {
|
|
|
19405
19579
|
|
|
19406
19580
|
// src/cli/make-config/handler.ts
|
|
19407
19581
|
init_invariant();
|
|
19408
|
-
import
|
|
19582
|
+
import path65 from "node:path";
|
|
19409
19583
|
import { stdin as input2 } from "node:process";
|
|
19410
19584
|
|
|
19411
19585
|
// src/cli/make-config/interactive.ts
|
|
@@ -19415,7 +19589,7 @@ import { createInterface as createInterface3 } from "node:readline/promises";
|
|
|
19415
19589
|
// src/cli/make-config/v2-edits.ts
|
|
19416
19590
|
init_apitogo_config_core();
|
|
19417
19591
|
import { access as access8, mkdir as mkdir15, readFile as readFile23, writeFile as writeFile18 } from "node:fs/promises";
|
|
19418
|
-
import
|
|
19592
|
+
import path64 from "node:path";
|
|
19419
19593
|
import { glob as glob8 } from "glob";
|
|
19420
19594
|
init_invariant();
|
|
19421
19595
|
var ConfigEditError = class extends ApitogoError {
|
|
@@ -19428,10 +19602,10 @@ var exists4 = (target) => access8(target).then(
|
|
|
19428
19602
|
() => true,
|
|
19429
19603
|
() => false
|
|
19430
19604
|
);
|
|
19431
|
-
var toPosix2 = (value) => value.split(
|
|
19432
|
-
var relativeToConfig = (project, target) => toPosix2(
|
|
19605
|
+
var toPosix2 = (value) => value.split(path64.sep).join("/");
|
|
19606
|
+
var relativeToConfig = (project, target) => toPosix2(path64.relative(project.resolved.configDir, target)) || ".";
|
|
19433
19607
|
async function openConfigProject(dir) {
|
|
19434
|
-
const configPath =
|
|
19608
|
+
const configPath = path64.join(dir, APITOGO_CONFIG_FILENAME);
|
|
19435
19609
|
if (!await exists4(configPath)) {
|
|
19436
19610
|
throw new ConfigEditError(
|
|
19437
19611
|
`There is no ${APITOGO_CONFIG_FILENAME} in ${dir}.`,
|
|
@@ -19496,7 +19670,7 @@ function setPortalName(project, name) {
|
|
|
19496
19670
|
}
|
|
19497
19671
|
async function addGatewaySpec(project, specPath) {
|
|
19498
19672
|
const gateway = requireGateway(project);
|
|
19499
|
-
const absolute =
|
|
19673
|
+
const absolute = path64.resolve(project.dir, specPath);
|
|
19500
19674
|
if (!await exists4(absolute)) {
|
|
19501
19675
|
throw new ConfigEditError(`The OpenAPI file ${specPath} does not exist.`);
|
|
19502
19676
|
}
|
|
@@ -19540,7 +19714,7 @@ function parseBackendInput(input5) {
|
|
|
19540
19714
|
}
|
|
19541
19715
|
async function setGatewayOrigin(project, backend) {
|
|
19542
19716
|
const gateway = requireGateway(project);
|
|
19543
|
-
const source =
|
|
19717
|
+
const source = path64.resolve(project.dir, backend.source);
|
|
19544
19718
|
if (!await exists4(source)) {
|
|
19545
19719
|
throw new ConfigEditError(
|
|
19546
19720
|
`The API source folder ${backend.source} does not exist.`
|
|
@@ -19618,6 +19792,164 @@ export default function ${pageComponentName(slug)}() {
|
|
|
19618
19792
|
}
|
|
19619
19793
|
`;
|
|
19620
19794
|
}
|
|
19795
|
+
var HEADER_PAGES_FOLDER = "header-pages";
|
|
19796
|
+
var RESERVED_HEADER_SLUGS = [
|
|
19797
|
+
"index",
|
|
19798
|
+
"api",
|
|
19799
|
+
"pricing",
|
|
19800
|
+
"account",
|
|
19801
|
+
"login",
|
|
19802
|
+
"signup"
|
|
19803
|
+
];
|
|
19804
|
+
function buildTsxHeaderPage(slug, title, file, content) {
|
|
19805
|
+
const given = content?.trim() ? withoutLeadingH1(content) : "";
|
|
19806
|
+
const text2 = given ? `{${JSON.stringify(given)}}` : "Coming soon.";
|
|
19807
|
+
return `import { Callout, Heading, Typography } from "@lukoweb/apitogo/components";
|
|
19808
|
+
|
|
19809
|
+
/** The page's label in the header's top menu (portal.header.links in ${APITOGO_CONFIG_FILENAME}). */
|
|
19810
|
+
export const title = ${JSON.stringify(title)};
|
|
19811
|
+
|
|
19812
|
+
// This page is a React component: change it like any other one (add state, fetch data, use the portal's components).
|
|
19813
|
+
export default function ${pageComponentName(slug)}() {
|
|
19814
|
+
return (
|
|
19815
|
+
<section className="mx-auto max-w-screen-lg px-4 py-12 pt-(--padding-content-top)">
|
|
19816
|
+
<Typography>
|
|
19817
|
+
<Heading level={1}>{title}</Heading>
|
|
19818
|
+
<p>${text2}</p>
|
|
19819
|
+
{/* A note for you while you run the portal locally (\`apitogo run\`); the deployed portal does not show it. */}
|
|
19820
|
+
{import.meta.env.DEV && (
|
|
19821
|
+
<Callout type="info" title="Where this page lives">
|
|
19822
|
+
Edit <code>${file}</code>. The header's top menu links to it; the docs sidebar does not.
|
|
19823
|
+
</Callout>
|
|
19824
|
+
)}
|
|
19825
|
+
</Typography>
|
|
19826
|
+
</section>
|
|
19827
|
+
);
|
|
19828
|
+
}
|
|
19829
|
+
`;
|
|
19830
|
+
}
|
|
19831
|
+
var TSX_TITLE = /^export\s+const\s+title\s*(?::\s*string\s*)?=\s*.*$/m;
|
|
19832
|
+
async function writeHeaderPage(project, input5) {
|
|
19833
|
+
const portalConfig = requirePortal(project);
|
|
19834
|
+
const portal = project.resolved.portal;
|
|
19835
|
+
if (!portal?.docs.enabled || portal.docs.provider !== "apitogo") {
|
|
19836
|
+
throw new ConfigEditError(
|
|
19837
|
+
"This portal does not host pages.",
|
|
19838
|
+
'Header pages are served with the docs pages: they need portal.docs.provider "apitogo" and portal.docs.enabled not false.'
|
|
19839
|
+
);
|
|
19840
|
+
}
|
|
19841
|
+
const slug = normalizeDocsSlug(input5.slug);
|
|
19842
|
+
if (!slug) throw new ConfigEditError("The page path must not be empty.");
|
|
19843
|
+
if (slug.includes("/")) {
|
|
19844
|
+
throw new ConfigEditError(
|
|
19845
|
+
`A header page has a plain name, not a path: "${input5.slug}".`,
|
|
19846
|
+
"Pass one word, for example --page-slug partners (the page is then at /partners)."
|
|
19847
|
+
);
|
|
19848
|
+
}
|
|
19849
|
+
if (RESERVED_HEADER_SLUGS.includes(slug)) {
|
|
19850
|
+
throw new ConfigEditError(
|
|
19851
|
+
`The portal uses /${slug} itself, so a header page cannot have it.`,
|
|
19852
|
+
"Pick another name."
|
|
19853
|
+
);
|
|
19854
|
+
}
|
|
19855
|
+
const relative = (file2) => toPosix2(path64.relative(project.dir, file2));
|
|
19856
|
+
const docsBase = path64.join(portal.dir, "pages", slug);
|
|
19857
|
+
for (const file2 of [`${docsBase}.md`, `${docsBase}.mdx`, `${docsBase}.tsx`]) {
|
|
19858
|
+
if (await exists4(file2)) {
|
|
19859
|
+
throw new ConfigEditError(
|
|
19860
|
+
`The docs page ${relative(file2)} already has the address /${slug}.`,
|
|
19861
|
+
"Pick another name for the header page."
|
|
19862
|
+
);
|
|
19863
|
+
}
|
|
19864
|
+
}
|
|
19865
|
+
const base = path64.join(portal.dir, HEADER_PAGES_FOLDER, slug);
|
|
19866
|
+
const existing = (await Promise.all(
|
|
19867
|
+
[`${base}.tsx`, `${base}.mdx`, `${base}.md`].map(
|
|
19868
|
+
async (file2) => await exists4(file2) ? file2 : null
|
|
19869
|
+
)
|
|
19870
|
+
)).find((file2) => file2 !== null);
|
|
19871
|
+
let file;
|
|
19872
|
+
let title;
|
|
19873
|
+
let action;
|
|
19874
|
+
if (input5.update) {
|
|
19875
|
+
if (!existing) {
|
|
19876
|
+
throw new ConfigEditError(
|
|
19877
|
+
`There is no header page at ${relative(`${base}.${input5.format ?? "tsx"}`)}.`,
|
|
19878
|
+
"Leave out --page-update to add it."
|
|
19879
|
+
);
|
|
19880
|
+
}
|
|
19881
|
+
const source = await readFile23(existing, "utf8");
|
|
19882
|
+
const react2 = existing.endsWith(".tsx");
|
|
19883
|
+
title = input5.title?.trim() || (react2 ? tsxPageLabel(source, existing) : titleOf(source)) || slug;
|
|
19884
|
+
file = existing;
|
|
19885
|
+
action = "updated";
|
|
19886
|
+
if (react2) {
|
|
19887
|
+
await writeFile18(
|
|
19888
|
+
file,
|
|
19889
|
+
input5.content !== void 0 ? buildTsxHeaderPage(slug, title, relative(file), input5.content) : TSX_TITLE.test(source) ? source.replace(
|
|
19890
|
+
TSX_TITLE,
|
|
19891
|
+
`export const title = ${JSON.stringify(title)};`
|
|
19892
|
+
) : source,
|
|
19893
|
+
"utf8"
|
|
19894
|
+
);
|
|
19895
|
+
} else {
|
|
19896
|
+
const body = input5.content ?? source.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/, "").trim();
|
|
19897
|
+
await writeFile18(file, buildDocsPage(title, body), "utf8");
|
|
19898
|
+
}
|
|
19899
|
+
} else {
|
|
19900
|
+
if (existing) {
|
|
19901
|
+
throw new ConfigEditError(
|
|
19902
|
+
`A header page already exists at ${relative(existing)}.`,
|
|
19903
|
+
"Pass --page-update to change it."
|
|
19904
|
+
);
|
|
19905
|
+
}
|
|
19906
|
+
const given = input5.title?.trim();
|
|
19907
|
+
if (!given) {
|
|
19908
|
+
throw new ConfigEditError("A new page needs a title (--page-title).");
|
|
19909
|
+
}
|
|
19910
|
+
title = given;
|
|
19911
|
+
file = `${base}.${input5.format ?? "tsx"}`;
|
|
19912
|
+
action = "added";
|
|
19913
|
+
await mkdir15(path64.dirname(file), { recursive: true });
|
|
19914
|
+
await writeFile18(
|
|
19915
|
+
file,
|
|
19916
|
+
file.endsWith(".tsx") ? buildTsxHeaderPage(slug, title, relative(file), input5.content) : buildDocsPage(
|
|
19917
|
+
title,
|
|
19918
|
+
input5.content?.trim() ? input5.content : `{/* Write this page in Markdown. It is linked from the header's top menu (portal.header.links in ${APITOGO_CONFIG_FILENAME}), not from the docs sidebar. */}
|
|
19919
|
+
|
|
19920
|
+
Coming soon.`
|
|
19921
|
+
),
|
|
19922
|
+
"utf8"
|
|
19923
|
+
);
|
|
19924
|
+
}
|
|
19925
|
+
const page = relativeToConfig(project, file);
|
|
19926
|
+
const target = path64.resolve(file);
|
|
19927
|
+
const links = portalConfig.header?.links ?? [];
|
|
19928
|
+
const known = links.some(
|
|
19929
|
+
(link) => "page" in link && path64.resolve(project.resolved.configDir, link.page) === target
|
|
19930
|
+
);
|
|
19931
|
+
const nextLinks = known ? links.map(
|
|
19932
|
+
(link) => "page" in link && path64.resolve(project.resolved.configDir, link.page) === target ? { label: title, page: link.page } : link
|
|
19933
|
+
) : [...links, { label: title, page }];
|
|
19934
|
+
return {
|
|
19935
|
+
project: withConfig(project, {
|
|
19936
|
+
...project.config,
|
|
19937
|
+
portal: {
|
|
19938
|
+
...portalConfig,
|
|
19939
|
+
header: { ...portalConfig.header, links: nextLinks }
|
|
19940
|
+
}
|
|
19941
|
+
}),
|
|
19942
|
+
page: {
|
|
19943
|
+
action,
|
|
19944
|
+
slug,
|
|
19945
|
+
route: `/${slug}`,
|
|
19946
|
+
file: relative(file),
|
|
19947
|
+
format: path64.extname(file).slice(1),
|
|
19948
|
+
inPortal: true,
|
|
19949
|
+
header: true
|
|
19950
|
+
}
|
|
19951
|
+
};
|
|
19952
|
+
}
|
|
19621
19953
|
async function writeDocsPage(project, input5) {
|
|
19622
19954
|
requirePortal(project);
|
|
19623
19955
|
if (/^[A-Za-z]:[\\/]/.test(input5.slug.trim())) {
|
|
@@ -19641,13 +19973,13 @@ async function writeDocsPage(project, input5) {
|
|
|
19641
19973
|
"For example --page-order 1 puts the page first in the sidebar."
|
|
19642
19974
|
);
|
|
19643
19975
|
}
|
|
19644
|
-
const base =
|
|
19976
|
+
const base = path64.join(portal.dir, "pages", ...slug.split("/"));
|
|
19645
19977
|
const existing = (await Promise.all(
|
|
19646
19978
|
[`${base}.tsx`, `${base}.mdx`, `${base}.md`].map(
|
|
19647
19979
|
async (file2) => await exists4(file2) ? file2 : null
|
|
19648
19980
|
)
|
|
19649
19981
|
)).find((file2) => file2 !== null);
|
|
19650
|
-
const relative = (file2) => toPosix2(
|
|
19982
|
+
const relative = (file2) => toPosix2(path64.relative(project.dir, file2));
|
|
19651
19983
|
const write = (file2, title, order = input5.order) => writeFile18(
|
|
19652
19984
|
file2,
|
|
19653
19985
|
file2.endsWith(".tsx") ? buildTsxDocsPage(slug, title, relative(file2), input5.content, order) : buildDocsPage(title, input5.content, order),
|
|
@@ -19681,17 +20013,17 @@ async function writeDocsPage(project, input5) {
|
|
|
19681
20013
|
}
|
|
19682
20014
|
file = `${base}.${input5.format ?? "tsx"}`;
|
|
19683
20015
|
action = "added";
|
|
19684
|
-
await mkdir15(
|
|
20016
|
+
await mkdir15(path64.dirname(file), { recursive: true });
|
|
19685
20017
|
await write(file, title);
|
|
19686
20018
|
}
|
|
19687
|
-
const same = (match) =>
|
|
20019
|
+
const same = (match) => path64.resolve(match) === path64.resolve(file);
|
|
19688
20020
|
const inPortal = file.endsWith(".tsx") ? (await findTsxPages(portal.docs.content)).some((page) => same(page.file)) : (await glob8(portal.docs.content, { absolute: true })).some(same);
|
|
19689
20021
|
return {
|
|
19690
20022
|
action,
|
|
19691
20023
|
slug,
|
|
19692
20024
|
route: `/${slug}`,
|
|
19693
20025
|
file: relative(file),
|
|
19694
|
-
format:
|
|
20026
|
+
format: path64.extname(file).slice(1),
|
|
19695
20027
|
inPortal
|
|
19696
20028
|
};
|
|
19697
20029
|
}
|
|
@@ -19770,7 +20102,7 @@ async function readPlanCatalog(project) {
|
|
|
19770
20102
|
}
|
|
19771
20103
|
var skuOf = (item) => isPlainObject3(item) && typeof item.sku === "string" ? item.sku.trim().toLowerCase() : void 0;
|
|
19772
20104
|
async function writePlanCatalog(file, catalog, plans) {
|
|
19773
|
-
await mkdir15(
|
|
20105
|
+
await mkdir15(path64.dirname(file), { recursive: true });
|
|
19774
20106
|
await writeFile18(
|
|
19775
20107
|
file,
|
|
19776
20108
|
`${JSON.stringify({ ...catalog, plans }, null, 2)}
|
|
@@ -19793,7 +20125,7 @@ async function upsertPlan(project, plan2) {
|
|
|
19793
20125
|
return {
|
|
19794
20126
|
action: index === -1 ? "added" : "updated",
|
|
19795
20127
|
sku: plan2.sku,
|
|
19796
|
-
file: toPosix2(
|
|
20128
|
+
file: toPosix2(path64.relative(project.dir, file)),
|
|
19797
20129
|
paid,
|
|
19798
20130
|
needsBilling: paid && billing.provider !== "stripe"
|
|
19799
20131
|
};
|
|
@@ -19883,12 +20215,12 @@ async function removePlan(project, rawSku) {
|
|
|
19883
20215
|
if (next.length === catalog.plans.length) {
|
|
19884
20216
|
const known = catalog.plans.map(skuOf).filter(Boolean).join(", ");
|
|
19885
20217
|
throw new ConfigEditError(
|
|
19886
|
-
`There is no plan "${sku}" in ${toPosix2(
|
|
20218
|
+
`There is no plan "${sku}" in ${toPosix2(path64.relative(project.dir, file))}.`,
|
|
19887
20219
|
known ? `The plans are: ${known}.` : "The plans file has no plans."
|
|
19888
20220
|
);
|
|
19889
20221
|
}
|
|
19890
20222
|
await writePlanCatalog(file, catalog, next);
|
|
19891
|
-
return { sku, file: toPosix2(
|
|
20223
|
+
return { sku, file: toPosix2(path64.relative(project.dir, file)) };
|
|
19892
20224
|
}
|
|
19893
20225
|
|
|
19894
20226
|
// src/cli/make-config/wrap-up.ts
|
|
@@ -19911,6 +20243,12 @@ function printPageResult(page) {
|
|
|
19911
20243
|
printSuccessToConsole(
|
|
19912
20244
|
`Page ${page.action}: ${page.file} (route ${page.route})`
|
|
19913
20245
|
);
|
|
20246
|
+
if (page.header) {
|
|
20247
|
+
printHintToConsole(
|
|
20248
|
+
`The header's top menu links to it (portal.header.links); the docs sidebar does not. Edit the file to change the content. Run \`apitogo deploy --only portal\` to publish it.`
|
|
20249
|
+
);
|
|
20250
|
+
return;
|
|
20251
|
+
}
|
|
19914
20252
|
if (page.inPortal) {
|
|
19915
20253
|
printHintToConsole(
|
|
19916
20254
|
page.format === "tsx" ? "The page is a React component: edit it like any component. The sidebar is built from the pages folder, so the config does not change." : "The sidebar is built from the pages folder, so the config does not change. Edit the file to change the content."
|
|
@@ -20169,7 +20507,7 @@ async function applyConfigFlags(project, argv, changes) {
|
|
|
20169
20507
|
return { project: next, openApi };
|
|
20170
20508
|
}
|
|
20171
20509
|
async function makeConfig(argv) {
|
|
20172
|
-
const dir =
|
|
20510
|
+
const dir = path65.resolve(process.cwd(), argv.dir);
|
|
20173
20511
|
const interactive = shouldRunInteractive(argv);
|
|
20174
20512
|
const json = argv.json === true;
|
|
20175
20513
|
const changes = [];
|
|
@@ -20212,7 +20550,32 @@ async function makeConfig(argv) {
|
|
|
20212
20550
|
const applied = await applyConfigFlags(project, argv, changes);
|
|
20213
20551
|
project = applied.project;
|
|
20214
20552
|
openApi = applied.openApi;
|
|
20215
|
-
if (argv.pageSlug
|
|
20553
|
+
if (argv.pageHeader === true && argv.pageSlug === void 0) {
|
|
20554
|
+
throw new ApitogoError("--page-header needs --page-slug.", {
|
|
20555
|
+
developerHint: "Name the page, for example --page-slug partners --page-title Partners --page-header."
|
|
20556
|
+
});
|
|
20557
|
+
}
|
|
20558
|
+
if (argv.pageSlug !== void 0 && argv.pageHeader === true) {
|
|
20559
|
+
if (argv.pageOrder !== void 0) {
|
|
20560
|
+
throw new ApitogoError(
|
|
20561
|
+
"--page-order sets a place in the docs sidebar, which a header page is not in.",
|
|
20562
|
+
{
|
|
20563
|
+
developerHint: "Header links show in the order of portal.header.links in apitogo.config.json."
|
|
20564
|
+
}
|
|
20565
|
+
);
|
|
20566
|
+
}
|
|
20567
|
+
const written = await writeHeaderPage(project, {
|
|
20568
|
+
slug: argv.pageSlug,
|
|
20569
|
+
title: argv.pageTitle,
|
|
20570
|
+
content: argv.pageContent,
|
|
20571
|
+
update: argv.pageUpdate === true,
|
|
20572
|
+
format: argv.pageFormat
|
|
20573
|
+
});
|
|
20574
|
+
project = written.project;
|
|
20575
|
+
await saveConfigProject(project);
|
|
20576
|
+
page = written.page;
|
|
20577
|
+
changes.push(page.action === "added" ? "page_add" : "page_update");
|
|
20578
|
+
} else if (argv.pageSlug !== void 0) {
|
|
20216
20579
|
page = await writeDocsPage(project, {
|
|
20217
20580
|
slug: argv.pageSlug,
|
|
20218
20581
|
title: argv.pageTitle,
|
|
@@ -20361,6 +20724,10 @@ function addConfigOptions(yargs2) {
|
|
|
20361
20724
|
type: "boolean",
|
|
20362
20725
|
default: false,
|
|
20363
20726
|
describe: "Update an existing page instead of adding one"
|
|
20727
|
+
}).option("page-header", {
|
|
20728
|
+
type: "boolean",
|
|
20729
|
+
default: false,
|
|
20730
|
+
describe: "Make --page-slug a page of its own, linked from the header's top menu instead of the docs sidebar (<portal>/header-pages/<slug>.tsx; --page-format mdx for Markdown)"
|
|
20364
20731
|
}).option("plan-sku", {
|
|
20365
20732
|
type: "string",
|
|
20366
20733
|
describe: "Add or change the plan with this SKU in the plans file; the --plan-* options set its fields"
|
|
@@ -20398,7 +20765,10 @@ function addConfigOptions(yargs2) {
|
|
|
20398
20765
|
).example(
|
|
20399
20766
|
"$0 config --plan-sku enterprise --plan-price custom",
|
|
20400
20767
|
"A contact-us plan"
|
|
20401
|
-
).example("$0 config --remove-plan enterprise", "Take a plan out").
|
|
20768
|
+
).example("$0 config --remove-plan enterprise", "Take a plan out").example(
|
|
20769
|
+
"$0 config --page-slug partners --page-title Partners --page-header",
|
|
20770
|
+
"A page at /partners, linked from the header's top menu"
|
|
20771
|
+
).option("plan", {
|
|
20402
20772
|
type: "string",
|
|
20403
20773
|
describe: "JSON plan added to the plans file (plans.file, default apitogo/plans.json), or replacing the one with the same sku"
|
|
20404
20774
|
}).option("patch", {
|
|
@@ -20420,27 +20790,27 @@ var config_default = {
|
|
|
20420
20790
|
init_apitogo_config_core();
|
|
20421
20791
|
import { execFile } from "node:child_process";
|
|
20422
20792
|
import { readFile as readFile24 } from "node:fs/promises";
|
|
20423
|
-
import
|
|
20793
|
+
import path67 from "node:path";
|
|
20424
20794
|
import { promisify } from "node:util";
|
|
20425
20795
|
|
|
20426
20796
|
// src/cli/create/dry-run.ts
|
|
20427
20797
|
import { mkdir as mkdir16, mkdtemp, readdir as readdir4, rm as rm9 } from "node:fs/promises";
|
|
20428
20798
|
import { tmpdir } from "node:os";
|
|
20429
|
-
import
|
|
20799
|
+
import path66 from "node:path";
|
|
20430
20800
|
async function listFiles(root, dir = root) {
|
|
20431
20801
|
const entries = await readdir4(dir, { withFileTypes: true });
|
|
20432
20802
|
const nested = await Promise.all(
|
|
20433
20803
|
entries.map(async (entry) => {
|
|
20434
|
-
const full =
|
|
20804
|
+
const full = path66.join(dir, entry.name);
|
|
20435
20805
|
if (entry.isDirectory()) return listFiles(root, full);
|
|
20436
|
-
return [
|
|
20806
|
+
return [path66.relative(root, full).split(path66.sep).join("/")];
|
|
20437
20807
|
})
|
|
20438
20808
|
);
|
|
20439
20809
|
return nested.flat();
|
|
20440
20810
|
}
|
|
20441
20811
|
async function previewCreate(input5) {
|
|
20442
|
-
const scratch = await mkdtemp(
|
|
20443
|
-
const dir =
|
|
20812
|
+
const scratch = await mkdtemp(path66.join(tmpdir(), "apitogo-create-"));
|
|
20813
|
+
const dir = path66.join(scratch, "project");
|
|
20444
20814
|
try {
|
|
20445
20815
|
await mkdir16(dir);
|
|
20446
20816
|
await applyInitPlan(await planInit({ dir, name: input5.name }));
|
|
@@ -20473,9 +20843,9 @@ async function previewCreate(input5) {
|
|
|
20473
20843
|
var execFileAsync = promisify(execFile);
|
|
20474
20844
|
function nextStepHint(dir) {
|
|
20475
20845
|
const linked = loadConfigV2(dir).resolved.project.id;
|
|
20476
|
-
const cd =
|
|
20846
|
+
const cd = path67.resolve(dir) === path67.resolve(process.cwd());
|
|
20477
20847
|
const steps = linked ? "apitogo deploy" : "apitogo project create, then apitogo deploy";
|
|
20478
|
-
return cd ? `Next: ${steps}` : `Next: cd ${JSON.stringify(
|
|
20848
|
+
return cd ? `Next: ${steps}` : `Next: cd ${JSON.stringify(path67.relative(process.cwd(), dir))}, then ${steps}`;
|
|
20479
20849
|
}
|
|
20480
20850
|
function projectFolderName(name) {
|
|
20481
20851
|
return name.trim().replace(/[<>:"/\\|?*\s]+/g, "-").replace(/^[-.]+|[-.]+$/g, "") || "apitogo-project";
|
|
@@ -20501,13 +20871,13 @@ async function gitHasUncommittedChanges(dir) {
|
|
|
20501
20871
|
async function defaultName(dir) {
|
|
20502
20872
|
try {
|
|
20503
20873
|
const parsed = JSON.parse(
|
|
20504
|
-
await readFile24(
|
|
20874
|
+
await readFile24(path67.join(dir, "package.json"), "utf8")
|
|
20505
20875
|
);
|
|
20506
20876
|
if (typeof parsed.name === "string" && parsed.name.trim())
|
|
20507
20877
|
return parsed.name.replace(/^@[^/]+\//, "");
|
|
20508
20878
|
} catch {
|
|
20509
20879
|
}
|
|
20510
|
-
return
|
|
20880
|
+
return path67.basename(dir);
|
|
20511
20881
|
}
|
|
20512
20882
|
function parseServicesFlag(value) {
|
|
20513
20883
|
const names = (value ?? "").split(",").map((name) => name.trim()).filter(Boolean);
|
|
@@ -20533,7 +20903,7 @@ async function createProject(argv, deps = {}) {
|
|
|
20533
20903
|
if (!json) printDiagnosticsToConsole(line2);
|
|
20534
20904
|
};
|
|
20535
20905
|
try {
|
|
20536
|
-
const base =
|
|
20906
|
+
const base = path67.resolve(process.cwd(), argv.dir ?? ".");
|
|
20537
20907
|
let dir = base;
|
|
20538
20908
|
let requested = parseServicesFlag(argv.services);
|
|
20539
20909
|
let template = argv.template;
|
|
@@ -20556,8 +20926,8 @@ async function createProject(argv, deps = {}) {
|
|
|
20556
20926
|
default: await defaultName(base)
|
|
20557
20927
|
}) : await defaultName(base));
|
|
20558
20928
|
const folder = projectFolderName(name);
|
|
20559
|
-
if (argv.dir === void 0 && folder !==
|
|
20560
|
-
dir =
|
|
20929
|
+
if (argv.dir === void 0 && folder !== path67.basename(base))
|
|
20930
|
+
dir = path67.join(base, folder);
|
|
20561
20931
|
}
|
|
20562
20932
|
if (await (deps.hasUncommittedChanges ?? gitHasUncommittedChanges)(dir))
|
|
20563
20933
|
say(
|
|
@@ -20570,7 +20940,7 @@ async function createProject(argv, deps = {}) {
|
|
|
20570
20940
|
if (argv.dryRun) {
|
|
20571
20941
|
const services = requested.length > 0 ? requested : templateServices ? STARTER_SERVICES : [];
|
|
20572
20942
|
const preview2 = services.length > 0 ? await previewCreate({ name, template, services }) : void 0;
|
|
20573
|
-
const folder =
|
|
20943
|
+
const folder = path67.relative(process.cwd(), dir) || ".";
|
|
20574
20944
|
if (json)
|
|
20575
20945
|
console.log(
|
|
20576
20946
|
JSON.stringify({
|
|
@@ -20603,7 +20973,7 @@ async function createProject(argv, deps = {}) {
|
|
|
20603
20973
|
}
|
|
20604
20974
|
await applyInitPlan(plan2);
|
|
20605
20975
|
say(
|
|
20606
|
-
dir === base ? `Created ${APITOGO_CONFIG_FILENAME}.` : `Created ${
|
|
20976
|
+
dir === base ? `Created ${APITOGO_CONFIG_FILENAME}.` : `Created ${path67.relative(base, dir)}${path67.sep}${APITOGO_CONFIG_FILENAME}.`
|
|
20607
20977
|
);
|
|
20608
20978
|
} else {
|
|
20609
20979
|
say(`${APITOGO_CONFIG_FILENAME} exists: continuing from it.`);
|
|
@@ -20745,10 +21115,10 @@ var create_default = {
|
|
|
20745
21115
|
};
|
|
20746
21116
|
|
|
20747
21117
|
// src/cli/cmds/deploy.ts
|
|
20748
|
-
import
|
|
21118
|
+
import path86 from "node:path";
|
|
20749
21119
|
|
|
20750
21120
|
// src/cli/apply/handler.ts
|
|
20751
|
-
import
|
|
21121
|
+
import path79 from "node:path";
|
|
20752
21122
|
|
|
20753
21123
|
// src/cli/platform/helpers/gateway-plan-validation.ts
|
|
20754
21124
|
init_gateway_limits();
|
|
@@ -20967,11 +21337,11 @@ init_gateway_limits();
|
|
|
20967
21337
|
// src/cli/platform/helpers/deploy-artifact-hash.ts
|
|
20968
21338
|
import { createHash as createHash3 } from "node:crypto";
|
|
20969
21339
|
import { createReadStream, promises as fs6 } from "node:fs";
|
|
20970
|
-
import
|
|
21340
|
+
import path69 from "node:path";
|
|
20971
21341
|
|
|
20972
21342
|
// src/cli/platform/helpers/package-files.ts
|
|
20973
21343
|
import { promises as fs5 } from "node:fs";
|
|
20974
|
-
import
|
|
21344
|
+
import path68 from "node:path";
|
|
20975
21345
|
import ignore from "ignore";
|
|
20976
21346
|
var DEFAULT_EXCLUDES = /* @__PURE__ */ new Set([
|
|
20977
21347
|
"node_modules",
|
|
@@ -20985,7 +21355,7 @@ async function loadGitignore(rootDir, extraExcludes = []) {
|
|
|
20985
21355
|
const ig = ignore();
|
|
20986
21356
|
ig.add(["node_modules/", ".git/", "dist/", "bin/", "obj/"]);
|
|
20987
21357
|
if (extraExcludes.length > 0) ig.add([...extraExcludes]);
|
|
20988
|
-
const gitignorePath =
|
|
21358
|
+
const gitignorePath = path68.join(rootDir, ".gitignore");
|
|
20989
21359
|
try {
|
|
20990
21360
|
const content = await fs5.readFile(gitignorePath, "utf8");
|
|
20991
21361
|
ig.add(content);
|
|
@@ -20994,11 +21364,11 @@ async function loadGitignore(rootDir, extraExcludes = []) {
|
|
|
20994
21364
|
return ig;
|
|
20995
21365
|
}
|
|
20996
21366
|
async function collectFiles(rootDir, relativeDir, ig, files) {
|
|
20997
|
-
const absDir =
|
|
21367
|
+
const absDir = path68.join(rootDir, relativeDir);
|
|
20998
21368
|
const entries = await fs5.readdir(absDir, { withFileTypes: true });
|
|
20999
21369
|
for (const entry of entries) {
|
|
21000
|
-
const rel2 = relativeDir ?
|
|
21001
|
-
const relPosix = rel2.split(
|
|
21370
|
+
const rel2 = relativeDir ? path68.join(relativeDir, entry.name) : entry.name;
|
|
21371
|
+
const relPosix = rel2.split(path68.sep).join("/");
|
|
21002
21372
|
if (DEFAULT_EXCLUDES.has(entry.name) && !relativeDir) {
|
|
21003
21373
|
continue;
|
|
21004
21374
|
}
|
|
@@ -21013,7 +21383,7 @@ async function collectFiles(rootDir, relativeDir, ig, files) {
|
|
|
21013
21383
|
}
|
|
21014
21384
|
}
|
|
21015
21385
|
async function collectPackageableFiles(sourceDirectory, extraExcludes = []) {
|
|
21016
|
-
const resolved =
|
|
21386
|
+
const resolved = path68.resolve(sourceDirectory);
|
|
21017
21387
|
const stat7 = await fs5.stat(resolved).catch(() => null);
|
|
21018
21388
|
if (!stat7?.isDirectory()) {
|
|
21019
21389
|
throw new Error(`sourceDirectory is not a directory: ${resolved}`);
|
|
@@ -21039,7 +21409,7 @@ async function sha256File(filePath) {
|
|
|
21039
21409
|
return hash2.digest("hex");
|
|
21040
21410
|
}
|
|
21041
21411
|
async function hashDirectoryContents(rootDirectory, extraExcludes = []) {
|
|
21042
|
-
const resolved =
|
|
21412
|
+
const resolved = path69.resolve(rootDirectory);
|
|
21043
21413
|
const files = (await collectPackageableFiles(resolved, extraExcludes)).sort(
|
|
21044
21414
|
(a, b) => a.localeCompare(b)
|
|
21045
21415
|
);
|
|
@@ -21047,13 +21417,13 @@ async function hashDirectoryContents(rootDirectory, extraExcludes = []) {
|
|
|
21047
21417
|
for (const rel2 of files) {
|
|
21048
21418
|
hash2.update(rel2);
|
|
21049
21419
|
hash2.update("\0");
|
|
21050
|
-
hash2.update(await fs6.readFile(
|
|
21420
|
+
hash2.update(await fs6.readFile(path69.join(resolved, rel2)));
|
|
21051
21421
|
hash2.update("\0");
|
|
21052
21422
|
}
|
|
21053
21423
|
return hash2.digest("hex");
|
|
21054
21424
|
}
|
|
21055
21425
|
async function hashDevPortalSiteSources(siteDirectory, options) {
|
|
21056
|
-
const resolved =
|
|
21426
|
+
const resolved = path69.resolve(siteDirectory);
|
|
21057
21427
|
const hash2 = createHash3("sha256");
|
|
21058
21428
|
const candidates = [
|
|
21059
21429
|
"apitogo.config.json",
|
|
@@ -21063,7 +21433,7 @@ async function hashDevPortalSiteSources(siteDirectory, options) {
|
|
|
21063
21433
|
"zudoku.config.tsx"
|
|
21064
21434
|
];
|
|
21065
21435
|
for (const name of candidates) {
|
|
21066
|
-
const full =
|
|
21436
|
+
const full = path69.join(resolved, name);
|
|
21067
21437
|
try {
|
|
21068
21438
|
hash2.update(name);
|
|
21069
21439
|
hash2.update("\0");
|
|
@@ -21073,7 +21443,7 @@ async function hashDevPortalSiteSources(siteDirectory, options) {
|
|
|
21073
21443
|
}
|
|
21074
21444
|
}
|
|
21075
21445
|
for (const dir of ["pages", "landing", "src"]) {
|
|
21076
|
-
const full =
|
|
21446
|
+
const full = path69.join(resolved, dir);
|
|
21077
21447
|
try {
|
|
21078
21448
|
const st = await fs6.stat(full);
|
|
21079
21449
|
if (!st.isDirectory()) continue;
|
|
@@ -21302,8 +21672,8 @@ function normalizeActionKey(actionKey2) {
|
|
|
21302
21672
|
const trimmed = actionKey2.trim();
|
|
21303
21673
|
if (trimmed.includes(":")) {
|
|
21304
21674
|
const [method2, ...pathParts] = trimmed.split(":");
|
|
21305
|
-
const
|
|
21306
|
-
return `${method2?.toLowerCase()}:${
|
|
21675
|
+
const path101 = pathParts.join(":").trim();
|
|
21676
|
+
return `${method2?.toLowerCase()}:${path101.startsWith("/") ? path101 : `/${path101}`}`;
|
|
21307
21677
|
}
|
|
21308
21678
|
const spaceIndex = trimmed.indexOf(" ");
|
|
21309
21679
|
if (spaceIndex <= 0) {
|
|
@@ -21312,8 +21682,8 @@ function normalizeActionKey(actionKey2) {
|
|
|
21312
21682
|
);
|
|
21313
21683
|
}
|
|
21314
21684
|
const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
|
|
21315
|
-
const
|
|
21316
|
-
return `${method}:${
|
|
21685
|
+
const path100 = trimmed.slice(spaceIndex + 1).trim();
|
|
21686
|
+
return `${method}:${path100.startsWith("/") ? path100 : `/${path100}`}`;
|
|
21317
21687
|
}
|
|
21318
21688
|
async function applyGatewayPublicRoutes(client, projectId, routes, options) {
|
|
21319
21689
|
const applied = [];
|
|
@@ -21792,7 +22162,7 @@ async function upsertGatewayPlansFromManifest(client, config2, projectId, plans,
|
|
|
21792
22162
|
|
|
21793
22163
|
// src/cli/platform/helpers/openapi-gateway-servers.ts
|
|
21794
22164
|
import { mkdir as mkdir17, readFile as readFile25, writeFile as writeFile19 } from "node:fs/promises";
|
|
21795
|
-
import
|
|
22165
|
+
import path70 from "node:path";
|
|
21796
22166
|
import YAML2 from "yaml";
|
|
21797
22167
|
var GATEWAY_URL_ENV_KEY = "APITOGO_GATEWAY_URL";
|
|
21798
22168
|
var PUBLISH_OPENAPI_RELATIVE = ".apitogo/openapi-publish.json";
|
|
@@ -21824,7 +22194,7 @@ async function resolveProjectGatewayUrl(client, projectId) {
|
|
|
21824
22194
|
}
|
|
21825
22195
|
async function readOpenApiDocument(filePath) {
|
|
21826
22196
|
const content = await readFile25(filePath, "utf8");
|
|
21827
|
-
const ext =
|
|
22197
|
+
const ext = path70.extname(filePath).toLowerCase();
|
|
21828
22198
|
const parsed = ext === ".json" ? JSON.parse(content) : YAML2.parse(content);
|
|
21829
22199
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
21830
22200
|
throw new Error(`OpenAPI document must be an object: ${filePath}`);
|
|
@@ -21832,13 +22202,13 @@ async function readOpenApiDocument(filePath) {
|
|
|
21832
22202
|
return parsed;
|
|
21833
22203
|
}
|
|
21834
22204
|
async function materializePublishOpenApiWithGateway(siteDirectory, sourceOpenApiPath, gatewayUrl) {
|
|
21835
|
-
const site =
|
|
21836
|
-
const source =
|
|
22205
|
+
const site = path70.resolve(siteDirectory);
|
|
22206
|
+
const source = path70.resolve(sourceOpenApiPath);
|
|
21837
22207
|
const relativeInput = PUBLISH_OPENAPI_RELATIVE;
|
|
21838
|
-
const outputPath =
|
|
22208
|
+
const outputPath = path70.join(site, ...relativeInput.split("/"));
|
|
21839
22209
|
const doc = await readOpenApiDocument(source);
|
|
21840
22210
|
const rewritten = withGatewayServers(doc, gatewayUrl);
|
|
21841
|
-
await mkdir17(
|
|
22211
|
+
await mkdir17(path70.dirname(outputPath), { recursive: true });
|
|
21842
22212
|
await writeFile19(
|
|
21843
22213
|
outputPath,
|
|
21844
22214
|
`${JSON.stringify(rewritten, null, 2)}
|
|
@@ -21848,8 +22218,8 @@ async function materializePublishOpenApiWithGateway(siteDirectory, sourceOpenApi
|
|
|
21848
22218
|
return { outputPath, relativeInput };
|
|
21849
22219
|
}
|
|
21850
22220
|
async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
|
|
21851
|
-
const configPath =
|
|
21852
|
-
|
|
22221
|
+
const configPath = path70.join(
|
|
22222
|
+
path70.resolve(siteDirectory),
|
|
21853
22223
|
APITOGO_CONFIG_FILENAME2
|
|
21854
22224
|
);
|
|
21855
22225
|
const raw = await readFile25(configPath, "utf8");
|
|
@@ -21891,7 +22261,7 @@ async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
|
|
|
21891
22261
|
};
|
|
21892
22262
|
}
|
|
21893
22263
|
async function prepareOpenApiServersForGatewayBuild(options) {
|
|
21894
|
-
const siteDirectory =
|
|
22264
|
+
const siteDirectory = path70.resolve(options.siteDirectory);
|
|
21895
22265
|
let openApiPath = resolveBackendOpenApiPath(
|
|
21896
22266
|
options.manifest?.backend?.openApiPath,
|
|
21897
22267
|
{
|
|
@@ -21905,7 +22275,7 @@ async function prepareOpenApiServersForGatewayBuild(options) {
|
|
|
21905
22275
|
if (!openApiPath) {
|
|
21906
22276
|
try {
|
|
21907
22277
|
const raw = await readFile25(
|
|
21908
|
-
|
|
22278
|
+
path70.join(siteDirectory, APITOGO_CONFIG_FILENAME2),
|
|
21909
22279
|
"utf8"
|
|
21910
22280
|
);
|
|
21911
22281
|
const config2 = JSON.parse(raw);
|
|
@@ -21934,8 +22304,8 @@ function normalizeActionKeyFormat(actionKey2) {
|
|
|
21934
22304
|
const trimmed = actionKey2.trim();
|
|
21935
22305
|
if (trimmed.includes(":")) {
|
|
21936
22306
|
const [method2, ...pathParts] = trimmed.split(":");
|
|
21937
|
-
const
|
|
21938
|
-
return `${method2.toLowerCase()}:${
|
|
22307
|
+
const path101 = pathParts.join(":").trim();
|
|
22308
|
+
return `${method2.toLowerCase()}:${path101.startsWith("/") ? path101 : `/${path101}`}`;
|
|
21939
22309
|
}
|
|
21940
22310
|
const spaceIndex = trimmed.indexOf(" ");
|
|
21941
22311
|
if (spaceIndex <= 0) {
|
|
@@ -21944,8 +22314,8 @@ function normalizeActionKeyFormat(actionKey2) {
|
|
|
21944
22314
|
);
|
|
21945
22315
|
}
|
|
21946
22316
|
const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
|
|
21947
|
-
const
|
|
21948
|
-
return `${method}:${
|
|
22317
|
+
const path100 = trimmed.slice(spaceIndex + 1).trim();
|
|
22318
|
+
return `${method}:${path100.startsWith("/") ? path100 : `/${path100}`}`;
|
|
21949
22319
|
}
|
|
21950
22320
|
function normalizePublicRoute(route) {
|
|
21951
22321
|
const trimmed = route.trim();
|
|
@@ -21979,10 +22349,10 @@ function collectManifestPublicActionKeys(gateway) {
|
|
|
21979
22349
|
|
|
21980
22350
|
// src/cli/platform/helpers/publish-ledger.ts
|
|
21981
22351
|
import { mkdir as mkdir18, readFile as readFile26, writeFile as writeFile20 } from "node:fs/promises";
|
|
21982
|
-
import
|
|
22352
|
+
import path71 from "node:path";
|
|
21983
22353
|
var PUBLISH_LEDGER_RELATIVE_PATH = ".apitogo/publish-state.json";
|
|
21984
22354
|
function publishLedgerPath(siteDirectory) {
|
|
21985
|
-
return
|
|
22355
|
+
return path71.join(path71.resolve(siteDirectory), PUBLISH_LEDGER_RELATIVE_PATH);
|
|
21986
22356
|
}
|
|
21987
22357
|
async function readPublishLedger(siteDirectory) {
|
|
21988
22358
|
const filePath = publishLedgerPath(siteDirectory);
|
|
@@ -21999,7 +22369,7 @@ async function readPublishLedger(siteDirectory) {
|
|
|
21999
22369
|
}
|
|
22000
22370
|
async function writePublishLedger(siteDirectory, ledger) {
|
|
22001
22371
|
const filePath = publishLedgerPath(siteDirectory);
|
|
22002
|
-
await mkdir18(
|
|
22372
|
+
await mkdir18(path71.dirname(filePath), { recursive: true });
|
|
22003
22373
|
const next = {
|
|
22004
22374
|
...ledger,
|
|
22005
22375
|
version: 1,
|
|
@@ -22520,7 +22890,7 @@ async function createProjectWithWarmPoolRetry(client, body, options) {
|
|
|
22520
22890
|
// src/cli/platform/helpers/backend-packaging.ts
|
|
22521
22891
|
import { mkdtemp as mkdtemp2, readdir as readdir5, rm as rm10 } from "node:fs/promises";
|
|
22522
22892
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
22523
|
-
import
|
|
22893
|
+
import path72 from "node:path";
|
|
22524
22894
|
async function directoryHasRuntimeConfig(dir) {
|
|
22525
22895
|
if (!await pathExists(dir)) {
|
|
22526
22896
|
return false;
|
|
@@ -22562,20 +22932,20 @@ function runDotnetPublish(projectDir, outputDir) {
|
|
|
22562
22932
|
async function findCsproj(projectDir) {
|
|
22563
22933
|
const entries = await readdir5(projectDir);
|
|
22564
22934
|
const csproj = entries.find((name) => name.endsWith(".csproj"));
|
|
22565
|
-
return csproj ?
|
|
22935
|
+
return csproj ? path72.join(projectDir, csproj) : null;
|
|
22566
22936
|
}
|
|
22567
22937
|
async function prepareBackendPackagingDirectory(args) {
|
|
22568
|
-
const sourceDirectory =
|
|
22938
|
+
const sourceDirectory = path72.resolve(args.sourceDirectory);
|
|
22569
22939
|
if (args.publishDirectory?.trim()) {
|
|
22570
22940
|
return {
|
|
22571
|
-
directory:
|
|
22941
|
+
directory: path72.resolve(args.publishDirectory),
|
|
22572
22942
|
packagingMode: "published"
|
|
22573
22943
|
};
|
|
22574
22944
|
}
|
|
22575
22945
|
if (await directoryHasRuntimeConfig(sourceDirectory)) {
|
|
22576
22946
|
return { directory: sourceDirectory, packagingMode: "published" };
|
|
22577
22947
|
}
|
|
22578
|
-
const publishSubdir =
|
|
22948
|
+
const publishSubdir = path72.join(sourceDirectory, "publish");
|
|
22579
22949
|
if (await directoryHasRuntimeConfig(publishSubdir)) {
|
|
22580
22950
|
return { directory: publishSubdir, packagingMode: "published" };
|
|
22581
22951
|
}
|
|
@@ -22587,9 +22957,9 @@ async function prepareBackendPackagingDirectory(args) {
|
|
|
22587
22957
|
return { directory: sourceDirectory, packagingMode: "source" };
|
|
22588
22958
|
}
|
|
22589
22959
|
const tempRoot = await mkdtemp2(
|
|
22590
|
-
|
|
22960
|
+
path72.join(tmpdir2(), "apitogo-dotnet-publish-")
|
|
22591
22961
|
);
|
|
22592
|
-
const outputDir =
|
|
22962
|
+
const outputDir = path72.join(tempRoot, "publish");
|
|
22593
22963
|
const result = await runDotnetPublish(sourceDirectory, outputDir);
|
|
22594
22964
|
if (result.exitCode !== 0) {
|
|
22595
22965
|
await rm10(tempRoot, { recursive: true, force: true });
|
|
@@ -22634,13 +23004,13 @@ function formatJobStatusResponse(options) {
|
|
|
22634
23004
|
|
|
22635
23005
|
// src/cli/platform/helpers/openapi.ts
|
|
22636
23006
|
import { promises as fs7 } from "node:fs";
|
|
22637
|
-
import
|
|
23007
|
+
import path73 from "node:path";
|
|
22638
23008
|
import SwaggerParser from "@apidevtools/swagger-parser";
|
|
22639
23009
|
import YAML3 from "yaml";
|
|
22640
23010
|
async function validateOpenApiFile(filePath) {
|
|
22641
|
-
const resolved =
|
|
23011
|
+
const resolved = path73.resolve(filePath);
|
|
22642
23012
|
const content = await fs7.readFile(resolved, "utf8");
|
|
22643
|
-
const ext =
|
|
23013
|
+
const ext = path73.extname(resolved).toLowerCase();
|
|
22644
23014
|
let parsed;
|
|
22645
23015
|
try {
|
|
22646
23016
|
parsed = ext === ".json" ? JSON.parse(content) : YAML3.parse(content);
|
|
@@ -22684,12 +23054,12 @@ async function validateOpenApiFile(filePath) {
|
|
|
22684
23054
|
// src/cli/platform/helpers/zip.ts
|
|
22685
23055
|
import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, promises as fs8 } from "node:fs";
|
|
22686
23056
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
22687
|
-
import
|
|
23057
|
+
import path74 from "node:path";
|
|
22688
23058
|
import { ZipArchive } from "archiver";
|
|
22689
23059
|
async function packageBackendDirectory(sourceDirectory, extraExcludes = []) {
|
|
22690
|
-
const resolved =
|
|
23060
|
+
const resolved = path74.resolve(sourceDirectory);
|
|
22691
23061
|
const files = await collectPackageableFiles(resolved, extraExcludes);
|
|
22692
|
-
const zipPath =
|
|
23062
|
+
const zipPath = path74.join(
|
|
22693
23063
|
tmpdir3(),
|
|
22694
23064
|
`apitogo-backend-${Date.now()}-${Math.random().toString(36).slice(2)}.zip`
|
|
22695
23065
|
);
|
|
@@ -22701,8 +23071,8 @@ async function packageBackendDirectory(sourceDirectory, extraExcludes = []) {
|
|
|
22701
23071
|
output4.on("error", reject);
|
|
22702
23072
|
archive.pipe(output4);
|
|
22703
23073
|
for (const rel2 of files) {
|
|
22704
|
-
archive.append(createReadStream2(
|
|
22705
|
-
name: rel2.split(
|
|
23074
|
+
archive.append(createReadStream2(path74.join(resolved, rel2)), {
|
|
23075
|
+
name: rel2.split(path74.sep).join("/")
|
|
22706
23076
|
});
|
|
22707
23077
|
}
|
|
22708
23078
|
void archive.finalize();
|
|
@@ -24272,11 +24642,11 @@ async function resolveProjectIdForPublish(client, config2, args, wait, progress,
|
|
|
24272
24642
|
}
|
|
24273
24643
|
|
|
24274
24644
|
// src/cli/platform/tools/dev-portal-site-build.ts
|
|
24275
|
-
import
|
|
24645
|
+
import path78 from "node:path";
|
|
24276
24646
|
|
|
24277
24647
|
// src/cli/platform/helpers/dev-portal-site-api-url.ts
|
|
24278
24648
|
import { readdir as readdir6, readFile as readFile27, writeFile as writeFile21 } from "node:fs/promises";
|
|
24279
|
-
import
|
|
24649
|
+
import path75 from "node:path";
|
|
24280
24650
|
var SITE_API_BASE_URL_ENV_KEY = "VITE_APITOGO_AUTHENTICATION_API_BASE_URL";
|
|
24281
24651
|
var PLACEHOLDER_HOST_MARKERS = [
|
|
24282
24652
|
"dp-example.azurecontainerapps.io",
|
|
@@ -24297,10 +24667,10 @@ function isPlaceholderDevPortalApiUrl(apiBaseUrl) {
|
|
|
24297
24667
|
return PLACEHOLDER_HOST_MARKERS.some((marker) => normalized.includes(marker));
|
|
24298
24668
|
}
|
|
24299
24669
|
async function readSiteApiBaseUrl(sourceDirectory) {
|
|
24300
|
-
const resolved =
|
|
24670
|
+
const resolved = path75.resolve(sourceDirectory);
|
|
24301
24671
|
for (const envFile of [".env", ".env.production"]) {
|
|
24302
24672
|
try {
|
|
24303
|
-
const content = await readFile27(
|
|
24673
|
+
const content = await readFile27(path75.join(resolved, envFile), "utf8");
|
|
24304
24674
|
const lines = [...content.matchAll(ENV_LINE_GLOBAL_RE)];
|
|
24305
24675
|
if (lines.length === 0) {
|
|
24306
24676
|
continue;
|
|
@@ -24325,11 +24695,11 @@ async function readSiteApiBaseUrl(sourceDirectory) {
|
|
|
24325
24695
|
return null;
|
|
24326
24696
|
}
|
|
24327
24697
|
async function patchSiteApiBaseUrl(sourceDirectory, apiBaseUrl) {
|
|
24328
|
-
const resolved =
|
|
24698
|
+
const resolved = path75.resolve(sourceDirectory);
|
|
24329
24699
|
const line2 = `${SITE_API_BASE_URL_ENV_KEY}=${apiBaseUrl}`;
|
|
24330
24700
|
let patchedExisting = false;
|
|
24331
24701
|
for (const envFile of [".env.production", ".env"]) {
|
|
24332
|
-
const envPath =
|
|
24702
|
+
const envPath = path75.join(resolved, envFile);
|
|
24333
24703
|
try {
|
|
24334
24704
|
const content = await readFile27(envPath, "utf8");
|
|
24335
24705
|
const withoutAssignments = content.replace(ENV_LINE_GLOBAL_RE, "").replace(/\n{3,}/g, "\n\n").trimEnd();
|
|
@@ -24343,7 +24713,7 @@ ${line2}
|
|
|
24343
24713
|
}
|
|
24344
24714
|
}
|
|
24345
24715
|
if (!patchedExisting) {
|
|
24346
|
-
await writeFile21(
|
|
24716
|
+
await writeFile21(path75.join(resolved, ".env"), `${line2}
|
|
24347
24717
|
`);
|
|
24348
24718
|
}
|
|
24349
24719
|
}
|
|
@@ -24351,7 +24721,7 @@ function tryProjectId(explicit, manifestProjectId, config2) {
|
|
|
24351
24721
|
return explicit?.trim() || manifestProjectId?.trim() || config2.defaultProjectId?.trim() || void 0;
|
|
24352
24722
|
}
|
|
24353
24723
|
async function ensureLiveSiteApiBaseUrlForBuild(_client, config2, args, resolveFromProject) {
|
|
24354
|
-
const sourceDirectory =
|
|
24724
|
+
const sourceDirectory = path75.resolve(args.sourceDirectory);
|
|
24355
24725
|
const explicit = args.apiBaseUrl?.trim();
|
|
24356
24726
|
if (explicit && !isPlaceholderDevPortalApiUrl(explicit)) {
|
|
24357
24727
|
await patchSiteApiBaseUrl(sourceDirectory, explicit);
|
|
@@ -24387,7 +24757,7 @@ async function* walkFiles(root) {
|
|
|
24387
24757
|
return;
|
|
24388
24758
|
}
|
|
24389
24759
|
for (const entry of entries) {
|
|
24390
|
-
const full =
|
|
24760
|
+
const full = path75.join(root, entry.name);
|
|
24391
24761
|
if (entry.isDirectory()) {
|
|
24392
24762
|
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
24393
24763
|
continue;
|
|
@@ -24399,8 +24769,8 @@ async function* walkFiles(root) {
|
|
|
24399
24769
|
}
|
|
24400
24770
|
}
|
|
24401
24771
|
async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiBaseUrl) {
|
|
24402
|
-
const dist =
|
|
24403
|
-
const siteRoot =
|
|
24772
|
+
const dist = path75.resolve(distDirectory);
|
|
24773
|
+
const siteRoot = path75.dirname(dist);
|
|
24404
24774
|
const fromEnv = expectedApiBaseUrl?.trim() || await readSiteApiBaseUrl(siteRoot) || await readSiteApiBaseUrl(dist);
|
|
24405
24775
|
if (!fromEnv || isPlaceholderDevPortalApiUrl(fromEnv)) {
|
|
24406
24776
|
throw new Error(
|
|
@@ -24436,7 +24806,7 @@ async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiB
|
|
|
24436
24806
|
|
|
24437
24807
|
// src/cli/platform/tools/dev-portal.ts
|
|
24438
24808
|
import { promises as fs10 } from "node:fs";
|
|
24439
|
-
import
|
|
24809
|
+
import path77 from "node:path";
|
|
24440
24810
|
|
|
24441
24811
|
// src/cli/platform/helpers/dev-portal-backend-job.ts
|
|
24442
24812
|
var DEV_PORTAL_BACKEND_UPDATE_RESOURCE_TYPE = "DevPortalBackendUpdate";
|
|
@@ -24546,7 +24916,7 @@ async function snapshotBackendUpdateJobIds(client, projectId) {
|
|
|
24546
24916
|
// src/cli/platform/helpers/tarball.ts
|
|
24547
24917
|
import { createReadStream as createReadStream3, createWriteStream as createWriteStream3, promises as fs9 } from "node:fs";
|
|
24548
24918
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
24549
|
-
import
|
|
24919
|
+
import path76 from "node:path";
|
|
24550
24920
|
import { TarArchive } from "archiver";
|
|
24551
24921
|
var DEV_PORTAL_DEPLOY_ARCHIVE_ROOT = "dist";
|
|
24552
24922
|
function normalizeArchiveRoot(archiveRoot) {
|
|
@@ -24557,10 +24927,10 @@ function normalizeArchiveRoot(archiveRoot) {
|
|
|
24557
24927
|
return `${trimmed}/`;
|
|
24558
24928
|
}
|
|
24559
24929
|
async function packageDirectoryAsTarGz(sourceDirectory, options) {
|
|
24560
|
-
const resolved =
|
|
24930
|
+
const resolved = path76.resolve(sourceDirectory);
|
|
24561
24931
|
const files = await collectPackageableFiles(resolved);
|
|
24562
24932
|
const entryPrefix = options?.archiveRoot ? normalizeArchiveRoot(options.archiveRoot) : "";
|
|
24563
|
-
const archivePath =
|
|
24933
|
+
const archivePath = path76.join(
|
|
24564
24934
|
tmpdir4(),
|
|
24565
24935
|
`apitogo-docs-${Date.now()}-${Math.random().toString(36).slice(2)}.tgz`
|
|
24566
24936
|
);
|
|
@@ -24572,8 +24942,8 @@ async function packageDirectoryAsTarGz(sourceDirectory, options) {
|
|
|
24572
24942
|
output4.on("error", reject);
|
|
24573
24943
|
archive.pipe(output4);
|
|
24574
24944
|
for (const rel2 of files) {
|
|
24575
|
-
const entryName = entryPrefix + rel2.split(
|
|
24576
|
-
archive.append(createReadStream3(
|
|
24945
|
+
const entryName = entryPrefix + rel2.split(path76.sep).join("/");
|
|
24946
|
+
archive.append(createReadStream3(path76.join(resolved, rel2)), {
|
|
24577
24947
|
name: entryName
|
|
24578
24948
|
});
|
|
24579
24949
|
}
|
|
@@ -24815,7 +25185,7 @@ function validateDeployArchiveInput(args) {
|
|
|
24815
25185
|
async function resolveDevPortalArchive(args) {
|
|
24816
25186
|
validateDeployArchiveInput(args);
|
|
24817
25187
|
if (args.archivePath?.trim()) {
|
|
24818
|
-
const archivePath =
|
|
25188
|
+
const archivePath = path77.resolve(args.archivePath.trim());
|
|
24819
25189
|
const stat7 = await fs10.stat(archivePath).catch(() => null);
|
|
24820
25190
|
if (!stat7?.isFile()) {
|
|
24821
25191
|
throw new Error(`archivePath is not a file: ${archivePath}`);
|
|
@@ -24880,7 +25250,7 @@ async function handleDeployDevPortal(client, config2, args, progress) {
|
|
|
24880
25250
|
// src/cli/platform/tools/dev-portal-site-build.ts
|
|
24881
25251
|
async function handleBuildDevPortalSite(client, config2, args, progress) {
|
|
24882
25252
|
const buildProgress = progress?.child("Build dev portal site");
|
|
24883
|
-
const sourceDirectory =
|
|
25253
|
+
const sourceDirectory = path78.resolve(args.sourceDirectory);
|
|
24884
25254
|
await buildProgress?.onStep("Ensuring live portal API URL");
|
|
24885
25255
|
const apiBaseUrl = await ensureLiveSiteApiBaseUrlForBuild(
|
|
24886
25256
|
client,
|
|
@@ -26386,7 +26756,7 @@ function resultLooksFailed(payload) {
|
|
|
26386
26756
|
return parsed.status === "failed" || parsed.status === "blocked";
|
|
26387
26757
|
}
|
|
26388
26758
|
async function apply(argv) {
|
|
26389
|
-
const sourceDirectory =
|
|
26759
|
+
const sourceDirectory = path79.resolve(process.cwd(), argv.dir);
|
|
26390
26760
|
let config2;
|
|
26391
26761
|
try {
|
|
26392
26762
|
config2 = loadConfig();
|
|
@@ -26456,7 +26826,7 @@ async function apply(argv) {
|
|
|
26456
26826
|
if (canPromptInteractively && parsed?.status === "blocked" && parsed.reason === "project_not_found") {
|
|
26457
26827
|
const resolution = await resolveProjectNotFoundInteractively(
|
|
26458
26828
|
parsed,
|
|
26459
|
-
|
|
26829
|
+
path79.basename(sourceDirectory)
|
|
26460
26830
|
);
|
|
26461
26831
|
if (resolution) {
|
|
26462
26832
|
effectiveProjectId = void 0;
|
|
@@ -26476,7 +26846,7 @@ async function apply(argv) {
|
|
|
26476
26846
|
while (canPromptInteractively && parsed?.status === "blocked" && parsed.reason === "project_name_exists") {
|
|
26477
26847
|
const resolution = await resolveProjectNameExistsInteractively(
|
|
26478
26848
|
parsed,
|
|
26479
|
-
effectiveProjectName ??
|
|
26849
|
+
effectiveProjectName ?? path79.basename(sourceDirectory)
|
|
26480
26850
|
);
|
|
26481
26851
|
if (!resolution) {
|
|
26482
26852
|
break;
|
|
@@ -26547,11 +26917,11 @@ async function apply(argv) {
|
|
|
26547
26917
|
}
|
|
26548
26918
|
|
|
26549
26919
|
// src/cli/deploy/command.ts
|
|
26550
|
-
import
|
|
26920
|
+
import path85 from "node:path";
|
|
26551
26921
|
init_invariant();
|
|
26552
26922
|
|
|
26553
26923
|
// src/cli/project/create-handler.ts
|
|
26554
|
-
import
|
|
26924
|
+
import path80 from "node:path";
|
|
26555
26925
|
import open2 from "open";
|
|
26556
26926
|
init_invariant();
|
|
26557
26927
|
|
|
@@ -26865,7 +27235,7 @@ async function createLinkedProject(argv, dir, options = {}) {
|
|
|
26865
27235
|
}
|
|
26866
27236
|
}
|
|
26867
27237
|
async function createProject2(argv) {
|
|
26868
|
-
const dir =
|
|
27238
|
+
const dir = path80.resolve(process.cwd(), argv.dir ?? ".");
|
|
26869
27239
|
if (await isConfigV2(dir)) {
|
|
26870
27240
|
await createLinkedProject(argv, dir);
|
|
26871
27241
|
return;
|
|
@@ -26925,7 +27295,7 @@ async function createProject2(argv) {
|
|
|
26925
27295
|
}
|
|
26926
27296
|
|
|
26927
27297
|
// src/cli/secrets/handler.ts
|
|
26928
|
-
import
|
|
27298
|
+
import path81 from "node:path";
|
|
26929
27299
|
init_invariant();
|
|
26930
27300
|
|
|
26931
27301
|
// src/cli/secrets/input.ts
|
|
@@ -26990,7 +27360,7 @@ var SecretsError = class extends ApitogoError {
|
|
|
26990
27360
|
async function resolveProjectId2(argv, deps) {
|
|
26991
27361
|
const explicit = argv.projectId?.trim();
|
|
26992
27362
|
if (explicit) return explicit;
|
|
26993
|
-
const dir =
|
|
27363
|
+
const dir = path81.resolve(process.cwd(), argv.dir ?? ".");
|
|
26994
27364
|
if (await isConfigV2(dir)) {
|
|
26995
27365
|
const id = loadConfigV2(dir).resolved.project.id;
|
|
26996
27366
|
if (id) return id;
|
|
@@ -27075,7 +27445,7 @@ var KNOWN_SECRET_PLACES = {
|
|
|
27075
27445
|
async function wireKnownSecret(argv, name) {
|
|
27076
27446
|
const place = KNOWN_SECRET_PLACES[name.toUpperCase()];
|
|
27077
27447
|
if (!place) return void 0;
|
|
27078
|
-
const dir =
|
|
27448
|
+
const dir = path81.resolve(process.cwd(), argv.dir ?? ".");
|
|
27079
27449
|
if (!await isConfigV2(dir)) return void 0;
|
|
27080
27450
|
const project = await openConfigProject(dir);
|
|
27081
27451
|
const plans = project.resolved.plans;
|
|
@@ -27136,7 +27506,7 @@ async function secrets(argv) {
|
|
|
27136
27506
|
}
|
|
27137
27507
|
|
|
27138
27508
|
// src/cli/deploy/stripe-key.ts
|
|
27139
|
-
import
|
|
27509
|
+
import path82 from "node:path";
|
|
27140
27510
|
init_invariant();
|
|
27141
27511
|
var StripeKeyError = class extends ApitogoError {
|
|
27142
27512
|
constructor(message, developerHint) {
|
|
@@ -27154,7 +27524,7 @@ async function ensureStripeKey(argv, deps) {
|
|
|
27154
27524
|
if (!wantsPlans(argv.only)) return { status: "not-needed" };
|
|
27155
27525
|
let resolved;
|
|
27156
27526
|
try {
|
|
27157
|
-
resolved = loadConfigV2(
|
|
27527
|
+
resolved = loadConfigV2(path82.resolve(process.cwd(), argv.dir)).resolved;
|
|
27158
27528
|
} catch {
|
|
27159
27529
|
return { status: "not-needed" };
|
|
27160
27530
|
}
|
|
@@ -28091,7 +28461,7 @@ init_invariant();
|
|
|
28091
28461
|
|
|
28092
28462
|
// src/cli/portal/report.ts
|
|
28093
28463
|
import { access as access9 } from "node:fs/promises";
|
|
28094
|
-
import
|
|
28464
|
+
import path83 from "node:path";
|
|
28095
28465
|
|
|
28096
28466
|
// src/cli/deploy/identity.ts
|
|
28097
28467
|
init_invariant();
|
|
@@ -28862,7 +29232,7 @@ async function planPortalService(resolved, ledger) {
|
|
|
28862
29232
|
const hash2 = await portalBuildHash(resolved, prepared);
|
|
28863
29233
|
const previous = stepOf(ledger, "portal", "build");
|
|
28864
29234
|
const built = await exists5(
|
|
28865
|
-
|
|
29235
|
+
path83.join(resolved.state.buildDir, "index.html")
|
|
28866
29236
|
);
|
|
28867
29237
|
if (previous?.status === "succeeded" && previous.hash === hash2 && built) {
|
|
28868
29238
|
return {
|
|
@@ -29248,7 +29618,7 @@ async function statusV2(dir, only, options = {}) {
|
|
|
29248
29618
|
if (service === "portal") {
|
|
29249
29619
|
const build2 = stepOf(ledger, "portal", "build");
|
|
29250
29620
|
const built = await exists5(
|
|
29251
|
-
|
|
29621
|
+
path83.join(resolved.state.buildDir, "index.html")
|
|
29252
29622
|
);
|
|
29253
29623
|
const state = build2?.status === "failed" ? "build-failed" : build2?.status === "succeeded" && built ? "built" : "not-built";
|
|
29254
29624
|
services.push({
|
|
@@ -29259,7 +29629,7 @@ async function statusV2(dir, only, options = {}) {
|
|
|
29259
29629
|
...build2?.finishedAt ? [`last build: ${build2.finishedAt}`] : [],
|
|
29260
29630
|
...build2?.status === "failed" ? [`error: ${build2.error ?? "unknown"}`] : [],
|
|
29261
29631
|
...state === "built" ? [
|
|
29262
|
-
`output: ${
|
|
29632
|
+
`output: ${path83.relative(resolved.configDir, resolved.state.buildDir)}`
|
|
29263
29633
|
] : [],
|
|
29264
29634
|
...url2 ? [`url: ${url2}`] : ["url: not known (portal is not deployed yet)"],
|
|
29265
29635
|
...await hostingLine(resolved, manifest, options.hostingRemote)
|
|
@@ -29326,7 +29696,7 @@ function formatStatus(output4) {
|
|
|
29326
29696
|
|
|
29327
29697
|
// src/cli/deploy/static-web-config.ts
|
|
29328
29698
|
import { access as access10, writeFile as writeFile22 } from "node:fs/promises";
|
|
29329
|
-
import
|
|
29699
|
+
import path84 from "node:path";
|
|
29330
29700
|
var STATIC_WEB_CONFIG_FILE = "staticwebapp.config.json";
|
|
29331
29701
|
var STATIC_WEB_CONFIG_VERSION = 3;
|
|
29332
29702
|
var CLIENT_ONLY_ROUTES = [
|
|
@@ -29344,7 +29714,7 @@ var DEFAULT_STATIC_WEB_CONFIG = {
|
|
|
29344
29714
|
}
|
|
29345
29715
|
};
|
|
29346
29716
|
async function ensureStaticWebConfig(buildDir) {
|
|
29347
|
-
const file =
|
|
29717
|
+
const file = path84.join(buildDir, STATIC_WEB_CONFIG_FILE);
|
|
29348
29718
|
try {
|
|
29349
29719
|
await access10(file);
|
|
29350
29720
|
return false;
|
|
@@ -29699,7 +30069,7 @@ function formatDeploy(output4) {
|
|
|
29699
30069
|
// src/cli/deploy/command.ts
|
|
29700
30070
|
async function ensureLinkedProject(argv, deps) {
|
|
29701
30071
|
if (argv.projectId?.trim() || deps.envProjectId?.trim()) return true;
|
|
29702
|
-
const dir =
|
|
30072
|
+
const dir = path85.resolve(process.cwd(), argv.dir);
|
|
29703
30073
|
let linked;
|
|
29704
30074
|
try {
|
|
29705
30075
|
linked = Boolean(loadConfigV2(dir).resolved.project.id);
|
|
@@ -29750,7 +30120,7 @@ async function deployProject(argv) {
|
|
|
29750
30120
|
try {
|
|
29751
30121
|
const config2 = loadConfig();
|
|
29752
30122
|
const client = new PlatformApiClient(config2);
|
|
29753
|
-
const dir =
|
|
30123
|
+
const dir = path85.resolve(process.cwd(), argv.dir);
|
|
29754
30124
|
const deploy = (only) => deployV2(
|
|
29755
30125
|
{
|
|
29756
30126
|
dir,
|
|
@@ -29858,7 +30228,7 @@ var deploy_default = {
|
|
|
29858
30228
|
}),
|
|
29859
30229
|
handler: async (argv) => {
|
|
29860
30230
|
await captureEvent({ argv, event: "apitogo deploy" });
|
|
29861
|
-
if (!await isLegacyConfig(
|
|
30231
|
+
if (!await isLegacyConfig(path86.resolve(process.cwd(), argv.dir))) {
|
|
29862
30232
|
await deployProject(argv);
|
|
29863
30233
|
return;
|
|
29864
30234
|
}
|
|
@@ -29868,7 +30238,7 @@ var deploy_default = {
|
|
|
29868
30238
|
|
|
29869
30239
|
// src/cli/export/handler.ts
|
|
29870
30240
|
import { mkdir as mkdir19, writeFile as writeFile23 } from "node:fs/promises";
|
|
29871
|
-
import
|
|
30241
|
+
import path87 from "node:path";
|
|
29872
30242
|
init_invariant();
|
|
29873
30243
|
var ExportError = class extends ApitogoError {
|
|
29874
30244
|
constructor(message, developerHint) {
|
|
@@ -29882,7 +30252,7 @@ async function exportOpenApi(args, deps) {
|
|
|
29882
30252
|
`Cannot export "${args.target}".`,
|
|
29883
30253
|
"Only `apitogo export openapi` exists."
|
|
29884
30254
|
);
|
|
29885
|
-
const dir =
|
|
30255
|
+
const dir = path87.resolve(process.cwd(), args.dir ?? ".");
|
|
29886
30256
|
if (!await isConfigV2(dir))
|
|
29887
30257
|
throw new ExportError(
|
|
29888
30258
|
"This command needs a config version 2 project.",
|
|
@@ -29907,8 +30277,8 @@ async function exportOpenApi(args, deps) {
|
|
|
29907
30277
|
throw error;
|
|
29908
30278
|
}
|
|
29909
30279
|
if (!args.out) return { text: text2 };
|
|
29910
|
-
const file =
|
|
29911
|
-
await mkdir19(
|
|
30280
|
+
const file = path87.resolve(process.cwd(), args.out);
|
|
30281
|
+
await mkdir19(path87.dirname(file), { recursive: true });
|
|
29912
30282
|
await writeFile23(file, text2);
|
|
29913
30283
|
return { text: text2, file };
|
|
29914
30284
|
}
|
|
@@ -30001,8 +30371,8 @@ import open3 from "open";
|
|
|
30001
30371
|
import colors14 from "picocolors";
|
|
30002
30372
|
|
|
30003
30373
|
// src/cli/platform/device-auth.ts
|
|
30004
|
-
function url(apiUrl,
|
|
30005
|
-
return `${apiUrl}${
|
|
30374
|
+
function url(apiUrl, path100) {
|
|
30375
|
+
return `${apiUrl}${path100.startsWith("/") ? path100 : `/${path100}`}`;
|
|
30006
30376
|
}
|
|
30007
30377
|
async function requestDeviceCode(apiUrl) {
|
|
30008
30378
|
const response = await fetchWithRetry(
|
|
@@ -30184,7 +30554,7 @@ var logout_default = {
|
|
|
30184
30554
|
};
|
|
30185
30555
|
|
|
30186
30556
|
// src/cli/portal/commands.ts
|
|
30187
|
-
import
|
|
30557
|
+
import path88 from "node:path";
|
|
30188
30558
|
init_invariant();
|
|
30189
30559
|
function parseOnly(value) {
|
|
30190
30560
|
if (value === void 0) return void 0;
|
|
@@ -30201,7 +30571,7 @@ function parseOnly(value) {
|
|
|
30201
30571
|
async function run2(command2, argv, compute, format) {
|
|
30202
30572
|
const json = argv.json === true;
|
|
30203
30573
|
try {
|
|
30204
|
-
const dir =
|
|
30574
|
+
const dir = path88.resolve(process.cwd(), argv.dir ?? ".");
|
|
30205
30575
|
if (!await isConfigV2(dir)) {
|
|
30206
30576
|
throw new ServiceEditError(
|
|
30207
30577
|
`${command2} works with a config version 2 project, and there is none in ${dir}.`,
|
|
@@ -30563,14 +30933,14 @@ var remove_default = {
|
|
|
30563
30933
|
|
|
30564
30934
|
// src/cli/dev/handler.ts
|
|
30565
30935
|
init_joinUrl();
|
|
30566
|
-
import
|
|
30936
|
+
import path91 from "node:path";
|
|
30567
30937
|
|
|
30568
30938
|
// src/vite/dev-server.ts
|
|
30569
30939
|
init_logger();
|
|
30570
30940
|
import fs11 from "node:fs/promises";
|
|
30571
30941
|
import http from "node:http";
|
|
30572
30942
|
import https from "node:https";
|
|
30573
|
-
import
|
|
30943
|
+
import path90 from "node:path";
|
|
30574
30944
|
import { createHttpTerminator } from "http-terminator";
|
|
30575
30945
|
import {
|
|
30576
30946
|
createServer as createViteServer,
|
|
@@ -30615,7 +30985,7 @@ function withSsrGraphParts(config2, ssrConfig) {
|
|
|
30615
30985
|
// src/vite/pagefind-dev-index.ts
|
|
30616
30986
|
init_invariant();
|
|
30617
30987
|
init_joinUrl();
|
|
30618
|
-
import
|
|
30988
|
+
import path89 from "node:path";
|
|
30619
30989
|
import { createIndex as createIndex2 } from "pagefind";
|
|
30620
30990
|
import { isRunnableDevEnvironment } from "vite";
|
|
30621
30991
|
async function* buildPagefindDevIndex(vite, config2) {
|
|
@@ -30668,7 +31038,7 @@ async function* buildPagefindDevIndex(vite, config2) {
|
|
|
30668
31038
|
path: urlPath
|
|
30669
31039
|
};
|
|
30670
31040
|
}
|
|
30671
|
-
const outputPath =
|
|
31041
|
+
const outputPath = path89.join(vite.config.publicDir, "pagefind");
|
|
30672
31042
|
await pagefindIndex.writeFiles({ outputPath });
|
|
30673
31043
|
yield { type: "complete", success: true, indexed };
|
|
30674
31044
|
}
|
|
@@ -30687,9 +31057,9 @@ var DevServer = class {
|
|
|
30687
31057
|
this.protocol = "https";
|
|
30688
31058
|
const { dir } = this.options;
|
|
30689
31059
|
const [key, cert, ca] = await Promise.all([
|
|
30690
|
-
fs11.readFile(
|
|
30691
|
-
fs11.readFile(
|
|
30692
|
-
config2.https.ca ? fs11.readFile(
|
|
31060
|
+
fs11.readFile(path90.resolve(dir, config2.https.key)),
|
|
31061
|
+
fs11.readFile(path90.resolve(dir, config2.https.cert)),
|
|
31062
|
+
config2.https.ca ? fs11.readFile(path90.resolve(dir, config2.https.ca)) : void 0
|
|
30693
31063
|
]);
|
|
30694
31064
|
return https.createServer({ key, cert, ca });
|
|
30695
31065
|
}
|
|
@@ -30706,7 +31076,7 @@ var DevServer = class {
|
|
|
30706
31076
|
);
|
|
30707
31077
|
const server = await this.createNodeServer(config2);
|
|
30708
31078
|
if (config2.search?.type === "pagefind" && viteConfig.publicDir !== false) {
|
|
30709
|
-
const publicRoot =
|
|
31079
|
+
const publicRoot = path90.resolve(
|
|
30710
31080
|
this.options.dir,
|
|
30711
31081
|
typeof viteConfig.publicDir === "string" ? viteConfig.publicDir : "public"
|
|
30712
31082
|
);
|
|
@@ -30723,7 +31093,7 @@ var DevServer = class {
|
|
|
30723
31093
|
// built-in transform middleware which would treat the path as a static asset.
|
|
30724
31094
|
name: "apitogo:entry-client",
|
|
30725
31095
|
configureServer(server2) {
|
|
30726
|
-
const entryPath =
|
|
31096
|
+
const entryPath = path90.posix.join(
|
|
30727
31097
|
server2.config.base,
|
|
30728
31098
|
"/__z/entry.client.tsx"
|
|
30729
31099
|
);
|
|
@@ -30891,7 +31261,7 @@ init_package_json();
|
|
|
30891
31261
|
async function dev(argv) {
|
|
30892
31262
|
const packageJson3 = getZudokuPackageJson();
|
|
30893
31263
|
process.env.NODE_ENV = "development";
|
|
30894
|
-
let dir =
|
|
31264
|
+
let dir = path91.resolve(process.cwd(), argv.dir);
|
|
30895
31265
|
if (await isConfigV2(dir)) {
|
|
30896
31266
|
const { root, prepared } = await preparePortalWorkspace(dir, "development");
|
|
30897
31267
|
dir = root;
|
|
@@ -31026,12 +31396,12 @@ var secrets_default = {
|
|
|
31026
31396
|
};
|
|
31027
31397
|
|
|
31028
31398
|
// src/cli/cmds/status.ts
|
|
31029
|
-
import
|
|
31399
|
+
import path93 from "node:path";
|
|
31030
31400
|
|
|
31031
31401
|
// src/cli/status/handler.ts
|
|
31032
|
-
import
|
|
31402
|
+
import path92 from "node:path";
|
|
31033
31403
|
async function status(argv) {
|
|
31034
|
-
const sourceDirectory =
|
|
31404
|
+
const sourceDirectory = path92.resolve(process.cwd(), argv.dir);
|
|
31035
31405
|
let config2;
|
|
31036
31406
|
try {
|
|
31037
31407
|
config2 = loadConfig();
|
|
@@ -31157,7 +31527,7 @@ var status_default = {
|
|
|
31157
31527
|
}),
|
|
31158
31528
|
handler: async (argv) => {
|
|
31159
31529
|
await captureEvent({ argv, event: "apitogo status" });
|
|
31160
|
-
if (await isConfigV2(
|
|
31530
|
+
if (await isConfigV2(path93.resolve(process.cwd(), argv.dir))) {
|
|
31161
31531
|
await statusOfProject(argv);
|
|
31162
31532
|
return;
|
|
31163
31533
|
}
|
|
@@ -31166,11 +31536,11 @@ var status_default = {
|
|
|
31166
31536
|
};
|
|
31167
31537
|
|
|
31168
31538
|
// src/cli/cmds/teardown.ts
|
|
31169
|
-
import
|
|
31539
|
+
import path96 from "node:path";
|
|
31170
31540
|
|
|
31171
31541
|
// src/cli/teardown/command.ts
|
|
31172
31542
|
init_invariant();
|
|
31173
|
-
import
|
|
31543
|
+
import path94 from "node:path";
|
|
31174
31544
|
import { createInterface as createInterface7 } from "node:readline/promises";
|
|
31175
31545
|
|
|
31176
31546
|
// src/cli/teardown/v2.ts
|
|
@@ -31531,7 +31901,7 @@ async function teardownProject(argv) {
|
|
|
31531
31901
|
const progress = createConsoleProgressReporter();
|
|
31532
31902
|
const result = await teardownV2(
|
|
31533
31903
|
{
|
|
31534
|
-
dir:
|
|
31904
|
+
dir: path94.resolve(process.cwd(), argv.dir),
|
|
31535
31905
|
projectId: argv.projectId,
|
|
31536
31906
|
only: Array.isArray(argv.only) ? argv.only.join(",") : argv.only,
|
|
31537
31907
|
yes: argv.yes === true,
|
|
@@ -31590,7 +31960,7 @@ async function teardownProject(argv) {
|
|
|
31590
31960
|
}
|
|
31591
31961
|
|
|
31592
31962
|
// src/cli/teardown/handler.ts
|
|
31593
|
-
import
|
|
31963
|
+
import path95 from "node:path";
|
|
31594
31964
|
function resultLooksFailed3(payload) {
|
|
31595
31965
|
try {
|
|
31596
31966
|
const parsed = JSON.parse(payload);
|
|
@@ -31606,7 +31976,7 @@ async function teardown(argv) {
|
|
|
31606
31976
|
);
|
|
31607
31977
|
return;
|
|
31608
31978
|
}
|
|
31609
|
-
const sourceDirectory =
|
|
31979
|
+
const sourceDirectory = path95.resolve(process.cwd(), argv.dir);
|
|
31610
31980
|
let config2;
|
|
31611
31981
|
try {
|
|
31612
31982
|
config2 = loadConfig();
|
|
@@ -31684,7 +32054,7 @@ var teardown_default = {
|
|
|
31684
32054
|
}),
|
|
31685
32055
|
handler: async (argv) => {
|
|
31686
32056
|
await captureEvent({ argv, event: "apitogo teardown" });
|
|
31687
|
-
if (!await isLegacyConfig(
|
|
32057
|
+
if (!await isLegacyConfig(path96.resolve(process.cwd(), argv.dir))) {
|
|
31688
32058
|
await teardownProject(argv);
|
|
31689
32059
|
return;
|
|
31690
32060
|
}
|
|
@@ -31694,7 +32064,7 @@ var teardown_default = {
|
|
|
31694
32064
|
|
|
31695
32065
|
// src/cli/teardown/reset-command.ts
|
|
31696
32066
|
init_invariant();
|
|
31697
|
-
import
|
|
32067
|
+
import path97 from "node:path";
|
|
31698
32068
|
|
|
31699
32069
|
// src/cli/teardown/reset.ts
|
|
31700
32070
|
init_invariant();
|
|
@@ -31817,7 +32187,7 @@ async function resetProject(argv) {
|
|
|
31817
32187
|
const config2 = loadConfig();
|
|
31818
32188
|
const result = await resetProjectV2(
|
|
31819
32189
|
{
|
|
31820
|
-
dir:
|
|
32190
|
+
dir: path97.resolve(process.cwd(), argv.dir),
|
|
31821
32191
|
projectId: argv.projectId,
|
|
31822
32192
|
yes: argv.yes === true
|
|
31823
32193
|
},
|
|
@@ -31881,7 +32251,7 @@ var test_reset_default = {
|
|
|
31881
32251
|
};
|
|
31882
32252
|
|
|
31883
32253
|
// src/cli/test-sign-in/handler.ts
|
|
31884
|
-
import
|
|
32254
|
+
import path98 from "node:path";
|
|
31885
32255
|
init_invariant();
|
|
31886
32256
|
var TestSignInError = class extends ApitogoError {
|
|
31887
32257
|
constructor(message, developerHint) {
|
|
@@ -31892,7 +32262,7 @@ var TestSignInError = class extends ApitogoError {
|
|
|
31892
32262
|
async function resolveProjectId3(argv) {
|
|
31893
32263
|
const explicit = argv.projectId?.trim();
|
|
31894
32264
|
if (explicit) return explicit;
|
|
31895
|
-
const dir =
|
|
32265
|
+
const dir = path98.resolve(process.cwd(), argv.dir ?? ".");
|
|
31896
32266
|
if (await isConfigV2(dir)) {
|
|
31897
32267
|
const id = loadConfigV2(dir).resolved.project.id;
|
|
31898
32268
|
if (id) return id;
|
|
@@ -32032,36 +32402,36 @@ function createApitogoCli(argv) {
|
|
|
32032
32402
|
// src/cli/local-handoff.ts
|
|
32033
32403
|
import { spawn as spawn2 } from "node:child_process";
|
|
32034
32404
|
import { existsSync as existsSync9, realpathSync as realpathSync2 } from "node:fs";
|
|
32035
|
-
import
|
|
32405
|
+
import path99 from "node:path";
|
|
32036
32406
|
var LOCAL_HANDOFF_ENV = "APITOGO_LOCAL_CLI";
|
|
32037
32407
|
var PACKAGE_NAME = "@lukoweb/apitogo";
|
|
32038
32408
|
var resolveProjectDir = (argv, cwd) => {
|
|
32039
32409
|
for (let i = 0; i < argv.length; i++) {
|
|
32040
32410
|
const arg = argv[i];
|
|
32041
32411
|
const next = argv[i + 1];
|
|
32042
|
-
if (arg === "--dir" && next) return
|
|
32412
|
+
if (arg === "--dir" && next) return path99.resolve(cwd, next);
|
|
32043
32413
|
if (arg?.startsWith("--dir=")) {
|
|
32044
|
-
return
|
|
32414
|
+
return path99.resolve(cwd, arg.slice("--dir=".length));
|
|
32045
32415
|
}
|
|
32046
32416
|
}
|
|
32047
32417
|
return cwd;
|
|
32048
32418
|
};
|
|
32049
32419
|
var findLocalCli = (projectDir, runningRoot) => {
|
|
32050
|
-
let dir =
|
|
32420
|
+
let dir = path99.resolve(projectDir);
|
|
32051
32421
|
let localPackageRoot;
|
|
32052
32422
|
while (!localPackageRoot) {
|
|
32053
|
-
const candidate =
|
|
32054
|
-
if (existsSync9(
|
|
32423
|
+
const candidate = path99.join(dir, "node_modules", PACKAGE_NAME);
|
|
32424
|
+
if (existsSync9(path99.join(candidate, "package.json"))) {
|
|
32055
32425
|
localPackageRoot = candidate;
|
|
32056
|
-
} else if (dir ===
|
|
32426
|
+
} else if (dir === path99.dirname(dir)) {
|
|
32057
32427
|
return void 0;
|
|
32058
32428
|
} else {
|
|
32059
|
-
dir =
|
|
32429
|
+
dir = path99.dirname(dir);
|
|
32060
32430
|
}
|
|
32061
32431
|
}
|
|
32062
32432
|
const localRoot = realpathSync2(localPackageRoot);
|
|
32063
32433
|
if (localRoot === realpathSync2(runningRoot)) return void 0;
|
|
32064
|
-
return
|
|
32434
|
+
return path99.join(localRoot, "cli.js");
|
|
32065
32435
|
};
|
|
32066
32436
|
var handoffToLocalCli = async (argv, runningRoot) => {
|
|
32067
32437
|
if (process.env[LOCAL_HANDOFF_ENV] || process.env.ZUDOKU_ENV === "internal") {
|
|
@@ -32073,7 +32443,7 @@ var handoffToLocalCli = async (argv, runningRoot) => {
|
|
|
32073
32443
|
);
|
|
32074
32444
|
if (!localCli) return void 0;
|
|
32075
32445
|
printDiagnosticsToConsole(
|
|
32076
|
-
`Using the project's local ${PACKAGE_NAME} (${
|
|
32446
|
+
`Using the project's local ${PACKAGE_NAME} (${path99.dirname(localCli)})`
|
|
32077
32447
|
);
|
|
32078
32448
|
const child = spawn2(process.execPath, [localCli, ...argv], {
|
|
32079
32449
|
stdio: "inherit",
|