@lukoweb/apitogo 0.2.60 → 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 +893 -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 +76 -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;
|
|
@@ -8346,11 +8447,38 @@ function planPortal(profile, manifest) {
|
|
|
8346
8447
|
var SITE_CONFIG_FILE = "apitogo.config.json";
|
|
8347
8448
|
var REFERENCE_SPEC_FILE = "openapi/gateway.json";
|
|
8348
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
|
+
}
|
|
8349
8461
|
function buildSiteConfig(resolved, plan2, theme, extras = {}) {
|
|
8350
8462
|
const portal = resolved.portal;
|
|
8351
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
|
+
}));
|
|
8352
8473
|
const navigation = [
|
|
8353
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
|
+
})),
|
|
8354
8482
|
...plan2.apiReference ? [
|
|
8355
8483
|
{
|
|
8356
8484
|
type: "link",
|
|
@@ -8389,9 +8517,10 @@ function buildSiteConfig(resolved, plan2, theme, extras = {}) {
|
|
|
8389
8517
|
},
|
|
8390
8518
|
...plan2.docs ? {
|
|
8391
8519
|
docs: {
|
|
8392
|
-
files:
|
|
8393
|
-
|
|
8394
|
-
|
|
8520
|
+
files: [
|
|
8521
|
+
...portal?.docs.content ?? [],
|
|
8522
|
+
...headerPages.map(toGlobPath)
|
|
8523
|
+
].map((glob9) => contentGlob(resolved.configDir, glob9))
|
|
8395
8524
|
}
|
|
8396
8525
|
} : {},
|
|
8397
8526
|
...plan2.search ? { search: { type: plan2.search } } : {},
|
|
@@ -8406,12 +8535,13 @@ function buildSiteConfig(resolved, plan2, theme, extras = {}) {
|
|
|
8406
8535
|
} : {},
|
|
8407
8536
|
...navigation.length > 0 ? { navigation } : {},
|
|
8408
8537
|
// The sidebar link above is only seen inside the docs; the header is what every page shows. A header navigation
|
|
8409
|
-
// replaces the docs tab, so the docs get a header link of their own.
|
|
8410
|
-
...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 ? {
|
|
8411
8540
|
header: {
|
|
8412
8541
|
navigation: [
|
|
8413
8542
|
...plan2.docs && extras.docsPath ? [{ label: "Documentation", to: extras.docsPath }] : [],
|
|
8414
|
-
{ label: "API Reference", to: `/${API_REFERENCE_PATH}` }
|
|
8543
|
+
...plan2.apiReference ? [{ label: "API Reference", to: `/${API_REFERENCE_PATH}` }] : [],
|
|
8544
|
+
...shownHeaderLinks
|
|
8415
8545
|
]
|
|
8416
8546
|
}
|
|
8417
8547
|
} : {},
|
|
@@ -8617,10 +8747,14 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
|
|
|
8617
8747
|
const tsxPages = plan2.docs ? (await findTsxPages(profile.docs.content)).filter(
|
|
8618
8748
|
(page) => !markdownRoutes.includes(page.route)
|
|
8619
8749
|
) : [];
|
|
8750
|
+
const importPathOf = (file) => `./${CONTENT_LINK}/${path14.relative(resolved.configDir, file).split(path14.sep).join("/")}`;
|
|
8620
8751
|
const wrapperPages = tsxPages.map((page, index) => ({
|
|
8621
8752
|
id: `${TSX_PAGE_ELEMENT_PREFIX}${index}`,
|
|
8622
|
-
importPath:
|
|
8753
|
+
importPath: importPathOf(page.file)
|
|
8623
8754
|
}));
|
|
8755
|
+
const headerWrapperPages = headerTsxPages(resolved, plan2).map(
|
|
8756
|
+
(page) => ({ id: page.id, importPath: importPathOf(page.file) })
|
|
8757
|
+
);
|
|
8624
8758
|
const hostedDocRoutes = [
|
|
8625
8759
|
.../* @__PURE__ */ new Set([...markdownRoutes, ...tsxPages.map((page) => page.route)])
|
|
8626
8760
|
].sort();
|
|
@@ -8691,14 +8825,20 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
|
|
|
8691
8825
|
protectedRoutes: protectedRoutesFor({
|
|
8692
8826
|
requireAuth: resolved.portal?.requireAuth,
|
|
8693
8827
|
hasAuth: !!plan2.auth,
|
|
8694
|
-
|
|
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,
|
|
8695
8835
|
apiReferencePath: plan2.apiReference ? `/${API_REFERENCE_PATH}` : void 0
|
|
8696
8836
|
})
|
|
8697
8837
|
}
|
|
8698
8838
|
);
|
|
8699
8839
|
const wrapper = renderWrapper(
|
|
8700
8840
|
plan2,
|
|
8701
|
-
wrapperPages,
|
|
8841
|
+
[...wrapperPages, ...headerWrapperPages],
|
|
8702
8842
|
resolved.portal?.footer ? wrapperImport(contentFile(resolved.configDir, resolved.portal.footer)) : void 0
|
|
8703
8843
|
);
|
|
8704
8844
|
const wrapperPath = path14.join(resolved.state.generatedDir, WRAPPER_FILE);
|
|
@@ -10105,7 +10245,7 @@ init_invariant();
|
|
|
10105
10245
|
// src/cli/check/v2.ts
|
|
10106
10246
|
init_apitogo_config_core();
|
|
10107
10247
|
import { readFile as readFile18 } from "node:fs/promises";
|
|
10108
|
-
import
|
|
10248
|
+
import path52 from "node:path";
|
|
10109
10249
|
|
|
10110
10250
|
// src/cli/platform/client/platform-api.ts
|
|
10111
10251
|
import { basename } from "node:path";
|
|
@@ -10218,8 +10358,8 @@ var PlatformApiClient = class {
|
|
|
10218
10358
|
constructor(config2) {
|
|
10219
10359
|
this.config = config2;
|
|
10220
10360
|
}
|
|
10221
|
-
url(
|
|
10222
|
-
return `${this.config.apiUrl}${
|
|
10361
|
+
url(path100) {
|
|
10362
|
+
return `${this.config.apiUrl}${path100.startsWith("/") ? path100 : `/${path100}`}`;
|
|
10223
10363
|
}
|
|
10224
10364
|
headers(extra) {
|
|
10225
10365
|
return {
|
|
@@ -10229,9 +10369,9 @@ var PlatformApiClient = class {
|
|
|
10229
10369
|
...extra
|
|
10230
10370
|
};
|
|
10231
10371
|
}
|
|
10232
|
-
async request(method,
|
|
10372
|
+
async request(method, path100, init3) {
|
|
10233
10373
|
const response = await fetchWithRetry(
|
|
10234
|
-
this.url(
|
|
10374
|
+
this.url(path100),
|
|
10235
10375
|
{
|
|
10236
10376
|
method,
|
|
10237
10377
|
...init3,
|
|
@@ -10699,15 +10839,15 @@ var PlatformApiClient = class {
|
|
|
10699
10839
|
}
|
|
10700
10840
|
);
|
|
10701
10841
|
}
|
|
10702
|
-
deleteDevPortalPage(projectId,
|
|
10703
|
-
const query = new URLSearchParams({ path:
|
|
10842
|
+
deleteDevPortalPage(projectId, path100) {
|
|
10843
|
+
const query = new URLSearchParams({ path: path100 });
|
|
10704
10844
|
return this.request(
|
|
10705
10845
|
"DELETE",
|
|
10706
10846
|
`/api/v1/projects/${projectId}/dev-portal/pages/files?${query.toString()}`
|
|
10707
10847
|
);
|
|
10708
10848
|
}
|
|
10709
|
-
renameDevPortalPage(projectId,
|
|
10710
|
-
const query = new URLSearchParams({ path:
|
|
10849
|
+
renameDevPortalPage(projectId, path100, newName) {
|
|
10850
|
+
const query = new URLSearchParams({ path: path100 });
|
|
10711
10851
|
return this.request(
|
|
10712
10852
|
"POST",
|
|
10713
10853
|
`/api/v1/projects/${projectId}/dev-portal/pages/files/rename?${query.toString()}`,
|
|
@@ -10823,8 +10963,8 @@ var PlatformApiClient = class {
|
|
|
10823
10963
|
* the project-less endpoint is used; `planTier` overrides the tier used for paid-plan checks.
|
|
10824
10964
|
*/
|
|
10825
10965
|
validateGatewayPlans(plans, options = {}) {
|
|
10826
|
-
const
|
|
10827
|
-
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, {
|
|
10828
10968
|
headers: { "Content-Type": "application/json" },
|
|
10829
10969
|
body: JSON.stringify({ plans, planTier: options.planTier })
|
|
10830
10970
|
});
|
|
@@ -11052,11 +11192,11 @@ import {
|
|
|
11052
11192
|
rm as rm8,
|
|
11053
11193
|
writeFile as writeFile15
|
|
11054
11194
|
} from "node:fs/promises";
|
|
11055
|
-
import
|
|
11195
|
+
import path51 from "node:path";
|
|
11056
11196
|
|
|
11057
11197
|
// src/vite/build.ts
|
|
11058
11198
|
import { mkdir as mkdir11, readFile as readFile13, rename as rename5, rm as rm7, writeFile as writeFile13 } from "node:fs/promises";
|
|
11059
|
-
import
|
|
11199
|
+
import path49 from "node:path";
|
|
11060
11200
|
import { build as esbuild } from "esbuild";
|
|
11061
11201
|
import { build as viteBuild, mergeConfig as mergeConfig3 } from "vite";
|
|
11062
11202
|
|
|
@@ -11192,7 +11332,7 @@ init_invariant();
|
|
|
11192
11332
|
init_joinUrl();
|
|
11193
11333
|
|
|
11194
11334
|
// src/vite/config.ts
|
|
11195
|
-
import
|
|
11335
|
+
import path44 from "node:path";
|
|
11196
11336
|
import dotenv from "dotenv";
|
|
11197
11337
|
import colors8 from "picocolors";
|
|
11198
11338
|
import {
|
|
@@ -11203,7 +11343,7 @@ import {
|
|
|
11203
11343
|
// package.json
|
|
11204
11344
|
var package_default = {
|
|
11205
11345
|
name: "@lukoweb/apitogo",
|
|
11206
|
-
version: "0.2.
|
|
11346
|
+
version: "0.2.61",
|
|
11207
11347
|
type: "module",
|
|
11208
11348
|
sideEffects: [
|
|
11209
11349
|
"**/*.css",
|
|
@@ -11988,14 +12128,14 @@ var flattenAllOf = (schema2) => {
|
|
|
11988
12128
|
};
|
|
11989
12129
|
|
|
11990
12130
|
// src/lib/util/traverse.ts
|
|
11991
|
-
var traverse = (specification, transform,
|
|
11992
|
-
const transformed = transform(specification,
|
|
12131
|
+
var traverse = (specification, transform, path100 = []) => {
|
|
12132
|
+
const transformed = transform(specification, path100);
|
|
11993
12133
|
if (typeof transformed !== "object" || transformed === null) {
|
|
11994
12134
|
return transformed;
|
|
11995
12135
|
}
|
|
11996
12136
|
const result = Array.isArray(transformed) ? [] : {};
|
|
11997
12137
|
for (const [key, value] of Object.entries(transformed)) {
|
|
11998
|
-
const currentPath = [...
|
|
12138
|
+
const currentPath = [...path100, key];
|
|
11999
12139
|
if (Array.isArray(value)) {
|
|
12000
12140
|
result[key] = value.map(
|
|
12001
12141
|
(item, index) => typeof item === "object" && item != null ? traverse(item, transform, [...currentPath, index.toString()]) : item
|
|
@@ -12023,9 +12163,9 @@ var resolveLocalRef = (schema2, ref) => {
|
|
|
12023
12163
|
if (schemaCache?.has(ref)) {
|
|
12024
12164
|
return schemaCache.get(ref);
|
|
12025
12165
|
}
|
|
12026
|
-
const
|
|
12166
|
+
const path100 = ref.split("/").slice(1);
|
|
12027
12167
|
let current = schema2;
|
|
12028
|
-
for (const segment of
|
|
12168
|
+
for (const segment of path100) {
|
|
12029
12169
|
if (!current || typeof current !== "object") {
|
|
12030
12170
|
current = null;
|
|
12031
12171
|
}
|
|
@@ -12044,7 +12184,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
12044
12184
|
}
|
|
12045
12185
|
const cloned = structuredClone(schema2);
|
|
12046
12186
|
const visited = /* @__PURE__ */ new Set();
|
|
12047
|
-
const resolve = async (current,
|
|
12187
|
+
const resolve = async (current, path100) => {
|
|
12048
12188
|
if (isIndexableObject(current)) {
|
|
12049
12189
|
if (visited.has(current)) {
|
|
12050
12190
|
return CIRCULAR_REF;
|
|
@@ -12052,7 +12192,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
12052
12192
|
visited.add(current);
|
|
12053
12193
|
if (Array.isArray(current)) {
|
|
12054
12194
|
for (let index = 0; index < current.length; index++) {
|
|
12055
|
-
current[index] = await resolve(current[index], `${
|
|
12195
|
+
current[index] = await resolve(current[index], `${path100}/${index}`);
|
|
12056
12196
|
}
|
|
12057
12197
|
} else {
|
|
12058
12198
|
if ("$ref" in current && typeof current.$ref === "string") {
|
|
@@ -12063,13 +12203,13 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
12063
12203
|
for (const resolver of resolvers) {
|
|
12064
12204
|
const resolved = await resolver($ref);
|
|
12065
12205
|
if (resolved) {
|
|
12066
|
-
result2 = await resolve(resolved,
|
|
12206
|
+
result2 = await resolve(resolved, path100);
|
|
12067
12207
|
break;
|
|
12068
12208
|
}
|
|
12069
12209
|
}
|
|
12070
12210
|
if (result2 === void 0) {
|
|
12071
12211
|
const resolved = await resolveLocalRef(cloned, $ref);
|
|
12072
|
-
result2 = await resolve(resolved,
|
|
12212
|
+
result2 = await resolve(resolved, path100);
|
|
12073
12213
|
}
|
|
12074
12214
|
if (hasSiblings) {
|
|
12075
12215
|
if (result2 === CIRCULAR_REF) {
|
|
@@ -12082,7 +12222,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
12082
12222
|
return result2;
|
|
12083
12223
|
}
|
|
12084
12224
|
for (const key in current) {
|
|
12085
|
-
current[key] = await resolve(current[key], `${
|
|
12225
|
+
current[key] = await resolve(current[key], `${path100}/${key}`);
|
|
12086
12226
|
}
|
|
12087
12227
|
}
|
|
12088
12228
|
visited.delete(current);
|
|
@@ -12121,9 +12261,9 @@ var upgradeSchema = (schema2) => {
|
|
|
12121
12261
|
}
|
|
12122
12262
|
return sub;
|
|
12123
12263
|
});
|
|
12124
|
-
schema2 = traverse(schema2, (sub,
|
|
12264
|
+
schema2 = traverse(schema2, (sub, path100) => {
|
|
12125
12265
|
if (sub.example !== void 0) {
|
|
12126
|
-
if (isSchemaPath(
|
|
12266
|
+
if (isSchemaPath(path100 ?? [])) {
|
|
12127
12267
|
sub.examples = [sub.example];
|
|
12128
12268
|
} else {
|
|
12129
12269
|
sub.examples = {
|
|
@@ -12136,11 +12276,11 @@ var upgradeSchema = (schema2) => {
|
|
|
12136
12276
|
}
|
|
12137
12277
|
return sub;
|
|
12138
12278
|
});
|
|
12139
|
-
schema2 = traverse(schema2, (schema3,
|
|
12279
|
+
schema2 = traverse(schema2, (schema3, path100) => {
|
|
12140
12280
|
if (schema3.type === "object" && schema3.properties !== void 0) {
|
|
12141
|
-
const parentPath =
|
|
12281
|
+
const parentPath = path100?.slice(0, -1);
|
|
12142
12282
|
const isMultipart = parentPath?.some((segment, index) => {
|
|
12143
|
-
return segment === "content" &&
|
|
12283
|
+
return segment === "content" && path100?.[index + 1] === "multipart/form-data";
|
|
12144
12284
|
});
|
|
12145
12285
|
if (isMultipart) {
|
|
12146
12286
|
const entries = Object.entries(schema3.properties);
|
|
@@ -12154,8 +12294,8 @@ var upgradeSchema = (schema2) => {
|
|
|
12154
12294
|
}
|
|
12155
12295
|
return schema3;
|
|
12156
12296
|
});
|
|
12157
|
-
schema2 = traverse(schema2, (schema3,
|
|
12158
|
-
if (
|
|
12297
|
+
schema2 = traverse(schema2, (schema3, path100) => {
|
|
12298
|
+
if (path100?.includes("content") && path100.includes("application/octet-stream")) {
|
|
12159
12299
|
return {};
|
|
12160
12300
|
}
|
|
12161
12301
|
if (schema3.type === "string" && schema3.format === "binary") {
|
|
@@ -12181,11 +12321,11 @@ var upgradeSchema = (schema2) => {
|
|
|
12181
12321
|
}
|
|
12182
12322
|
return sub;
|
|
12183
12323
|
});
|
|
12184
|
-
schema2 = traverse(schema2, (schema3,
|
|
12324
|
+
schema2 = traverse(schema2, (schema3, path100) => {
|
|
12185
12325
|
if (schema3.type === "string" && schema3.format === "byte") {
|
|
12186
|
-
const parentPath =
|
|
12326
|
+
const parentPath = path100?.slice(0, -1);
|
|
12187
12327
|
const contentMediaType = parentPath?.find(
|
|
12188
|
-
(_, index) =>
|
|
12328
|
+
(_, index) => path100?.[index - 1] === "content"
|
|
12189
12329
|
);
|
|
12190
12330
|
return {
|
|
12191
12331
|
type: "string",
|
|
@@ -12197,7 +12337,7 @@ var upgradeSchema = (schema2) => {
|
|
|
12197
12337
|
});
|
|
12198
12338
|
return schema2;
|
|
12199
12339
|
};
|
|
12200
|
-
function isSchemaPath(
|
|
12340
|
+
function isSchemaPath(path100) {
|
|
12201
12341
|
const schemaLocations = [
|
|
12202
12342
|
["components", "schemas"],
|
|
12203
12343
|
"properties",
|
|
@@ -12210,10 +12350,10 @@ function isSchemaPath(path99) {
|
|
|
12210
12350
|
];
|
|
12211
12351
|
return schemaLocations.some((location) => {
|
|
12212
12352
|
if (Array.isArray(location)) {
|
|
12213
|
-
return location.every((segment, index) =>
|
|
12353
|
+
return location.every((segment, index) => path100[index] === segment);
|
|
12214
12354
|
}
|
|
12215
|
-
return
|
|
12216
|
-
}) ||
|
|
12355
|
+
return path100.includes(location);
|
|
12356
|
+
}) || path100.includes("schema") || path100.some((segment) => segment.endsWith("Schema"));
|
|
12217
12357
|
}
|
|
12218
12358
|
|
|
12219
12359
|
// src/lib/oas/parser/index.ts
|
|
@@ -12295,13 +12435,13 @@ var OPENAPI_PROPS = /* @__PURE__ */ new Set([
|
|
|
12295
12435
|
"anyOf",
|
|
12296
12436
|
"oneOf"
|
|
12297
12437
|
]);
|
|
12298
|
-
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()) => {
|
|
12299
12439
|
if (obj === null || typeof obj !== "object") return obj;
|
|
12300
12440
|
const refPath = obj.__$ref;
|
|
12301
12441
|
const isCircular = currentPath.has(obj) || typeof refPath === "string" && currentRefPaths.has(refPath);
|
|
12302
12442
|
if (isCircular) {
|
|
12303
12443
|
if (typeof refPath === "string") return SCHEMA_REF_PREFIX + refPath;
|
|
12304
|
-
const circularProp =
|
|
12444
|
+
const circularProp = path100.find((p) => !OPENAPI_PROPS.has(p)) || path100[0];
|
|
12305
12445
|
return [CIRCULAR_REF, circularProp].filter(Boolean).join(":");
|
|
12306
12446
|
}
|
|
12307
12447
|
if (refs.has(obj)) return refs.get(obj);
|
|
@@ -12311,7 +12451,7 @@ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs
|
|
|
12311
12451
|
value,
|
|
12312
12452
|
currentPath,
|
|
12313
12453
|
refs,
|
|
12314
|
-
[...
|
|
12454
|
+
[...path100, key],
|
|
12315
12455
|
currentRefPaths
|
|
12316
12456
|
);
|
|
12317
12457
|
const result = Array.isArray(obj) ? obj.map((item, i) => recurse(item, i.toString())) : Object.fromEntries(
|
|
@@ -12346,7 +12486,7 @@ var resolveExtensions = (obj) => Object.fromEntries(
|
|
|
12346
12486
|
var getAllTags = (schema2) => {
|
|
12347
12487
|
const rootTags = schema2.tags ?? [];
|
|
12348
12488
|
const operations = Object.values(schema2.paths ?? {}).flatMap(
|
|
12349
|
-
(
|
|
12489
|
+
(path100) => HttpMethods.map((k) => path100?.[k]).filter((op) => op != null)
|
|
12350
12490
|
);
|
|
12351
12491
|
const operationTags = new Set(operations.flatMap((op) => op.tags ?? []));
|
|
12352
12492
|
const hasUntaggedOperations = operations.some(
|
|
@@ -12401,7 +12541,7 @@ var getAllSlugs = (ops, schemaTags = []) => {
|
|
|
12401
12541
|
var getOperationSlugKey = (op) => [op.path, op.method, op.operationId, op.summary].filter(Boolean).join("-");
|
|
12402
12542
|
var getAllOperations = (paths) => {
|
|
12403
12543
|
const operations = Object.entries(paths ?? {}).flatMap(
|
|
12404
|
-
([
|
|
12544
|
+
([path100, value]) => HttpMethods.flatMap((method) => {
|
|
12405
12545
|
if (!value?.[method]) return [];
|
|
12406
12546
|
const operation = value[method];
|
|
12407
12547
|
const pathParameters = value.parameters ?? [];
|
|
@@ -12421,7 +12561,7 @@ var getAllOperations = (paths) => {
|
|
|
12421
12561
|
return {
|
|
12422
12562
|
...operation,
|
|
12423
12563
|
method,
|
|
12424
|
-
path:
|
|
12564
|
+
path: path100,
|
|
12425
12565
|
parameters,
|
|
12426
12566
|
servers,
|
|
12427
12567
|
tags: operation.tags ?? []
|
|
@@ -12779,8 +12919,8 @@ var Schema = builder.objectRef("Schema").implement({
|
|
|
12779
12919
|
}),
|
|
12780
12920
|
paths: t.field({
|
|
12781
12921
|
type: [PathItem],
|
|
12782
|
-
resolve: (root) => Object.entries(root.paths ?? {}).map(([
|
|
12783
|
-
path:
|
|
12922
|
+
resolve: (root) => Object.entries(root.paths ?? {}).map(([path100, value]) => ({
|
|
12923
|
+
path: path100,
|
|
12784
12924
|
// biome-ignore lint/style/noNonNullAssertion: value is guaranteed to be defined
|
|
12785
12925
|
methods: Object.keys(value)
|
|
12786
12926
|
}))
|
|
@@ -12945,7 +13085,7 @@ init_joinUrl();
|
|
|
12945
13085
|
|
|
12946
13086
|
// src/vite/api/schema-codegen.ts
|
|
12947
13087
|
var unescapeJsonPointer = (uri) => decodeURIComponent(uri.replace(/~1/g, "/").replace(/~0/g, "~"));
|
|
12948
|
-
var getSegmentsFromPath = (
|
|
13088
|
+
var getSegmentsFromPath = (path100) => path100.split("/").slice(1).map(unescapeJsonPointer);
|
|
12949
13089
|
var createLocalRefMap = (obj) => {
|
|
12950
13090
|
const refMap = /* @__PURE__ */ new Map();
|
|
12951
13091
|
const siblingsMap = /* @__PURE__ */ new Map();
|
|
@@ -12976,16 +13116,16 @@ var replaceMarkers = (code, mergedRefs) => code.replace(/"__refMap:(.*?)"/g, '__
|
|
|
12976
13116
|
/"__refMap\+Siblings:(.*?)"/g,
|
|
12977
13117
|
(_, key) => mergedRefs.get(key) ?? `__refMap["${key}"]`
|
|
12978
13118
|
);
|
|
12979
|
-
var lookup = (schema2,
|
|
12980
|
-
const parts = getSegmentsFromPath(
|
|
13119
|
+
var lookup = (schema2, path100, filePath) => {
|
|
13120
|
+
const parts = getSegmentsFromPath(path100);
|
|
12981
13121
|
let val = schema2;
|
|
12982
13122
|
for (const part of parts) {
|
|
12983
13123
|
while (val.$ref?.startsWith("#/")) {
|
|
12984
|
-
val = val.$ref ===
|
|
13124
|
+
val = val.$ref === path100 ? val : lookup(schema2, val.$ref, filePath);
|
|
12985
13125
|
}
|
|
12986
13126
|
if (val[part] === void 0) {
|
|
12987
13127
|
throw new Error(
|
|
12988
|
-
`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}`
|
|
12989
13129
|
);
|
|
12990
13130
|
}
|
|
12991
13131
|
val = val[part];
|
|
@@ -13232,8 +13372,8 @@ var SchemaManager = class {
|
|
|
13232
13372
|
}
|
|
13233
13373
|
}
|
|
13234
13374
|
};
|
|
13235
|
-
getLatestSchema = (
|
|
13236
|
-
getSchemasForPath = (
|
|
13375
|
+
getLatestSchema = (path100) => this.processedSchemas[path100]?.at(0);
|
|
13376
|
+
getSchemasForPath = (path100) => this.processedSchemas[path100];
|
|
13237
13377
|
getSchemaImports = () => Object.values(this.processedSchemas).flat().filter((s) => s.importKey);
|
|
13238
13378
|
getUrlToFilePathMap = () => {
|
|
13239
13379
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -14357,8 +14497,32 @@ init_loader();
|
|
|
14357
14497
|
init_ProtectedRoutesSchema();
|
|
14358
14498
|
init_joinUrl();
|
|
14359
14499
|
import { mkdir as mkdir8, writeFile as writeFile10 } from "node:fs/promises";
|
|
14360
|
-
import
|
|
14500
|
+
import path37 from "node:path";
|
|
14361
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
|
|
14362
14526
|
var processMarkdownFile = async (filePath) => {
|
|
14363
14527
|
const { content: markdownContent, data: frontmatter } = await readFrontmatter(filePath);
|
|
14364
14528
|
let finalMarkdown = markdownContent;
|
|
@@ -14445,7 +14609,7 @@ var viteMarkdownExportPlugin = () => {
|
|
|
14445
14609
|
if (process.env.NODE_ENV !== "production" || Object.keys(markdownFiles).length === 0 || !needsMdFiles) {
|
|
14446
14610
|
return;
|
|
14447
14611
|
}
|
|
14448
|
-
const distDir =
|
|
14612
|
+
const distDir = path37.join(
|
|
14449
14613
|
config2.__meta.rootDir,
|
|
14450
14614
|
"dist",
|
|
14451
14615
|
config2.basePath ?? ""
|
|
@@ -14465,16 +14629,15 @@ var viteMarkdownExportPlugin = () => {
|
|
|
14465
14629
|
description,
|
|
14466
14630
|
content: finalMarkdown
|
|
14467
14631
|
});
|
|
14468
|
-
const
|
|
14469
|
-
|
|
14470
|
-
await mkdir8(path36.dirname(outputPath), { recursive: true });
|
|
14632
|
+
const outputPath = markdownOutputPath(distDir, routePath);
|
|
14633
|
+
await mkdir8(path37.dirname(outputPath), { recursive: true });
|
|
14471
14634
|
await writeFile10(outputPath, finalMarkdown, "utf-8");
|
|
14472
14635
|
} catch (error) {
|
|
14473
14636
|
console.warn(`Failed to export markdown for ${routePath}:`, error);
|
|
14474
14637
|
}
|
|
14475
14638
|
}
|
|
14476
14639
|
if (config2.docs?.llms?.llmsTxt || config2.docs?.llms?.llmsTxtFull) {
|
|
14477
|
-
const markdownInfoPath =
|
|
14640
|
+
const markdownInfoPath = path37.join(
|
|
14478
14641
|
config2.__meta.rootDir,
|
|
14479
14642
|
"node_modules/.apitogo/markdown-info.json"
|
|
14480
14643
|
);
|
|
@@ -14626,9 +14789,9 @@ var remarkCodeTabs = () => (tree) => {
|
|
|
14626
14789
|
};
|
|
14627
14790
|
|
|
14628
14791
|
// src/vite/mdx/remark-inject-filepath.ts
|
|
14629
|
-
import
|
|
14792
|
+
import path38 from "node:path";
|
|
14630
14793
|
var remarkInjectFilepath = (rootDir) => (tree, vfile) => {
|
|
14631
|
-
const relativePath =
|
|
14794
|
+
const relativePath = path38.relative(rootDir, vfile.path).split(path38.sep).join(path38.posix.sep);
|
|
14632
14795
|
tree.children.unshift(exportMdxjsConst("__filepath", relativePath));
|
|
14633
14796
|
};
|
|
14634
14797
|
|
|
@@ -14715,18 +14878,18 @@ var remarkLastModified = () => {
|
|
|
14715
14878
|
};
|
|
14716
14879
|
|
|
14717
14880
|
// src/vite/mdx/remark-link-rewrite.ts
|
|
14718
|
-
import
|
|
14881
|
+
import path39 from "node:path";
|
|
14719
14882
|
import { visit as visit5 } from "unist-util-visit";
|
|
14720
14883
|
var remarkLinkRewrite = (basePath = "") => (tree) => {
|
|
14721
14884
|
visit5(tree, "link", (node) => {
|
|
14722
14885
|
if (!node.url) return;
|
|
14723
14886
|
if (node.url.startsWith("http") || node.url.startsWith("mailto:")) return;
|
|
14724
14887
|
node.url = node.url.replace(/\\/g, "/");
|
|
14725
|
-
const base =
|
|
14888
|
+
const base = path39.posix.join(basePath);
|
|
14726
14889
|
if (basePath && node.url.startsWith(base)) {
|
|
14727
14890
|
node.url = node.url.slice(base.length);
|
|
14728
14891
|
} else if (!node.url.startsWith("/") && !node.url.startsWith("#")) {
|
|
14729
|
-
node.url =
|
|
14892
|
+
node.url = path39.posix.join("..", node.url);
|
|
14730
14893
|
}
|
|
14731
14894
|
node.url = node.url.replace(/\.mdx?(#.*)?$/, "$1");
|
|
14732
14895
|
});
|
|
@@ -14946,14 +15109,14 @@ var plugin_mdx_default = viteMdxPlugin;
|
|
|
14946
15109
|
|
|
14947
15110
|
// src/vite/plugin-modules.ts
|
|
14948
15111
|
init_loader();
|
|
14949
|
-
import
|
|
15112
|
+
import path40 from "node:path";
|
|
14950
15113
|
import { normalizePath as normalizePath2 } from "vite";
|
|
14951
|
-
var getLandingModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(
|
|
14952
|
-
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";
|
|
14953
15116
|
var getBillingPluginImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(
|
|
14954
|
-
|
|
15117
|
+
path40.join(moduleDir, "../plugin-dev-portal-billing/src/index.ts")
|
|
14955
15118
|
) : "@lukoweb/apitogo-plugin-dev-portal-billing";
|
|
14956
|
-
var resolveProjectPageImport = (rootDir, pagePath) => normalizePath2(
|
|
15119
|
+
var resolveProjectPageImport = (rootDir, pagePath) => normalizePath2(path40.resolve(rootDir, pagePath));
|
|
14957
15120
|
var viteModulesPlugin = () => {
|
|
14958
15121
|
const virtualModuleId4 = "virtual:zudoku-modules-plugin";
|
|
14959
15122
|
const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
|
|
@@ -15095,17 +15258,17 @@ var plugin_modules_default = viteModulesPlugin;
|
|
|
15095
15258
|
|
|
15096
15259
|
// src/vite/plugin-offroot-resolve.ts
|
|
15097
15260
|
init_loader();
|
|
15098
|
-
import
|
|
15261
|
+
import path41 from "node:path";
|
|
15099
15262
|
function stripQuery(id) {
|
|
15100
15263
|
const query = id.indexOf("?");
|
|
15101
15264
|
return query === -1 ? id : id.slice(0, query);
|
|
15102
15265
|
}
|
|
15103
15266
|
function isInside(parent, child) {
|
|
15104
|
-
const relative =
|
|
15105
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
15267
|
+
const relative = path41.relative(path41.resolve(parent), path41.resolve(child));
|
|
15268
|
+
return relative === "" || !relative.startsWith("..") && !path41.isAbsolute(relative);
|
|
15106
15269
|
}
|
|
15107
15270
|
function isBareSpecifier(source) {
|
|
15108
|
-
return !source.startsWith("\0") && !source.startsWith(".") && !source.startsWith("/") && !
|
|
15271
|
+
return !source.startsWith("\0") && !source.startsWith(".") && !source.startsWith("/") && !path41.isAbsolute(source);
|
|
15109
15272
|
}
|
|
15110
15273
|
function isInsideNodeModules(filePath) {
|
|
15111
15274
|
return filePath.split(/[\\/]/).includes("node_modules");
|
|
@@ -15129,7 +15292,7 @@ function viteOffrootResolvePlugin() {
|
|
|
15129
15292
|
if (!shouldResolveFromSiteRoot(source, importer, rootDir)) {
|
|
15130
15293
|
return;
|
|
15131
15294
|
}
|
|
15132
|
-
return this.resolve(source,
|
|
15295
|
+
return this.resolve(source, path41.join(rootDir, "package.json"), {
|
|
15133
15296
|
...options,
|
|
15134
15297
|
skipSelf: true
|
|
15135
15298
|
});
|
|
@@ -15139,7 +15302,7 @@ function viteOffrootResolvePlugin() {
|
|
|
15139
15302
|
|
|
15140
15303
|
// src/vite/plugin-search.ts
|
|
15141
15304
|
init_loader();
|
|
15142
|
-
import
|
|
15305
|
+
import path42 from "node:path";
|
|
15143
15306
|
var viteSearchPlugin = () => {
|
|
15144
15307
|
const virtualModuleId4 = "virtual:zudoku-search-plugin";
|
|
15145
15308
|
const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
|
|
@@ -15157,7 +15320,7 @@ var viteSearchPlugin = () => {
|
|
|
15157
15320
|
return resolvedVirtualModuleId5;
|
|
15158
15321
|
}
|
|
15159
15322
|
if (id === "/pagefind/pagefind.js" && resolvedViteConfig?.publicDir) {
|
|
15160
|
-
return
|
|
15323
|
+
return path42.join(resolvedViteConfig.publicDir, "pagefind/pagefind.js");
|
|
15161
15324
|
}
|
|
15162
15325
|
},
|
|
15163
15326
|
async load(id) {
|
|
@@ -15298,27 +15461,27 @@ function vitePlugin() {
|
|
|
15298
15461
|
|
|
15299
15462
|
// src/vite/watch-ignore.ts
|
|
15300
15463
|
import { lstatSync, realpathSync } from "node:fs";
|
|
15301
|
-
import
|
|
15464
|
+
import path43 from "node:path";
|
|
15302
15465
|
var STATE_INSIDE_CONTENT = /[\\/]content[\\/](?:\.apitogo|apitogo[\\/]\.state)(?:[\\/]|$)/;
|
|
15303
15466
|
var within = (base, file) => {
|
|
15304
|
-
const resolvedBase =
|
|
15305
|
-
const resolvedFile =
|
|
15306
|
-
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);
|
|
15307
15470
|
};
|
|
15308
15471
|
var unique = (paths) => [...new Set(paths)];
|
|
15309
15472
|
function isWorkspace(root) {
|
|
15310
15473
|
try {
|
|
15311
|
-
return
|
|
15474
|
+
return path43.basename(root) === "generated" && lstatSync(path43.join(root, "content")).isSymbolicLink();
|
|
15312
15475
|
} catch {
|
|
15313
15476
|
return false;
|
|
15314
15477
|
}
|
|
15315
15478
|
}
|
|
15316
15479
|
function tenantDir(root) {
|
|
15317
|
-
return isWorkspace(root) ? realpathSync(
|
|
15480
|
+
return isWorkspace(root) ? realpathSync(path43.join(root, "content")) : void 0;
|
|
15318
15481
|
}
|
|
15319
15482
|
function stateIgnore(root) {
|
|
15320
15483
|
if (!isWorkspace(root)) return void 0;
|
|
15321
|
-
const state =
|
|
15484
|
+
const state = path43.dirname(root);
|
|
15322
15485
|
const states = unique([state, realpathSync(state)]);
|
|
15323
15486
|
const roots = unique([root, realpathSync(root)]);
|
|
15324
15487
|
return (file) => {
|
|
@@ -15327,19 +15490,28 @@ function stateIgnore(root) {
|
|
|
15327
15490
|
return STATE_INSIDE_CONTENT.test(file);
|
|
15328
15491
|
};
|
|
15329
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
|
+
}
|
|
15330
15502
|
function devServerAllow(root, moduleDir) {
|
|
15331
15503
|
const tenant = tenantDir(root);
|
|
15332
|
-
return [root,
|
|
15504
|
+
return [root, path43.dirname(root), moduleDir, ...tenant ? [tenant] : []];
|
|
15333
15505
|
}
|
|
15334
15506
|
|
|
15335
15507
|
// src/vite/config.ts
|
|
15336
15508
|
var resolveMergedPublicDir = (rootDir, merged) => {
|
|
15337
15509
|
if (merged.publicDir === false) return void 0;
|
|
15338
15510
|
const rel2 = typeof merged.publicDir === "string" ? merged.publicDir : "public";
|
|
15339
|
-
return
|
|
15511
|
+
return path44.resolve(rootDir, rel2);
|
|
15340
15512
|
};
|
|
15341
|
-
var getAppClientEntryPath = () =>
|
|
15342
|
-
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");
|
|
15343
15515
|
var hasLoggedCdnInfo = false;
|
|
15344
15516
|
var MEDIA_REGEX = /\.(a?png|jpe?g|gif|bmp|svg|webp|tiff|ico|webm|ogg|mp3|wav|m4a|avif|mp4)/i;
|
|
15345
15517
|
var defineEnvVars = (vars) => Object.fromEntries(
|
|
@@ -15370,7 +15542,7 @@ async function getViteConfig(dir, configEnv) {
|
|
|
15370
15542
|
const ignoreState = stateIgnore(dir);
|
|
15371
15543
|
if (ZuploEnv.isZuplo) {
|
|
15372
15544
|
dotenv.config({
|
|
15373
|
-
path:
|
|
15545
|
+
path: path44.resolve(config2.__meta.rootDir, "../.env.zuplo"),
|
|
15374
15546
|
quiet: true
|
|
15375
15547
|
});
|
|
15376
15548
|
}
|
|
@@ -15425,6 +15597,7 @@ async function getViteConfig(dir, configEnv) {
|
|
|
15425
15597
|
`${dir}/.git`,
|
|
15426
15598
|
`${config2.__meta.moduleDir}/src/vite`,
|
|
15427
15599
|
`${config2.__meta.moduleDir}/src/cli`,
|
|
15600
|
+
nestedStateIgnore(dir),
|
|
15428
15601
|
...ignoreState ? [ignoreState] : []
|
|
15429
15602
|
]
|
|
15430
15603
|
}
|
|
@@ -15433,8 +15606,8 @@ async function getViteConfig(dir, configEnv) {
|
|
|
15433
15606
|
ssr: configEnv.isSsrBuild,
|
|
15434
15607
|
sourcemap: true,
|
|
15435
15608
|
target: "es2022",
|
|
15436
|
-
outDir:
|
|
15437
|
-
|
|
15609
|
+
outDir: path44.resolve(
|
|
15610
|
+
path44.join(
|
|
15438
15611
|
dir,
|
|
15439
15612
|
"dist",
|
|
15440
15613
|
config2.basePath ?? "",
|
|
@@ -15453,7 +15626,7 @@ async function getViteConfig(dir, configEnv) {
|
|
|
15453
15626
|
},
|
|
15454
15627
|
experimental: {
|
|
15455
15628
|
renderBuiltUrl(filename) {
|
|
15456
|
-
if (cdnUrl?.base && [".js", ".css"].includes(
|
|
15629
|
+
if (cdnUrl?.base && [".js", ".css"].includes(path44.extname(filename))) {
|
|
15457
15630
|
return joinUrl(cdnUrl.base, filename);
|
|
15458
15631
|
}
|
|
15459
15632
|
if (cdnUrl?.media && MEDIA_REGEX.test(filename)) {
|
|
@@ -15466,7 +15639,7 @@ async function getViteConfig(dir, configEnv) {
|
|
|
15466
15639
|
esbuildOptions: {
|
|
15467
15640
|
target: "es2022"
|
|
15468
15641
|
},
|
|
15469
|
-
entries: [
|
|
15642
|
+
entries: [path44.posix.join(getZudokuRootDir(), "src/{app,lib}/**")],
|
|
15470
15643
|
exclude: [
|
|
15471
15644
|
"@lukoweb/apitogo",
|
|
15472
15645
|
"@lukoweb/apitogo-plugin-dev-portal-billing"
|
|
@@ -15570,7 +15743,7 @@ init_package_json();
|
|
|
15570
15743
|
init_joinUrl();
|
|
15571
15744
|
import assert from "node:assert";
|
|
15572
15745
|
import { cp, mkdir as mkdir9, writeFile as writeFile11 } from "node:fs/promises";
|
|
15573
|
-
import
|
|
15746
|
+
import path45 from "node:path";
|
|
15574
15747
|
var pkgJson = getZudokuPackageJson();
|
|
15575
15748
|
function generateOutput({
|
|
15576
15749
|
config: config2,
|
|
@@ -15627,9 +15800,9 @@ async function writeOutput(dir, {
|
|
|
15627
15800
|
rewrites
|
|
15628
15801
|
}) {
|
|
15629
15802
|
const output4 = generateOutput({ config: config2, redirects, rewrites });
|
|
15630
|
-
const outputDir = process.env.VERCEL ?
|
|
15803
|
+
const outputDir = process.env.VERCEL ? path45.join(dir, ".vercel/output") : path45.join(dir, "dist/.output");
|
|
15631
15804
|
await mkdir9(outputDir, { recursive: true });
|
|
15632
|
-
const outputFile =
|
|
15805
|
+
const outputFile = path45.join(outputDir, "config.json");
|
|
15633
15806
|
await writeFile11(outputFile, JSON.stringify(output4, null, 2), "utf-8");
|
|
15634
15807
|
if (process.env.VERCEL) {
|
|
15635
15808
|
console.log("Wrote Vercel output to", outputDir);
|
|
@@ -15639,9 +15812,9 @@ async function writeOutput(dir, {
|
|
|
15639
15812
|
// src/vite/prerender/prerender.ts
|
|
15640
15813
|
init_logger();
|
|
15641
15814
|
init_file_exists();
|
|
15642
|
-
import { readFile as readFile12
|
|
15815
|
+
import { readFile as readFile12 } from "node:fs/promises";
|
|
15643
15816
|
import os from "node:os";
|
|
15644
|
-
import
|
|
15817
|
+
import path48 from "node:path";
|
|
15645
15818
|
import { pathToFileURL } from "node:url";
|
|
15646
15819
|
import { createIndex } from "pagefind";
|
|
15647
15820
|
import colors11 from "picocolors";
|
|
@@ -15683,7 +15856,7 @@ function throttle(fn) {
|
|
|
15683
15856
|
init_joinUrl();
|
|
15684
15857
|
import { createWriteStream, existsSync as existsSync5 } from "node:fs";
|
|
15685
15858
|
import { mkdir as mkdir10 } from "node:fs/promises";
|
|
15686
|
-
import
|
|
15859
|
+
import path46 from "node:path";
|
|
15687
15860
|
import colors9 from "picocolors";
|
|
15688
15861
|
import { SitemapStream } from "sitemap";
|
|
15689
15862
|
async function generateSitemap({
|
|
@@ -15697,11 +15870,11 @@ async function generateSitemap({
|
|
|
15697
15870
|
return;
|
|
15698
15871
|
}
|
|
15699
15872
|
const sitemap = new SitemapStream({ hostname: config2.siteUrl });
|
|
15700
|
-
const outputDir =
|
|
15873
|
+
const outputDir = path46.resolve(baseOutputDir, config2.outDir ?? "");
|
|
15701
15874
|
if (!existsSync5(outputDir)) {
|
|
15702
15875
|
await mkdir10(outputDir, { recursive: true });
|
|
15703
15876
|
}
|
|
15704
|
-
const sitemapOutputPath =
|
|
15877
|
+
const sitemapOutputPath = path46.join(outputDir, "sitemap.xml");
|
|
15705
15878
|
const writeStream = createWriteStream(sitemapOutputPath);
|
|
15706
15879
|
sitemap.pipe(writeStream);
|
|
15707
15880
|
let lastmod;
|
|
@@ -15731,14 +15904,14 @@ async function generateSitemap({
|
|
|
15731
15904
|
|
|
15732
15905
|
// src/vite/prerender/utils.ts
|
|
15733
15906
|
init_joinUrl();
|
|
15734
|
-
var resolveRoutePath = (
|
|
15735
|
-
const segments =
|
|
15907
|
+
var resolveRoutePath = (path100) => {
|
|
15908
|
+
const segments = path100.split("/");
|
|
15736
15909
|
if (segments.some((s) => s.startsWith(":") && !s.endsWith("?"))) {
|
|
15737
15910
|
return void 0;
|
|
15738
15911
|
}
|
|
15739
15912
|
return segments.filter((s) => !s.startsWith(":")).join("/") || void 0;
|
|
15740
15913
|
};
|
|
15741
|
-
var isSkipped = (
|
|
15914
|
+
var isSkipped = (path100) => path100.includes("*") || /^\d+$/.test(path100);
|
|
15742
15915
|
var resolveRoutes = (routes, parentPath = "") => routes.flatMap((route) => {
|
|
15743
15916
|
if (route.path && isSkipped(route.path)) return [];
|
|
15744
15917
|
const routePath = route.path ? resolveRoutePath(route.path) : void 0;
|
|
@@ -15788,12 +15961,12 @@ var prerender = async ({
|
|
|
15788
15961
|
serverConfigFilename,
|
|
15789
15962
|
writeRedirects = true
|
|
15790
15963
|
}) => {
|
|
15791
|
-
const distDir =
|
|
15964
|
+
const distDir = path48.join(dir, "dist", basePath);
|
|
15792
15965
|
const serverConfigPath = pathToFileURL(
|
|
15793
|
-
|
|
15966
|
+
path48.join(distDir, "server", serverConfigFilename)
|
|
15794
15967
|
).href;
|
|
15795
15968
|
const entryServerPath = pathToFileURL(
|
|
15796
|
-
|
|
15969
|
+
path48.join(distDir, "server/entry.server.js")
|
|
15797
15970
|
).href;
|
|
15798
15971
|
const rawConfig = await import(serverConfigPath).then(
|
|
15799
15972
|
(m) => m.default
|
|
@@ -15878,7 +16051,7 @@ var prerender = async ({
|
|
|
15878
16051
|
})
|
|
15879
16052
|
);
|
|
15880
16053
|
const pagefindWriteResult = await pagefindIndex?.writeFiles({
|
|
15881
|
-
outputPath:
|
|
16054
|
+
outputPath: path48.join(distDir, "pagefind")
|
|
15882
16055
|
});
|
|
15883
16056
|
const seconds = ((performance.now() - start) / 1e3).toFixed(1);
|
|
15884
16057
|
const message = `\u2713 finished prerendering ${paths.length} routes in ${seconds} seconds using ${maxThreads} workers`;
|
|
@@ -15910,7 +16083,7 @@ var prerender = async ({
|
|
|
15910
16083
|
const { generateLlmsTxtFiles: generateLlmsTxtFiles2 } = await Promise.resolve().then(() => (init_llms(), llms_exports));
|
|
15911
16084
|
const docsConfig = DocsConfigSchema2.parse(config2.docs);
|
|
15912
16085
|
const llmsConfig = docsConfig.llms ?? {};
|
|
15913
|
-
const markdownInfoPath =
|
|
16086
|
+
const markdownInfoPath = path48.join(
|
|
15914
16087
|
dir,
|
|
15915
16088
|
"node_modules/.apitogo/markdown-info.json"
|
|
15916
16089
|
);
|
|
@@ -15932,10 +16105,7 @@ var prerender = async ({
|
|
|
15932
16105
|
});
|
|
15933
16106
|
}
|
|
15934
16107
|
if (!docsConfig.publishMarkdown) {
|
|
15935
|
-
await
|
|
15936
|
-
markdownFileInfos.map((info) => rm6(info.filePath).catch(() => {
|
|
15937
|
-
}))
|
|
15938
|
-
);
|
|
16108
|
+
await removeExportedMarkdown(distDir, markdownFileInfos);
|
|
15939
16109
|
}
|
|
15940
16110
|
}
|
|
15941
16111
|
return { workerResults, rewrites };
|
|
@@ -16001,7 +16171,7 @@ async function runBuild(options) {
|
|
|
16001
16171
|
html,
|
|
16002
16172
|
basePath: config2.basePath
|
|
16003
16173
|
});
|
|
16004
|
-
await rm7(
|
|
16174
|
+
await rm7(path49.join(clientOutDir, "index.html"), { force: true });
|
|
16005
16175
|
} else {
|
|
16006
16176
|
await runPrerender({
|
|
16007
16177
|
dir,
|
|
@@ -16025,7 +16195,7 @@ var runPrerender = async (options) => {
|
|
|
16025
16195
|
serverConfigFilename,
|
|
16026
16196
|
writeRedirects: process.env.VERCEL === void 0
|
|
16027
16197
|
});
|
|
16028
|
-
const indexHtml =
|
|
16198
|
+
const indexHtml = path49.join(clientOutDir, "index.html");
|
|
16029
16199
|
if (!workerResults.find((r) => r.outputPath === indexHtml)) {
|
|
16030
16200
|
await writeFile13(indexHtml, html, "utf-8");
|
|
16031
16201
|
}
|
|
@@ -16035,15 +16205,15 @@ var runPrerender = async (options) => {
|
|
|
16035
16205
|
for (const statusPage of statusPages) {
|
|
16036
16206
|
await rename5(
|
|
16037
16207
|
statusPage,
|
|
16038
|
-
|
|
16208
|
+
path49.join(dir, DIST_DIR, path49.basename(statusPage))
|
|
16039
16209
|
);
|
|
16040
16210
|
}
|
|
16041
16211
|
await rm7(serverOutDir, { recursive: true, force: true });
|
|
16042
16212
|
if (process.env.VERCEL) {
|
|
16043
|
-
await mkdir11(
|
|
16213
|
+
await mkdir11(path49.join(dir, ".vercel/output/static"), { recursive: true });
|
|
16044
16214
|
await rename5(
|
|
16045
|
-
|
|
16046
|
-
|
|
16215
|
+
path49.join(dir, DIST_DIR),
|
|
16216
|
+
path49.join(dir, ".vercel/output/static")
|
|
16047
16217
|
);
|
|
16048
16218
|
}
|
|
16049
16219
|
await writeOutput(dir, {
|
|
@@ -16053,7 +16223,7 @@ var runPrerender = async (options) => {
|
|
|
16053
16223
|
});
|
|
16054
16224
|
if (ZuploEnv.isZuplo && issuer) {
|
|
16055
16225
|
await writeFile13(
|
|
16056
|
-
|
|
16226
|
+
path49.join(dir, DIST_DIR, ".output/zuplo.json"),
|
|
16057
16227
|
JSON.stringify({ issuer }, null, 2),
|
|
16058
16228
|
"utf-8"
|
|
16059
16229
|
);
|
|
@@ -16065,10 +16235,10 @@ var runPrerender = async (options) => {
|
|
|
16065
16235
|
};
|
|
16066
16236
|
var bundleSSREntry = async (options) => {
|
|
16067
16237
|
const { dir, adapter, serverOutDir, serverConfigFilename, html, basePath } = options;
|
|
16068
|
-
const tempEntryPath =
|
|
16238
|
+
const tempEntryPath = path49.join(dir, "__ssr-entry.ts");
|
|
16069
16239
|
const packageRoot = getZudokuRootDir();
|
|
16070
16240
|
const templateContent = await readFile13(
|
|
16071
|
-
|
|
16241
|
+
path49.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
|
|
16072
16242
|
"utf-8"
|
|
16073
16243
|
);
|
|
16074
16244
|
const entryContent = templateContent.replace('"__TEMPLATE__"', JSON.stringify(html)).replace('"__CONFIG_FILE__"', JSON.stringify(`./${serverConfigFilename}`)).replace(
|
|
@@ -16083,9 +16253,9 @@ var bundleSSREntry = async (options) => {
|
|
|
16083
16253
|
platform: adapter === "node" ? "node" : "neutral",
|
|
16084
16254
|
target: "es2022",
|
|
16085
16255
|
format: "esm",
|
|
16086
|
-
outfile:
|
|
16256
|
+
outfile: path49.join(serverOutDir, "entry.js"),
|
|
16087
16257
|
external: ["./entry.server.js", `./${serverConfigFilename}`],
|
|
16088
|
-
nodePaths: [
|
|
16258
|
+
nodePaths: [path49.join(packageRoot, "node_modules")],
|
|
16089
16259
|
banner: { js: "// Bundled SSR entry" }
|
|
16090
16260
|
});
|
|
16091
16261
|
} finally {
|
|
@@ -16099,7 +16269,7 @@ init_package_json();
|
|
|
16099
16269
|
// src/cli/init/v2-packages.ts
|
|
16100
16270
|
import { existsSync as existsSync6 } from "node:fs";
|
|
16101
16271
|
import { readFile as readFile14, writeFile as writeFile14 } from "node:fs/promises";
|
|
16102
|
-
import
|
|
16272
|
+
import path50 from "node:path";
|
|
16103
16273
|
var CORE_PACKAGES = [
|
|
16104
16274
|
"@lukoweb/apitogo",
|
|
16105
16275
|
"react",
|
|
@@ -16116,7 +16286,7 @@ function packageNameFrom(name) {
|
|
|
16116
16286
|
return slug || "portal";
|
|
16117
16287
|
}
|
|
16118
16288
|
async function ensurePackageJson(dir, name) {
|
|
16119
|
-
const file =
|
|
16289
|
+
const file = path50.join(dir, "package.json");
|
|
16120
16290
|
if (existsSync6(file)) return false;
|
|
16121
16291
|
await writeFile14(
|
|
16122
16292
|
file,
|
|
@@ -16135,11 +16305,11 @@ async function ensurePackageJson(dir, name) {
|
|
|
16135
16305
|
return true;
|
|
16136
16306
|
}
|
|
16137
16307
|
function isPackageInstalled(startDir, name) {
|
|
16138
|
-
let dir =
|
|
16308
|
+
let dir = path50.resolve(startDir);
|
|
16139
16309
|
for (; ; ) {
|
|
16140
|
-
if (existsSync6(
|
|
16310
|
+
if (existsSync6(path50.join(dir, "node_modules", name, "package.json")))
|
|
16141
16311
|
return true;
|
|
16142
|
-
const parent =
|
|
16312
|
+
const parent = path50.dirname(dir);
|
|
16143
16313
|
if (parent === dir) return false;
|
|
16144
16314
|
dir = parent;
|
|
16145
16315
|
}
|
|
@@ -16196,7 +16366,7 @@ function portalBuildStep(context, options = {}, build2 = runBuild) {
|
|
|
16196
16366
|
return {
|
|
16197
16367
|
name: "build",
|
|
16198
16368
|
hash: () => hash2,
|
|
16199
|
-
stillValid: () => access4(
|
|
16369
|
+
stillValid: () => access4(path51.join(buildDir, "index.html")).then(
|
|
16200
16370
|
() => true,
|
|
16201
16371
|
() => false
|
|
16202
16372
|
),
|
|
@@ -16213,11 +16383,11 @@ function portalBuildStep(context, options = {}, build2 = runBuild) {
|
|
|
16213
16383
|
else process.env.NODE_ENV = originalNodeEnv;
|
|
16214
16384
|
}
|
|
16215
16385
|
await rm8(buildDir, { recursive: true, force: true });
|
|
16216
|
-
await mkdir12(
|
|
16217
|
-
await rename6(
|
|
16386
|
+
await mkdir12(path51.dirname(buildDir), { recursive: true });
|
|
16387
|
+
await rename6(path51.join(root, "dist"), buildDir);
|
|
16218
16388
|
if (prepared.publishedManifest) {
|
|
16219
16389
|
await writeFile15(
|
|
16220
|
-
|
|
16390
|
+
path51.join(buildDir, MANIFEST_FILE),
|
|
16221
16391
|
`${JSON.stringify(prepared.publishedManifest, null, 2)}
|
|
16222
16392
|
`
|
|
16223
16393
|
);
|
|
@@ -16248,15 +16418,15 @@ async function buildV2(options) {
|
|
|
16248
16418
|
// src/cli/check/gateway-online.ts
|
|
16249
16419
|
import { readFile as readFile16 } from "node:fs/promises";
|
|
16250
16420
|
var SPEC_SEND_LIMIT = 5 * 1024 * 1024 + 64 * 1024;
|
|
16251
|
-
var issue2 = (code,
|
|
16421
|
+
var issue2 = (code, path100, message, hint) => ({ code, path: path100, message, hint });
|
|
16252
16422
|
function capabilityIssues(gateway, answer) {
|
|
16253
16423
|
const can = answer.capabilities;
|
|
16254
16424
|
const plan2 = `your ${answer.tier} plan`;
|
|
16255
16425
|
const found = [];
|
|
16256
|
-
const unsupported = (
|
|
16426
|
+
const unsupported = (path100, what, hint) => found.push(
|
|
16257
16427
|
issue2(
|
|
16258
16428
|
"GATEWAY_CAPABILITY_UNSUPPORTED",
|
|
16259
|
-
|
|
16429
|
+
path100,
|
|
16260
16430
|
`${what} is not available on ${plan2}.`,
|
|
16261
16431
|
hint
|
|
16262
16432
|
)
|
|
@@ -16467,9 +16637,9 @@ function toPlatformPlans(plans, options = {}) {
|
|
|
16467
16637
|
}
|
|
16468
16638
|
|
|
16469
16639
|
// src/cli/check/services-online.ts
|
|
16470
|
-
var issue3 = (code,
|
|
16640
|
+
var issue3 = (code, path100, message, hint) => ({
|
|
16471
16641
|
code,
|
|
16472
|
-
path:
|
|
16642
|
+
path: path100,
|
|
16473
16643
|
message,
|
|
16474
16644
|
hint
|
|
16475
16645
|
});
|
|
@@ -16581,7 +16751,7 @@ var withPlanName = (message, sku) => !sku || message.toLowerCase().startsWith(`p
|
|
|
16581
16751
|
async function isConfigV2(dir) {
|
|
16582
16752
|
try {
|
|
16583
16753
|
return /"version"\s*:\s*2\b/.test(
|
|
16584
|
-
await readFile18(
|
|
16754
|
+
await readFile18(path52.join(dir, APITOGO_CONFIG_FILENAME), "utf8")
|
|
16585
16755
|
);
|
|
16586
16756
|
} catch {
|
|
16587
16757
|
return false;
|
|
@@ -16590,7 +16760,7 @@ async function isConfigV2(dir) {
|
|
|
16590
16760
|
async function isLegacyConfig(dir) {
|
|
16591
16761
|
let text2;
|
|
16592
16762
|
try {
|
|
16593
|
-
text2 = await readFile18(
|
|
16763
|
+
text2 = await readFile18(path52.join(dir, APITOGO_CONFIG_FILENAME), "utf8");
|
|
16594
16764
|
} catch {
|
|
16595
16765
|
return false;
|
|
16596
16766
|
}
|
|
@@ -16738,7 +16908,7 @@ async function validatePortalBuild(dir) {
|
|
|
16738
16908
|
}
|
|
16739
16909
|
}
|
|
16740
16910
|
async function runCheckV2(dir, args = {}, deps = {}) {
|
|
16741
|
-
const configPath =
|
|
16911
|
+
const configPath = path52.join(dir, APITOGO_CONFIG_FILENAME);
|
|
16742
16912
|
let report;
|
|
16743
16913
|
try {
|
|
16744
16914
|
const { config: config2, resolved } = loadConfigV2(dir);
|
|
@@ -16848,7 +17018,7 @@ async function checkV2(dir, args, deps = platformDependencies(args)) {
|
|
|
16848
17018
|
init_package_json();
|
|
16849
17019
|
|
|
16850
17020
|
// src/cli/init/v2-handler.ts
|
|
16851
|
-
import
|
|
17021
|
+
import path53 from "node:path";
|
|
16852
17022
|
import { createInterface } from "node:readline/promises";
|
|
16853
17023
|
function parseDocsFlag(value) {
|
|
16854
17024
|
if (value === void 0) return void 0;
|
|
@@ -16870,15 +17040,15 @@ async function ask(question) {
|
|
|
16870
17040
|
}
|
|
16871
17041
|
function describePlan(plan2) {
|
|
16872
17042
|
return {
|
|
16873
|
-
willCreate: plan2.entries.filter((entry) => !plan2.keep.includes(entry.path)).map((entry) =>
|
|
16874
|
-
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)),
|
|
16875
17045
|
replacesConfig: plan2.replacesConfig
|
|
16876
17046
|
};
|
|
16877
17047
|
}
|
|
16878
17048
|
async function initV2(argv) {
|
|
16879
17049
|
const json = argv.json === true;
|
|
16880
17050
|
try {
|
|
16881
|
-
const dir =
|
|
17051
|
+
const dir = path53.resolve(process.cwd(), argv.dir ?? ".");
|
|
16882
17052
|
const plan2 = await planInit({
|
|
16883
17053
|
dir,
|
|
16884
17054
|
name: argv.name,
|
|
@@ -16919,8 +17089,8 @@ async function initV2(argv) {
|
|
|
16919
17089
|
status: "created",
|
|
16920
17090
|
dir,
|
|
16921
17091
|
...describePlan(plan2),
|
|
16922
|
-
created: result.created.map((p) =>
|
|
16923
|
-
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))
|
|
16924
17094
|
},
|
|
16925
17095
|
null,
|
|
16926
17096
|
2
|
|
@@ -16929,7 +17099,7 @@ async function initV2(argv) {
|
|
|
16929
17099
|
return;
|
|
16930
17100
|
}
|
|
16931
17101
|
printResultToConsole(
|
|
16932
|
-
`Created ${
|
|
17102
|
+
`Created ${path53.basename(plan2.configPath)} (config version 2) in ${dir}.`
|
|
16933
17103
|
);
|
|
16934
17104
|
printHintToConsole(
|
|
16935
17105
|
"Next: add a service with `apitogo add <portal|gateway|identity|plans>`, or run `apitogo create` for a guided setup."
|
|
@@ -16956,7 +17126,7 @@ async function initV2(argv) {
|
|
|
16956
17126
|
|
|
16957
17127
|
// src/cli/services/packages.ts
|
|
16958
17128
|
import { existsSync as existsSync7 } from "node:fs";
|
|
16959
|
-
import
|
|
17129
|
+
import path54 from "node:path";
|
|
16960
17130
|
|
|
16961
17131
|
// src/cli/common/spawn-command.ts
|
|
16962
17132
|
import {
|
|
@@ -16989,18 +17159,18 @@ function packagesForConfig(config2) {
|
|
|
16989
17159
|
];
|
|
16990
17160
|
}
|
|
16991
17161
|
function isInstalled(dir, name) {
|
|
16992
|
-
for (let current =
|
|
16993
|
-
if (existsSync7(
|
|
17162
|
+
for (let current = path54.resolve(dir); ; current = path54.dirname(current)) {
|
|
17163
|
+
if (existsSync7(path54.join(current, "node_modules", name, "package.json")))
|
|
16994
17164
|
return true;
|
|
16995
|
-
if (
|
|
17165
|
+
if (path54.dirname(current) === current) return false;
|
|
16996
17166
|
}
|
|
16997
17167
|
}
|
|
16998
17168
|
function missingPackages(dir, names) {
|
|
16999
17169
|
return names.filter((name) => !isInstalled(dir, name));
|
|
17000
17170
|
}
|
|
17001
17171
|
function detectPackageManager(dir) {
|
|
17002
|
-
if (existsSync7(
|
|
17003
|
-
if (existsSync7(
|
|
17172
|
+
if (existsSync7(path54.join(dir, "pnpm-lock.yaml"))) return "pnpm";
|
|
17173
|
+
if (existsSync7(path54.join(dir, "yarn.lock"))) return "yarn";
|
|
17004
17174
|
return "npm";
|
|
17005
17175
|
}
|
|
17006
17176
|
function installSpecsCommand(manager, specs) {
|
|
@@ -17058,7 +17228,7 @@ async function installMissingPackages(dir, config2, version, options) {
|
|
|
17058
17228
|
reason: "--no-install was given",
|
|
17059
17229
|
command: shown
|
|
17060
17230
|
};
|
|
17061
|
-
await ensurePackageJson(dir, config2.project?.name ??
|
|
17231
|
+
await ensurePackageJson(dir, config2.project?.name ?? path54.basename(dir));
|
|
17062
17232
|
await (options.installer ?? runInstaller)(dir, command2);
|
|
17063
17233
|
return { status: "installed", packages: missing, command: shown };
|
|
17064
17234
|
}
|
|
@@ -17121,7 +17291,7 @@ var list = (value) => {
|
|
|
17121
17291
|
return items.length > 0 ? items : void 0;
|
|
17122
17292
|
};
|
|
17123
17293
|
function addOptionsFromArguments(service, argv) {
|
|
17124
|
-
const dir =
|
|
17294
|
+
const dir = path55.resolve(process.cwd(), argv.dir ?? ".");
|
|
17125
17295
|
const issuers = list(argv.issuer);
|
|
17126
17296
|
return {
|
|
17127
17297
|
dir,
|
|
@@ -17175,8 +17345,8 @@ function describe(edit, dir) {
|
|
|
17175
17345
|
return {
|
|
17176
17346
|
service: edit.service,
|
|
17177
17347
|
action: edit.action,
|
|
17178
|
-
willCreate: edit.files.map((file) =>
|
|
17179
|
-
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)),
|
|
17180
17350
|
notes: edit.notes
|
|
17181
17351
|
};
|
|
17182
17352
|
}
|
|
@@ -17190,7 +17360,7 @@ async function run(action, argv, plan2, deps = {}) {
|
|
|
17190
17360
|
`Choose one of ${SERVICES.join(", ")}.`
|
|
17191
17361
|
);
|
|
17192
17362
|
}
|
|
17193
|
-
const dir =
|
|
17363
|
+
const dir = path55.resolve(process.cwd(), argv.dir ?? ".");
|
|
17194
17364
|
if (!await isConfigV2(dir)) {
|
|
17195
17365
|
throw new ServiceEditError(
|
|
17196
17366
|
`${action} works with a config version 2 project, and there is none in ${dir}.`,
|
|
@@ -17258,7 +17428,7 @@ async function run(action, argv, plan2, deps = {}) {
|
|
|
17258
17428
|
{
|
|
17259
17429
|
status: action === "add" ? "added" : "removed",
|
|
17260
17430
|
...describe(edit, dir),
|
|
17261
|
-
created: created.map((file) =>
|
|
17431
|
+
created: created.map((file) => path55.relative(dir, file)),
|
|
17262
17432
|
...install ? { packages: install } : {}
|
|
17263
17433
|
},
|
|
17264
17434
|
null,
|
|
@@ -17268,7 +17438,7 @@ async function run(action, argv, plan2, deps = {}) {
|
|
|
17268
17438
|
return;
|
|
17269
17439
|
}
|
|
17270
17440
|
printResultToConsole(
|
|
17271
|
-
`${action === "add" ? "Added" : "Removed"} ${edit.service} in ${
|
|
17441
|
+
`${action === "add" ? "Added" : "Removed"} ${edit.service} in ${path55.basename(edit.configPath)}.`
|
|
17272
17442
|
);
|
|
17273
17443
|
} catch (error) {
|
|
17274
17444
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -17329,7 +17499,7 @@ var removeService = (argv) => run(
|
|
|
17329
17499
|
"remove",
|
|
17330
17500
|
argv,
|
|
17331
17501
|
(service) => planRemoveService(service, {
|
|
17332
|
-
dir:
|
|
17502
|
+
dir: path55.resolve(process.cwd(), argv.dir ?? "."),
|
|
17333
17503
|
deleteFiles: argv.deleteFiles === true
|
|
17334
17504
|
})
|
|
17335
17505
|
);
|
|
@@ -17481,16 +17651,16 @@ var add_default = {
|
|
|
17481
17651
|
};
|
|
17482
17652
|
|
|
17483
17653
|
// src/cli/build/handler.ts
|
|
17484
|
-
import
|
|
17654
|
+
import path57 from "node:path";
|
|
17485
17655
|
init_logger();
|
|
17486
17656
|
init_package_json();
|
|
17487
17657
|
|
|
17488
17658
|
// src/cli/preview/handler.ts
|
|
17489
|
-
import
|
|
17659
|
+
import path56 from "node:path";
|
|
17490
17660
|
import { preview as vitePreview } from "vite";
|
|
17491
17661
|
var DEFAULT_PREVIEW_PORT = 4e3;
|
|
17492
17662
|
async function preview(argv) {
|
|
17493
|
-
const dir =
|
|
17663
|
+
const dir = path56.resolve(process.cwd(), argv.dir);
|
|
17494
17664
|
const viteConfig = await getViteConfig(dir, {
|
|
17495
17665
|
command: "serve",
|
|
17496
17666
|
mode: "production",
|
|
@@ -17533,7 +17703,7 @@ async function build(argv) {
|
|
|
17533
17703
|
printDiagnosticsToConsole("");
|
|
17534
17704
|
printDiagnosticsToConsole("");
|
|
17535
17705
|
}
|
|
17536
|
-
const dir =
|
|
17706
|
+
const dir = path57.resolve(process.cwd(), argv.dir);
|
|
17537
17707
|
try {
|
|
17538
17708
|
if (await isConfigV2(dir)) {
|
|
17539
17709
|
const result = await buildV2({ dir, jsonOnly });
|
|
@@ -17598,10 +17768,10 @@ var build_default = {
|
|
|
17598
17768
|
};
|
|
17599
17769
|
|
|
17600
17770
|
// src/cli/check/handler.ts
|
|
17601
|
-
import
|
|
17771
|
+
import path63 from "node:path";
|
|
17602
17772
|
|
|
17603
17773
|
// src/cli/platform/tools/check-publish-readiness.ts
|
|
17604
|
-
import
|
|
17774
|
+
import path62 from "node:path";
|
|
17605
17775
|
|
|
17606
17776
|
// src/cli/platform/helpers/dev-portal-backend.ts
|
|
17607
17777
|
function deriveProvisioningState(backend) {
|
|
@@ -17686,7 +17856,7 @@ function formatDevPortalBackendResponse(projectId, backend) {
|
|
|
17686
17856
|
init_gateway_limits();
|
|
17687
17857
|
import { existsSync as existsSync8 } from "node:fs";
|
|
17688
17858
|
import { access as access5, mkdir as mkdir13, readFile as readFile19, writeFile as writeFile16 } from "node:fs/promises";
|
|
17689
|
-
import
|
|
17859
|
+
import path58 from "node:path";
|
|
17690
17860
|
|
|
17691
17861
|
// src/cli/make-config/header-pricing-nav.ts
|
|
17692
17862
|
var HEADER_PRICING_PATH = "/pricing";
|
|
@@ -17808,7 +17978,7 @@ function isPlanFree(plan2) {
|
|
|
17808
17978
|
return (plan2.priceAmount ?? 0) <= 0;
|
|
17809
17979
|
}
|
|
17810
17980
|
function manifestFilePath(siteDirectory) {
|
|
17811
|
-
return
|
|
17981
|
+
return path58.join(path58.resolve(siteDirectory), APITOGO_CONFIG_FILENAME2);
|
|
17812
17982
|
}
|
|
17813
17983
|
var STORED_MANIFEST_KEYS = [
|
|
17814
17984
|
"authentication",
|
|
@@ -18232,23 +18402,23 @@ function resolveBackendSourceDirectory(siteDirectory, sourceDirectory) {
|
|
|
18232
18402
|
if (!trimmed) {
|
|
18233
18403
|
return void 0;
|
|
18234
18404
|
}
|
|
18235
|
-
return
|
|
18405
|
+
return path58.resolve(siteDirectory, trimmed);
|
|
18236
18406
|
}
|
|
18237
18407
|
function resolveBackendOpenApiPath(openApiPath, options) {
|
|
18238
18408
|
const trimmed = openApiPath?.trim();
|
|
18239
18409
|
if (!trimmed) {
|
|
18240
18410
|
return void 0;
|
|
18241
18411
|
}
|
|
18242
|
-
if (
|
|
18412
|
+
if (path58.isAbsolute(trimmed)) {
|
|
18243
18413
|
return trimmed;
|
|
18244
18414
|
}
|
|
18245
|
-
const siteResolved =
|
|
18415
|
+
const siteResolved = path58.resolve(options.siteDirectory, trimmed);
|
|
18246
18416
|
if (existsSync8(siteResolved)) {
|
|
18247
18417
|
return siteResolved;
|
|
18248
18418
|
}
|
|
18249
18419
|
const backendDir = options.backendSourceDirectory?.trim();
|
|
18250
18420
|
if (backendDir) {
|
|
18251
|
-
const backendResolved =
|
|
18421
|
+
const backendResolved = path58.resolve(backendDir, trimmed);
|
|
18252
18422
|
if (existsSync8(backendResolved)) {
|
|
18253
18423
|
return backendResolved;
|
|
18254
18424
|
}
|
|
@@ -18273,7 +18443,7 @@ async function readManifest2(siteDirectory) {
|
|
|
18273
18443
|
}
|
|
18274
18444
|
async function writeManifest2(siteDirectory, manifest) {
|
|
18275
18445
|
const filePath = manifestFilePath(siteDirectory);
|
|
18276
|
-
await mkdir13(
|
|
18446
|
+
await mkdir13(path58.dirname(filePath), { recursive: true });
|
|
18277
18447
|
let config2 = {};
|
|
18278
18448
|
if (await pathExists(filePath)) {
|
|
18279
18449
|
const raw = await readFile19(filePath, "utf8");
|
|
@@ -18299,7 +18469,7 @@ import {
|
|
|
18299
18469
|
unlink,
|
|
18300
18470
|
writeFile as writeFile17
|
|
18301
18471
|
} from "node:fs/promises";
|
|
18302
|
-
import
|
|
18472
|
+
import path59 from "node:path";
|
|
18303
18473
|
var ENV_FILENAME = ".env";
|
|
18304
18474
|
var COLLAPSED_UPPERCASE_ALIASES2 = {
|
|
18305
18475
|
SECRETKEY: "secretKey",
|
|
@@ -18418,12 +18588,12 @@ async function readEnvFile(filePath) {
|
|
|
18418
18588
|
}
|
|
18419
18589
|
}
|
|
18420
18590
|
async function loadSiteEnv(siteDirectory) {
|
|
18421
|
-
const resolvedDirectory =
|
|
18591
|
+
const resolvedDirectory = path59.resolve(siteDirectory);
|
|
18422
18592
|
const merged = { ...process.env };
|
|
18423
18593
|
for (const fileName of [ENV_FILENAME, ".env.local"]) {
|
|
18424
18594
|
Object.assign(
|
|
18425
18595
|
merged,
|
|
18426
|
-
await readEnvFile(
|
|
18596
|
+
await readEnvFile(path59.join(resolvedDirectory, fileName))
|
|
18427
18597
|
);
|
|
18428
18598
|
}
|
|
18429
18599
|
return merged;
|
|
@@ -18460,7 +18630,7 @@ function buildAuthSecretsJson(secrets2, options) {
|
|
|
18460
18630
|
return payload;
|
|
18461
18631
|
}
|
|
18462
18632
|
function envFilePath(siteDirectory) {
|
|
18463
|
-
return
|
|
18633
|
+
return path59.join(path59.resolve(siteDirectory), ENV_FILENAME);
|
|
18464
18634
|
}
|
|
18465
18635
|
function getSecretsStatus(siteDirectory, manifest, secrets2, envExists) {
|
|
18466
18636
|
const providerSecretStatus = {};
|
|
@@ -18496,7 +18666,7 @@ function validateSecretsForPublish(manifest, secrets2, emailOptions) {
|
|
|
18496
18666
|
}
|
|
18497
18667
|
async function siteEnvFileHasEntries(siteDirectory) {
|
|
18498
18668
|
for (const fileName of [ENV_FILENAME, ".env.local"]) {
|
|
18499
|
-
const loaded = await readEnvFile(
|
|
18669
|
+
const loaded = await readEnvFile(path59.join(siteDirectory, fileName));
|
|
18500
18670
|
if (Object.keys(loaded).length > 0) {
|
|
18501
18671
|
return true;
|
|
18502
18672
|
}
|
|
@@ -18504,7 +18674,7 @@ async function siteEnvFileHasEntries(siteDirectory) {
|
|
|
18504
18674
|
return false;
|
|
18505
18675
|
}
|
|
18506
18676
|
async function resolvePublishConfig(siteDirectory, emailOptions) {
|
|
18507
|
-
const resolvedDirectory =
|
|
18677
|
+
const resolvedDirectory = path59.resolve(siteDirectory);
|
|
18508
18678
|
const manifestRaw = await readManifest2(resolvedDirectory);
|
|
18509
18679
|
if (!manifestRaw) {
|
|
18510
18680
|
throw new Error("apitogo.config.json not found in sourceDirectory.");
|
|
@@ -18536,11 +18706,11 @@ var SECRETS_COLLECTION_INSTRUCTION = "For go-live, plans must already be in apit
|
|
|
18536
18706
|
init_gateway_limits();
|
|
18537
18707
|
import { readFile as readFile21 } from "node:fs/promises";
|
|
18538
18708
|
import { createRequire as createRequire2 } from "node:module";
|
|
18539
|
-
import
|
|
18709
|
+
import path60 from "node:path";
|
|
18540
18710
|
var cachedFallbackTs;
|
|
18541
18711
|
async function loadTypeScriptForSite(sourceDirectory) {
|
|
18542
18712
|
const require2 = createRequire2(
|
|
18543
|
-
|
|
18713
|
+
path60.join(path60.resolve(sourceDirectory), "package.json")
|
|
18544
18714
|
);
|
|
18545
18715
|
try {
|
|
18546
18716
|
return require2("typescript");
|
|
@@ -18587,7 +18757,7 @@ async function referencedFileExists(sourceDirectory, reference) {
|
|
|
18587
18757
|
return true;
|
|
18588
18758
|
}
|
|
18589
18759
|
return pathExists(
|
|
18590
|
-
|
|
18760
|
+
path60.resolve(sourceDirectory, reference.replace(/^\.\//, ""))
|
|
18591
18761
|
);
|
|
18592
18762
|
}
|
|
18593
18763
|
async function validateSiteConfigStructure(config2, sourceDirectory) {
|
|
@@ -18702,11 +18872,11 @@ var DEFAULT_TSX_CANDIDATES = [
|
|
|
18702
18872
|
"landing/LandingPage.tsx"
|
|
18703
18873
|
];
|
|
18704
18874
|
async function validateDevPortalSiteConfig(sourceDirectory, options) {
|
|
18705
|
-
const resolvedDir =
|
|
18875
|
+
const resolvedDir = path60.resolve(sourceDirectory);
|
|
18706
18876
|
const issues = [];
|
|
18707
18877
|
const checkedFiles = [];
|
|
18708
18878
|
const skippedChecks = [];
|
|
18709
|
-
const jsonPath =
|
|
18879
|
+
const jsonPath = path60.join(resolvedDir, APITOGO_CONFIG_FILENAME2);
|
|
18710
18880
|
if (await pathExists(jsonPath)) {
|
|
18711
18881
|
checkedFiles.push(APITOGO_CONFIG_FILENAME2);
|
|
18712
18882
|
let parsed;
|
|
@@ -18738,7 +18908,7 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
|
|
|
18738
18908
|
);
|
|
18739
18909
|
const existingTsxFiles = [];
|
|
18740
18910
|
for (const relativeFile of tsxFiles) {
|
|
18741
|
-
if (await pathExists(
|
|
18911
|
+
if (await pathExists(path60.join(resolvedDir, relativeFile))) {
|
|
18742
18912
|
existingTsxFiles.push(relativeFile);
|
|
18743
18913
|
}
|
|
18744
18914
|
}
|
|
@@ -18752,7 +18922,7 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
|
|
|
18752
18922
|
for (const relativeFile of existingTsxFiles) {
|
|
18753
18923
|
checkedFiles.push(relativeFile);
|
|
18754
18924
|
const content = await readFile21(
|
|
18755
|
-
|
|
18925
|
+
path60.join(resolvedDir, relativeFile),
|
|
18756
18926
|
"utf8"
|
|
18757
18927
|
);
|
|
18758
18928
|
issues.push(
|
|
@@ -18774,7 +18944,7 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
|
|
|
18774
18944
|
|
|
18775
18945
|
// src/cli/platform/helpers/npm-build.ts
|
|
18776
18946
|
import { access as access7, readFile as readFile22 } from "node:fs/promises";
|
|
18777
|
-
import
|
|
18947
|
+
import path61 from "node:path";
|
|
18778
18948
|
var BUILD_LOG_TAIL_BYTES = 8192;
|
|
18779
18949
|
var MIN_NODE_MAJOR = 20;
|
|
18780
18950
|
var NpmBuildError = class extends Error {
|
|
@@ -18840,13 +19010,13 @@ function runCommand(command2, args, cwd, env) {
|
|
|
18840
19010
|
}
|
|
18841
19011
|
async function runNpmInstall(sourceDirectory, options) {
|
|
18842
19012
|
assertNodeVersion(options?.nodeVersion);
|
|
18843
|
-
const cwd =
|
|
18844
|
-
const packageJsonPath =
|
|
19013
|
+
const cwd = path61.resolve(sourceDirectory);
|
|
19014
|
+
const packageJsonPath = path61.join(cwd, "package.json");
|
|
18845
19015
|
if (!await pathExists2(packageJsonPath)) {
|
|
18846
19016
|
throw new Error(`package.json not found in sourceDirectory: ${cwd}`);
|
|
18847
19017
|
}
|
|
18848
19018
|
const startedAt = Date.now();
|
|
18849
|
-
const lockPath =
|
|
19019
|
+
const lockPath = path61.join(cwd, "package-lock.json");
|
|
18850
19020
|
const installArgs = await pathExists2(lockPath) ? ["ci"] : ["install"];
|
|
18851
19021
|
const install = await runCommand("npm", installArgs, cwd);
|
|
18852
19022
|
const installLog = install.output;
|
|
@@ -18864,8 +19034,8 @@ async function runNpmInstall(sourceDirectory, options) {
|
|
|
18864
19034
|
}
|
|
18865
19035
|
async function runNpmBuild(sourceDirectory, options) {
|
|
18866
19036
|
assertNodeVersion(options?.nodeVersion);
|
|
18867
|
-
const cwd =
|
|
18868
|
-
const packageJsonPath =
|
|
19037
|
+
const cwd = path61.resolve(sourceDirectory);
|
|
19038
|
+
const packageJsonPath = path61.join(cwd, "package.json");
|
|
18869
19039
|
if (!await pathExists2(packageJsonPath)) {
|
|
18870
19040
|
throw new Error(`package.json not found in sourceDirectory: ${cwd}`);
|
|
18871
19041
|
}
|
|
@@ -18882,8 +19052,8 @@ async function runNpmBuild(sourceDirectory, options) {
|
|
|
18882
19052
|
build2.exitCode
|
|
18883
19053
|
);
|
|
18884
19054
|
}
|
|
18885
|
-
const distPath =
|
|
18886
|
-
const indexPath =
|
|
19055
|
+
const distPath = path61.join(cwd, "dist");
|
|
19056
|
+
const indexPath = path61.join(distPath, "index.html");
|
|
18887
19057
|
if (!await pathExists2(indexPath)) {
|
|
18888
19058
|
throw new NpmBuildError(
|
|
18889
19059
|
`Build completed but dist/index.html was not found at ${indexPath}`,
|
|
@@ -19267,7 +19437,7 @@ function validateManifestForPlatformPublish(manifest) {
|
|
|
19267
19437
|
|
|
19268
19438
|
// src/cli/platform/tools/check-publish-readiness.ts
|
|
19269
19439
|
async function checkPublishReadiness(client, _config, args) {
|
|
19270
|
-
const sourceDirectory =
|
|
19440
|
+
const sourceDirectory = path62.resolve(args.sourceDirectory);
|
|
19271
19441
|
const manifest = await readManifest2(sourceDirectory) ?? createScaffoldManifest();
|
|
19272
19442
|
const emailOptions = await resolveEmailOptionsForPublish(
|
|
19273
19443
|
client,
|
|
@@ -19345,7 +19515,7 @@ async function checkPublishReadiness(client, _config, args) {
|
|
|
19345
19515
|
|
|
19346
19516
|
// src/cli/check/handler.ts
|
|
19347
19517
|
async function check(argv) {
|
|
19348
|
-
const sourceDirectory =
|
|
19518
|
+
const sourceDirectory = path63.resolve(process.cwd(), argv.dir);
|
|
19349
19519
|
if (await isConfigV2(sourceDirectory)) {
|
|
19350
19520
|
await checkV2(sourceDirectory, argv);
|
|
19351
19521
|
return;
|
|
@@ -19409,7 +19579,7 @@ var check_default = {
|
|
|
19409
19579
|
|
|
19410
19580
|
// src/cli/make-config/handler.ts
|
|
19411
19581
|
init_invariant();
|
|
19412
|
-
import
|
|
19582
|
+
import path65 from "node:path";
|
|
19413
19583
|
import { stdin as input2 } from "node:process";
|
|
19414
19584
|
|
|
19415
19585
|
// src/cli/make-config/interactive.ts
|
|
@@ -19419,7 +19589,7 @@ import { createInterface as createInterface3 } from "node:readline/promises";
|
|
|
19419
19589
|
// src/cli/make-config/v2-edits.ts
|
|
19420
19590
|
init_apitogo_config_core();
|
|
19421
19591
|
import { access as access8, mkdir as mkdir15, readFile as readFile23, writeFile as writeFile18 } from "node:fs/promises";
|
|
19422
|
-
import
|
|
19592
|
+
import path64 from "node:path";
|
|
19423
19593
|
import { glob as glob8 } from "glob";
|
|
19424
19594
|
init_invariant();
|
|
19425
19595
|
var ConfigEditError = class extends ApitogoError {
|
|
@@ -19432,10 +19602,10 @@ var exists4 = (target) => access8(target).then(
|
|
|
19432
19602
|
() => true,
|
|
19433
19603
|
() => false
|
|
19434
19604
|
);
|
|
19435
|
-
var toPosix2 = (value) => value.split(
|
|
19436
|
-
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)) || ".";
|
|
19437
19607
|
async function openConfigProject(dir) {
|
|
19438
|
-
const configPath =
|
|
19608
|
+
const configPath = path64.join(dir, APITOGO_CONFIG_FILENAME);
|
|
19439
19609
|
if (!await exists4(configPath)) {
|
|
19440
19610
|
throw new ConfigEditError(
|
|
19441
19611
|
`There is no ${APITOGO_CONFIG_FILENAME} in ${dir}.`,
|
|
@@ -19500,7 +19670,7 @@ function setPortalName(project, name) {
|
|
|
19500
19670
|
}
|
|
19501
19671
|
async function addGatewaySpec(project, specPath) {
|
|
19502
19672
|
const gateway = requireGateway(project);
|
|
19503
|
-
const absolute =
|
|
19673
|
+
const absolute = path64.resolve(project.dir, specPath);
|
|
19504
19674
|
if (!await exists4(absolute)) {
|
|
19505
19675
|
throw new ConfigEditError(`The OpenAPI file ${specPath} does not exist.`);
|
|
19506
19676
|
}
|
|
@@ -19544,7 +19714,7 @@ function parseBackendInput(input5) {
|
|
|
19544
19714
|
}
|
|
19545
19715
|
async function setGatewayOrigin(project, backend) {
|
|
19546
19716
|
const gateway = requireGateway(project);
|
|
19547
|
-
const source =
|
|
19717
|
+
const source = path64.resolve(project.dir, backend.source);
|
|
19548
19718
|
if (!await exists4(source)) {
|
|
19549
19719
|
throw new ConfigEditError(
|
|
19550
19720
|
`The API source folder ${backend.source} does not exist.`
|
|
@@ -19622,6 +19792,164 @@ export default function ${pageComponentName(slug)}() {
|
|
|
19622
19792
|
}
|
|
19623
19793
|
`;
|
|
19624
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
|
+
}
|
|
19625
19953
|
async function writeDocsPage(project, input5) {
|
|
19626
19954
|
requirePortal(project);
|
|
19627
19955
|
if (/^[A-Za-z]:[\\/]/.test(input5.slug.trim())) {
|
|
@@ -19645,13 +19973,13 @@ async function writeDocsPage(project, input5) {
|
|
|
19645
19973
|
"For example --page-order 1 puts the page first in the sidebar."
|
|
19646
19974
|
);
|
|
19647
19975
|
}
|
|
19648
|
-
const base =
|
|
19976
|
+
const base = path64.join(portal.dir, "pages", ...slug.split("/"));
|
|
19649
19977
|
const existing = (await Promise.all(
|
|
19650
19978
|
[`${base}.tsx`, `${base}.mdx`, `${base}.md`].map(
|
|
19651
19979
|
async (file2) => await exists4(file2) ? file2 : null
|
|
19652
19980
|
)
|
|
19653
19981
|
)).find((file2) => file2 !== null);
|
|
19654
|
-
const relative = (file2) => toPosix2(
|
|
19982
|
+
const relative = (file2) => toPosix2(path64.relative(project.dir, file2));
|
|
19655
19983
|
const write = (file2, title, order = input5.order) => writeFile18(
|
|
19656
19984
|
file2,
|
|
19657
19985
|
file2.endsWith(".tsx") ? buildTsxDocsPage(slug, title, relative(file2), input5.content, order) : buildDocsPage(title, input5.content, order),
|
|
@@ -19685,17 +20013,17 @@ async function writeDocsPage(project, input5) {
|
|
|
19685
20013
|
}
|
|
19686
20014
|
file = `${base}.${input5.format ?? "tsx"}`;
|
|
19687
20015
|
action = "added";
|
|
19688
|
-
await mkdir15(
|
|
20016
|
+
await mkdir15(path64.dirname(file), { recursive: true });
|
|
19689
20017
|
await write(file, title);
|
|
19690
20018
|
}
|
|
19691
|
-
const same = (match) =>
|
|
20019
|
+
const same = (match) => path64.resolve(match) === path64.resolve(file);
|
|
19692
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);
|
|
19693
20021
|
return {
|
|
19694
20022
|
action,
|
|
19695
20023
|
slug,
|
|
19696
20024
|
route: `/${slug}`,
|
|
19697
20025
|
file: relative(file),
|
|
19698
|
-
format:
|
|
20026
|
+
format: path64.extname(file).slice(1),
|
|
19699
20027
|
inPortal
|
|
19700
20028
|
};
|
|
19701
20029
|
}
|
|
@@ -19774,7 +20102,7 @@ async function readPlanCatalog(project) {
|
|
|
19774
20102
|
}
|
|
19775
20103
|
var skuOf = (item) => isPlainObject3(item) && typeof item.sku === "string" ? item.sku.trim().toLowerCase() : void 0;
|
|
19776
20104
|
async function writePlanCatalog(file, catalog, plans) {
|
|
19777
|
-
await mkdir15(
|
|
20105
|
+
await mkdir15(path64.dirname(file), { recursive: true });
|
|
19778
20106
|
await writeFile18(
|
|
19779
20107
|
file,
|
|
19780
20108
|
`${JSON.stringify({ ...catalog, plans }, null, 2)}
|
|
@@ -19797,7 +20125,7 @@ async function upsertPlan(project, plan2) {
|
|
|
19797
20125
|
return {
|
|
19798
20126
|
action: index === -1 ? "added" : "updated",
|
|
19799
20127
|
sku: plan2.sku,
|
|
19800
|
-
file: toPosix2(
|
|
20128
|
+
file: toPosix2(path64.relative(project.dir, file)),
|
|
19801
20129
|
paid,
|
|
19802
20130
|
needsBilling: paid && billing.provider !== "stripe"
|
|
19803
20131
|
};
|
|
@@ -19887,12 +20215,12 @@ async function removePlan(project, rawSku) {
|
|
|
19887
20215
|
if (next.length === catalog.plans.length) {
|
|
19888
20216
|
const known = catalog.plans.map(skuOf).filter(Boolean).join(", ");
|
|
19889
20217
|
throw new ConfigEditError(
|
|
19890
|
-
`There is no plan "${sku}" in ${toPosix2(
|
|
20218
|
+
`There is no plan "${sku}" in ${toPosix2(path64.relative(project.dir, file))}.`,
|
|
19891
20219
|
known ? `The plans are: ${known}.` : "The plans file has no plans."
|
|
19892
20220
|
);
|
|
19893
20221
|
}
|
|
19894
20222
|
await writePlanCatalog(file, catalog, next);
|
|
19895
|
-
return { sku, file: toPosix2(
|
|
20223
|
+
return { sku, file: toPosix2(path64.relative(project.dir, file)) };
|
|
19896
20224
|
}
|
|
19897
20225
|
|
|
19898
20226
|
// src/cli/make-config/wrap-up.ts
|
|
@@ -19915,6 +20243,12 @@ function printPageResult(page) {
|
|
|
19915
20243
|
printSuccessToConsole(
|
|
19916
20244
|
`Page ${page.action}: ${page.file} (route ${page.route})`
|
|
19917
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
|
+
}
|
|
19918
20252
|
if (page.inPortal) {
|
|
19919
20253
|
printHintToConsole(
|
|
19920
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."
|
|
@@ -20173,7 +20507,7 @@ async function applyConfigFlags(project, argv, changes) {
|
|
|
20173
20507
|
return { project: next, openApi };
|
|
20174
20508
|
}
|
|
20175
20509
|
async function makeConfig(argv) {
|
|
20176
|
-
const dir =
|
|
20510
|
+
const dir = path65.resolve(process.cwd(), argv.dir);
|
|
20177
20511
|
const interactive = shouldRunInteractive(argv);
|
|
20178
20512
|
const json = argv.json === true;
|
|
20179
20513
|
const changes = [];
|
|
@@ -20216,7 +20550,32 @@ async function makeConfig(argv) {
|
|
|
20216
20550
|
const applied = await applyConfigFlags(project, argv, changes);
|
|
20217
20551
|
project = applied.project;
|
|
20218
20552
|
openApi = applied.openApi;
|
|
20219
|
-
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) {
|
|
20220
20579
|
page = await writeDocsPage(project, {
|
|
20221
20580
|
slug: argv.pageSlug,
|
|
20222
20581
|
title: argv.pageTitle,
|
|
@@ -20365,6 +20724,10 @@ function addConfigOptions(yargs2) {
|
|
|
20365
20724
|
type: "boolean",
|
|
20366
20725
|
default: false,
|
|
20367
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)"
|
|
20368
20731
|
}).option("plan-sku", {
|
|
20369
20732
|
type: "string",
|
|
20370
20733
|
describe: "Add or change the plan with this SKU in the plans file; the --plan-* options set its fields"
|
|
@@ -20402,7 +20765,10 @@ function addConfigOptions(yargs2) {
|
|
|
20402
20765
|
).example(
|
|
20403
20766
|
"$0 config --plan-sku enterprise --plan-price custom",
|
|
20404
20767
|
"A contact-us plan"
|
|
20405
|
-
).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", {
|
|
20406
20772
|
type: "string",
|
|
20407
20773
|
describe: "JSON plan added to the plans file (plans.file, default apitogo/plans.json), or replacing the one with the same sku"
|
|
20408
20774
|
}).option("patch", {
|
|
@@ -20424,27 +20790,27 @@ var config_default = {
|
|
|
20424
20790
|
init_apitogo_config_core();
|
|
20425
20791
|
import { execFile } from "node:child_process";
|
|
20426
20792
|
import { readFile as readFile24 } from "node:fs/promises";
|
|
20427
|
-
import
|
|
20793
|
+
import path67 from "node:path";
|
|
20428
20794
|
import { promisify } from "node:util";
|
|
20429
20795
|
|
|
20430
20796
|
// src/cli/create/dry-run.ts
|
|
20431
20797
|
import { mkdir as mkdir16, mkdtemp, readdir as readdir4, rm as rm9 } from "node:fs/promises";
|
|
20432
20798
|
import { tmpdir } from "node:os";
|
|
20433
|
-
import
|
|
20799
|
+
import path66 from "node:path";
|
|
20434
20800
|
async function listFiles(root, dir = root) {
|
|
20435
20801
|
const entries = await readdir4(dir, { withFileTypes: true });
|
|
20436
20802
|
const nested = await Promise.all(
|
|
20437
20803
|
entries.map(async (entry) => {
|
|
20438
|
-
const full =
|
|
20804
|
+
const full = path66.join(dir, entry.name);
|
|
20439
20805
|
if (entry.isDirectory()) return listFiles(root, full);
|
|
20440
|
-
return [
|
|
20806
|
+
return [path66.relative(root, full).split(path66.sep).join("/")];
|
|
20441
20807
|
})
|
|
20442
20808
|
);
|
|
20443
20809
|
return nested.flat();
|
|
20444
20810
|
}
|
|
20445
20811
|
async function previewCreate(input5) {
|
|
20446
|
-
const scratch = await mkdtemp(
|
|
20447
|
-
const dir =
|
|
20812
|
+
const scratch = await mkdtemp(path66.join(tmpdir(), "apitogo-create-"));
|
|
20813
|
+
const dir = path66.join(scratch, "project");
|
|
20448
20814
|
try {
|
|
20449
20815
|
await mkdir16(dir);
|
|
20450
20816
|
await applyInitPlan(await planInit({ dir, name: input5.name }));
|
|
@@ -20477,9 +20843,9 @@ async function previewCreate(input5) {
|
|
|
20477
20843
|
var execFileAsync = promisify(execFile);
|
|
20478
20844
|
function nextStepHint(dir) {
|
|
20479
20845
|
const linked = loadConfigV2(dir).resolved.project.id;
|
|
20480
|
-
const cd =
|
|
20846
|
+
const cd = path67.resolve(dir) === path67.resolve(process.cwd());
|
|
20481
20847
|
const steps = linked ? "apitogo deploy" : "apitogo project create, then apitogo deploy";
|
|
20482
|
-
return cd ? `Next: ${steps}` : `Next: cd ${JSON.stringify(
|
|
20848
|
+
return cd ? `Next: ${steps}` : `Next: cd ${JSON.stringify(path67.relative(process.cwd(), dir))}, then ${steps}`;
|
|
20483
20849
|
}
|
|
20484
20850
|
function projectFolderName(name) {
|
|
20485
20851
|
return name.trim().replace(/[<>:"/\\|?*\s]+/g, "-").replace(/^[-.]+|[-.]+$/g, "") || "apitogo-project";
|
|
@@ -20505,13 +20871,13 @@ async function gitHasUncommittedChanges(dir) {
|
|
|
20505
20871
|
async function defaultName(dir) {
|
|
20506
20872
|
try {
|
|
20507
20873
|
const parsed = JSON.parse(
|
|
20508
|
-
await readFile24(
|
|
20874
|
+
await readFile24(path67.join(dir, "package.json"), "utf8")
|
|
20509
20875
|
);
|
|
20510
20876
|
if (typeof parsed.name === "string" && parsed.name.trim())
|
|
20511
20877
|
return parsed.name.replace(/^@[^/]+\//, "");
|
|
20512
20878
|
} catch {
|
|
20513
20879
|
}
|
|
20514
|
-
return
|
|
20880
|
+
return path67.basename(dir);
|
|
20515
20881
|
}
|
|
20516
20882
|
function parseServicesFlag(value) {
|
|
20517
20883
|
const names = (value ?? "").split(",").map((name) => name.trim()).filter(Boolean);
|
|
@@ -20537,7 +20903,7 @@ async function createProject(argv, deps = {}) {
|
|
|
20537
20903
|
if (!json) printDiagnosticsToConsole(line2);
|
|
20538
20904
|
};
|
|
20539
20905
|
try {
|
|
20540
|
-
const base =
|
|
20906
|
+
const base = path67.resolve(process.cwd(), argv.dir ?? ".");
|
|
20541
20907
|
let dir = base;
|
|
20542
20908
|
let requested = parseServicesFlag(argv.services);
|
|
20543
20909
|
let template = argv.template;
|
|
@@ -20560,8 +20926,8 @@ async function createProject(argv, deps = {}) {
|
|
|
20560
20926
|
default: await defaultName(base)
|
|
20561
20927
|
}) : await defaultName(base));
|
|
20562
20928
|
const folder = projectFolderName(name);
|
|
20563
|
-
if (argv.dir === void 0 && folder !==
|
|
20564
|
-
dir =
|
|
20929
|
+
if (argv.dir === void 0 && folder !== path67.basename(base))
|
|
20930
|
+
dir = path67.join(base, folder);
|
|
20565
20931
|
}
|
|
20566
20932
|
if (await (deps.hasUncommittedChanges ?? gitHasUncommittedChanges)(dir))
|
|
20567
20933
|
say(
|
|
@@ -20574,7 +20940,7 @@ async function createProject(argv, deps = {}) {
|
|
|
20574
20940
|
if (argv.dryRun) {
|
|
20575
20941
|
const services = requested.length > 0 ? requested : templateServices ? STARTER_SERVICES : [];
|
|
20576
20942
|
const preview2 = services.length > 0 ? await previewCreate({ name, template, services }) : void 0;
|
|
20577
|
-
const folder =
|
|
20943
|
+
const folder = path67.relative(process.cwd(), dir) || ".";
|
|
20578
20944
|
if (json)
|
|
20579
20945
|
console.log(
|
|
20580
20946
|
JSON.stringify({
|
|
@@ -20607,7 +20973,7 @@ async function createProject(argv, deps = {}) {
|
|
|
20607
20973
|
}
|
|
20608
20974
|
await applyInitPlan(plan2);
|
|
20609
20975
|
say(
|
|
20610
|
-
dir === base ? `Created ${APITOGO_CONFIG_FILENAME}.` : `Created ${
|
|
20976
|
+
dir === base ? `Created ${APITOGO_CONFIG_FILENAME}.` : `Created ${path67.relative(base, dir)}${path67.sep}${APITOGO_CONFIG_FILENAME}.`
|
|
20611
20977
|
);
|
|
20612
20978
|
} else {
|
|
20613
20979
|
say(`${APITOGO_CONFIG_FILENAME} exists: continuing from it.`);
|
|
@@ -20749,10 +21115,10 @@ var create_default = {
|
|
|
20749
21115
|
};
|
|
20750
21116
|
|
|
20751
21117
|
// src/cli/cmds/deploy.ts
|
|
20752
|
-
import
|
|
21118
|
+
import path86 from "node:path";
|
|
20753
21119
|
|
|
20754
21120
|
// src/cli/apply/handler.ts
|
|
20755
|
-
import
|
|
21121
|
+
import path79 from "node:path";
|
|
20756
21122
|
|
|
20757
21123
|
// src/cli/platform/helpers/gateway-plan-validation.ts
|
|
20758
21124
|
init_gateway_limits();
|
|
@@ -20971,11 +21337,11 @@ init_gateway_limits();
|
|
|
20971
21337
|
// src/cli/platform/helpers/deploy-artifact-hash.ts
|
|
20972
21338
|
import { createHash as createHash3 } from "node:crypto";
|
|
20973
21339
|
import { createReadStream, promises as fs6 } from "node:fs";
|
|
20974
|
-
import
|
|
21340
|
+
import path69 from "node:path";
|
|
20975
21341
|
|
|
20976
21342
|
// src/cli/platform/helpers/package-files.ts
|
|
20977
21343
|
import { promises as fs5 } from "node:fs";
|
|
20978
|
-
import
|
|
21344
|
+
import path68 from "node:path";
|
|
20979
21345
|
import ignore from "ignore";
|
|
20980
21346
|
var DEFAULT_EXCLUDES = /* @__PURE__ */ new Set([
|
|
20981
21347
|
"node_modules",
|
|
@@ -20989,7 +21355,7 @@ async function loadGitignore(rootDir, extraExcludes = []) {
|
|
|
20989
21355
|
const ig = ignore();
|
|
20990
21356
|
ig.add(["node_modules/", ".git/", "dist/", "bin/", "obj/"]);
|
|
20991
21357
|
if (extraExcludes.length > 0) ig.add([...extraExcludes]);
|
|
20992
|
-
const gitignorePath =
|
|
21358
|
+
const gitignorePath = path68.join(rootDir, ".gitignore");
|
|
20993
21359
|
try {
|
|
20994
21360
|
const content = await fs5.readFile(gitignorePath, "utf8");
|
|
20995
21361
|
ig.add(content);
|
|
@@ -20998,11 +21364,11 @@ async function loadGitignore(rootDir, extraExcludes = []) {
|
|
|
20998
21364
|
return ig;
|
|
20999
21365
|
}
|
|
21000
21366
|
async function collectFiles(rootDir, relativeDir, ig, files) {
|
|
21001
|
-
const absDir =
|
|
21367
|
+
const absDir = path68.join(rootDir, relativeDir);
|
|
21002
21368
|
const entries = await fs5.readdir(absDir, { withFileTypes: true });
|
|
21003
21369
|
for (const entry of entries) {
|
|
21004
|
-
const rel2 = relativeDir ?
|
|
21005
|
-
const relPosix = rel2.split(
|
|
21370
|
+
const rel2 = relativeDir ? path68.join(relativeDir, entry.name) : entry.name;
|
|
21371
|
+
const relPosix = rel2.split(path68.sep).join("/");
|
|
21006
21372
|
if (DEFAULT_EXCLUDES.has(entry.name) && !relativeDir) {
|
|
21007
21373
|
continue;
|
|
21008
21374
|
}
|
|
@@ -21017,7 +21383,7 @@ async function collectFiles(rootDir, relativeDir, ig, files) {
|
|
|
21017
21383
|
}
|
|
21018
21384
|
}
|
|
21019
21385
|
async function collectPackageableFiles(sourceDirectory, extraExcludes = []) {
|
|
21020
|
-
const resolved =
|
|
21386
|
+
const resolved = path68.resolve(sourceDirectory);
|
|
21021
21387
|
const stat7 = await fs5.stat(resolved).catch(() => null);
|
|
21022
21388
|
if (!stat7?.isDirectory()) {
|
|
21023
21389
|
throw new Error(`sourceDirectory is not a directory: ${resolved}`);
|
|
@@ -21043,7 +21409,7 @@ async function sha256File(filePath) {
|
|
|
21043
21409
|
return hash2.digest("hex");
|
|
21044
21410
|
}
|
|
21045
21411
|
async function hashDirectoryContents(rootDirectory, extraExcludes = []) {
|
|
21046
|
-
const resolved =
|
|
21412
|
+
const resolved = path69.resolve(rootDirectory);
|
|
21047
21413
|
const files = (await collectPackageableFiles(resolved, extraExcludes)).sort(
|
|
21048
21414
|
(a, b) => a.localeCompare(b)
|
|
21049
21415
|
);
|
|
@@ -21051,13 +21417,13 @@ async function hashDirectoryContents(rootDirectory, extraExcludes = []) {
|
|
|
21051
21417
|
for (const rel2 of files) {
|
|
21052
21418
|
hash2.update(rel2);
|
|
21053
21419
|
hash2.update("\0");
|
|
21054
|
-
hash2.update(await fs6.readFile(
|
|
21420
|
+
hash2.update(await fs6.readFile(path69.join(resolved, rel2)));
|
|
21055
21421
|
hash2.update("\0");
|
|
21056
21422
|
}
|
|
21057
21423
|
return hash2.digest("hex");
|
|
21058
21424
|
}
|
|
21059
21425
|
async function hashDevPortalSiteSources(siteDirectory, options) {
|
|
21060
|
-
const resolved =
|
|
21426
|
+
const resolved = path69.resolve(siteDirectory);
|
|
21061
21427
|
const hash2 = createHash3("sha256");
|
|
21062
21428
|
const candidates = [
|
|
21063
21429
|
"apitogo.config.json",
|
|
@@ -21067,7 +21433,7 @@ async function hashDevPortalSiteSources(siteDirectory, options) {
|
|
|
21067
21433
|
"zudoku.config.tsx"
|
|
21068
21434
|
];
|
|
21069
21435
|
for (const name of candidates) {
|
|
21070
|
-
const full =
|
|
21436
|
+
const full = path69.join(resolved, name);
|
|
21071
21437
|
try {
|
|
21072
21438
|
hash2.update(name);
|
|
21073
21439
|
hash2.update("\0");
|
|
@@ -21077,7 +21443,7 @@ async function hashDevPortalSiteSources(siteDirectory, options) {
|
|
|
21077
21443
|
}
|
|
21078
21444
|
}
|
|
21079
21445
|
for (const dir of ["pages", "landing", "src"]) {
|
|
21080
|
-
const full =
|
|
21446
|
+
const full = path69.join(resolved, dir);
|
|
21081
21447
|
try {
|
|
21082
21448
|
const st = await fs6.stat(full);
|
|
21083
21449
|
if (!st.isDirectory()) continue;
|
|
@@ -21306,8 +21672,8 @@ function normalizeActionKey(actionKey2) {
|
|
|
21306
21672
|
const trimmed = actionKey2.trim();
|
|
21307
21673
|
if (trimmed.includes(":")) {
|
|
21308
21674
|
const [method2, ...pathParts] = trimmed.split(":");
|
|
21309
|
-
const
|
|
21310
|
-
return `${method2?.toLowerCase()}:${
|
|
21675
|
+
const path101 = pathParts.join(":").trim();
|
|
21676
|
+
return `${method2?.toLowerCase()}:${path101.startsWith("/") ? path101 : `/${path101}`}`;
|
|
21311
21677
|
}
|
|
21312
21678
|
const spaceIndex = trimmed.indexOf(" ");
|
|
21313
21679
|
if (spaceIndex <= 0) {
|
|
@@ -21316,8 +21682,8 @@ function normalizeActionKey(actionKey2) {
|
|
|
21316
21682
|
);
|
|
21317
21683
|
}
|
|
21318
21684
|
const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
|
|
21319
|
-
const
|
|
21320
|
-
return `${method}:${
|
|
21685
|
+
const path100 = trimmed.slice(spaceIndex + 1).trim();
|
|
21686
|
+
return `${method}:${path100.startsWith("/") ? path100 : `/${path100}`}`;
|
|
21321
21687
|
}
|
|
21322
21688
|
async function applyGatewayPublicRoutes(client, projectId, routes, options) {
|
|
21323
21689
|
const applied = [];
|
|
@@ -21796,7 +22162,7 @@ async function upsertGatewayPlansFromManifest(client, config2, projectId, plans,
|
|
|
21796
22162
|
|
|
21797
22163
|
// src/cli/platform/helpers/openapi-gateway-servers.ts
|
|
21798
22164
|
import { mkdir as mkdir17, readFile as readFile25, writeFile as writeFile19 } from "node:fs/promises";
|
|
21799
|
-
import
|
|
22165
|
+
import path70 from "node:path";
|
|
21800
22166
|
import YAML2 from "yaml";
|
|
21801
22167
|
var GATEWAY_URL_ENV_KEY = "APITOGO_GATEWAY_URL";
|
|
21802
22168
|
var PUBLISH_OPENAPI_RELATIVE = ".apitogo/openapi-publish.json";
|
|
@@ -21828,7 +22194,7 @@ async function resolveProjectGatewayUrl(client, projectId) {
|
|
|
21828
22194
|
}
|
|
21829
22195
|
async function readOpenApiDocument(filePath) {
|
|
21830
22196
|
const content = await readFile25(filePath, "utf8");
|
|
21831
|
-
const ext =
|
|
22197
|
+
const ext = path70.extname(filePath).toLowerCase();
|
|
21832
22198
|
const parsed = ext === ".json" ? JSON.parse(content) : YAML2.parse(content);
|
|
21833
22199
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
21834
22200
|
throw new Error(`OpenAPI document must be an object: ${filePath}`);
|
|
@@ -21836,13 +22202,13 @@ async function readOpenApiDocument(filePath) {
|
|
|
21836
22202
|
return parsed;
|
|
21837
22203
|
}
|
|
21838
22204
|
async function materializePublishOpenApiWithGateway(siteDirectory, sourceOpenApiPath, gatewayUrl) {
|
|
21839
|
-
const site =
|
|
21840
|
-
const source =
|
|
22205
|
+
const site = path70.resolve(siteDirectory);
|
|
22206
|
+
const source = path70.resolve(sourceOpenApiPath);
|
|
21841
22207
|
const relativeInput = PUBLISH_OPENAPI_RELATIVE;
|
|
21842
|
-
const outputPath =
|
|
22208
|
+
const outputPath = path70.join(site, ...relativeInput.split("/"));
|
|
21843
22209
|
const doc = await readOpenApiDocument(source);
|
|
21844
22210
|
const rewritten = withGatewayServers(doc, gatewayUrl);
|
|
21845
|
-
await mkdir17(
|
|
22211
|
+
await mkdir17(path70.dirname(outputPath), { recursive: true });
|
|
21846
22212
|
await writeFile19(
|
|
21847
22213
|
outputPath,
|
|
21848
22214
|
`${JSON.stringify(rewritten, null, 2)}
|
|
@@ -21852,8 +22218,8 @@ async function materializePublishOpenApiWithGateway(siteDirectory, sourceOpenApi
|
|
|
21852
22218
|
return { outputPath, relativeInput };
|
|
21853
22219
|
}
|
|
21854
22220
|
async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
|
|
21855
|
-
const configPath =
|
|
21856
|
-
|
|
22221
|
+
const configPath = path70.join(
|
|
22222
|
+
path70.resolve(siteDirectory),
|
|
21857
22223
|
APITOGO_CONFIG_FILENAME2
|
|
21858
22224
|
);
|
|
21859
22225
|
const raw = await readFile25(configPath, "utf8");
|
|
@@ -21895,7 +22261,7 @@ async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
|
|
|
21895
22261
|
};
|
|
21896
22262
|
}
|
|
21897
22263
|
async function prepareOpenApiServersForGatewayBuild(options) {
|
|
21898
|
-
const siteDirectory =
|
|
22264
|
+
const siteDirectory = path70.resolve(options.siteDirectory);
|
|
21899
22265
|
let openApiPath = resolveBackendOpenApiPath(
|
|
21900
22266
|
options.manifest?.backend?.openApiPath,
|
|
21901
22267
|
{
|
|
@@ -21909,7 +22275,7 @@ async function prepareOpenApiServersForGatewayBuild(options) {
|
|
|
21909
22275
|
if (!openApiPath) {
|
|
21910
22276
|
try {
|
|
21911
22277
|
const raw = await readFile25(
|
|
21912
|
-
|
|
22278
|
+
path70.join(siteDirectory, APITOGO_CONFIG_FILENAME2),
|
|
21913
22279
|
"utf8"
|
|
21914
22280
|
);
|
|
21915
22281
|
const config2 = JSON.parse(raw);
|
|
@@ -21938,8 +22304,8 @@ function normalizeActionKeyFormat(actionKey2) {
|
|
|
21938
22304
|
const trimmed = actionKey2.trim();
|
|
21939
22305
|
if (trimmed.includes(":")) {
|
|
21940
22306
|
const [method2, ...pathParts] = trimmed.split(":");
|
|
21941
|
-
const
|
|
21942
|
-
return `${method2.toLowerCase()}:${
|
|
22307
|
+
const path101 = pathParts.join(":").trim();
|
|
22308
|
+
return `${method2.toLowerCase()}:${path101.startsWith("/") ? path101 : `/${path101}`}`;
|
|
21943
22309
|
}
|
|
21944
22310
|
const spaceIndex = trimmed.indexOf(" ");
|
|
21945
22311
|
if (spaceIndex <= 0) {
|
|
@@ -21948,8 +22314,8 @@ function normalizeActionKeyFormat(actionKey2) {
|
|
|
21948
22314
|
);
|
|
21949
22315
|
}
|
|
21950
22316
|
const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
|
|
21951
|
-
const
|
|
21952
|
-
return `${method}:${
|
|
22317
|
+
const path100 = trimmed.slice(spaceIndex + 1).trim();
|
|
22318
|
+
return `${method}:${path100.startsWith("/") ? path100 : `/${path100}`}`;
|
|
21953
22319
|
}
|
|
21954
22320
|
function normalizePublicRoute(route) {
|
|
21955
22321
|
const trimmed = route.trim();
|
|
@@ -21983,10 +22349,10 @@ function collectManifestPublicActionKeys(gateway) {
|
|
|
21983
22349
|
|
|
21984
22350
|
// src/cli/platform/helpers/publish-ledger.ts
|
|
21985
22351
|
import { mkdir as mkdir18, readFile as readFile26, writeFile as writeFile20 } from "node:fs/promises";
|
|
21986
|
-
import
|
|
22352
|
+
import path71 from "node:path";
|
|
21987
22353
|
var PUBLISH_LEDGER_RELATIVE_PATH = ".apitogo/publish-state.json";
|
|
21988
22354
|
function publishLedgerPath(siteDirectory) {
|
|
21989
|
-
return
|
|
22355
|
+
return path71.join(path71.resolve(siteDirectory), PUBLISH_LEDGER_RELATIVE_PATH);
|
|
21990
22356
|
}
|
|
21991
22357
|
async function readPublishLedger(siteDirectory) {
|
|
21992
22358
|
const filePath = publishLedgerPath(siteDirectory);
|
|
@@ -22003,7 +22369,7 @@ async function readPublishLedger(siteDirectory) {
|
|
|
22003
22369
|
}
|
|
22004
22370
|
async function writePublishLedger(siteDirectory, ledger) {
|
|
22005
22371
|
const filePath = publishLedgerPath(siteDirectory);
|
|
22006
|
-
await mkdir18(
|
|
22372
|
+
await mkdir18(path71.dirname(filePath), { recursive: true });
|
|
22007
22373
|
const next = {
|
|
22008
22374
|
...ledger,
|
|
22009
22375
|
version: 1,
|
|
@@ -22524,7 +22890,7 @@ async function createProjectWithWarmPoolRetry(client, body, options) {
|
|
|
22524
22890
|
// src/cli/platform/helpers/backend-packaging.ts
|
|
22525
22891
|
import { mkdtemp as mkdtemp2, readdir as readdir5, rm as rm10 } from "node:fs/promises";
|
|
22526
22892
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
22527
|
-
import
|
|
22893
|
+
import path72 from "node:path";
|
|
22528
22894
|
async function directoryHasRuntimeConfig(dir) {
|
|
22529
22895
|
if (!await pathExists(dir)) {
|
|
22530
22896
|
return false;
|
|
@@ -22566,20 +22932,20 @@ function runDotnetPublish(projectDir, outputDir) {
|
|
|
22566
22932
|
async function findCsproj(projectDir) {
|
|
22567
22933
|
const entries = await readdir5(projectDir);
|
|
22568
22934
|
const csproj = entries.find((name) => name.endsWith(".csproj"));
|
|
22569
|
-
return csproj ?
|
|
22935
|
+
return csproj ? path72.join(projectDir, csproj) : null;
|
|
22570
22936
|
}
|
|
22571
22937
|
async function prepareBackendPackagingDirectory(args) {
|
|
22572
|
-
const sourceDirectory =
|
|
22938
|
+
const sourceDirectory = path72.resolve(args.sourceDirectory);
|
|
22573
22939
|
if (args.publishDirectory?.trim()) {
|
|
22574
22940
|
return {
|
|
22575
|
-
directory:
|
|
22941
|
+
directory: path72.resolve(args.publishDirectory),
|
|
22576
22942
|
packagingMode: "published"
|
|
22577
22943
|
};
|
|
22578
22944
|
}
|
|
22579
22945
|
if (await directoryHasRuntimeConfig(sourceDirectory)) {
|
|
22580
22946
|
return { directory: sourceDirectory, packagingMode: "published" };
|
|
22581
22947
|
}
|
|
22582
|
-
const publishSubdir =
|
|
22948
|
+
const publishSubdir = path72.join(sourceDirectory, "publish");
|
|
22583
22949
|
if (await directoryHasRuntimeConfig(publishSubdir)) {
|
|
22584
22950
|
return { directory: publishSubdir, packagingMode: "published" };
|
|
22585
22951
|
}
|
|
@@ -22591,9 +22957,9 @@ async function prepareBackendPackagingDirectory(args) {
|
|
|
22591
22957
|
return { directory: sourceDirectory, packagingMode: "source" };
|
|
22592
22958
|
}
|
|
22593
22959
|
const tempRoot = await mkdtemp2(
|
|
22594
|
-
|
|
22960
|
+
path72.join(tmpdir2(), "apitogo-dotnet-publish-")
|
|
22595
22961
|
);
|
|
22596
|
-
const outputDir =
|
|
22962
|
+
const outputDir = path72.join(tempRoot, "publish");
|
|
22597
22963
|
const result = await runDotnetPublish(sourceDirectory, outputDir);
|
|
22598
22964
|
if (result.exitCode !== 0) {
|
|
22599
22965
|
await rm10(tempRoot, { recursive: true, force: true });
|
|
@@ -22638,13 +23004,13 @@ function formatJobStatusResponse(options) {
|
|
|
22638
23004
|
|
|
22639
23005
|
// src/cli/platform/helpers/openapi.ts
|
|
22640
23006
|
import { promises as fs7 } from "node:fs";
|
|
22641
|
-
import
|
|
23007
|
+
import path73 from "node:path";
|
|
22642
23008
|
import SwaggerParser from "@apidevtools/swagger-parser";
|
|
22643
23009
|
import YAML3 from "yaml";
|
|
22644
23010
|
async function validateOpenApiFile(filePath) {
|
|
22645
|
-
const resolved =
|
|
23011
|
+
const resolved = path73.resolve(filePath);
|
|
22646
23012
|
const content = await fs7.readFile(resolved, "utf8");
|
|
22647
|
-
const ext =
|
|
23013
|
+
const ext = path73.extname(resolved).toLowerCase();
|
|
22648
23014
|
let parsed;
|
|
22649
23015
|
try {
|
|
22650
23016
|
parsed = ext === ".json" ? JSON.parse(content) : YAML3.parse(content);
|
|
@@ -22688,12 +23054,12 @@ async function validateOpenApiFile(filePath) {
|
|
|
22688
23054
|
// src/cli/platform/helpers/zip.ts
|
|
22689
23055
|
import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, promises as fs8 } from "node:fs";
|
|
22690
23056
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
22691
|
-
import
|
|
23057
|
+
import path74 from "node:path";
|
|
22692
23058
|
import { ZipArchive } from "archiver";
|
|
22693
23059
|
async function packageBackendDirectory(sourceDirectory, extraExcludes = []) {
|
|
22694
|
-
const resolved =
|
|
23060
|
+
const resolved = path74.resolve(sourceDirectory);
|
|
22695
23061
|
const files = await collectPackageableFiles(resolved, extraExcludes);
|
|
22696
|
-
const zipPath =
|
|
23062
|
+
const zipPath = path74.join(
|
|
22697
23063
|
tmpdir3(),
|
|
22698
23064
|
`apitogo-backend-${Date.now()}-${Math.random().toString(36).slice(2)}.zip`
|
|
22699
23065
|
);
|
|
@@ -22705,8 +23071,8 @@ async function packageBackendDirectory(sourceDirectory, extraExcludes = []) {
|
|
|
22705
23071
|
output4.on("error", reject);
|
|
22706
23072
|
archive.pipe(output4);
|
|
22707
23073
|
for (const rel2 of files) {
|
|
22708
|
-
archive.append(createReadStream2(
|
|
22709
|
-
name: rel2.split(
|
|
23074
|
+
archive.append(createReadStream2(path74.join(resolved, rel2)), {
|
|
23075
|
+
name: rel2.split(path74.sep).join("/")
|
|
22710
23076
|
});
|
|
22711
23077
|
}
|
|
22712
23078
|
void archive.finalize();
|
|
@@ -24276,11 +24642,11 @@ async function resolveProjectIdForPublish(client, config2, args, wait, progress,
|
|
|
24276
24642
|
}
|
|
24277
24643
|
|
|
24278
24644
|
// src/cli/platform/tools/dev-portal-site-build.ts
|
|
24279
|
-
import
|
|
24645
|
+
import path78 from "node:path";
|
|
24280
24646
|
|
|
24281
24647
|
// src/cli/platform/helpers/dev-portal-site-api-url.ts
|
|
24282
24648
|
import { readdir as readdir6, readFile as readFile27, writeFile as writeFile21 } from "node:fs/promises";
|
|
24283
|
-
import
|
|
24649
|
+
import path75 from "node:path";
|
|
24284
24650
|
var SITE_API_BASE_URL_ENV_KEY = "VITE_APITOGO_AUTHENTICATION_API_BASE_URL";
|
|
24285
24651
|
var PLACEHOLDER_HOST_MARKERS = [
|
|
24286
24652
|
"dp-example.azurecontainerapps.io",
|
|
@@ -24301,10 +24667,10 @@ function isPlaceholderDevPortalApiUrl(apiBaseUrl) {
|
|
|
24301
24667
|
return PLACEHOLDER_HOST_MARKERS.some((marker) => normalized.includes(marker));
|
|
24302
24668
|
}
|
|
24303
24669
|
async function readSiteApiBaseUrl(sourceDirectory) {
|
|
24304
|
-
const resolved =
|
|
24670
|
+
const resolved = path75.resolve(sourceDirectory);
|
|
24305
24671
|
for (const envFile of [".env", ".env.production"]) {
|
|
24306
24672
|
try {
|
|
24307
|
-
const content = await readFile27(
|
|
24673
|
+
const content = await readFile27(path75.join(resolved, envFile), "utf8");
|
|
24308
24674
|
const lines = [...content.matchAll(ENV_LINE_GLOBAL_RE)];
|
|
24309
24675
|
if (lines.length === 0) {
|
|
24310
24676
|
continue;
|
|
@@ -24329,11 +24695,11 @@ async function readSiteApiBaseUrl(sourceDirectory) {
|
|
|
24329
24695
|
return null;
|
|
24330
24696
|
}
|
|
24331
24697
|
async function patchSiteApiBaseUrl(sourceDirectory, apiBaseUrl) {
|
|
24332
|
-
const resolved =
|
|
24698
|
+
const resolved = path75.resolve(sourceDirectory);
|
|
24333
24699
|
const line2 = `${SITE_API_BASE_URL_ENV_KEY}=${apiBaseUrl}`;
|
|
24334
24700
|
let patchedExisting = false;
|
|
24335
24701
|
for (const envFile of [".env.production", ".env"]) {
|
|
24336
|
-
const envPath =
|
|
24702
|
+
const envPath = path75.join(resolved, envFile);
|
|
24337
24703
|
try {
|
|
24338
24704
|
const content = await readFile27(envPath, "utf8");
|
|
24339
24705
|
const withoutAssignments = content.replace(ENV_LINE_GLOBAL_RE, "").replace(/\n{3,}/g, "\n\n").trimEnd();
|
|
@@ -24347,7 +24713,7 @@ ${line2}
|
|
|
24347
24713
|
}
|
|
24348
24714
|
}
|
|
24349
24715
|
if (!patchedExisting) {
|
|
24350
|
-
await writeFile21(
|
|
24716
|
+
await writeFile21(path75.join(resolved, ".env"), `${line2}
|
|
24351
24717
|
`);
|
|
24352
24718
|
}
|
|
24353
24719
|
}
|
|
@@ -24355,7 +24721,7 @@ function tryProjectId(explicit, manifestProjectId, config2) {
|
|
|
24355
24721
|
return explicit?.trim() || manifestProjectId?.trim() || config2.defaultProjectId?.trim() || void 0;
|
|
24356
24722
|
}
|
|
24357
24723
|
async function ensureLiveSiteApiBaseUrlForBuild(_client, config2, args, resolveFromProject) {
|
|
24358
|
-
const sourceDirectory =
|
|
24724
|
+
const sourceDirectory = path75.resolve(args.sourceDirectory);
|
|
24359
24725
|
const explicit = args.apiBaseUrl?.trim();
|
|
24360
24726
|
if (explicit && !isPlaceholderDevPortalApiUrl(explicit)) {
|
|
24361
24727
|
await patchSiteApiBaseUrl(sourceDirectory, explicit);
|
|
@@ -24391,7 +24757,7 @@ async function* walkFiles(root) {
|
|
|
24391
24757
|
return;
|
|
24392
24758
|
}
|
|
24393
24759
|
for (const entry of entries) {
|
|
24394
|
-
const full =
|
|
24760
|
+
const full = path75.join(root, entry.name);
|
|
24395
24761
|
if (entry.isDirectory()) {
|
|
24396
24762
|
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
24397
24763
|
continue;
|
|
@@ -24403,8 +24769,8 @@ async function* walkFiles(root) {
|
|
|
24403
24769
|
}
|
|
24404
24770
|
}
|
|
24405
24771
|
async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiBaseUrl) {
|
|
24406
|
-
const dist =
|
|
24407
|
-
const siteRoot =
|
|
24772
|
+
const dist = path75.resolve(distDirectory);
|
|
24773
|
+
const siteRoot = path75.dirname(dist);
|
|
24408
24774
|
const fromEnv = expectedApiBaseUrl?.trim() || await readSiteApiBaseUrl(siteRoot) || await readSiteApiBaseUrl(dist);
|
|
24409
24775
|
if (!fromEnv || isPlaceholderDevPortalApiUrl(fromEnv)) {
|
|
24410
24776
|
throw new Error(
|
|
@@ -24440,7 +24806,7 @@ async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiB
|
|
|
24440
24806
|
|
|
24441
24807
|
// src/cli/platform/tools/dev-portal.ts
|
|
24442
24808
|
import { promises as fs10 } from "node:fs";
|
|
24443
|
-
import
|
|
24809
|
+
import path77 from "node:path";
|
|
24444
24810
|
|
|
24445
24811
|
// src/cli/platform/helpers/dev-portal-backend-job.ts
|
|
24446
24812
|
var DEV_PORTAL_BACKEND_UPDATE_RESOURCE_TYPE = "DevPortalBackendUpdate";
|
|
@@ -24550,7 +24916,7 @@ async function snapshotBackendUpdateJobIds(client, projectId) {
|
|
|
24550
24916
|
// src/cli/platform/helpers/tarball.ts
|
|
24551
24917
|
import { createReadStream as createReadStream3, createWriteStream as createWriteStream3, promises as fs9 } from "node:fs";
|
|
24552
24918
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
24553
|
-
import
|
|
24919
|
+
import path76 from "node:path";
|
|
24554
24920
|
import { TarArchive } from "archiver";
|
|
24555
24921
|
var DEV_PORTAL_DEPLOY_ARCHIVE_ROOT = "dist";
|
|
24556
24922
|
function normalizeArchiveRoot(archiveRoot) {
|
|
@@ -24561,10 +24927,10 @@ function normalizeArchiveRoot(archiveRoot) {
|
|
|
24561
24927
|
return `${trimmed}/`;
|
|
24562
24928
|
}
|
|
24563
24929
|
async function packageDirectoryAsTarGz(sourceDirectory, options) {
|
|
24564
|
-
const resolved =
|
|
24930
|
+
const resolved = path76.resolve(sourceDirectory);
|
|
24565
24931
|
const files = await collectPackageableFiles(resolved);
|
|
24566
24932
|
const entryPrefix = options?.archiveRoot ? normalizeArchiveRoot(options.archiveRoot) : "";
|
|
24567
|
-
const archivePath =
|
|
24933
|
+
const archivePath = path76.join(
|
|
24568
24934
|
tmpdir4(),
|
|
24569
24935
|
`apitogo-docs-${Date.now()}-${Math.random().toString(36).slice(2)}.tgz`
|
|
24570
24936
|
);
|
|
@@ -24576,8 +24942,8 @@ async function packageDirectoryAsTarGz(sourceDirectory, options) {
|
|
|
24576
24942
|
output4.on("error", reject);
|
|
24577
24943
|
archive.pipe(output4);
|
|
24578
24944
|
for (const rel2 of files) {
|
|
24579
|
-
const entryName = entryPrefix + rel2.split(
|
|
24580
|
-
archive.append(createReadStream3(
|
|
24945
|
+
const entryName = entryPrefix + rel2.split(path76.sep).join("/");
|
|
24946
|
+
archive.append(createReadStream3(path76.join(resolved, rel2)), {
|
|
24581
24947
|
name: entryName
|
|
24582
24948
|
});
|
|
24583
24949
|
}
|
|
@@ -24819,7 +25185,7 @@ function validateDeployArchiveInput(args) {
|
|
|
24819
25185
|
async function resolveDevPortalArchive(args) {
|
|
24820
25186
|
validateDeployArchiveInput(args);
|
|
24821
25187
|
if (args.archivePath?.trim()) {
|
|
24822
|
-
const archivePath =
|
|
25188
|
+
const archivePath = path77.resolve(args.archivePath.trim());
|
|
24823
25189
|
const stat7 = await fs10.stat(archivePath).catch(() => null);
|
|
24824
25190
|
if (!stat7?.isFile()) {
|
|
24825
25191
|
throw new Error(`archivePath is not a file: ${archivePath}`);
|
|
@@ -24884,7 +25250,7 @@ async function handleDeployDevPortal(client, config2, args, progress) {
|
|
|
24884
25250
|
// src/cli/platform/tools/dev-portal-site-build.ts
|
|
24885
25251
|
async function handleBuildDevPortalSite(client, config2, args, progress) {
|
|
24886
25252
|
const buildProgress = progress?.child("Build dev portal site");
|
|
24887
|
-
const sourceDirectory =
|
|
25253
|
+
const sourceDirectory = path78.resolve(args.sourceDirectory);
|
|
24888
25254
|
await buildProgress?.onStep("Ensuring live portal API URL");
|
|
24889
25255
|
const apiBaseUrl = await ensureLiveSiteApiBaseUrlForBuild(
|
|
24890
25256
|
client,
|
|
@@ -26390,7 +26756,7 @@ function resultLooksFailed(payload) {
|
|
|
26390
26756
|
return parsed.status === "failed" || parsed.status === "blocked";
|
|
26391
26757
|
}
|
|
26392
26758
|
async function apply(argv) {
|
|
26393
|
-
const sourceDirectory =
|
|
26759
|
+
const sourceDirectory = path79.resolve(process.cwd(), argv.dir);
|
|
26394
26760
|
let config2;
|
|
26395
26761
|
try {
|
|
26396
26762
|
config2 = loadConfig();
|
|
@@ -26460,7 +26826,7 @@ async function apply(argv) {
|
|
|
26460
26826
|
if (canPromptInteractively && parsed?.status === "blocked" && parsed.reason === "project_not_found") {
|
|
26461
26827
|
const resolution = await resolveProjectNotFoundInteractively(
|
|
26462
26828
|
parsed,
|
|
26463
|
-
|
|
26829
|
+
path79.basename(sourceDirectory)
|
|
26464
26830
|
);
|
|
26465
26831
|
if (resolution) {
|
|
26466
26832
|
effectiveProjectId = void 0;
|
|
@@ -26480,7 +26846,7 @@ async function apply(argv) {
|
|
|
26480
26846
|
while (canPromptInteractively && parsed?.status === "blocked" && parsed.reason === "project_name_exists") {
|
|
26481
26847
|
const resolution = await resolveProjectNameExistsInteractively(
|
|
26482
26848
|
parsed,
|
|
26483
|
-
effectiveProjectName ??
|
|
26849
|
+
effectiveProjectName ?? path79.basename(sourceDirectory)
|
|
26484
26850
|
);
|
|
26485
26851
|
if (!resolution) {
|
|
26486
26852
|
break;
|
|
@@ -26551,11 +26917,11 @@ async function apply(argv) {
|
|
|
26551
26917
|
}
|
|
26552
26918
|
|
|
26553
26919
|
// src/cli/deploy/command.ts
|
|
26554
|
-
import
|
|
26920
|
+
import path85 from "node:path";
|
|
26555
26921
|
init_invariant();
|
|
26556
26922
|
|
|
26557
26923
|
// src/cli/project/create-handler.ts
|
|
26558
|
-
import
|
|
26924
|
+
import path80 from "node:path";
|
|
26559
26925
|
import open2 from "open";
|
|
26560
26926
|
init_invariant();
|
|
26561
26927
|
|
|
@@ -26869,7 +27235,7 @@ async function createLinkedProject(argv, dir, options = {}) {
|
|
|
26869
27235
|
}
|
|
26870
27236
|
}
|
|
26871
27237
|
async function createProject2(argv) {
|
|
26872
|
-
const dir =
|
|
27238
|
+
const dir = path80.resolve(process.cwd(), argv.dir ?? ".");
|
|
26873
27239
|
if (await isConfigV2(dir)) {
|
|
26874
27240
|
await createLinkedProject(argv, dir);
|
|
26875
27241
|
return;
|
|
@@ -26929,7 +27295,7 @@ async function createProject2(argv) {
|
|
|
26929
27295
|
}
|
|
26930
27296
|
|
|
26931
27297
|
// src/cli/secrets/handler.ts
|
|
26932
|
-
import
|
|
27298
|
+
import path81 from "node:path";
|
|
26933
27299
|
init_invariant();
|
|
26934
27300
|
|
|
26935
27301
|
// src/cli/secrets/input.ts
|
|
@@ -26994,7 +27360,7 @@ var SecretsError = class extends ApitogoError {
|
|
|
26994
27360
|
async function resolveProjectId2(argv, deps) {
|
|
26995
27361
|
const explicit = argv.projectId?.trim();
|
|
26996
27362
|
if (explicit) return explicit;
|
|
26997
|
-
const dir =
|
|
27363
|
+
const dir = path81.resolve(process.cwd(), argv.dir ?? ".");
|
|
26998
27364
|
if (await isConfigV2(dir)) {
|
|
26999
27365
|
const id = loadConfigV2(dir).resolved.project.id;
|
|
27000
27366
|
if (id) return id;
|
|
@@ -27079,7 +27445,7 @@ var KNOWN_SECRET_PLACES = {
|
|
|
27079
27445
|
async function wireKnownSecret(argv, name) {
|
|
27080
27446
|
const place = KNOWN_SECRET_PLACES[name.toUpperCase()];
|
|
27081
27447
|
if (!place) return void 0;
|
|
27082
|
-
const dir =
|
|
27448
|
+
const dir = path81.resolve(process.cwd(), argv.dir ?? ".");
|
|
27083
27449
|
if (!await isConfigV2(dir)) return void 0;
|
|
27084
27450
|
const project = await openConfigProject(dir);
|
|
27085
27451
|
const plans = project.resolved.plans;
|
|
@@ -27140,7 +27506,7 @@ async function secrets(argv) {
|
|
|
27140
27506
|
}
|
|
27141
27507
|
|
|
27142
27508
|
// src/cli/deploy/stripe-key.ts
|
|
27143
|
-
import
|
|
27509
|
+
import path82 from "node:path";
|
|
27144
27510
|
init_invariant();
|
|
27145
27511
|
var StripeKeyError = class extends ApitogoError {
|
|
27146
27512
|
constructor(message, developerHint) {
|
|
@@ -27158,7 +27524,7 @@ async function ensureStripeKey(argv, deps) {
|
|
|
27158
27524
|
if (!wantsPlans(argv.only)) return { status: "not-needed" };
|
|
27159
27525
|
let resolved;
|
|
27160
27526
|
try {
|
|
27161
|
-
resolved = loadConfigV2(
|
|
27527
|
+
resolved = loadConfigV2(path82.resolve(process.cwd(), argv.dir)).resolved;
|
|
27162
27528
|
} catch {
|
|
27163
27529
|
return { status: "not-needed" };
|
|
27164
27530
|
}
|
|
@@ -28095,7 +28461,7 @@ init_invariant();
|
|
|
28095
28461
|
|
|
28096
28462
|
// src/cli/portal/report.ts
|
|
28097
28463
|
import { access as access9 } from "node:fs/promises";
|
|
28098
|
-
import
|
|
28464
|
+
import path83 from "node:path";
|
|
28099
28465
|
|
|
28100
28466
|
// src/cli/deploy/identity.ts
|
|
28101
28467
|
init_invariant();
|
|
@@ -28866,7 +29232,7 @@ async function planPortalService(resolved, ledger) {
|
|
|
28866
29232
|
const hash2 = await portalBuildHash(resolved, prepared);
|
|
28867
29233
|
const previous = stepOf(ledger, "portal", "build");
|
|
28868
29234
|
const built = await exists5(
|
|
28869
|
-
|
|
29235
|
+
path83.join(resolved.state.buildDir, "index.html")
|
|
28870
29236
|
);
|
|
28871
29237
|
if (previous?.status === "succeeded" && previous.hash === hash2 && built) {
|
|
28872
29238
|
return {
|
|
@@ -29252,7 +29618,7 @@ async function statusV2(dir, only, options = {}) {
|
|
|
29252
29618
|
if (service === "portal") {
|
|
29253
29619
|
const build2 = stepOf(ledger, "portal", "build");
|
|
29254
29620
|
const built = await exists5(
|
|
29255
|
-
|
|
29621
|
+
path83.join(resolved.state.buildDir, "index.html")
|
|
29256
29622
|
);
|
|
29257
29623
|
const state = build2?.status === "failed" ? "build-failed" : build2?.status === "succeeded" && built ? "built" : "not-built";
|
|
29258
29624
|
services.push({
|
|
@@ -29263,7 +29629,7 @@ async function statusV2(dir, only, options = {}) {
|
|
|
29263
29629
|
...build2?.finishedAt ? [`last build: ${build2.finishedAt}`] : [],
|
|
29264
29630
|
...build2?.status === "failed" ? [`error: ${build2.error ?? "unknown"}`] : [],
|
|
29265
29631
|
...state === "built" ? [
|
|
29266
|
-
`output: ${
|
|
29632
|
+
`output: ${path83.relative(resolved.configDir, resolved.state.buildDir)}`
|
|
29267
29633
|
] : [],
|
|
29268
29634
|
...url2 ? [`url: ${url2}`] : ["url: not known (portal is not deployed yet)"],
|
|
29269
29635
|
...await hostingLine(resolved, manifest, options.hostingRemote)
|
|
@@ -29330,7 +29696,7 @@ function formatStatus(output4) {
|
|
|
29330
29696
|
|
|
29331
29697
|
// src/cli/deploy/static-web-config.ts
|
|
29332
29698
|
import { access as access10, writeFile as writeFile22 } from "node:fs/promises";
|
|
29333
|
-
import
|
|
29699
|
+
import path84 from "node:path";
|
|
29334
29700
|
var STATIC_WEB_CONFIG_FILE = "staticwebapp.config.json";
|
|
29335
29701
|
var STATIC_WEB_CONFIG_VERSION = 3;
|
|
29336
29702
|
var CLIENT_ONLY_ROUTES = [
|
|
@@ -29348,7 +29714,7 @@ var DEFAULT_STATIC_WEB_CONFIG = {
|
|
|
29348
29714
|
}
|
|
29349
29715
|
};
|
|
29350
29716
|
async function ensureStaticWebConfig(buildDir) {
|
|
29351
|
-
const file =
|
|
29717
|
+
const file = path84.join(buildDir, STATIC_WEB_CONFIG_FILE);
|
|
29352
29718
|
try {
|
|
29353
29719
|
await access10(file);
|
|
29354
29720
|
return false;
|
|
@@ -29703,7 +30069,7 @@ function formatDeploy(output4) {
|
|
|
29703
30069
|
// src/cli/deploy/command.ts
|
|
29704
30070
|
async function ensureLinkedProject(argv, deps) {
|
|
29705
30071
|
if (argv.projectId?.trim() || deps.envProjectId?.trim()) return true;
|
|
29706
|
-
const dir =
|
|
30072
|
+
const dir = path85.resolve(process.cwd(), argv.dir);
|
|
29707
30073
|
let linked;
|
|
29708
30074
|
try {
|
|
29709
30075
|
linked = Boolean(loadConfigV2(dir).resolved.project.id);
|
|
@@ -29754,7 +30120,7 @@ async function deployProject(argv) {
|
|
|
29754
30120
|
try {
|
|
29755
30121
|
const config2 = loadConfig();
|
|
29756
30122
|
const client = new PlatformApiClient(config2);
|
|
29757
|
-
const dir =
|
|
30123
|
+
const dir = path85.resolve(process.cwd(), argv.dir);
|
|
29758
30124
|
const deploy = (only) => deployV2(
|
|
29759
30125
|
{
|
|
29760
30126
|
dir,
|
|
@@ -29862,7 +30228,7 @@ var deploy_default = {
|
|
|
29862
30228
|
}),
|
|
29863
30229
|
handler: async (argv) => {
|
|
29864
30230
|
await captureEvent({ argv, event: "apitogo deploy" });
|
|
29865
|
-
if (!await isLegacyConfig(
|
|
30231
|
+
if (!await isLegacyConfig(path86.resolve(process.cwd(), argv.dir))) {
|
|
29866
30232
|
await deployProject(argv);
|
|
29867
30233
|
return;
|
|
29868
30234
|
}
|
|
@@ -29872,7 +30238,7 @@ var deploy_default = {
|
|
|
29872
30238
|
|
|
29873
30239
|
// src/cli/export/handler.ts
|
|
29874
30240
|
import { mkdir as mkdir19, writeFile as writeFile23 } from "node:fs/promises";
|
|
29875
|
-
import
|
|
30241
|
+
import path87 from "node:path";
|
|
29876
30242
|
init_invariant();
|
|
29877
30243
|
var ExportError = class extends ApitogoError {
|
|
29878
30244
|
constructor(message, developerHint) {
|
|
@@ -29886,7 +30252,7 @@ async function exportOpenApi(args, deps) {
|
|
|
29886
30252
|
`Cannot export "${args.target}".`,
|
|
29887
30253
|
"Only `apitogo export openapi` exists."
|
|
29888
30254
|
);
|
|
29889
|
-
const dir =
|
|
30255
|
+
const dir = path87.resolve(process.cwd(), args.dir ?? ".");
|
|
29890
30256
|
if (!await isConfigV2(dir))
|
|
29891
30257
|
throw new ExportError(
|
|
29892
30258
|
"This command needs a config version 2 project.",
|
|
@@ -29911,8 +30277,8 @@ async function exportOpenApi(args, deps) {
|
|
|
29911
30277
|
throw error;
|
|
29912
30278
|
}
|
|
29913
30279
|
if (!args.out) return { text: text2 };
|
|
29914
|
-
const file =
|
|
29915
|
-
await mkdir19(
|
|
30280
|
+
const file = path87.resolve(process.cwd(), args.out);
|
|
30281
|
+
await mkdir19(path87.dirname(file), { recursive: true });
|
|
29916
30282
|
await writeFile23(file, text2);
|
|
29917
30283
|
return { text: text2, file };
|
|
29918
30284
|
}
|
|
@@ -30005,8 +30371,8 @@ import open3 from "open";
|
|
|
30005
30371
|
import colors14 from "picocolors";
|
|
30006
30372
|
|
|
30007
30373
|
// src/cli/platform/device-auth.ts
|
|
30008
|
-
function url(apiUrl,
|
|
30009
|
-
return `${apiUrl}${
|
|
30374
|
+
function url(apiUrl, path100) {
|
|
30375
|
+
return `${apiUrl}${path100.startsWith("/") ? path100 : `/${path100}`}`;
|
|
30010
30376
|
}
|
|
30011
30377
|
async function requestDeviceCode(apiUrl) {
|
|
30012
30378
|
const response = await fetchWithRetry(
|
|
@@ -30188,7 +30554,7 @@ var logout_default = {
|
|
|
30188
30554
|
};
|
|
30189
30555
|
|
|
30190
30556
|
// src/cli/portal/commands.ts
|
|
30191
|
-
import
|
|
30557
|
+
import path88 from "node:path";
|
|
30192
30558
|
init_invariant();
|
|
30193
30559
|
function parseOnly(value) {
|
|
30194
30560
|
if (value === void 0) return void 0;
|
|
@@ -30205,7 +30571,7 @@ function parseOnly(value) {
|
|
|
30205
30571
|
async function run2(command2, argv, compute, format) {
|
|
30206
30572
|
const json = argv.json === true;
|
|
30207
30573
|
try {
|
|
30208
|
-
const dir =
|
|
30574
|
+
const dir = path88.resolve(process.cwd(), argv.dir ?? ".");
|
|
30209
30575
|
if (!await isConfigV2(dir)) {
|
|
30210
30576
|
throw new ServiceEditError(
|
|
30211
30577
|
`${command2} works with a config version 2 project, and there is none in ${dir}.`,
|
|
@@ -30567,14 +30933,14 @@ var remove_default = {
|
|
|
30567
30933
|
|
|
30568
30934
|
// src/cli/dev/handler.ts
|
|
30569
30935
|
init_joinUrl();
|
|
30570
|
-
import
|
|
30936
|
+
import path91 from "node:path";
|
|
30571
30937
|
|
|
30572
30938
|
// src/vite/dev-server.ts
|
|
30573
30939
|
init_logger();
|
|
30574
30940
|
import fs11 from "node:fs/promises";
|
|
30575
30941
|
import http from "node:http";
|
|
30576
30942
|
import https from "node:https";
|
|
30577
|
-
import
|
|
30943
|
+
import path90 from "node:path";
|
|
30578
30944
|
import { createHttpTerminator } from "http-terminator";
|
|
30579
30945
|
import {
|
|
30580
30946
|
createServer as createViteServer,
|
|
@@ -30619,7 +30985,7 @@ function withSsrGraphParts(config2, ssrConfig) {
|
|
|
30619
30985
|
// src/vite/pagefind-dev-index.ts
|
|
30620
30986
|
init_invariant();
|
|
30621
30987
|
init_joinUrl();
|
|
30622
|
-
import
|
|
30988
|
+
import path89 from "node:path";
|
|
30623
30989
|
import { createIndex as createIndex2 } from "pagefind";
|
|
30624
30990
|
import { isRunnableDevEnvironment } from "vite";
|
|
30625
30991
|
async function* buildPagefindDevIndex(vite, config2) {
|
|
@@ -30672,7 +31038,7 @@ async function* buildPagefindDevIndex(vite, config2) {
|
|
|
30672
31038
|
path: urlPath
|
|
30673
31039
|
};
|
|
30674
31040
|
}
|
|
30675
|
-
const outputPath =
|
|
31041
|
+
const outputPath = path89.join(vite.config.publicDir, "pagefind");
|
|
30676
31042
|
await pagefindIndex.writeFiles({ outputPath });
|
|
30677
31043
|
yield { type: "complete", success: true, indexed };
|
|
30678
31044
|
}
|
|
@@ -30691,9 +31057,9 @@ var DevServer = class {
|
|
|
30691
31057
|
this.protocol = "https";
|
|
30692
31058
|
const { dir } = this.options;
|
|
30693
31059
|
const [key, cert, ca] = await Promise.all([
|
|
30694
|
-
fs11.readFile(
|
|
30695
|
-
fs11.readFile(
|
|
30696
|
-
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
|
|
30697
31063
|
]);
|
|
30698
31064
|
return https.createServer({ key, cert, ca });
|
|
30699
31065
|
}
|
|
@@ -30710,7 +31076,7 @@ var DevServer = class {
|
|
|
30710
31076
|
);
|
|
30711
31077
|
const server = await this.createNodeServer(config2);
|
|
30712
31078
|
if (config2.search?.type === "pagefind" && viteConfig.publicDir !== false) {
|
|
30713
|
-
const publicRoot =
|
|
31079
|
+
const publicRoot = path90.resolve(
|
|
30714
31080
|
this.options.dir,
|
|
30715
31081
|
typeof viteConfig.publicDir === "string" ? viteConfig.publicDir : "public"
|
|
30716
31082
|
);
|
|
@@ -30727,7 +31093,7 @@ var DevServer = class {
|
|
|
30727
31093
|
// built-in transform middleware which would treat the path as a static asset.
|
|
30728
31094
|
name: "apitogo:entry-client",
|
|
30729
31095
|
configureServer(server2) {
|
|
30730
|
-
const entryPath =
|
|
31096
|
+
const entryPath = path90.posix.join(
|
|
30731
31097
|
server2.config.base,
|
|
30732
31098
|
"/__z/entry.client.tsx"
|
|
30733
31099
|
);
|
|
@@ -30895,7 +31261,7 @@ init_package_json();
|
|
|
30895
31261
|
async function dev(argv) {
|
|
30896
31262
|
const packageJson3 = getZudokuPackageJson();
|
|
30897
31263
|
process.env.NODE_ENV = "development";
|
|
30898
|
-
let dir =
|
|
31264
|
+
let dir = path91.resolve(process.cwd(), argv.dir);
|
|
30899
31265
|
if (await isConfigV2(dir)) {
|
|
30900
31266
|
const { root, prepared } = await preparePortalWorkspace(dir, "development");
|
|
30901
31267
|
dir = root;
|
|
@@ -31030,12 +31396,12 @@ var secrets_default = {
|
|
|
31030
31396
|
};
|
|
31031
31397
|
|
|
31032
31398
|
// src/cli/cmds/status.ts
|
|
31033
|
-
import
|
|
31399
|
+
import path93 from "node:path";
|
|
31034
31400
|
|
|
31035
31401
|
// src/cli/status/handler.ts
|
|
31036
|
-
import
|
|
31402
|
+
import path92 from "node:path";
|
|
31037
31403
|
async function status(argv) {
|
|
31038
|
-
const sourceDirectory =
|
|
31404
|
+
const sourceDirectory = path92.resolve(process.cwd(), argv.dir);
|
|
31039
31405
|
let config2;
|
|
31040
31406
|
try {
|
|
31041
31407
|
config2 = loadConfig();
|
|
@@ -31161,7 +31527,7 @@ var status_default = {
|
|
|
31161
31527
|
}),
|
|
31162
31528
|
handler: async (argv) => {
|
|
31163
31529
|
await captureEvent({ argv, event: "apitogo status" });
|
|
31164
|
-
if (await isConfigV2(
|
|
31530
|
+
if (await isConfigV2(path93.resolve(process.cwd(), argv.dir))) {
|
|
31165
31531
|
await statusOfProject(argv);
|
|
31166
31532
|
return;
|
|
31167
31533
|
}
|
|
@@ -31170,11 +31536,11 @@ var status_default = {
|
|
|
31170
31536
|
};
|
|
31171
31537
|
|
|
31172
31538
|
// src/cli/cmds/teardown.ts
|
|
31173
|
-
import
|
|
31539
|
+
import path96 from "node:path";
|
|
31174
31540
|
|
|
31175
31541
|
// src/cli/teardown/command.ts
|
|
31176
31542
|
init_invariant();
|
|
31177
|
-
import
|
|
31543
|
+
import path94 from "node:path";
|
|
31178
31544
|
import { createInterface as createInterface7 } from "node:readline/promises";
|
|
31179
31545
|
|
|
31180
31546
|
// src/cli/teardown/v2.ts
|
|
@@ -31535,7 +31901,7 @@ async function teardownProject(argv) {
|
|
|
31535
31901
|
const progress = createConsoleProgressReporter();
|
|
31536
31902
|
const result = await teardownV2(
|
|
31537
31903
|
{
|
|
31538
|
-
dir:
|
|
31904
|
+
dir: path94.resolve(process.cwd(), argv.dir),
|
|
31539
31905
|
projectId: argv.projectId,
|
|
31540
31906
|
only: Array.isArray(argv.only) ? argv.only.join(",") : argv.only,
|
|
31541
31907
|
yes: argv.yes === true,
|
|
@@ -31594,7 +31960,7 @@ async function teardownProject(argv) {
|
|
|
31594
31960
|
}
|
|
31595
31961
|
|
|
31596
31962
|
// src/cli/teardown/handler.ts
|
|
31597
|
-
import
|
|
31963
|
+
import path95 from "node:path";
|
|
31598
31964
|
function resultLooksFailed3(payload) {
|
|
31599
31965
|
try {
|
|
31600
31966
|
const parsed = JSON.parse(payload);
|
|
@@ -31610,7 +31976,7 @@ async function teardown(argv) {
|
|
|
31610
31976
|
);
|
|
31611
31977
|
return;
|
|
31612
31978
|
}
|
|
31613
|
-
const sourceDirectory =
|
|
31979
|
+
const sourceDirectory = path95.resolve(process.cwd(), argv.dir);
|
|
31614
31980
|
let config2;
|
|
31615
31981
|
try {
|
|
31616
31982
|
config2 = loadConfig();
|
|
@@ -31688,7 +32054,7 @@ var teardown_default = {
|
|
|
31688
32054
|
}),
|
|
31689
32055
|
handler: async (argv) => {
|
|
31690
32056
|
await captureEvent({ argv, event: "apitogo teardown" });
|
|
31691
|
-
if (!await isLegacyConfig(
|
|
32057
|
+
if (!await isLegacyConfig(path96.resolve(process.cwd(), argv.dir))) {
|
|
31692
32058
|
await teardownProject(argv);
|
|
31693
32059
|
return;
|
|
31694
32060
|
}
|
|
@@ -31698,7 +32064,7 @@ var teardown_default = {
|
|
|
31698
32064
|
|
|
31699
32065
|
// src/cli/teardown/reset-command.ts
|
|
31700
32066
|
init_invariant();
|
|
31701
|
-
import
|
|
32067
|
+
import path97 from "node:path";
|
|
31702
32068
|
|
|
31703
32069
|
// src/cli/teardown/reset.ts
|
|
31704
32070
|
init_invariant();
|
|
@@ -31821,7 +32187,7 @@ async function resetProject(argv) {
|
|
|
31821
32187
|
const config2 = loadConfig();
|
|
31822
32188
|
const result = await resetProjectV2(
|
|
31823
32189
|
{
|
|
31824
|
-
dir:
|
|
32190
|
+
dir: path97.resolve(process.cwd(), argv.dir),
|
|
31825
32191
|
projectId: argv.projectId,
|
|
31826
32192
|
yes: argv.yes === true
|
|
31827
32193
|
},
|
|
@@ -31885,7 +32251,7 @@ var test_reset_default = {
|
|
|
31885
32251
|
};
|
|
31886
32252
|
|
|
31887
32253
|
// src/cli/test-sign-in/handler.ts
|
|
31888
|
-
import
|
|
32254
|
+
import path98 from "node:path";
|
|
31889
32255
|
init_invariant();
|
|
31890
32256
|
var TestSignInError = class extends ApitogoError {
|
|
31891
32257
|
constructor(message, developerHint) {
|
|
@@ -31896,7 +32262,7 @@ var TestSignInError = class extends ApitogoError {
|
|
|
31896
32262
|
async function resolveProjectId3(argv) {
|
|
31897
32263
|
const explicit = argv.projectId?.trim();
|
|
31898
32264
|
if (explicit) return explicit;
|
|
31899
|
-
const dir =
|
|
32265
|
+
const dir = path98.resolve(process.cwd(), argv.dir ?? ".");
|
|
31900
32266
|
if (await isConfigV2(dir)) {
|
|
31901
32267
|
const id = loadConfigV2(dir).resolved.project.id;
|
|
31902
32268
|
if (id) return id;
|
|
@@ -32036,36 +32402,36 @@ function createApitogoCli(argv) {
|
|
|
32036
32402
|
// src/cli/local-handoff.ts
|
|
32037
32403
|
import { spawn as spawn2 } from "node:child_process";
|
|
32038
32404
|
import { existsSync as existsSync9, realpathSync as realpathSync2 } from "node:fs";
|
|
32039
|
-
import
|
|
32405
|
+
import path99 from "node:path";
|
|
32040
32406
|
var LOCAL_HANDOFF_ENV = "APITOGO_LOCAL_CLI";
|
|
32041
32407
|
var PACKAGE_NAME = "@lukoweb/apitogo";
|
|
32042
32408
|
var resolveProjectDir = (argv, cwd) => {
|
|
32043
32409
|
for (let i = 0; i < argv.length; i++) {
|
|
32044
32410
|
const arg = argv[i];
|
|
32045
32411
|
const next = argv[i + 1];
|
|
32046
|
-
if (arg === "--dir" && next) return
|
|
32412
|
+
if (arg === "--dir" && next) return path99.resolve(cwd, next);
|
|
32047
32413
|
if (arg?.startsWith("--dir=")) {
|
|
32048
|
-
return
|
|
32414
|
+
return path99.resolve(cwd, arg.slice("--dir=".length));
|
|
32049
32415
|
}
|
|
32050
32416
|
}
|
|
32051
32417
|
return cwd;
|
|
32052
32418
|
};
|
|
32053
32419
|
var findLocalCli = (projectDir, runningRoot) => {
|
|
32054
|
-
let dir =
|
|
32420
|
+
let dir = path99.resolve(projectDir);
|
|
32055
32421
|
let localPackageRoot;
|
|
32056
32422
|
while (!localPackageRoot) {
|
|
32057
|
-
const candidate =
|
|
32058
|
-
if (existsSync9(
|
|
32423
|
+
const candidate = path99.join(dir, "node_modules", PACKAGE_NAME);
|
|
32424
|
+
if (existsSync9(path99.join(candidate, "package.json"))) {
|
|
32059
32425
|
localPackageRoot = candidate;
|
|
32060
|
-
} else if (dir ===
|
|
32426
|
+
} else if (dir === path99.dirname(dir)) {
|
|
32061
32427
|
return void 0;
|
|
32062
32428
|
} else {
|
|
32063
|
-
dir =
|
|
32429
|
+
dir = path99.dirname(dir);
|
|
32064
32430
|
}
|
|
32065
32431
|
}
|
|
32066
32432
|
const localRoot = realpathSync2(localPackageRoot);
|
|
32067
32433
|
if (localRoot === realpathSync2(runningRoot)) return void 0;
|
|
32068
|
-
return
|
|
32434
|
+
return path99.join(localRoot, "cli.js");
|
|
32069
32435
|
};
|
|
32070
32436
|
var handoffToLocalCli = async (argv, runningRoot) => {
|
|
32071
32437
|
if (process.env[LOCAL_HANDOFF_ENV] || process.env.ZUDOKU_ENV === "internal") {
|
|
@@ -32077,7 +32443,7 @@ var handoffToLocalCli = async (argv, runningRoot) => {
|
|
|
32077
32443
|
);
|
|
32078
32444
|
if (!localCli) return void 0;
|
|
32079
32445
|
printDiagnosticsToConsole(
|
|
32080
|
-
`Using the project's local ${PACKAGE_NAME} (${
|
|
32446
|
+
`Using the project's local ${PACKAGE_NAME} (${path99.dirname(localCli)})`
|
|
32081
32447
|
);
|
|
32082
32448
|
const child = spawn2(process.execPath, [localCli, ...argv], {
|
|
32083
32449
|
stdio: "inherit",
|