@lukoweb/apitogo 0.2.47 → 0.2.50
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 +1034 -761
- package/docs/cli/shape.md +11 -10
- package/docs/cli/walkthrough.md +14 -25
- package/docs/configuration/make-config.mdx +16 -12
- package/docs/configuration/navigation.mdx +1 -1
- package/docs/guides/custom-pages.md +33 -4
- package/package.json +1 -1
- package/src/config/v2/__fixtures__/scenario-a-docs-only.json +6 -6
- package/src/config/v2/__fixtures__/scenario-b-managed-origin.json +14 -14
- package/src/config/v2/__fixtures__/scenario-c-proxy-oidc.json +15 -15
- package/src/config/v2/__fixtures__/scenario-h-full-stack.json +28 -28
- package/src/config/v2/billing.ts +59 -0
- package/src/config/v2/docs-navigation.ts +95 -72
- package/src/config/v2/errors.ts +42 -42
- package/src/config/v2/gateway-reference.ts +220 -220
- package/src/config/v2/gateway-request.ts +123 -123
- package/src/config/v2/index.ts +8 -0
- package/src/config/v2/layout.ts +237 -237
- package/src/config/v2/load.ts +70 -70
- package/src/config/v2/parse.ts +214 -214
- package/src/config/v2/portal-profile.ts +88 -88
- package/src/config/v2/resolve.ts +6 -1
- package/src/config/v2/rules.ts +31 -16
- package/src/config/v2/services.ts +5 -20
- package/src/config/v2/tsx-pages.ts +100 -0
- package/src/config/v2/workspace.ts +5 -0
- package/src/config/v2/wrapper.ts +88 -9
package/dist/cli/cli.js
CHANGED
|
@@ -757,12 +757,12 @@ var init_transform_config = __esm({
|
|
|
757
757
|
|
|
758
758
|
// src/config/apitogo-config-loader.node.ts
|
|
759
759
|
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
|
|
760
|
-
import
|
|
760
|
+
import path18 from "node:path";
|
|
761
761
|
function loadApitogoConfig(rootDir = process.cwd()) {
|
|
762
|
-
const configPath =
|
|
762
|
+
const configPath = path18.join(path18.resolve(rootDir), APITOGO_CONFIG_FILENAME);
|
|
763
763
|
if (!existsSync3(configPath)) {
|
|
764
764
|
throw new Error(
|
|
765
|
-
`Missing ${APITOGO_CONFIG_FILENAME} in ${
|
|
765
|
+
`Missing ${APITOGO_CONFIG_FILENAME} in ${path18.resolve(rootDir)}`
|
|
766
766
|
);
|
|
767
767
|
}
|
|
768
768
|
const raw = readFileSync3(configPath, "utf8");
|
|
@@ -837,7 +837,7 @@ import { stat as stat4 } from "node:fs/promises";
|
|
|
837
837
|
var fileExists;
|
|
838
838
|
var init_file_exists = __esm({
|
|
839
839
|
"src/config/file-exists.ts"() {
|
|
840
|
-
fileExists = (
|
|
840
|
+
fileExists = (path97) => stat4(path97).then(() => true).catch(() => false);
|
|
841
841
|
}
|
|
842
842
|
});
|
|
843
843
|
|
|
@@ -1095,7 +1095,7 @@ var init_landing_manifest = __esm({
|
|
|
1095
1095
|
});
|
|
1096
1096
|
|
|
1097
1097
|
// src/config/local-manifest.ts
|
|
1098
|
-
import
|
|
1098
|
+
import path19 from "node:path";
|
|
1099
1099
|
import { z as z7 } from "zod";
|
|
1100
1100
|
function isPricingEnabled(manifest) {
|
|
1101
1101
|
return manifest?.pricing?.enabled === true;
|
|
@@ -1148,8 +1148,8 @@ function resolveManifestEnv(viteMode) {
|
|
|
1148
1148
|
return viteMode === "production" ? "production" : "development";
|
|
1149
1149
|
}
|
|
1150
1150
|
function manifestPathsForEnv(rootDir, _env) {
|
|
1151
|
-
const resolvedRoot =
|
|
1152
|
-
const configPath =
|
|
1151
|
+
const resolvedRoot = path19.resolve(rootDir);
|
|
1152
|
+
const configPath = path19.join(resolvedRoot, APITOGO_CONFIG_FILENAME);
|
|
1153
1153
|
return {
|
|
1154
1154
|
basePath: configPath,
|
|
1155
1155
|
overridePath: configPath,
|
|
@@ -1841,7 +1841,7 @@ var init_shadcn_registry = __esm({
|
|
|
1841
1841
|
|
|
1842
1842
|
// src/vite/plugin-theme.ts
|
|
1843
1843
|
import { createRequire } from "node:module";
|
|
1844
|
-
import
|
|
1844
|
+
import path20 from "node:path";
|
|
1845
1845
|
import { normalizeTheme } from "shiki";
|
|
1846
1846
|
var THEME_VARIABLES, uncamelize, processColorValue, generateCss, generateRegistryCss, processCustomCss, MAIN_REPLACE, DEFAULT_THEME_REPLACE, GOOGLE_FONTS, getGoogleFontUrl, processFont, processFontConfig, bundledFont, DEFAULT_FONT_SANS, DEFAULT_FONT_MONO, DEFAULT_FONT_HEADING, processFonts, MODULE_SOURCE_PACKAGES, resolveModuleSourceDirs, virtualModuleId, resolvedVirtualModuleId, viteThemePlugin;
|
|
1847
1847
|
var init_plugin_theme = __esm({
|
|
@@ -1956,11 +1956,11 @@ var init_plugin_theme = __esm({
|
|
|
1956
1956
|
};
|
|
1957
1957
|
};
|
|
1958
1958
|
bundledFont = (pkg) => {
|
|
1959
|
-
const dir =
|
|
1959
|
+
const dir = path20.dirname(
|
|
1960
1960
|
createRequire(import.meta.url).resolve(`@fontsource/${pkg}/package.json`)
|
|
1961
1961
|
);
|
|
1962
1962
|
return [400, 500, 600, 700].map(
|
|
1963
|
-
(weight) =>
|
|
1963
|
+
(weight) => path20.join(dir, `latin-${weight}.css`).split(path20.sep).join("/")
|
|
1964
1964
|
);
|
|
1965
1965
|
};
|
|
1966
1966
|
DEFAULT_FONT_SANS = '"IBM Plex Sans", system-ui, sans-serif';
|
|
@@ -2029,7 +2029,7 @@ var init_plugin_theme = __esm({
|
|
|
2029
2029
|
resolveModuleSourceDirs = (config2) => {
|
|
2030
2030
|
if (config2.__meta.mode === "internal") {
|
|
2031
2031
|
return MODULE_SOURCE_PACKAGES.map(
|
|
2032
|
-
(pkg) =>
|
|
2032
|
+
(pkg) => path20.join(
|
|
2033
2033
|
config2.__meta.moduleDir,
|
|
2034
2034
|
"..",
|
|
2035
2035
|
pkg.replace("@lukoweb/apitogo-", ""),
|
|
@@ -2038,12 +2038,12 @@ var init_plugin_theme = __esm({
|
|
|
2038
2038
|
);
|
|
2039
2039
|
}
|
|
2040
2040
|
const require2 = createRequire(
|
|
2041
|
-
|
|
2041
|
+
path20.join(config2.__meta.rootDir, "package.json")
|
|
2042
2042
|
);
|
|
2043
2043
|
const dirs = [];
|
|
2044
2044
|
for (const pkg of MODULE_SOURCE_PACKAGES) {
|
|
2045
2045
|
try {
|
|
2046
|
-
dirs.push(
|
|
2046
|
+
dirs.push(path20.dirname(require2.resolve(pkg)));
|
|
2047
2047
|
} catch {
|
|
2048
2048
|
}
|
|
2049
2049
|
}
|
|
@@ -2170,7 +2170,7 @@ ${rootVars.join("\n")}
|
|
|
2170
2170
|
...config2.__meta.dependencies,
|
|
2171
2171
|
...config2.__pluginDirs ?? [],
|
|
2172
2172
|
...resolveModuleSourceDirs(config2)
|
|
2173
|
-
].map((file) =>
|
|
2173
|
+
].map((file) => path20.relative(path20.dirname(id), file))
|
|
2174
2174
|
);
|
|
2175
2175
|
const code = [...files].map((file) => `@source "${file}";`);
|
|
2176
2176
|
code.push("@theme inline {");
|
|
@@ -5012,7 +5012,7 @@ var init_ZudokuConfig = __esm({
|
|
|
5012
5012
|
|
|
5013
5013
|
// src/config/loader.ts
|
|
5014
5014
|
import { stat as stat5 } from "node:fs/promises";
|
|
5015
|
-
import
|
|
5015
|
+
import path21 from "node:path";
|
|
5016
5016
|
import colors6 from "picocolors";
|
|
5017
5017
|
import {
|
|
5018
5018
|
runnerImport,
|
|
@@ -5039,7 +5039,7 @@ function mergeJsonConfigWithRuntimeOverrides(fileConfig, importedConfig) {
|
|
|
5039
5039
|
}
|
|
5040
5040
|
async function getConfigFilePath(rootDir) {
|
|
5041
5041
|
for (const fileName of zudokuConfigFiles) {
|
|
5042
|
-
const filepath =
|
|
5042
|
+
const filepath = path21.join(rootDir, fileName);
|
|
5043
5043
|
if (await fileExists(filepath)) {
|
|
5044
5044
|
return filepath;
|
|
5045
5045
|
}
|
|
@@ -5268,7 +5268,7 @@ __export(llms_exports, {
|
|
|
5268
5268
|
generateLlmsTxtFiles: () => generateLlmsTxtFiles
|
|
5269
5269
|
});
|
|
5270
5270
|
import { writeFile as writeFile12 } from "node:fs/promises";
|
|
5271
|
-
import
|
|
5271
|
+
import path45 from "node:path";
|
|
5272
5272
|
import colors10 from "picocolors";
|
|
5273
5273
|
async function generateLlmsTxtFiles({
|
|
5274
5274
|
markdownFileInfos,
|
|
@@ -5303,7 +5303,7 @@ async function generateLlmsTxtFiles({
|
|
|
5303
5303
|
}
|
|
5304
5304
|
}
|
|
5305
5305
|
const llmsTxt2 = llmsTxtParts.join("\n");
|
|
5306
|
-
await writeFile12(
|
|
5306
|
+
await writeFile12(path45.join(baseOutputDir, "llms.txt"), llmsTxt2, "utf-8");
|
|
5307
5307
|
if (process.env.APITOGO_JSON_ONLY !== "1") {
|
|
5308
5308
|
console.log(colors10.blue("\u2713 generated llms.txt"));
|
|
5309
5309
|
}
|
|
@@ -5331,7 +5331,7 @@ ${info.content}
|
|
|
5331
5331
|
}
|
|
5332
5332
|
const llmsFull = llmsFullParts.join("\n");
|
|
5333
5333
|
await writeFile12(
|
|
5334
|
-
|
|
5334
|
+
path45.join(baseOutputDir, "llms-full.txt"),
|
|
5335
5335
|
llmsFull,
|
|
5336
5336
|
"utf-8"
|
|
5337
5337
|
);
|
|
@@ -5834,7 +5834,37 @@ Run the command with --help to see its options.`;
|
|
|
5834
5834
|
import yargs from "yargs/yargs";
|
|
5835
5835
|
|
|
5836
5836
|
// src/cli/services/handler.ts
|
|
5837
|
-
import
|
|
5837
|
+
import path53 from "node:path";
|
|
5838
|
+
|
|
5839
|
+
// src/config/v2/billing.ts
|
|
5840
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
5841
|
+
var DEFAULT_STRIPE_KEY_SECRET = "STRIPE_API_KEY";
|
|
5842
|
+
function isPaidPlan(plan2) {
|
|
5843
|
+
return plan2.pricingModel !== "custom" && typeof plan2.priceAmount === "number" && plan2.priceAmount > 0;
|
|
5844
|
+
}
|
|
5845
|
+
async function paidPlanSkus(resolved) {
|
|
5846
|
+
const file = resolved.plans?.file;
|
|
5847
|
+
if (!file) return [];
|
|
5848
|
+
try {
|
|
5849
|
+
const raw = JSON.parse(await readFile2(file, "utf8"));
|
|
5850
|
+
if (!Array.isArray(raw.plans)) return [];
|
|
5851
|
+
return raw.plans.filter(
|
|
5852
|
+
(plan2) => typeof plan2 === "object" && plan2 !== null && isPaidPlan(plan2)
|
|
5853
|
+
).map((plan2) => String(plan2.sku ?? "?"));
|
|
5854
|
+
} catch {
|
|
5855
|
+
return [];
|
|
5856
|
+
}
|
|
5857
|
+
}
|
|
5858
|
+
async function billingNeeded(resolved) {
|
|
5859
|
+
const plans = resolved.plans;
|
|
5860
|
+
if (!plans?.enabled || plans.billing.provider !== "stripe") return false;
|
|
5861
|
+
return (await paidPlanSkus(resolved)).length > 0;
|
|
5862
|
+
}
|
|
5863
|
+
function stripeKeySecretName(resolved) {
|
|
5864
|
+
const ref = resolved.plans?.billing.apiKey;
|
|
5865
|
+
const match = ref ? /^secret:(.+)$/.exec(ref) : null;
|
|
5866
|
+
return match?.[1] ?? DEFAULT_STRIPE_KEY_SECRET;
|
|
5867
|
+
}
|
|
5838
5868
|
|
|
5839
5869
|
// src/config/v2/errors.ts
|
|
5840
5870
|
init_invariant();
|
|
@@ -6043,8 +6073,8 @@ var ConfigV2Schema = z.strictObject({
|
|
|
6043
6073
|
var REMOVED_KEYS = {
|
|
6044
6074
|
"plans.provider": "plans.provider was removed. Only plans.billing.provider (stripe or none) is selectable."
|
|
6045
6075
|
};
|
|
6046
|
-
function pathToString(
|
|
6047
|
-
return
|
|
6076
|
+
function pathToString(path97) {
|
|
6077
|
+
return path97.reduce(
|
|
6048
6078
|
(acc, segment) => typeof segment === "number" ? `${acc}[${segment}]` : acc === "" ? String(segment) : `${acc}.${String(segment)}`,
|
|
6049
6079
|
""
|
|
6050
6080
|
);
|
|
@@ -6064,9 +6094,9 @@ function step(schema2, segment) {
|
|
|
6064
6094
|
}
|
|
6065
6095
|
return void 0;
|
|
6066
6096
|
}
|
|
6067
|
-
function knownKeysAt(
|
|
6097
|
+
function knownKeysAt(path97) {
|
|
6068
6098
|
let current = ConfigV2Schema;
|
|
6069
|
-
for (const segment of
|
|
6099
|
+
for (const segment of path97) {
|
|
6070
6100
|
if (!current) return [];
|
|
6071
6101
|
current = step(current, segment);
|
|
6072
6102
|
}
|
|
@@ -6102,7 +6132,7 @@ function unknownKeyHint(fullPath, key, known) {
|
|
|
6102
6132
|
return known.length > 0 ? `Allowed keys: ${known.join(", ")}.` : void 0;
|
|
6103
6133
|
}
|
|
6104
6134
|
function mapIssue(issue4) {
|
|
6105
|
-
const
|
|
6135
|
+
const path97 = pathToString(issue4.path);
|
|
6106
6136
|
switch (issue4.code) {
|
|
6107
6137
|
case "unrecognized_keys":
|
|
6108
6138
|
return issue4.keys.map((key) => {
|
|
@@ -6118,20 +6148,20 @@ function mapIssue(issue4) {
|
|
|
6118
6148
|
return [
|
|
6119
6149
|
{
|
|
6120
6150
|
code: "CONFIG_INVALID_VALUE",
|
|
6121
|
-
path:
|
|
6151
|
+
path: path97,
|
|
6122
6152
|
message: `must be one of: ${issue4.values.map((v) => JSON.stringify(v)).join(", ")}.`
|
|
6123
6153
|
}
|
|
6124
6154
|
];
|
|
6125
6155
|
case "custom": {
|
|
6126
6156
|
const code = typeof issue4.params?.code === "string" ? issue4.params.code : "CONFIG_INVALID_VALUE";
|
|
6127
|
-
return [{ code, path:
|
|
6157
|
+
return [{ code, path: path97, message: issue4.message ?? "is invalid." }];
|
|
6128
6158
|
}
|
|
6129
6159
|
case "invalid_type":
|
|
6130
6160
|
return [
|
|
6131
|
-
/received undefined/.test(issue4.message) ? { code: "CONFIG_MISSING_FIELD", path:
|
|
6161
|
+
/received undefined/.test(issue4.message) ? { code: "CONFIG_MISSING_FIELD", path: path97, message: "is required." } : { code: "CONFIG_INVALID_VALUE", path: path97, message: issue4.message }
|
|
6132
6162
|
];
|
|
6133
6163
|
default:
|
|
6134
|
-
return [{ code: "CONFIG_INVALID_VALUE", path:
|
|
6164
|
+
return [{ code: "CONFIG_INVALID_VALUE", path: path97, message: issue4.message }];
|
|
6135
6165
|
}
|
|
6136
6166
|
}
|
|
6137
6167
|
function isRecord(value) {
|
|
@@ -6453,7 +6483,7 @@ function resolveConfigV2(config2, configPath) {
|
|
|
6453
6483
|
docs: {
|
|
6454
6484
|
enabled: portal.docs?.enabled ?? true,
|
|
6455
6485
|
provider,
|
|
6456
|
-
content: provider === "external" ? [] : portal.docs?.content ? portal.docs.content.map((
|
|
6486
|
+
content: provider === "external" ? [] : portal.docs?.content ? portal.docs.content.map((glob9) => fromConfig(configDir, glob9)) : [toGlobPath(path7.join(dir, "pages", "**", "*.{md,mdx}"))],
|
|
6457
6487
|
url: portal.docs?.url
|
|
6458
6488
|
},
|
|
6459
6489
|
console: { enabled: portal.console?.enabled ?? true },
|
|
@@ -6495,7 +6525,8 @@ function resolveConfigV2(config2, configPath) {
|
|
|
6495
6525
|
file: plans.file ? path7.resolve(configDir, plans.file) : path7.join(root, "plans.json"),
|
|
6496
6526
|
billing: {
|
|
6497
6527
|
provider: plans.billing?.provider ?? "stripe",
|
|
6498
|
-
|
|
6528
|
+
// Stripe is the only provider. Its key lives in the STRIPE_API_KEY secret unless the config names another.
|
|
6529
|
+
apiKey: plans.billing?.apiKey ?? ((plans.billing?.provider ?? "stripe") === "stripe" ? "secret:STRIPE_API_KEY" : void 0),
|
|
6499
6530
|
webhookSecret: plans.billing?.webhookSecret,
|
|
6500
6531
|
successUrl: plans.billing?.successUrl,
|
|
6501
6532
|
cancelUrl: plans.billing?.cancelUrl
|
|
@@ -6575,10 +6606,141 @@ function loadConfigV2(pathOrDir) {
|
|
|
6575
6606
|
}
|
|
6576
6607
|
|
|
6577
6608
|
// src/config/v2/rules.ts
|
|
6578
|
-
import { readdir as readdir2, readFile as
|
|
6609
|
+
import { readdir as readdir2, readFile as readFile4, stat as stat2 } from "node:fs/promises";
|
|
6610
|
+
import path10 from "node:path";
|
|
6611
|
+
import { glob as glob2 } from "glob";
|
|
6612
|
+
import { parse as parseYaml } from "yaml";
|
|
6613
|
+
|
|
6614
|
+
// src/config/v2/tsx-pages.ts
|
|
6615
|
+
import { readFile as readFile3 } from "node:fs/promises";
|
|
6579
6616
|
import path9 from "node:path";
|
|
6580
6617
|
import { glob } from "glob";
|
|
6581
|
-
import
|
|
6618
|
+
import globParent from "glob-parent";
|
|
6619
|
+
|
|
6620
|
+
// src/config/v2/docs-navigation.ts
|
|
6621
|
+
var DOCS_NAVIGATION_LABEL = "Documentation";
|
|
6622
|
+
var emptyBranch = () => ({ pages: /* @__PURE__ */ new Map(), folders: /* @__PURE__ */ new Map() });
|
|
6623
|
+
function folderLabel(name) {
|
|
6624
|
+
const words = name.replace(/[-_]+/g, " ").trim();
|
|
6625
|
+
return words.charAt(0).toUpperCase() + words.slice(1);
|
|
6626
|
+
}
|
|
6627
|
+
var byName = (a, b) => a.localeCompare(b);
|
|
6628
|
+
var toItems = (branch, prefix) => {
|
|
6629
|
+
const names = [...branch.pages.keys()].sort(
|
|
6630
|
+
(a, b) => a === "index" ? -1 : b === "index" ? 1 : byName(a, b)
|
|
6631
|
+
);
|
|
6632
|
+
const folders = [...branch.folders.keys()].sort(byName);
|
|
6633
|
+
const folderPath = prefix === "" ? "/" : `/${prefix.slice(0, -1)}`;
|
|
6634
|
+
return [
|
|
6635
|
+
...names.map((name) => {
|
|
6636
|
+
const page = branch.pages.get(name);
|
|
6637
|
+
if (page.kind === "custom") {
|
|
6638
|
+
return {
|
|
6639
|
+
type: "custom-page",
|
|
6640
|
+
// The index page of a folder is the folder's own address.
|
|
6641
|
+
path: name === "index" ? folderPath : page.route,
|
|
6642
|
+
label: page.label,
|
|
6643
|
+
element: page.element
|
|
6644
|
+
};
|
|
6645
|
+
}
|
|
6646
|
+
return name === "index" ? { type: "doc", file: `${prefix}${name}`, path: folderPath } : `${prefix}${name}`;
|
|
6647
|
+
}),
|
|
6648
|
+
...folders.map(
|
|
6649
|
+
(folder) => ({
|
|
6650
|
+
type: "category",
|
|
6651
|
+
label: folderLabel(folder),
|
|
6652
|
+
collapsible: true,
|
|
6653
|
+
collapsed: false,
|
|
6654
|
+
items: toItems(
|
|
6655
|
+
branch.folders.get(folder) ?? emptyBranch(),
|
|
6656
|
+
`${prefix}${folder}/`
|
|
6657
|
+
)
|
|
6658
|
+
})
|
|
6659
|
+
)
|
|
6660
|
+
];
|
|
6661
|
+
};
|
|
6662
|
+
var branchOf = (root, route) => {
|
|
6663
|
+
const parts = route.split("/").filter(Boolean);
|
|
6664
|
+
const page = parts.pop();
|
|
6665
|
+
const branch = parts.reduce((current, folder) => {
|
|
6666
|
+
const next = current.folders.get(folder) ?? emptyBranch();
|
|
6667
|
+
current.folders.set(folder, next);
|
|
6668
|
+
return next;
|
|
6669
|
+
}, root);
|
|
6670
|
+
return { branch, page };
|
|
6671
|
+
};
|
|
6672
|
+
function docsNavigation(routes, customPages = []) {
|
|
6673
|
+
const root = emptyBranch();
|
|
6674
|
+
for (const route of routes) {
|
|
6675
|
+
const { branch, page } = branchOf(root, route);
|
|
6676
|
+
if (page) branch.pages.set(page, { kind: "doc" });
|
|
6677
|
+
}
|
|
6678
|
+
for (const custom of customPages) {
|
|
6679
|
+
const { branch, page } = branchOf(root, custom.route);
|
|
6680
|
+
if (page && !branch.pages.has(page))
|
|
6681
|
+
branch.pages.set(page, { kind: "custom", ...custom });
|
|
6682
|
+
}
|
|
6683
|
+
const items = toItems(root, "");
|
|
6684
|
+
return items.length === 0 ? [] : [{ type: "category", label: DOCS_NAVIGATION_LABEL, items }];
|
|
6685
|
+
}
|
|
6686
|
+
|
|
6687
|
+
// src/config/v2/tsx-pages.ts
|
|
6688
|
+
var IGNORED = ["**/node_modules/**", "**/dist/**", "**/.git/**"];
|
|
6689
|
+
function isTsxHelper(relative) {
|
|
6690
|
+
return relative.split("/").some((part) => part.startsWith("_")) || /\.(test|spec|stories)\.tsx$/.test(relative) || relative.split("/").includes("node_modules");
|
|
6691
|
+
}
|
|
6692
|
+
function tsxPagePatterns(contentGlobs) {
|
|
6693
|
+
const globs = contentGlobs.map(toGlobPath);
|
|
6694
|
+
const included = globs.filter((pattern) => !pattern.startsWith("!"));
|
|
6695
|
+
const excluded = globs.filter((pattern) => pattern.startsWith("!"));
|
|
6696
|
+
return [
|
|
6697
|
+
...new Set(
|
|
6698
|
+
included.map(
|
|
6699
|
+
(pattern) => path9.posix.join(globParent(pattern), "**", "*.tsx")
|
|
6700
|
+
)
|
|
6701
|
+
),
|
|
6702
|
+
...excluded
|
|
6703
|
+
];
|
|
6704
|
+
}
|
|
6705
|
+
var TITLE = /export\s+const\s+title\s*(?::\s*string\s*)?=\s*(["'`])((?:\\.|(?!\1).)*)\1/;
|
|
6706
|
+
function tsxPageLabel(source, file) {
|
|
6707
|
+
const match = TITLE.exec(source);
|
|
6708
|
+
if (match?.[2]) return match[2].replace(/\\(.)/g, "$1");
|
|
6709
|
+
const name = path9.basename(file, ".tsx");
|
|
6710
|
+
return folderLabel(
|
|
6711
|
+
name === "index" ? path9.basename(path9.dirname(file)) : name
|
|
6712
|
+
);
|
|
6713
|
+
}
|
|
6714
|
+
async function findTsxPages(contentGlobs) {
|
|
6715
|
+
const patterns = tsxPagePatterns(contentGlobs);
|
|
6716
|
+
const ignore2 = [
|
|
6717
|
+
...IGNORED,
|
|
6718
|
+
...patterns.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1))
|
|
6719
|
+
];
|
|
6720
|
+
const found = /* @__PURE__ */ new Map();
|
|
6721
|
+
for (const pattern of patterns.filter((p) => !p.startsWith("!"))) {
|
|
6722
|
+
const parent = globParent(pattern);
|
|
6723
|
+
const files = await glob(pattern, {
|
|
6724
|
+
absolute: true,
|
|
6725
|
+
posix: true,
|
|
6726
|
+
nodir: true,
|
|
6727
|
+
ignore: ignore2
|
|
6728
|
+
});
|
|
6729
|
+
for (const raw of files.sort()) {
|
|
6730
|
+
const file = raw.replace(/^\/\/\?\//, "");
|
|
6731
|
+
const relative = path9.posix.relative(parent, file);
|
|
6732
|
+
if (isTsxHelper(relative)) continue;
|
|
6733
|
+
const route = `/${relative.replace(/\.tsx$/, "")}`;
|
|
6734
|
+
if (found.has(route)) continue;
|
|
6735
|
+
const source = await readFile3(file, "utf8").catch(() => "");
|
|
6736
|
+
found.set(route, { route, file, label: tsxPageLabel(source, file) });
|
|
6737
|
+
}
|
|
6738
|
+
}
|
|
6739
|
+
return [...found.values()].sort((a, b) => a.route.localeCompare(b.route));
|
|
6740
|
+
}
|
|
6741
|
+
var TSX_PAGE_ELEMENT_PREFIX = "apitogo:tsx-page:";
|
|
6742
|
+
|
|
6743
|
+
// src/config/v2/rules.ts
|
|
6582
6744
|
var SPEC_MAX_BYTES = 5 * 1024 * 1024;
|
|
6583
6745
|
var SECRET_REFERENCE2 = /^secret:([A-Za-z_][A-Za-z0-9_]*)$/;
|
|
6584
6746
|
async function isFile(target) {
|
|
@@ -6727,13 +6889,13 @@ async function portalRules(config2, resolved, out) {
|
|
|
6727
6889
|
}
|
|
6728
6890
|
if (await isFile(portal.theme)) {
|
|
6729
6891
|
try {
|
|
6730
|
-
JSON.parse(await
|
|
6892
|
+
JSON.parse(await readFile4(portal.theme, "utf8"));
|
|
6731
6893
|
} catch (error) {
|
|
6732
6894
|
out.error({
|
|
6733
6895
|
code: "PORTAL_THEME_INVALID",
|
|
6734
6896
|
path: "portal.theme",
|
|
6735
6897
|
message: `the theme file is not valid JSON (${error instanceof Error ? error.message : String(error)}).`,
|
|
6736
|
-
hint:
|
|
6898
|
+
hint: path10.relative(resolved.configDir, portal.theme)
|
|
6737
6899
|
});
|
|
6738
6900
|
}
|
|
6739
6901
|
}
|
|
@@ -6742,16 +6904,17 @@ async function docsContentRule(config2, patterns, resolved, out) {
|
|
|
6742
6904
|
const globs = patterns.map(toGlobPath);
|
|
6743
6905
|
const include = globs.filter((pattern) => !pattern.startsWith("!"));
|
|
6744
6906
|
const ignore2 = globs.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1));
|
|
6745
|
-
const matches = include.length > 0 ? await
|
|
6907
|
+
const matches = include.length > 0 ? await glob2(include, { nodir: true, ignore: ignore2, absolute: true }) : [];
|
|
6746
6908
|
if (matches.length > 0) return;
|
|
6909
|
+
if ((await findTsxPages(patterns)).length > 0) return;
|
|
6747
6910
|
const shown = config2.portal?.docs?.content ?? [
|
|
6748
|
-
|
|
6911
|
+
path10.relative(resolved.configDir, patterns[0] ?? "")
|
|
6749
6912
|
];
|
|
6750
6913
|
out.warn({
|
|
6751
6914
|
code: "PORTAL_DOCS_EMPTY",
|
|
6752
6915
|
path: "portal.docs",
|
|
6753
6916
|
message: `portal.docs matched 0 files (${shown.join(", ")}). The site will only contain the API reference.`,
|
|
6754
|
-
hint: "Add .md or .
|
|
6917
|
+
hint: "Add .md, .mdx or .tsx pages, or point docs.content at your existing docs."
|
|
6755
6918
|
});
|
|
6756
6919
|
}
|
|
6757
6920
|
function isIpLiteral(hostname) {
|
|
@@ -6818,8 +6981,8 @@ async function gatewayRules(resolved, out) {
|
|
|
6818
6981
|
}
|
|
6819
6982
|
}
|
|
6820
6983
|
if (origin.source) {
|
|
6821
|
-
const inside =
|
|
6822
|
-
if (inside.startsWith("..") ||
|
|
6984
|
+
const inside = path10.relative(resolved.configDir, origin.source);
|
|
6985
|
+
if (inside.startsWith("..") || path10.isAbsolute(inside)) {
|
|
6823
6986
|
out.error({
|
|
6824
6987
|
code: "GATEWAY_ORIGIN_INVALID",
|
|
6825
6988
|
path: "gateway.origin.source",
|
|
@@ -6904,7 +7067,7 @@ async function gatewayRules(resolved, out) {
|
|
|
6904
7067
|
}
|
|
6905
7068
|
async function specRule(spec, index, resolved, out) {
|
|
6906
7069
|
const at = `gateway.specs[${index}]`;
|
|
6907
|
-
const shown =
|
|
7070
|
+
const shown = path10.relative(resolved.configDir, spec);
|
|
6908
7071
|
const info = await stat2(spec).catch(() => void 0);
|
|
6909
7072
|
if (!info?.isFile()) {
|
|
6910
7073
|
out.error({
|
|
@@ -6924,7 +7087,7 @@ async function specRule(spec, index, resolved, out) {
|
|
|
6924
7087
|
}
|
|
6925
7088
|
let document;
|
|
6926
7089
|
try {
|
|
6927
|
-
const text = await
|
|
7090
|
+
const text = await readFile4(spec, "utf8");
|
|
6928
7091
|
document = spec.toLowerCase().endsWith(".json") ? JSON.parse(text) : parseYaml(text);
|
|
6929
7092
|
} catch (error) {
|
|
6930
7093
|
out.error({
|
|
@@ -7066,19 +7229,19 @@ function identityRules(config2, resolved, out) {
|
|
|
7066
7229
|
}
|
|
7067
7230
|
}
|
|
7068
7231
|
}
|
|
7069
|
-
async function plansRules(
|
|
7232
|
+
async function plansRules(resolved, out, paid) {
|
|
7070
7233
|
const plans = resolved.plans;
|
|
7071
7234
|
if (!plans?.enabled) return;
|
|
7072
7235
|
if (!await isFile(plans.file)) {
|
|
7073
7236
|
out.error({
|
|
7074
7237
|
code: "PLANS_FILE_INVALID",
|
|
7075
7238
|
path: "plans.file",
|
|
7076
|
-
message: `the plan catalog was not found: ${
|
|
7239
|
+
message: `the plan catalog was not found: ${path10.relative(resolved.configDir, plans.file)}.`,
|
|
7077
7240
|
hint: "Create it with `apitogo add plans`."
|
|
7078
7241
|
});
|
|
7079
7242
|
} else {
|
|
7080
7243
|
try {
|
|
7081
|
-
JSON.parse(await
|
|
7244
|
+
JSON.parse(await readFile4(plans.file, "utf8"));
|
|
7082
7245
|
} catch (error) {
|
|
7083
7246
|
out.error({
|
|
7084
7247
|
code: "PLANS_FILE_INVALID",
|
|
@@ -7087,15 +7250,7 @@ async function plansRules(config2, resolved, out) {
|
|
|
7087
7250
|
});
|
|
7088
7251
|
}
|
|
7089
7252
|
}
|
|
7090
|
-
if (
|
|
7091
|
-
if (!config2.plans?.billing?.apiKey) {
|
|
7092
|
-
out.error({
|
|
7093
|
-
code: "PLANS_BILLING_INCOMPLETE",
|
|
7094
|
-
path: "plans.billing.apiKey",
|
|
7095
|
-
message: "plans.billing.apiKey is required when billing.provider is stripe.",
|
|
7096
|
-
hint: 'Set it to a secret reference, for example "secret:STRIPE_API_KEY".'
|
|
7097
|
-
});
|
|
7098
|
-
}
|
|
7253
|
+
if (paid) {
|
|
7099
7254
|
const headless = !(resolved.portal?.enabled === true);
|
|
7100
7255
|
for (const field of ["successUrl", "cancelUrl"]) {
|
|
7101
7256
|
if (headless && !plans.billing[field]) {
|
|
@@ -7109,8 +7264,12 @@ async function plansRules(config2, resolved, out) {
|
|
|
7109
7264
|
}
|
|
7110
7265
|
}
|
|
7111
7266
|
}
|
|
7112
|
-
function secretRules(config2, context, out, skipped) {
|
|
7113
|
-
const
|
|
7267
|
+
function secretRules(config2, resolved, context, out, skipped, paid) {
|
|
7268
|
+
const stripeKeyPath = "plans.billing.apiKey";
|
|
7269
|
+
const named = collectSecretRefs(config2).filter(
|
|
7270
|
+
(ref) => paid || !ref.path.startsWith("plans.billing")
|
|
7271
|
+
);
|
|
7272
|
+
const refs = paid && !named.some((ref) => ref.path === stripeKeyPath) ? [...named, { name: stripeKeySecretName(resolved), path: stripeKeyPath }] : named;
|
|
7114
7273
|
if (refs.length === 0) return;
|
|
7115
7274
|
if (!context.knownSecrets) {
|
|
7116
7275
|
skipped.push(
|
|
@@ -7119,7 +7278,14 @@ function secretRules(config2, context, out, skipped) {
|
|
|
7119
7278
|
return;
|
|
7120
7279
|
}
|
|
7121
7280
|
for (const ref of refs) {
|
|
7122
|
-
if (!context.knownSecrets.has(ref.name)) {
|
|
7281
|
+
if (ref.path === stripeKeyPath && !context.knownSecrets.has(ref.name)) {
|
|
7282
|
+
out.warn({
|
|
7283
|
+
code: "SECRET_NOT_SET",
|
|
7284
|
+
path: ref.path,
|
|
7285
|
+
message: `a plan has a price, and the Stripe key (secret ${ref.name}) is not set yet.`,
|
|
7286
|
+
hint: `apitogo deploy asks for it. Or run: apitogo secrets set ${ref.name}`
|
|
7287
|
+
});
|
|
7288
|
+
} else if (!context.knownSecrets.has(ref.name)) {
|
|
7123
7289
|
out.error({
|
|
7124
7290
|
code: "SECRET_NOT_SET",
|
|
7125
7291
|
path: ref.path,
|
|
@@ -7139,12 +7305,13 @@ async function checkConfigV2(config2, resolved, context = {}) {
|
|
|
7139
7305
|
error: (issue4) => errors.push(issue4),
|
|
7140
7306
|
warn: (issue4) => warnings.push(issue4)
|
|
7141
7307
|
};
|
|
7308
|
+
const paid = await billingNeeded(resolved);
|
|
7142
7309
|
dependencyRules(config2, resolved, out);
|
|
7143
|
-
secretRules(config2, context, out, skipped);
|
|
7310
|
+
secretRules(config2, resolved, context, out, skipped, paid);
|
|
7144
7311
|
await portalRules(config2, resolved, out);
|
|
7145
7312
|
await gatewayRules(resolved, out);
|
|
7146
7313
|
identityRules(config2, resolved, out);
|
|
7147
|
-
await plansRules(
|
|
7314
|
+
await plansRules(resolved, out, paid);
|
|
7148
7315
|
return { errors, warnings, skipped };
|
|
7149
7316
|
}
|
|
7150
7317
|
|
|
@@ -7190,8 +7357,8 @@ function portalProfile(resolved) {
|
|
|
7190
7357
|
}
|
|
7191
7358
|
|
|
7192
7359
|
// src/config/v2/manifest.ts
|
|
7193
|
-
import { mkdir as mkdir3, readFile as
|
|
7194
|
-
import
|
|
7360
|
+
import { mkdir as mkdir3, readFile as readFile5, rename, rm, writeFile as writeFile4 } from "node:fs/promises";
|
|
7361
|
+
import path11 from "node:path";
|
|
7195
7362
|
import { z as z3 } from "zod";
|
|
7196
7363
|
var SUPPORTED_MANIFEST_SCHEMA = 1;
|
|
7197
7364
|
var Capabilities = z3.record(z3.string(), z3.boolean()).default({});
|
|
@@ -7240,7 +7407,7 @@ var ServiceManifestSchema = z3.looseObject({
|
|
|
7240
7407
|
}).optional()
|
|
7241
7408
|
}).default({})
|
|
7242
7409
|
});
|
|
7243
|
-
var issue = (code,
|
|
7410
|
+
var issue = (code, path97, message, hint) => ({ code, path: path97, message, hint });
|
|
7244
7411
|
function parseManifest(raw, file = "services.json") {
|
|
7245
7412
|
const version = typeof raw === "object" && raw !== null && "schemaVersion" in raw ? raw.schemaVersion : void 0;
|
|
7246
7413
|
if (typeof version === "number" && version > SUPPORTED_MANIFEST_SCHEMA) {
|
|
@@ -7273,7 +7440,7 @@ async function readManifest(state) {
|
|
|
7273
7440
|
const file = manifestPathFor(state);
|
|
7274
7441
|
let text;
|
|
7275
7442
|
try {
|
|
7276
|
-
text = await
|
|
7443
|
+
text = await readFile5(file, "utf8");
|
|
7277
7444
|
} catch (error) {
|
|
7278
7445
|
if (error.code === "ENOENT") return void 0;
|
|
7279
7446
|
throw error;
|
|
@@ -7457,7 +7624,7 @@ function withPlansEntry(existing, info) {
|
|
|
7457
7624
|
}
|
|
7458
7625
|
async function writeManifest(state, manifest) {
|
|
7459
7626
|
const file = manifestPathFor(state);
|
|
7460
|
-
await mkdir3(
|
|
7627
|
+
await mkdir3(path11.dirname(file), { recursive: true });
|
|
7461
7628
|
const temporary = `${file}.${process.pid}.tmp`;
|
|
7462
7629
|
try {
|
|
7463
7630
|
await writeFile4(
|
|
@@ -7488,7 +7655,7 @@ async function removeServicesFromManifest(state, names) {
|
|
|
7488
7655
|
}
|
|
7489
7656
|
|
|
7490
7657
|
// src/config/v2/gateway-reference.ts
|
|
7491
|
-
import { readFile as
|
|
7658
|
+
import { readFile as readFile6 } from "node:fs/promises";
|
|
7492
7659
|
import { parse } from "yaml";
|
|
7493
7660
|
var DEFAULT_KEY_HEADER = "Ocp-Apim-Subscription-Key";
|
|
7494
7661
|
var METHODS = [
|
|
@@ -7502,8 +7669,8 @@ var METHODS = [
|
|
|
7502
7669
|
"trace"
|
|
7503
7670
|
];
|
|
7504
7671
|
var isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7505
|
-
function actionKey(method,
|
|
7506
|
-
const trimmed =
|
|
7672
|
+
function actionKey(method, path97) {
|
|
7673
|
+
const trimmed = path97.trim();
|
|
7507
7674
|
const withSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
7508
7675
|
const normalized = withSlash.length > 1 ? withSlash.replace(/\/+$/, "") || "/" : withSlash;
|
|
7509
7676
|
return `${method.trim().toLowerCase()}:${normalized}`;
|
|
@@ -7540,8 +7707,8 @@ var ReferenceSpecError = class extends Error {
|
|
|
7540
7707
|
};
|
|
7541
7708
|
function operationsOf(paths) {
|
|
7542
7709
|
return Object.entries(paths).flatMap(
|
|
7543
|
-
([
|
|
7544
|
-
(method) => [
|
|
7710
|
+
([path97, item]) => isObject(item) ? METHODS.filter((method) => isObject(item[method])).map(
|
|
7711
|
+
(method) => [path97, item, method]
|
|
7545
7712
|
) : []
|
|
7546
7713
|
);
|
|
7547
7714
|
}
|
|
@@ -7556,14 +7723,14 @@ function buildReferenceSpec(specText, options) {
|
|
|
7556
7723
|
throw new ReferenceSpecError("The OpenAPI file could not be read.");
|
|
7557
7724
|
const doc = structuredClone(root);
|
|
7558
7725
|
const paths = isObject(doc.paths) ? doc.paths : {};
|
|
7559
|
-
for (const [
|
|
7560
|
-
if (options.deniedOperations.has(actionKey(method,
|
|
7726
|
+
for (const [path97, item, method] of operationsOf(paths))
|
|
7727
|
+
if (options.deniedOperations.has(actionKey(method, path97)))
|
|
7561
7728
|
delete item[method];
|
|
7562
|
-
for (const [
|
|
7729
|
+
for (const [path97, item] of Object.entries(paths))
|
|
7563
7730
|
if (!isObject(item) || !METHODS.some((method) => method in item))
|
|
7564
|
-
delete paths[
|
|
7565
|
-
for (const [
|
|
7566
|
-
if (options.publicOperations.has(actionKey(method,
|
|
7731
|
+
delete paths[path97];
|
|
7732
|
+
for (const [path97, item, method] of operationsOf(paths))
|
|
7733
|
+
if (options.publicOperations.has(actionKey(method, path97)))
|
|
7567
7734
|
item[method].security = [];
|
|
7568
7735
|
doc.servers = [{ url: options.gatewayBaseUrl.replace(/\/+$/, "") }];
|
|
7569
7736
|
for (const item of Object.values(paths)) {
|
|
@@ -7626,7 +7793,7 @@ async function renderReferenceSpec(gateway, gatewayBaseUrl, keyHeaderName) {
|
|
|
7626
7793
|
throw new ReferenceSpecError("gateway.specs lists no OpenAPI file.");
|
|
7627
7794
|
let text;
|
|
7628
7795
|
try {
|
|
7629
|
-
text = await
|
|
7796
|
+
text = await readFile6(file, "utf8");
|
|
7630
7797
|
} catch {
|
|
7631
7798
|
throw new ReferenceSpecError(`Cannot read the OpenAPI file ${file}.`);
|
|
7632
7799
|
}
|
|
@@ -7697,69 +7864,16 @@ function stableJson(value) {
|
|
|
7697
7864
|
}
|
|
7698
7865
|
|
|
7699
7866
|
// src/config/v2/wrapper.ts
|
|
7700
|
-
import { mkdir as mkdir4, readFile as
|
|
7701
|
-
import
|
|
7702
|
-
|
|
7703
|
-
// src/config/v2/docs-navigation.ts
|
|
7704
|
-
var DOCS_NAVIGATION_LABEL = "Documentation";
|
|
7705
|
-
var emptyBranch = () => ({ pages: /* @__PURE__ */ new Set(), folders: /* @__PURE__ */ new Map() });
|
|
7706
|
-
function folderLabel(name) {
|
|
7707
|
-
const words = name.replace(/[-_]+/g, " ").trim();
|
|
7708
|
-
return words.charAt(0).toUpperCase() + words.slice(1);
|
|
7709
|
-
}
|
|
7710
|
-
var byName = (a, b) => a.localeCompare(b);
|
|
7711
|
-
var toItems = (branch, prefix) => {
|
|
7712
|
-
const pages = [...branch.pages].sort(
|
|
7713
|
-
(a, b) => a === "index" ? -1 : b === "index" ? 1 : byName(a, b)
|
|
7714
|
-
);
|
|
7715
|
-
const folders = [...branch.folders.keys()].sort(byName);
|
|
7716
|
-
return [
|
|
7717
|
-
// The index page of a folder is the folder's own address, so the sidebar also shows on `/`.
|
|
7718
|
-
...pages.map(
|
|
7719
|
-
(page) => page === "index" ? {
|
|
7720
|
-
type: "doc",
|
|
7721
|
-
file: `${prefix}${page}`,
|
|
7722
|
-
path: prefix === "" ? "/" : `/${prefix.slice(0, -1)}`
|
|
7723
|
-
} : `${prefix}${page}`
|
|
7724
|
-
),
|
|
7725
|
-
...folders.map(
|
|
7726
|
-
(folder) => ({
|
|
7727
|
-
type: "category",
|
|
7728
|
-
label: folderLabel(folder),
|
|
7729
|
-
collapsible: true,
|
|
7730
|
-
collapsed: false,
|
|
7731
|
-
items: toItems(
|
|
7732
|
-
branch.folders.get(folder) ?? emptyBranch(),
|
|
7733
|
-
`${prefix}${folder}/`
|
|
7734
|
-
)
|
|
7735
|
-
})
|
|
7736
|
-
)
|
|
7737
|
-
];
|
|
7738
|
-
};
|
|
7739
|
-
function docsNavigation(routes) {
|
|
7740
|
-
const root = emptyBranch();
|
|
7741
|
-
for (const route of routes) {
|
|
7742
|
-
const parts = route.split("/").filter(Boolean);
|
|
7743
|
-
const page = parts.pop();
|
|
7744
|
-
if (!page) continue;
|
|
7745
|
-
const branch = parts.reduce((current, folder) => {
|
|
7746
|
-
const next = current.folders.get(folder) ?? emptyBranch();
|
|
7747
|
-
current.folders.set(folder, next);
|
|
7748
|
-
return next;
|
|
7749
|
-
}, root);
|
|
7750
|
-
branch.pages.add(page);
|
|
7751
|
-
}
|
|
7752
|
-
const items = toItems(root, "");
|
|
7753
|
-
return items.length === 0 ? [] : [{ type: "category", label: DOCS_NAVIGATION_LABEL, items }];
|
|
7754
|
-
}
|
|
7867
|
+
import { mkdir as mkdir4, readFile as readFile8, rename as rename2, rm as rm2, writeFile as writeFile5 } from "node:fs/promises";
|
|
7868
|
+
import path13 from "node:path";
|
|
7755
7869
|
|
|
7756
7870
|
// src/config/v2/home-redirect.ts
|
|
7757
|
-
import
|
|
7758
|
-
import { glob as
|
|
7759
|
-
import
|
|
7871
|
+
import path12 from "node:path";
|
|
7872
|
+
import { glob as glob3 } from "glob";
|
|
7873
|
+
import globParent2 from "glob-parent";
|
|
7760
7874
|
|
|
7761
7875
|
// src/lib/util/readFrontmatter.ts
|
|
7762
|
-
import { readFile as
|
|
7876
|
+
import { readFile as readFile7 } from "node:fs/promises";
|
|
7763
7877
|
import matter from "gray-matter";
|
|
7764
7878
|
import { parse as parse2, stringify } from "yaml";
|
|
7765
7879
|
var yaml = {
|
|
@@ -7767,25 +7881,25 @@ var yaml = {
|
|
|
7767
7881
|
stringify: (obj) => stringify(obj)
|
|
7768
7882
|
};
|
|
7769
7883
|
var readFrontmatter = async (filePath) => {
|
|
7770
|
-
const content = await
|
|
7884
|
+
const content = await readFile7(filePath, "utf-8");
|
|
7771
7885
|
const normalizedContent = content.replace(/\r\n/g, "\n");
|
|
7772
7886
|
return matter(normalizedContent, { engines: { yaml } });
|
|
7773
7887
|
};
|
|
7774
7888
|
|
|
7775
7889
|
// src/config/v2/home-redirect.ts
|
|
7776
|
-
var
|
|
7890
|
+
var IGNORED2 = ["**/node_modules/**", "**/dist/**", "**/.git/**"];
|
|
7777
7891
|
async function docRoutes(patterns, options = {}) {
|
|
7778
7892
|
const globs = patterns.map(toGlobPath);
|
|
7779
7893
|
const excluded = globs.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1));
|
|
7780
7894
|
const included = globs.filter((pattern) => !pattern.startsWith("!"));
|
|
7781
7895
|
const routes = await Promise.all(
|
|
7782
7896
|
included.map(async (pattern) => {
|
|
7783
|
-
const files = await
|
|
7897
|
+
const files = await glob3(pattern, {
|
|
7784
7898
|
absolute: true,
|
|
7785
7899
|
posix: true,
|
|
7786
|
-
ignore: [...
|
|
7900
|
+
ignore: [...IGNORED2, ...excluded]
|
|
7787
7901
|
});
|
|
7788
|
-
const parent =
|
|
7902
|
+
const parent = globParent2(pattern);
|
|
7789
7903
|
const published = options.includeDrafts ? files : (await Promise.all(
|
|
7790
7904
|
files.map(async (file) => ({
|
|
7791
7905
|
file,
|
|
@@ -7793,7 +7907,7 @@ async function docRoutes(patterns, options = {}) {
|
|
|
7793
7907
|
}))
|
|
7794
7908
|
)).filter(({ draft }) => !draft).map(({ file }) => file);
|
|
7795
7909
|
return published.map(
|
|
7796
|
-
(file) => `/${
|
|
7910
|
+
(file) => `/${path12.posix.relative(parent, file.replace(/^\/\/\?\//, "")).replace(/\.mdx?$/, "")}`
|
|
7797
7911
|
);
|
|
7798
7912
|
})
|
|
7799
7913
|
);
|
|
@@ -7842,10 +7956,10 @@ function protectedRoutesFor(input5) {
|
|
|
7842
7956
|
// src/config/v2/wrapper.ts
|
|
7843
7957
|
var WRAPPER_FILE = "apitogo.config.tsx";
|
|
7844
7958
|
var CONTENT_LINK = "content";
|
|
7845
|
-
function contentGlob(configDir,
|
|
7846
|
-
const negated =
|
|
7847
|
-
const absolute = negated ?
|
|
7848
|
-
const relative =
|
|
7959
|
+
function contentGlob(configDir, glob9) {
|
|
7960
|
+
const negated = glob9.startsWith("!");
|
|
7961
|
+
const absolute = negated ? glob9.slice(1) : glob9;
|
|
7962
|
+
const relative = path13.relative(configDir, absolute).split(path13.sep).join("/");
|
|
7849
7963
|
return `${negated ? "!" : ""}/${CONTENT_LINK}/${relative}`;
|
|
7850
7964
|
}
|
|
7851
7965
|
var PLANS_CONSOLE_CAPABILITIES = [
|
|
@@ -8014,7 +8128,7 @@ function buildSiteConfig(resolved, plan2, theme, extras = {}) {
|
|
|
8014
8128
|
enabled: true,
|
|
8015
8129
|
path: "/",
|
|
8016
8130
|
layout: "landing",
|
|
8017
|
-
page: portal.landing.split(
|
|
8131
|
+
page: portal.landing.split(path13.sep).join("/")
|
|
8018
8132
|
}
|
|
8019
8133
|
} : {},
|
|
8020
8134
|
// The plans pages (pricing, choosing a plan) exist only when billing is on, and the plans service is what makes it so.
|
|
@@ -8031,7 +8145,7 @@ function buildSiteConfig(resolved, plan2, theme, extras = {}) {
|
|
|
8031
8145
|
...plan2.docs ? {
|
|
8032
8146
|
docs: {
|
|
8033
8147
|
files: portal?.docs.content.map(
|
|
8034
|
-
(
|
|
8148
|
+
(glob9) => contentGlob(resolved.configDir, glob9)
|
|
8035
8149
|
)
|
|
8036
8150
|
}
|
|
8037
8151
|
} : {},
|
|
@@ -8077,33 +8191,72 @@ function authenticationFor(plan2) {
|
|
|
8077
8191
|
return { type: "openid", ...signIn };
|
|
8078
8192
|
}
|
|
8079
8193
|
var PREVIEW_BANNER_MESSAGE = "Preview mode: sign in with demo@apitogo.local / password to try the console. Run `apitogo deploy` for the real services.";
|
|
8080
|
-
function renderWrapper(plan2) {
|
|
8194
|
+
function renderWrapper(plan2, pages = []) {
|
|
8081
8195
|
const imports = [
|
|
8082
8196
|
'import { buildApitogoConfig } from "@lukoweb/apitogo/build-config";',
|
|
8083
8197
|
...plan2.plansPlugin ? [
|
|
8084
8198
|
'import { devPortalBillingPlugin } from "@lukoweb/apitogo-plugin-dev-portal-billing";'
|
|
8085
8199
|
] : [],
|
|
8200
|
+
...pages.length > 0 ? ['import { createElement } from "react";'] : [],
|
|
8201
|
+
...pages.map(
|
|
8202
|
+
(page, index) => `import TsxPage${index} from ${JSON.stringify(page.importPath)};`
|
|
8203
|
+
),
|
|
8086
8204
|
`import siteConfig from "./${SITE_CONFIG_FILE}";`
|
|
8087
8205
|
];
|
|
8088
8206
|
const plugins = plan2.plansPlugin ? `[devPortalBillingPlugin(${JSON.stringify(plan2.plansPlugin)})]` : "[]";
|
|
8207
|
+
const pageLines = pages.length === 0 ? [] : [
|
|
8208
|
+
"",
|
|
8209
|
+
"// React docs pages: each sidebar placeholder becomes the page's component.",
|
|
8210
|
+
"const tsxPages: Record<string, any> = {",
|
|
8211
|
+
...pages.map(
|
|
8212
|
+
(page, index) => ` ${JSON.stringify(page.id)}: TsxPage${index},`
|
|
8213
|
+
),
|
|
8214
|
+
"};",
|
|
8215
|
+
"const withTsxPages = (items: any[]): any[] =>",
|
|
8216
|
+
" items.map((item) => {",
|
|
8217
|
+
' if (item === null || typeof item !== "object") return item;',
|
|
8218
|
+
" const page =",
|
|
8219
|
+
' typeof item.element === "string" ? tsxPages[item.element] : undefined;',
|
|
8220
|
+
" return {",
|
|
8221
|
+
" ...item,",
|
|
8222
|
+
" ...(page ? { element: createElement(page) } : {}),",
|
|
8223
|
+
" ...(Array.isArray(item.items) ? { items: withTsxPages(item.items) } : {}),",
|
|
8224
|
+
" };",
|
|
8225
|
+
" });"
|
|
8226
|
+
];
|
|
8089
8227
|
return [
|
|
8090
8228
|
"// Generated by apitogo from apitogo.config.json and services.json. Do not edit: it is rewritten on every build.",
|
|
8091
8229
|
...plan2.preview ? [
|
|
8092
8230
|
"// PREVIEW: built from a stand-in manifest for local runs. A production build refuses this file."
|
|
8093
8231
|
] : [],
|
|
8094
8232
|
...imports,
|
|
8233
|
+
...pageLines,
|
|
8095
8234
|
"",
|
|
8096
|
-
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
|
|
8235
|
+
// The components go in after buildApitogoConfig: it copies the config with structuredClone, which cannot copy a
|
|
8236
|
+
// React element.
|
|
8237
|
+
...pages.length > 0 ? [
|
|
8238
|
+
"const config = buildApitogoConfig({",
|
|
8239
|
+
" ...siteConfig,",
|
|
8240
|
+
` plugins: ${plugins},`,
|
|
8241
|
+
"});",
|
|
8242
|
+
"",
|
|
8243
|
+
"export default {",
|
|
8244
|
+
" ...config,",
|
|
8245
|
+
" navigation: withTsxPages((config as any).navigation ?? []),",
|
|
8246
|
+
"};"
|
|
8247
|
+
] : [
|
|
8248
|
+
"export default buildApitogoConfig({",
|
|
8249
|
+
" ...siteConfig,",
|
|
8250
|
+
` plugins: ${plugins},`,
|
|
8251
|
+
"});"
|
|
8252
|
+
],
|
|
8100
8253
|
""
|
|
8101
8254
|
].join("\n");
|
|
8102
8255
|
}
|
|
8103
8256
|
async function readDemoPlans(file) {
|
|
8104
8257
|
if (!file) return void 0;
|
|
8105
8258
|
try {
|
|
8106
|
-
const parsed = JSON.parse(await
|
|
8259
|
+
const parsed = JSON.parse(await readFile8(file, "utf8"));
|
|
8107
8260
|
return Array.isArray(parsed.plans) ? parsed.plans : void 0;
|
|
8108
8261
|
} catch {
|
|
8109
8262
|
return void 0;
|
|
@@ -8113,7 +8266,7 @@ async function readTheme(resolved) {
|
|
|
8113
8266
|
const file = resolved.portal?.theme;
|
|
8114
8267
|
if (!file) return void 0;
|
|
8115
8268
|
try {
|
|
8116
|
-
return JSON.parse(await
|
|
8269
|
+
return JSON.parse(await readFile8(file, "utf8"));
|
|
8117
8270
|
} catch {
|
|
8118
8271
|
return void 0;
|
|
8119
8272
|
}
|
|
@@ -8171,9 +8324,19 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
|
|
|
8171
8324
|
});
|
|
8172
8325
|
}
|
|
8173
8326
|
}
|
|
8174
|
-
const
|
|
8327
|
+
const markdownRoutes = plan2.docs ? await docRoutes(profile.docs.content, {
|
|
8175
8328
|
includeDrafts: mode === "development"
|
|
8176
8329
|
}) : [];
|
|
8330
|
+
const tsxPages = plan2.docs ? (await findTsxPages(profile.docs.content)).filter(
|
|
8331
|
+
(page) => !markdownRoutes.includes(page.route)
|
|
8332
|
+
) : [];
|
|
8333
|
+
const wrapperPages = tsxPages.map((page, index) => ({
|
|
8334
|
+
id: `${TSX_PAGE_ELEMENT_PREFIX}${index}`,
|
|
8335
|
+
importPath: `./${CONTENT_LINK}/${path13.relative(resolved.configDir, page.file).split(path13.sep).join("/")}`
|
|
8336
|
+
}));
|
|
8337
|
+
const hostedDocRoutes = [
|
|
8338
|
+
.../* @__PURE__ */ new Set([...markdownRoutes, ...tsxPages.map((page) => page.route)])
|
|
8339
|
+
].sort();
|
|
8177
8340
|
if (plan2.plansPlugin && plan2.docs) {
|
|
8178
8341
|
const landing = hostedDocRoutes.some(
|
|
8179
8342
|
(route) => route === "/" || route === "/index"
|
|
@@ -8195,7 +8358,14 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
|
|
|
8195
8358
|
await readTheme(resolved),
|
|
8196
8359
|
{
|
|
8197
8360
|
redirects: home ? [home] : [],
|
|
8198
|
-
docsNavigation: docsNavigation(
|
|
8361
|
+
docsNavigation: docsNavigation(
|
|
8362
|
+
markdownRoutes,
|
|
8363
|
+
tsxPages.map((page, index) => ({
|
|
8364
|
+
route: page.route,
|
|
8365
|
+
label: page.label,
|
|
8366
|
+
element: wrapperPages[index]?.id ?? ""
|
|
8367
|
+
}))
|
|
8368
|
+
),
|
|
8199
8369
|
docsPath: pickLandingRoute(hostedDocRoutes),
|
|
8200
8370
|
demoPlans: plan2.demo && plan2.plansPlugin ? await readDemoPlans(resolved.plans?.file) : void 0,
|
|
8201
8371
|
protectedRoutes: protectedRoutesFor({
|
|
@@ -8206,21 +8376,21 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
|
|
|
8206
8376
|
})
|
|
8207
8377
|
}
|
|
8208
8378
|
);
|
|
8209
|
-
const wrapper = renderWrapper(plan2);
|
|
8210
|
-
const wrapperPath =
|
|
8379
|
+
const wrapper = renderWrapper(plan2, wrapperPages);
|
|
8380
|
+
const wrapperPath = path13.join(resolved.state.generatedDir, WRAPPER_FILE);
|
|
8211
8381
|
if (options.write !== false) {
|
|
8212
|
-
await mkdir4(
|
|
8382
|
+
await mkdir4(path13.dirname(wrapperPath), { recursive: true });
|
|
8213
8383
|
await writeFile5(
|
|
8214
|
-
|
|
8384
|
+
path13.join(path13.dirname(wrapperPath), SITE_CONFIG_FILE),
|
|
8215
8385
|
`${JSON.stringify(siteConfig, null, 2)}
|
|
8216
8386
|
`
|
|
8217
8387
|
);
|
|
8218
|
-
const referenceFile =
|
|
8219
|
-
|
|
8388
|
+
const referenceFile = path13.join(
|
|
8389
|
+
path13.dirname(wrapperPath),
|
|
8220
8390
|
REFERENCE_SPEC_FILE
|
|
8221
8391
|
);
|
|
8222
8392
|
if (referenceSpec !== void 0) {
|
|
8223
|
-
await mkdir4(
|
|
8393
|
+
await mkdir4(path13.dirname(referenceFile), { recursive: true });
|
|
8224
8394
|
await writeFile5(referenceFile, referenceSpec);
|
|
8225
8395
|
} else {
|
|
8226
8396
|
await rm2(referenceFile, { force: true });
|
|
@@ -8249,9 +8419,9 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
|
|
|
8249
8419
|
|
|
8250
8420
|
// src/config/v2/workspace.ts
|
|
8251
8421
|
import { createHash as createHash2 } from "node:crypto";
|
|
8252
|
-
import { access as access2, lstat, readFile as
|
|
8253
|
-
import
|
|
8254
|
-
import { glob as
|
|
8422
|
+
import { access as access2, lstat, readFile as readFile9, rm as rm3, writeFile as writeFile6 } from "node:fs/promises";
|
|
8423
|
+
import path14 from "node:path";
|
|
8424
|
+
import { glob as glob4 } from "glob";
|
|
8255
8425
|
|
|
8256
8426
|
// src/config/v2/link-directory.ts
|
|
8257
8427
|
import { symlink } from "node:fs/promises";
|
|
@@ -8284,18 +8454,18 @@ async function relink(target, link) {
|
|
|
8284
8454
|
}
|
|
8285
8455
|
var GENERATED_PACKAGE_JSON = '{\n "private": true,\n "type": "module"\n}\n';
|
|
8286
8456
|
async function writeGeneratedPackageJson(root) {
|
|
8287
|
-
const file =
|
|
8288
|
-
const current = await
|
|
8457
|
+
const file = path14.join(root, "package.json");
|
|
8458
|
+
const current = await readFile9(file, "utf8").catch(() => void 0);
|
|
8289
8459
|
if (current !== GENERATED_PACKAGE_JSON)
|
|
8290
8460
|
await writeFile6(file, GENERATED_PACKAGE_JSON, "utf8");
|
|
8291
8461
|
}
|
|
8292
8462
|
async function materializeWorkspace(resolved, prepared) {
|
|
8293
|
-
const root =
|
|
8463
|
+
const root = path14.dirname(prepared.wrapperPath);
|
|
8294
8464
|
await ensureStateDir(resolved.state);
|
|
8295
8465
|
await writeGeneratedPackageJson(root);
|
|
8296
|
-
await relink(resolved.configDir,
|
|
8297
|
-
const publicDir = resolved.portal &&
|
|
8298
|
-
const publicLink =
|
|
8466
|
+
await relink(resolved.configDir, path14.join(root, CONTENT_LINK));
|
|
8467
|
+
const publicDir = resolved.portal && path14.join(resolved.portal.dir, "public");
|
|
8468
|
+
const publicLink = path14.join(root, "public");
|
|
8299
8469
|
if (publicDir && await exists2(publicDir)) {
|
|
8300
8470
|
await relink(publicDir, publicLink);
|
|
8301
8471
|
} else {
|
|
@@ -8304,7 +8474,7 @@ async function materializeWorkspace(resolved, prepared) {
|
|
|
8304
8474
|
return root;
|
|
8305
8475
|
}
|
|
8306
8476
|
async function configFingerprint(configPath) {
|
|
8307
|
-
const text = await
|
|
8477
|
+
const text = await readFile9(configPath, "utf8");
|
|
8308
8478
|
try {
|
|
8309
8479
|
const raw = JSON.parse(text);
|
|
8310
8480
|
if (raw.project) {
|
|
@@ -8320,8 +8490,10 @@ async function portalArtifactHash(resolved, manifestText, cliVersion, wrapper =
|
|
|
8320
8490
|
const portal = resolved.portal;
|
|
8321
8491
|
const patterns = [
|
|
8322
8492
|
...portal?.docs.content ?? [],
|
|
8493
|
+
// React docs pages and the helpers next to them are imported by the wrapper, so their contents decide the build too.
|
|
8494
|
+
...portal?.docs.provider === "apitogo" ? tsxPagePatterns(portal.docs.content) : [],
|
|
8323
8495
|
...resolved.gateway?.specs ?? [],
|
|
8324
|
-
...portal ? [portal.theme,
|
|
8496
|
+
...portal ? [portal.theme, path14.join(portal.dir, "public", "**", "*")] : []
|
|
8325
8497
|
];
|
|
8326
8498
|
const positive = patterns.filter((p) => !p.startsWith("!"));
|
|
8327
8499
|
const ignore2 = patterns.filter((p) => p.startsWith("!")).map((p) => p.slice(1));
|
|
@@ -8329,7 +8501,7 @@ async function portalArtifactHash(resolved, manifestText, cliVersion, wrapper =
|
|
|
8329
8501
|
...new Set(
|
|
8330
8502
|
(await Promise.all(
|
|
8331
8503
|
positive.map(
|
|
8332
|
-
(pattern) =>
|
|
8504
|
+
(pattern) => glob4(pattern.split(path14.sep).join("/"), {
|
|
8333
8505
|
absolute: true,
|
|
8334
8506
|
nodir: true,
|
|
8335
8507
|
ignore: [...ignore2, "**/node_modules/**"]
|
|
@@ -8351,9 +8523,9 @@ async function portalArtifactHash(resolved, manifestText, cliVersion, wrapper =
|
|
|
8351
8523
|
`);
|
|
8352
8524
|
}
|
|
8353
8525
|
for (const file of files) {
|
|
8354
|
-
hash2.update(`file:${
|
|
8526
|
+
hash2.update(`file:${path14.relative(resolved.configDir, file)}
|
|
8355
8527
|
`);
|
|
8356
|
-
hash2.update(await
|
|
8528
|
+
hash2.update(await readFile9(file));
|
|
8357
8529
|
}
|
|
8358
8530
|
return hash2.digest("hex");
|
|
8359
8531
|
}
|
|
@@ -8369,7 +8541,7 @@ import {
|
|
|
8369
8541
|
stat as stat3,
|
|
8370
8542
|
writeFile as writeFile7
|
|
8371
8543
|
} from "node:fs/promises";
|
|
8372
|
-
import
|
|
8544
|
+
import path15 from "node:path";
|
|
8373
8545
|
|
|
8374
8546
|
// src/config/v2/full-server.ts
|
|
8375
8547
|
var FULL_SERVER_SOURCE = "server";
|
|
@@ -8735,7 +8907,7 @@ var exists3 = (target) => access3(target).then(
|
|
|
8735
8907
|
() => true,
|
|
8736
8908
|
() => false
|
|
8737
8909
|
);
|
|
8738
|
-
var rel = (dir, target) =>
|
|
8910
|
+
var rel = (dir, target) => path15.relative(dir, target).split(path15.sep).join("/") || ".";
|
|
8739
8911
|
var BLANK_SPEC = (name) => `openapi: 3.1.0
|
|
8740
8912
|
info:
|
|
8741
8913
|
title: ${JSON.stringify(name)}
|
|
@@ -8834,14 +9006,14 @@ function pair(value, flag, unit) {
|
|
|
8834
9006
|
return [Number(match[1]), Number(match[2])];
|
|
8835
9007
|
}
|
|
8836
9008
|
function insideProject(dir, requested, what) {
|
|
8837
|
-
const absolute =
|
|
8838
|
-
const relative =
|
|
8839
|
-
if (relative === "" || relative.startsWith("..") ||
|
|
9009
|
+
const absolute = path15.resolve(dir, requested);
|
|
9010
|
+
const relative = path15.relative(dir, absolute);
|
|
9011
|
+
if (relative === "" || relative.startsWith("..") || path15.isAbsolute(relative)) {
|
|
8840
9012
|
throw new ServiceEditError(
|
|
8841
9013
|
`${what} "${requested}" is outside the project directory.`
|
|
8842
9014
|
);
|
|
8843
9015
|
}
|
|
8844
|
-
return relative.split(
|
|
9016
|
+
return relative.split(path15.sep).join("/");
|
|
8845
9017
|
}
|
|
8846
9018
|
async function addFile(context, target, content) {
|
|
8847
9019
|
if (await exists3(target)) context.keep.push(target);
|
|
@@ -8893,16 +9065,16 @@ async function buildPortal(context) {
|
|
|
8893
9065
|
{ value: "starter", label: "A starter page I can edit" },
|
|
8894
9066
|
{ value: "blank", label: "An empty pages folder" }
|
|
8895
9067
|
]);
|
|
8896
|
-
const pages =
|
|
9068
|
+
const pages = path15.join(resolved.root, "portal", "pages");
|
|
8897
9069
|
if (template === "blank")
|
|
8898
|
-
await addFile(context,
|
|
9070
|
+
await addFile(context, path15.join(pages, ".gitkeep"), "");
|
|
8899
9071
|
else if (isFilled(options.template)) {
|
|
8900
9072
|
await addFile(
|
|
8901
9073
|
context,
|
|
8902
|
-
|
|
9074
|
+
path15.join(pages, "introduction.mdx"),
|
|
8903
9075
|
starterPage(name)
|
|
8904
9076
|
);
|
|
8905
|
-
const landingFile =
|
|
9077
|
+
const landingFile = path15.join(
|
|
8906
9078
|
resolved.root,
|
|
8907
9079
|
"portal",
|
|
8908
9080
|
"landing",
|
|
@@ -8920,7 +9092,7 @@ async function buildPortal(context) {
|
|
|
8920
9092
|
} else
|
|
8921
9093
|
await addFile(
|
|
8922
9094
|
context,
|
|
8923
|
-
|
|
9095
|
+
path15.join(pages, "index.mdx"),
|
|
8924
9096
|
starterPage(name)
|
|
8925
9097
|
);
|
|
8926
9098
|
}
|
|
@@ -8936,18 +9108,18 @@ async function buildPortal(context) {
|
|
|
8936
9108
|
};
|
|
8937
9109
|
}
|
|
8938
9110
|
async function createSourceFolder(context, sourcePath, runtime, writeSample) {
|
|
8939
|
-
const folder =
|
|
9111
|
+
const folder = path15.join(context.dir, sourcePath);
|
|
8940
9112
|
const entries = await readdir3(folder).catch(() => []);
|
|
8941
9113
|
if (entries.some((name) => name !== ".gitkeep")) return false;
|
|
8942
9114
|
if (writeSample && runtime === FULL_SERVER_RUNTIME) {
|
|
8943
9115
|
for (const [file, content] of Object.entries(
|
|
8944
9116
|
fullServerFiles(context.resolved.project.name)
|
|
8945
9117
|
))
|
|
8946
|
-
await addFile(context,
|
|
9118
|
+
await addFile(context, path15.join(folder, file), content);
|
|
8947
9119
|
return true;
|
|
8948
9120
|
}
|
|
8949
9121
|
if (entries.length === 0)
|
|
8950
|
-
await addFile(context,
|
|
9122
|
+
await addFile(context, path15.join(folder, ".gitkeep"), "");
|
|
8951
9123
|
context.notes.push(
|
|
8952
9124
|
`The folder ${sourcePath}/ is empty: put your backend code there before you deploy.`
|
|
8953
9125
|
);
|
|
@@ -9059,7 +9231,7 @@ async function buildGateway(context) {
|
|
|
9059
9231
|
specs = [];
|
|
9060
9232
|
for (const requested of requestedSpecs) {
|
|
9061
9233
|
const relative = insideProject(dir, requested, "OpenAPI file");
|
|
9062
|
-
if (!await stat3(
|
|
9234
|
+
if (!await stat3(path15.join(dir, relative)).then(
|
|
9063
9235
|
(s) => s.isFile(),
|
|
9064
9236
|
() => false
|
|
9065
9237
|
)) {
|
|
@@ -9070,7 +9242,7 @@ async function buildGateway(context) {
|
|
|
9070
9242
|
specs.push(relative);
|
|
9071
9243
|
}
|
|
9072
9244
|
} else if (createSpec) {
|
|
9073
|
-
const target =
|
|
9245
|
+
const target = path15.join(resolved.apisDir, "openapi.yaml");
|
|
9074
9246
|
await addFile(
|
|
9075
9247
|
context,
|
|
9076
9248
|
target,
|
|
@@ -9163,35 +9335,22 @@ async function buildPlans(context) {
|
|
|
9163
9335
|
const { options, dir, resolved } = context;
|
|
9164
9336
|
const o = options.plans ?? {};
|
|
9165
9337
|
const template = o.template ?? (options.template === "blank" ? "none" : isFilled(options.template) ? "starter" : "free");
|
|
9166
|
-
const billing = o.billing ?? (template === "tiered" ? "stripe" : "none");
|
|
9167
|
-
if (template === "tiered" && billing === "none") {
|
|
9168
|
-
throw new ServiceEditError(
|
|
9169
|
-
"The tiered template has paid plans, which need a billing provider.",
|
|
9170
|
-
"Use --billing stripe, or --template free."
|
|
9171
|
-
);
|
|
9172
|
-
}
|
|
9173
9338
|
const file = o.file ? insideProject(dir, o.file, "Plans file") : void 0;
|
|
9174
|
-
const target = file ?
|
|
9339
|
+
const target = file ? path15.join(dir, file) : resolved.plans?.file ?? path15.join(resolved.root, "plans.json");
|
|
9175
9340
|
await addFile(
|
|
9176
9341
|
context,
|
|
9177
9342
|
target,
|
|
9178
9343
|
`${JSON.stringify({ version: 1, plans: PLAN_TEMPLATES[template] }, null, 2)}
|
|
9179
9344
|
`
|
|
9180
9345
|
);
|
|
9181
|
-
if (
|
|
9346
|
+
if (PLAN_TEMPLATES[template].some((plan2) => isPaidPlan(plan2))) {
|
|
9182
9347
|
context.notes.push(
|
|
9183
|
-
"
|
|
9348
|
+
"A plan has a price, so payments go through Stripe: apitogo deploy asks for your Stripe secret key."
|
|
9184
9349
|
);
|
|
9185
9350
|
}
|
|
9186
9351
|
return {
|
|
9187
9352
|
...options.disabled ? { enabled: false } : {},
|
|
9188
|
-
...file ? { file } : {}
|
|
9189
|
-
...billing === "stripe" ? {
|
|
9190
|
-
billing: {
|
|
9191
|
-
provider: "stripe",
|
|
9192
|
-
apiKey: "secret:STRIPE_API_KEY"
|
|
9193
|
-
}
|
|
9194
|
-
} : { billing: { provider: "none" } }
|
|
9353
|
+
...file ? { file } : {}
|
|
9195
9354
|
};
|
|
9196
9355
|
}
|
|
9197
9356
|
function reparse(configPath, raw) {
|
|
@@ -9210,11 +9369,11 @@ function dependencyProblems(config2, configPath) {
|
|
|
9210
9369
|
return checkDependencies(config2, resolveConfigV2(config2, configPath));
|
|
9211
9370
|
}
|
|
9212
9371
|
async function planAddService(service, options) {
|
|
9213
|
-
const dir =
|
|
9372
|
+
const dir = path15.resolve(options.dir);
|
|
9214
9373
|
const { config: config2, resolved } = loadConfigV2(dir);
|
|
9215
9374
|
if (config2[service] !== void 0) {
|
|
9216
9375
|
throw new ServiceEditError(
|
|
9217
|
-
`${service} is already in ${
|
|
9376
|
+
`${service} is already in ${path15.basename(resolved.configPath)}.`,
|
|
9218
9377
|
`Edit the file, or run \`apitogo remove ${service}\` first. Its files are kept.`
|
|
9219
9378
|
);
|
|
9220
9379
|
}
|
|
@@ -9259,11 +9418,11 @@ async function planAddService(service, options) {
|
|
|
9259
9418
|
};
|
|
9260
9419
|
}
|
|
9261
9420
|
async function planRemoveService(service, options) {
|
|
9262
|
-
const dir =
|
|
9421
|
+
const dir = path15.resolve(options.dir);
|
|
9263
9422
|
const { config: config2, resolved } = loadConfigV2(dir);
|
|
9264
9423
|
if (config2[service] === void 0) {
|
|
9265
9424
|
throw new ServiceEditError(
|
|
9266
|
-
`${service} is not in ${
|
|
9425
|
+
`${service} is not in ${path15.basename(resolved.configPath)}.`
|
|
9267
9426
|
);
|
|
9268
9427
|
}
|
|
9269
9428
|
const { [service]: removed, ...rest } = config2;
|
|
@@ -9287,8 +9446,8 @@ async function planRemoveService(service, options) {
|
|
|
9287
9446
|
if (service === "gateway" && r.gateway) owned.push(...r.gateway.specs);
|
|
9288
9447
|
void removed;
|
|
9289
9448
|
const inside = (target) => {
|
|
9290
|
-
const relative =
|
|
9291
|
-
return relative !== "" && !relative.startsWith("..") && !
|
|
9449
|
+
const relative = path15.relative(resolved.root, target);
|
|
9450
|
+
return relative !== "" && !relative.startsWith("..") && !path15.isAbsolute(relative);
|
|
9292
9451
|
};
|
|
9293
9452
|
const deletes = [];
|
|
9294
9453
|
const left = [];
|
|
@@ -9327,7 +9486,7 @@ async function writeConfig(configPath, config2) {
|
|
|
9327
9486
|
async function applyServiceEdit(edit) {
|
|
9328
9487
|
const created = [];
|
|
9329
9488
|
for (const file of edit.files) {
|
|
9330
|
-
await mkdir5(
|
|
9489
|
+
await mkdir5(path15.dirname(file.path), { recursive: true });
|
|
9331
9490
|
try {
|
|
9332
9491
|
await writeFile7(file.path, file.content, { flag: "wx" });
|
|
9333
9492
|
created.push(file.path);
|
|
@@ -9343,7 +9502,7 @@ async function applyServiceEdit(edit) {
|
|
|
9343
9502
|
function formatServiceEdit(edit) {
|
|
9344
9503
|
const verb = edit.action === "add" ? "Adds" : "Removes";
|
|
9345
9504
|
return [
|
|
9346
|
-
`${verb} the ${edit.service} section in ${
|
|
9505
|
+
`${verb} the ${edit.service} section in ${path15.basename(edit.configPath)}.`,
|
|
9347
9506
|
...edit.files.length > 0 ? [
|
|
9348
9507
|
"Will create:",
|
|
9349
9508
|
...edit.files.map((file) => ` ${rel(edit.dir, file.path)}`)
|
|
@@ -9383,8 +9542,8 @@ async function clearProjectId(dir, projectId) {
|
|
|
9383
9542
|
|
|
9384
9543
|
// src/config/v2/ledger.ts
|
|
9385
9544
|
init_invariant();
|
|
9386
|
-
import { mkdir as mkdir6, readFile as
|
|
9387
|
-
import
|
|
9545
|
+
import { mkdir as mkdir6, readFile as readFile10, rename as rename4, rm as rm5, writeFile as writeFile8 } from "node:fs/promises";
|
|
9546
|
+
import path16 from "node:path";
|
|
9388
9547
|
var LEDGER_VERSION = 1;
|
|
9389
9548
|
var LedgerError = class extends ApitogoError {
|
|
9390
9549
|
constructor(code, message, developerHint) {
|
|
@@ -9400,7 +9559,7 @@ var emptyLedger = () => ({
|
|
|
9400
9559
|
async function readLedger(state) {
|
|
9401
9560
|
let text;
|
|
9402
9561
|
try {
|
|
9403
|
-
text = await
|
|
9562
|
+
text = await readFile10(state.file, "utf8");
|
|
9404
9563
|
} catch (error) {
|
|
9405
9564
|
if (error.code === "ENOENT")
|
|
9406
9565
|
return emptyLedger();
|
|
@@ -9439,7 +9598,7 @@ function corrupt(file, why) {
|
|
|
9439
9598
|
);
|
|
9440
9599
|
}
|
|
9441
9600
|
async function writeLedger(state, ledger) {
|
|
9442
|
-
await mkdir6(
|
|
9601
|
+
await mkdir6(path16.dirname(state.file), { recursive: true });
|
|
9443
9602
|
const temporary = `${state.file}.${process.pid}.tmp`;
|
|
9444
9603
|
try {
|
|
9445
9604
|
await writeFile8(temporary, `${JSON.stringify(ledger, null, 2)}
|
|
@@ -9535,8 +9694,8 @@ init_invariant();
|
|
|
9535
9694
|
|
|
9536
9695
|
// src/cli/check/v2.ts
|
|
9537
9696
|
init_apitogo_config_core();
|
|
9538
|
-
import { readFile as
|
|
9539
|
-
import
|
|
9697
|
+
import { readFile as readFile17 } from "node:fs/promises";
|
|
9698
|
+
import path50 from "node:path";
|
|
9540
9699
|
|
|
9541
9700
|
// src/cli/platform/client/platform-api.ts
|
|
9542
9701
|
import { basename } from "node:path";
|
|
@@ -9649,8 +9808,8 @@ var PlatformApiClient = class {
|
|
|
9649
9808
|
constructor(config2) {
|
|
9650
9809
|
this.config = config2;
|
|
9651
9810
|
}
|
|
9652
|
-
url(
|
|
9653
|
-
return `${this.config.apiUrl}${
|
|
9811
|
+
url(path97) {
|
|
9812
|
+
return `${this.config.apiUrl}${path97.startsWith("/") ? path97 : `/${path97}`}`;
|
|
9654
9813
|
}
|
|
9655
9814
|
headers(extra) {
|
|
9656
9815
|
return {
|
|
@@ -9660,9 +9819,9 @@ var PlatformApiClient = class {
|
|
|
9660
9819
|
...extra
|
|
9661
9820
|
};
|
|
9662
9821
|
}
|
|
9663
|
-
async request(method,
|
|
9822
|
+
async request(method, path97, init3) {
|
|
9664
9823
|
const response = await fetchWithRetry(
|
|
9665
|
-
this.url(
|
|
9824
|
+
this.url(path97),
|
|
9666
9825
|
{
|
|
9667
9826
|
method,
|
|
9668
9827
|
...init3,
|
|
@@ -10108,15 +10267,15 @@ var PlatformApiClient = class {
|
|
|
10108
10267
|
}
|
|
10109
10268
|
);
|
|
10110
10269
|
}
|
|
10111
|
-
deleteDevPortalPage(projectId,
|
|
10112
|
-
const query = new URLSearchParams({ path:
|
|
10270
|
+
deleteDevPortalPage(projectId, path97) {
|
|
10271
|
+
const query = new URLSearchParams({ path: path97 });
|
|
10113
10272
|
return this.request(
|
|
10114
10273
|
"DELETE",
|
|
10115
10274
|
`/api/v1/projects/${projectId}/dev-portal/pages/files?${query.toString()}`
|
|
10116
10275
|
);
|
|
10117
10276
|
}
|
|
10118
|
-
renameDevPortalPage(projectId,
|
|
10119
|
-
const query = new URLSearchParams({ path:
|
|
10277
|
+
renameDevPortalPage(projectId, path97, newName) {
|
|
10278
|
+
const query = new URLSearchParams({ path: path97 });
|
|
10120
10279
|
return this.request(
|
|
10121
10280
|
"POST",
|
|
10122
10281
|
`/api/v1/projects/${projectId}/dev-portal/pages/files/rename?${query.toString()}`,
|
|
@@ -10232,8 +10391,8 @@ var PlatformApiClient = class {
|
|
|
10232
10391
|
* the project-less endpoint is used; `planTier` overrides the tier used for paid-plan checks.
|
|
10233
10392
|
*/
|
|
10234
10393
|
validateGatewayPlans(plans, options = {}) {
|
|
10235
|
-
const
|
|
10236
|
-
return this.request("POST",
|
|
10394
|
+
const path97 = options.projectId ? `/api/v1/projects/${options.projectId}/gateway/plans/validate` : "/api/v1/gateway/plans/validate";
|
|
10395
|
+
return this.request("POST", path97, {
|
|
10237
10396
|
headers: { "Content-Type": "application/json" },
|
|
10238
10397
|
body: JSON.stringify({ plans, planTier: options.planTier })
|
|
10239
10398
|
});
|
|
@@ -10358,8 +10517,8 @@ var PlatformApiClient = class {
|
|
|
10358
10517
|
}
|
|
10359
10518
|
};
|
|
10360
10519
|
async function readFileBytes(filePath) {
|
|
10361
|
-
const { readFile:
|
|
10362
|
-
const buffer = await
|
|
10520
|
+
const { readFile: readFile28 } = await import("node:fs/promises");
|
|
10521
|
+
const buffer = await readFile28(filePath);
|
|
10363
10522
|
const arrayBuffer = new ArrayBuffer(buffer.byteLength);
|
|
10364
10523
|
new Uint8Array(arrayBuffer).set(buffer);
|
|
10365
10524
|
return arrayBuffer;
|
|
@@ -10370,8 +10529,8 @@ function isNotFoundError(error) {
|
|
|
10370
10529
|
|
|
10371
10530
|
// src/cli/platform/credentials-store.ts
|
|
10372
10531
|
import fs from "node:fs";
|
|
10373
|
-
import
|
|
10374
|
-
var CREDENTIALS_FILE =
|
|
10532
|
+
import path17 from "node:path";
|
|
10533
|
+
var CREDENTIALS_FILE = path17.join(
|
|
10375
10534
|
ZUDOKU_XDG_CONFIG_HOME,
|
|
10376
10535
|
"credentials.json"
|
|
10377
10536
|
);
|
|
@@ -10392,7 +10551,7 @@ function readStoredCredentials() {
|
|
|
10392
10551
|
}
|
|
10393
10552
|
}
|
|
10394
10553
|
function writeStoredCredentials(creds) {
|
|
10395
|
-
fs.mkdirSync(
|
|
10554
|
+
fs.mkdirSync(path17.dirname(CREDENTIALS_FILE), { recursive: true });
|
|
10396
10555
|
fs.writeFileSync(CREDENTIALS_FILE, JSON.stringify(creds, null, 2), {
|
|
10397
10556
|
mode: 384
|
|
10398
10557
|
});
|
|
@@ -10456,16 +10615,16 @@ function resolveProjectId(explicit, config2) {
|
|
|
10456
10615
|
import {
|
|
10457
10616
|
access as access4,
|
|
10458
10617
|
mkdir as mkdir12,
|
|
10459
|
-
readFile as
|
|
10618
|
+
readFile as readFile14,
|
|
10460
10619
|
rename as rename6,
|
|
10461
10620
|
rm as rm8,
|
|
10462
10621
|
writeFile as writeFile15
|
|
10463
10622
|
} from "node:fs/promises";
|
|
10464
|
-
import
|
|
10623
|
+
import path49 from "node:path";
|
|
10465
10624
|
|
|
10466
10625
|
// src/vite/build.ts
|
|
10467
|
-
import { mkdir as mkdir11, readFile as
|
|
10468
|
-
import
|
|
10626
|
+
import { mkdir as mkdir11, readFile as readFile12, rename as rename5, rm as rm7, writeFile as writeFile13 } from "node:fs/promises";
|
|
10627
|
+
import path47 from "node:path";
|
|
10469
10628
|
import { build as esbuild } from "esbuild";
|
|
10470
10629
|
import { build as viteBuild, mergeConfig as mergeConfig3 } from "vite";
|
|
10471
10630
|
|
|
@@ -10601,7 +10760,7 @@ init_invariant();
|
|
|
10601
10760
|
init_joinUrl();
|
|
10602
10761
|
|
|
10603
10762
|
// src/vite/config.ts
|
|
10604
|
-
import
|
|
10763
|
+
import path42 from "node:path";
|
|
10605
10764
|
import dotenv from "dotenv";
|
|
10606
10765
|
import colors8 from "picocolors";
|
|
10607
10766
|
import {
|
|
@@ -10612,7 +10771,7 @@ import {
|
|
|
10612
10771
|
// package.json
|
|
10613
10772
|
var package_default = {
|
|
10614
10773
|
name: "@lukoweb/apitogo",
|
|
10615
|
-
version: "0.2.
|
|
10774
|
+
version: "0.2.50",
|
|
10616
10775
|
type: "module",
|
|
10617
10776
|
sideEffects: [
|
|
10618
10777
|
"**/*.css",
|
|
@@ -11049,24 +11208,24 @@ async function loadDevPortalViteDefines(rootDir, mode) {
|
|
|
11049
11208
|
|
|
11050
11209
|
// src/vite/package-root.ts
|
|
11051
11210
|
init_file_exists();
|
|
11052
|
-
import
|
|
11211
|
+
import path22 from "node:path";
|
|
11053
11212
|
var findPackageRoot = async (startDir) => {
|
|
11054
11213
|
let dir = startDir;
|
|
11055
|
-
while (dir !==
|
|
11056
|
-
if (await fileExists(
|
|
11057
|
-
dir =
|
|
11214
|
+
while (dir !== path22.dirname(dir)) {
|
|
11215
|
+
if (await fileExists(path22.join(dir, "package.json"))) return dir;
|
|
11216
|
+
dir = path22.dirname(dir);
|
|
11058
11217
|
}
|
|
11059
11218
|
};
|
|
11060
11219
|
|
|
11061
11220
|
// src/vite/pagefind-dev-stub.ts
|
|
11062
11221
|
import fs2 from "node:fs/promises";
|
|
11063
|
-
import
|
|
11222
|
+
import path23 from "node:path";
|
|
11064
11223
|
var NOT_BUILT_YET = 'throw new Error("NOT_BUILT_YET");';
|
|
11065
11224
|
async function ensurePagefindDevStub(publicDir) {
|
|
11066
|
-
const pagefindPath =
|
|
11225
|
+
const pagefindPath = path23.join(publicDir, "pagefind/pagefind.js");
|
|
11067
11226
|
const exists6 = await fs2.stat(pagefindPath).catch(() => false);
|
|
11068
11227
|
if (!exists6) {
|
|
11069
|
-
await fs2.mkdir(
|
|
11228
|
+
await fs2.mkdir(path23.dirname(pagefindPath), { recursive: true });
|
|
11070
11229
|
await fs2.writeFile(pagefindPath, NOT_BUILT_YET);
|
|
11071
11230
|
}
|
|
11072
11231
|
}
|
|
@@ -11078,7 +11237,7 @@ import react from "@vitejs/plugin-react";
|
|
|
11078
11237
|
// src/vite/css/plugin.ts
|
|
11079
11238
|
init_loader();
|
|
11080
11239
|
init_plugin_theme();
|
|
11081
|
-
import
|
|
11240
|
+
import path24 from "node:path";
|
|
11082
11241
|
import { isCSSRequest as isCSSRequest2 } from "vite";
|
|
11083
11242
|
|
|
11084
11243
|
// src/vite/css/collect.ts
|
|
@@ -11113,7 +11272,7 @@ var VIRTUAL_ENTRY = "virtual:ssr-css.css";
|
|
|
11113
11272
|
function vitePluginSsrCss(pluginOpts) {
|
|
11114
11273
|
let server;
|
|
11115
11274
|
const config2 = getCurrentConfig();
|
|
11116
|
-
const virtualHref =
|
|
11275
|
+
const virtualHref = path24.join(
|
|
11117
11276
|
config2.basePath ?? "",
|
|
11118
11277
|
`/@id/__x00__${VIRTUAL_ENTRY}?direct`
|
|
11119
11278
|
);
|
|
@@ -11250,7 +11409,7 @@ var plugin_api_keys_default = viteApiKeysPlugin;
|
|
|
11250
11409
|
|
|
11251
11410
|
// src/vite/plugin-api.ts
|
|
11252
11411
|
import fs4 from "node:fs/promises";
|
|
11253
|
-
import
|
|
11412
|
+
import path30 from "node:path";
|
|
11254
11413
|
import { deepEqual as deepEqual2 } from "fast-equals";
|
|
11255
11414
|
import { runnerImport as runnerImport3 } from "vite";
|
|
11256
11415
|
init_package_json();
|
|
@@ -11259,7 +11418,7 @@ init_loader();
|
|
|
11259
11418
|
// src/config/validators/BuildSchema.ts
|
|
11260
11419
|
init_file_exists();
|
|
11261
11420
|
init_loader();
|
|
11262
|
-
import
|
|
11421
|
+
import path25 from "node:path";
|
|
11263
11422
|
import { runnerImport as runnerImport2 } from "vite";
|
|
11264
11423
|
import { z as z13 } from "zod";
|
|
11265
11424
|
var BuildProcessorSchema = z13.custom((val) => typeof val === "function");
|
|
@@ -11288,7 +11447,7 @@ var buildConfigFiles = [
|
|
|
11288
11447
|
];
|
|
11289
11448
|
async function getBuildConfigFilePath(rootDir) {
|
|
11290
11449
|
for (const fileName of buildConfigFiles) {
|
|
11291
|
-
const filepath =
|
|
11450
|
+
const filepath = path25.join(rootDir, fileName);
|
|
11292
11451
|
if (await fileExists(filepath)) {
|
|
11293
11452
|
return filepath;
|
|
11294
11453
|
}
|
|
@@ -11397,14 +11556,14 @@ var flattenAllOf = (schema2) => {
|
|
|
11397
11556
|
};
|
|
11398
11557
|
|
|
11399
11558
|
// src/lib/util/traverse.ts
|
|
11400
|
-
var traverse = (specification, transform,
|
|
11401
|
-
const transformed = transform(specification,
|
|
11559
|
+
var traverse = (specification, transform, path97 = []) => {
|
|
11560
|
+
const transformed = transform(specification, path97);
|
|
11402
11561
|
if (typeof transformed !== "object" || transformed === null) {
|
|
11403
11562
|
return transformed;
|
|
11404
11563
|
}
|
|
11405
11564
|
const result = Array.isArray(transformed) ? [] : {};
|
|
11406
11565
|
for (const [key, value] of Object.entries(transformed)) {
|
|
11407
|
-
const currentPath = [...
|
|
11566
|
+
const currentPath = [...path97, key];
|
|
11408
11567
|
if (Array.isArray(value)) {
|
|
11409
11568
|
result[key] = value.map(
|
|
11410
11569
|
(item, index) => typeof item === "object" && item != null ? traverse(item, transform, [...currentPath, index.toString()]) : item
|
|
@@ -11432,9 +11591,9 @@ var resolveLocalRef = (schema2, ref) => {
|
|
|
11432
11591
|
if (schemaCache?.has(ref)) {
|
|
11433
11592
|
return schemaCache.get(ref);
|
|
11434
11593
|
}
|
|
11435
|
-
const
|
|
11594
|
+
const path97 = ref.split("/").slice(1);
|
|
11436
11595
|
let current = schema2;
|
|
11437
|
-
for (const segment of
|
|
11596
|
+
for (const segment of path97) {
|
|
11438
11597
|
if (!current || typeof current !== "object") {
|
|
11439
11598
|
current = null;
|
|
11440
11599
|
}
|
|
@@ -11453,7 +11612,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
11453
11612
|
}
|
|
11454
11613
|
const cloned = structuredClone(schema2);
|
|
11455
11614
|
const visited = /* @__PURE__ */ new Set();
|
|
11456
|
-
const resolve = async (current,
|
|
11615
|
+
const resolve = async (current, path97) => {
|
|
11457
11616
|
if (isIndexableObject(current)) {
|
|
11458
11617
|
if (visited.has(current)) {
|
|
11459
11618
|
return CIRCULAR_REF;
|
|
@@ -11461,7 +11620,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
11461
11620
|
visited.add(current);
|
|
11462
11621
|
if (Array.isArray(current)) {
|
|
11463
11622
|
for (let index = 0; index < current.length; index++) {
|
|
11464
|
-
current[index] = await resolve(current[index], `${
|
|
11623
|
+
current[index] = await resolve(current[index], `${path97}/${index}`);
|
|
11465
11624
|
}
|
|
11466
11625
|
} else {
|
|
11467
11626
|
if ("$ref" in current && typeof current.$ref === "string") {
|
|
@@ -11472,13 +11631,13 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
11472
11631
|
for (const resolver of resolvers) {
|
|
11473
11632
|
const resolved = await resolver($ref);
|
|
11474
11633
|
if (resolved) {
|
|
11475
|
-
result2 = await resolve(resolved,
|
|
11634
|
+
result2 = await resolve(resolved, path97);
|
|
11476
11635
|
break;
|
|
11477
11636
|
}
|
|
11478
11637
|
}
|
|
11479
11638
|
if (result2 === void 0) {
|
|
11480
11639
|
const resolved = await resolveLocalRef(cloned, $ref);
|
|
11481
|
-
result2 = await resolve(resolved,
|
|
11640
|
+
result2 = await resolve(resolved, path97);
|
|
11482
11641
|
}
|
|
11483
11642
|
if (hasSiblings) {
|
|
11484
11643
|
if (result2 === CIRCULAR_REF) {
|
|
@@ -11491,7 +11650,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
11491
11650
|
return result2;
|
|
11492
11651
|
}
|
|
11493
11652
|
for (const key in current) {
|
|
11494
|
-
current[key] = await resolve(current[key], `${
|
|
11653
|
+
current[key] = await resolve(current[key], `${path97}/${key}`);
|
|
11495
11654
|
}
|
|
11496
11655
|
}
|
|
11497
11656
|
visited.delete(current);
|
|
@@ -11530,9 +11689,9 @@ var upgradeSchema = (schema2) => {
|
|
|
11530
11689
|
}
|
|
11531
11690
|
return sub;
|
|
11532
11691
|
});
|
|
11533
|
-
schema2 = traverse(schema2, (sub,
|
|
11692
|
+
schema2 = traverse(schema2, (sub, path97) => {
|
|
11534
11693
|
if (sub.example !== void 0) {
|
|
11535
|
-
if (isSchemaPath(
|
|
11694
|
+
if (isSchemaPath(path97 ?? [])) {
|
|
11536
11695
|
sub.examples = [sub.example];
|
|
11537
11696
|
} else {
|
|
11538
11697
|
sub.examples = {
|
|
@@ -11545,11 +11704,11 @@ var upgradeSchema = (schema2) => {
|
|
|
11545
11704
|
}
|
|
11546
11705
|
return sub;
|
|
11547
11706
|
});
|
|
11548
|
-
schema2 = traverse(schema2, (schema3,
|
|
11707
|
+
schema2 = traverse(schema2, (schema3, path97) => {
|
|
11549
11708
|
if (schema3.type === "object" && schema3.properties !== void 0) {
|
|
11550
|
-
const parentPath =
|
|
11709
|
+
const parentPath = path97?.slice(0, -1);
|
|
11551
11710
|
const isMultipart = parentPath?.some((segment, index) => {
|
|
11552
|
-
return segment === "content" &&
|
|
11711
|
+
return segment === "content" && path97?.[index + 1] === "multipart/form-data";
|
|
11553
11712
|
});
|
|
11554
11713
|
if (isMultipart) {
|
|
11555
11714
|
const entries = Object.entries(schema3.properties);
|
|
@@ -11563,8 +11722,8 @@ var upgradeSchema = (schema2) => {
|
|
|
11563
11722
|
}
|
|
11564
11723
|
return schema3;
|
|
11565
11724
|
});
|
|
11566
|
-
schema2 = traverse(schema2, (schema3,
|
|
11567
|
-
if (
|
|
11725
|
+
schema2 = traverse(schema2, (schema3, path97) => {
|
|
11726
|
+
if (path97?.includes("content") && path97.includes("application/octet-stream")) {
|
|
11568
11727
|
return {};
|
|
11569
11728
|
}
|
|
11570
11729
|
if (schema3.type === "string" && schema3.format === "binary") {
|
|
@@ -11590,11 +11749,11 @@ var upgradeSchema = (schema2) => {
|
|
|
11590
11749
|
}
|
|
11591
11750
|
return sub;
|
|
11592
11751
|
});
|
|
11593
|
-
schema2 = traverse(schema2, (schema3,
|
|
11752
|
+
schema2 = traverse(schema2, (schema3, path97) => {
|
|
11594
11753
|
if (schema3.type === "string" && schema3.format === "byte") {
|
|
11595
|
-
const parentPath =
|
|
11754
|
+
const parentPath = path97?.slice(0, -1);
|
|
11596
11755
|
const contentMediaType = parentPath?.find(
|
|
11597
|
-
(_, index) =>
|
|
11756
|
+
(_, index) => path97?.[index - 1] === "content"
|
|
11598
11757
|
);
|
|
11599
11758
|
return {
|
|
11600
11759
|
type: "string",
|
|
@@ -11606,7 +11765,7 @@ var upgradeSchema = (schema2) => {
|
|
|
11606
11765
|
});
|
|
11607
11766
|
return schema2;
|
|
11608
11767
|
};
|
|
11609
|
-
function isSchemaPath(
|
|
11768
|
+
function isSchemaPath(path97) {
|
|
11610
11769
|
const schemaLocations = [
|
|
11611
11770
|
["components", "schemas"],
|
|
11612
11771
|
"properties",
|
|
@@ -11619,10 +11778,10 @@ function isSchemaPath(path95) {
|
|
|
11619
11778
|
];
|
|
11620
11779
|
return schemaLocations.some((location) => {
|
|
11621
11780
|
if (Array.isArray(location)) {
|
|
11622
|
-
return location.every((segment, index) =>
|
|
11781
|
+
return location.every((segment, index) => path97[index] === segment);
|
|
11623
11782
|
}
|
|
11624
|
-
return
|
|
11625
|
-
}) ||
|
|
11783
|
+
return path97.includes(location);
|
|
11784
|
+
}) || path97.includes("schema") || path97.some((segment) => segment.endsWith("Schema"));
|
|
11626
11785
|
}
|
|
11627
11786
|
|
|
11628
11787
|
// src/lib/oas/parser/index.ts
|
|
@@ -11704,13 +11863,13 @@ var OPENAPI_PROPS = /* @__PURE__ */ new Set([
|
|
|
11704
11863
|
"anyOf",
|
|
11705
11864
|
"oneOf"
|
|
11706
11865
|
]);
|
|
11707
|
-
var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(),
|
|
11866
|
+
var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path97 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
|
|
11708
11867
|
if (obj === null || typeof obj !== "object") return obj;
|
|
11709
11868
|
const refPath = obj.__$ref;
|
|
11710
11869
|
const isCircular = currentPath.has(obj) || typeof refPath === "string" && currentRefPaths.has(refPath);
|
|
11711
11870
|
if (isCircular) {
|
|
11712
11871
|
if (typeof refPath === "string") return SCHEMA_REF_PREFIX + refPath;
|
|
11713
|
-
const circularProp =
|
|
11872
|
+
const circularProp = path97.find((p) => !OPENAPI_PROPS.has(p)) || path97[0];
|
|
11714
11873
|
return [CIRCULAR_REF, circularProp].filter(Boolean).join(":");
|
|
11715
11874
|
}
|
|
11716
11875
|
if (refs.has(obj)) return refs.get(obj);
|
|
@@ -11720,7 +11879,7 @@ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs
|
|
|
11720
11879
|
value,
|
|
11721
11880
|
currentPath,
|
|
11722
11881
|
refs,
|
|
11723
|
-
[...
|
|
11882
|
+
[...path97, key],
|
|
11724
11883
|
currentRefPaths
|
|
11725
11884
|
);
|
|
11726
11885
|
const result = Array.isArray(obj) ? obj.map((item, i) => recurse(item, i.toString())) : Object.fromEntries(
|
|
@@ -11755,7 +11914,7 @@ var resolveExtensions = (obj) => Object.fromEntries(
|
|
|
11755
11914
|
var getAllTags = (schema2) => {
|
|
11756
11915
|
const rootTags = schema2.tags ?? [];
|
|
11757
11916
|
const operations = Object.values(schema2.paths ?? {}).flatMap(
|
|
11758
|
-
(
|
|
11917
|
+
(path97) => HttpMethods.map((k) => path97?.[k]).filter((op) => op != null)
|
|
11759
11918
|
);
|
|
11760
11919
|
const operationTags = new Set(operations.flatMap((op) => op.tags ?? []));
|
|
11761
11920
|
const hasUntaggedOperations = operations.some(
|
|
@@ -11810,7 +11969,7 @@ var getAllSlugs = (ops, schemaTags = []) => {
|
|
|
11810
11969
|
var getOperationSlugKey = (op) => [op.path, op.method, op.operationId, op.summary].filter(Boolean).join("-");
|
|
11811
11970
|
var getAllOperations = (paths) => {
|
|
11812
11971
|
const operations = Object.entries(paths ?? {}).flatMap(
|
|
11813
|
-
([
|
|
11972
|
+
([path97, value]) => HttpMethods.flatMap((method) => {
|
|
11814
11973
|
if (!value?.[method]) return [];
|
|
11815
11974
|
const operation = value[method];
|
|
11816
11975
|
const pathParameters = value.parameters ?? [];
|
|
@@ -11830,7 +11989,7 @@ var getAllOperations = (paths) => {
|
|
|
11830
11989
|
return {
|
|
11831
11990
|
...operation,
|
|
11832
11991
|
method,
|
|
11833
|
-
path:
|
|
11992
|
+
path: path97,
|
|
11834
11993
|
parameters,
|
|
11835
11994
|
servers,
|
|
11836
11995
|
tags: operation.tags ?? []
|
|
@@ -12188,8 +12347,8 @@ var Schema = builder.objectRef("Schema").implement({
|
|
|
12188
12347
|
}),
|
|
12189
12348
|
paths: t.field({
|
|
12190
12349
|
type: [PathItem],
|
|
12191
|
-
resolve: (root) => Object.entries(root.paths ?? {}).map(([
|
|
12192
|
-
path:
|
|
12350
|
+
resolve: (root) => Object.entries(root.paths ?? {}).map(([path97, value]) => ({
|
|
12351
|
+
path: path97,
|
|
12193
12352
|
// biome-ignore lint/style/noNonNullAssertion: value is guaranteed to be defined
|
|
12194
12353
|
methods: Object.keys(value)
|
|
12195
12354
|
}))
|
|
@@ -12302,7 +12461,7 @@ var ensureArray = (value) => Array.isArray(value) ? value : [value];
|
|
|
12302
12461
|
|
|
12303
12462
|
// src/vite/api/SchemaManager.ts
|
|
12304
12463
|
import fs3 from "node:fs/promises";
|
|
12305
|
-
import
|
|
12464
|
+
import path26 from "node:path";
|
|
12306
12465
|
import {
|
|
12307
12466
|
$RefParser as $RefParser2
|
|
12308
12467
|
} from "@apidevtools/json-schema-ref-parser";
|
|
@@ -12354,7 +12513,7 @@ init_joinUrl();
|
|
|
12354
12513
|
|
|
12355
12514
|
// src/vite/api/schema-codegen.ts
|
|
12356
12515
|
var unescapeJsonPointer = (uri) => decodeURIComponent(uri.replace(/~1/g, "/").replace(/~0/g, "~"));
|
|
12357
|
-
var getSegmentsFromPath = (
|
|
12516
|
+
var getSegmentsFromPath = (path97) => path97.split("/").slice(1).map(unescapeJsonPointer);
|
|
12358
12517
|
var createLocalRefMap = (obj) => {
|
|
12359
12518
|
const refMap = /* @__PURE__ */ new Map();
|
|
12360
12519
|
const siblingsMap = /* @__PURE__ */ new Map();
|
|
@@ -12385,16 +12544,16 @@ var replaceMarkers = (code, mergedRefs) => code.replace(/"__refMap:(.*?)"/g, '__
|
|
|
12385
12544
|
/"__refMap\+Siblings:(.*?)"/g,
|
|
12386
12545
|
(_, key) => mergedRefs.get(key) ?? `__refMap["${key}"]`
|
|
12387
12546
|
);
|
|
12388
|
-
var lookup = (schema2,
|
|
12389
|
-
const parts = getSegmentsFromPath(
|
|
12547
|
+
var lookup = (schema2, path97, filePath) => {
|
|
12548
|
+
const parts = getSegmentsFromPath(path97);
|
|
12390
12549
|
let val = schema2;
|
|
12391
12550
|
for (const part of parts) {
|
|
12392
12551
|
while (val.$ref?.startsWith("#/")) {
|
|
12393
|
-
val = val.$ref ===
|
|
12552
|
+
val = val.$ref === path97 ? val : lookup(schema2, val.$ref, filePath);
|
|
12394
12553
|
}
|
|
12395
12554
|
if (val[part] === void 0) {
|
|
12396
12555
|
throw new Error(
|
|
12397
|
-
`Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${
|
|
12556
|
+
`Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path97}`
|
|
12398
12557
|
);
|
|
12399
12558
|
}
|
|
12400
12559
|
val = val[part];
|
|
@@ -12492,18 +12651,18 @@ var SchemaManager = class {
|
|
|
12492
12651
|
];
|
|
12493
12652
|
}
|
|
12494
12653
|
getPathForFile = (input5, params) => {
|
|
12495
|
-
const filePath =
|
|
12654
|
+
const filePath = path26.resolve(this.config.__meta.rootDir, input5);
|
|
12496
12655
|
const apis = ensureArray(this.config.apis ?? []);
|
|
12497
12656
|
for (const apiConfig of apis) {
|
|
12498
12657
|
if (!apiConfig || apiConfig.type !== "file" || !apiConfig.path) continue;
|
|
12499
12658
|
const match = normalizeInputs(apiConfig.input).some(
|
|
12500
|
-
(i) =>
|
|
12659
|
+
(i) => path26.resolve(this.config.__meta.rootDir, i.input) === filePath && deepEqual(i.params, params)
|
|
12501
12660
|
);
|
|
12502
12661
|
if (match) return apiConfig.path;
|
|
12503
12662
|
}
|
|
12504
12663
|
};
|
|
12505
12664
|
processSchema = async (input5) => {
|
|
12506
|
-
const filePath =
|
|
12665
|
+
const filePath = path26.resolve(this.config.__meta.rootDir, input5.input);
|
|
12507
12666
|
const params = input5.params;
|
|
12508
12667
|
const configuredPath = this.getPathForFile(input5.input, params);
|
|
12509
12668
|
if (!configuredPath) {
|
|
@@ -12539,9 +12698,9 @@ var SchemaManager = class {
|
|
|
12539
12698
|
const processedTime = Date.now();
|
|
12540
12699
|
const code = generateCode(processedSchema, filePath);
|
|
12541
12700
|
const prefixPath = slugify(configuredPath);
|
|
12542
|
-
const processedFilePath =
|
|
12701
|
+
const processedFilePath = path26.posix.join(
|
|
12543
12702
|
this.storeDir,
|
|
12544
|
-
`${prefixPath}-${
|
|
12703
|
+
`${prefixPath}-${path26.basename(filePath)}${paramsSuffix(params)}.js`
|
|
12545
12704
|
);
|
|
12546
12705
|
const importKey = processedFilePath;
|
|
12547
12706
|
await fs3.writeFile(processedFilePath, code);
|
|
@@ -12590,7 +12749,7 @@ var SchemaManager = class {
|
|
|
12590
12749
|
};
|
|
12591
12750
|
getAllTrackedFiles = () => Array.from(this.referencedBy.keys());
|
|
12592
12751
|
getFilesToReprocess = (changedFile) => {
|
|
12593
|
-
const resolvedPath =
|
|
12752
|
+
const resolvedPath = path26.resolve(this.config.__meta.rootDir, changedFile);
|
|
12594
12753
|
const referencedBy = this.referencedBy.get(resolvedPath);
|
|
12595
12754
|
if (!referencedBy) return [];
|
|
12596
12755
|
const filesToProcess = referencedBy.size === 0 ? [resolvedPath] : Array.from(referencedBy);
|
|
@@ -12619,7 +12778,7 @@ var SchemaManager = class {
|
|
|
12619
12778
|
version: "",
|
|
12620
12779
|
path: input5.path ?? "",
|
|
12621
12780
|
label: input5.label,
|
|
12622
|
-
inputPath:
|
|
12781
|
+
inputPath: path26.resolve(this.config.__meta.rootDir, input5.input),
|
|
12623
12782
|
params: input5.params,
|
|
12624
12783
|
importKey: "",
|
|
12625
12784
|
downloadUrl: "",
|
|
@@ -12639,8 +12798,8 @@ var SchemaManager = class {
|
|
|
12639
12798
|
}
|
|
12640
12799
|
}
|
|
12641
12800
|
};
|
|
12642
|
-
getLatestSchema = (
|
|
12643
|
-
getSchemasForPath = (
|
|
12801
|
+
getLatestSchema = (path97) => this.processedSchemas[path97]?.at(0);
|
|
12802
|
+
getSchemasForPath = (path97) => this.processedSchemas[path97];
|
|
12644
12803
|
getSchemaImports = () => Object.values(this.processedSchemas).flat().filter((s) => s.importKey);
|
|
12645
12804
|
getUrlToFilePathMap = () => {
|
|
12646
12805
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -12662,7 +12821,7 @@ var SchemaManager = class {
|
|
|
12662
12821
|
};
|
|
12663
12822
|
createSchemaPath = (inputPath, versionPath, apiPath, params) => {
|
|
12664
12823
|
const suffix = paramsSuffix(params);
|
|
12665
|
-
const extension = suffix ? ".json" :
|
|
12824
|
+
const extension = suffix ? ".json" : path26.extname(inputPath);
|
|
12666
12825
|
return joinUrl(
|
|
12667
12826
|
this.config.basePath,
|
|
12668
12827
|
apiPath,
|
|
@@ -12685,7 +12844,7 @@ var SchemaManager = class {
|
|
|
12685
12844
|
// src/vite/plugin-config-reload.ts
|
|
12686
12845
|
init_logger();
|
|
12687
12846
|
init_loader();
|
|
12688
|
-
import
|
|
12847
|
+
import path29 from "node:path";
|
|
12689
12848
|
import colors7 from "picocolors";
|
|
12690
12849
|
|
|
12691
12850
|
// src/vite/plugin-navigation.ts
|
|
@@ -12695,8 +12854,8 @@ import { stringify as stringify3 } from "javascript-stringify";
|
|
|
12695
12854
|
import { isElement } from "react-is";
|
|
12696
12855
|
|
|
12697
12856
|
// src/config/validators/NavigationSchema.ts
|
|
12698
|
-
import
|
|
12699
|
-
import { glob as
|
|
12857
|
+
import path27 from "node:path";
|
|
12858
|
+
import { glob as glob5 } from "glob";
|
|
12700
12859
|
import { fromMarkdown } from "mdast-util-from-markdown";
|
|
12701
12860
|
import { mdxFromMarkdown } from "mdast-util-mdx";
|
|
12702
12861
|
import { mdxjs } from "micromark-extension-mdxjs";
|
|
@@ -12730,7 +12889,7 @@ var extractRichH1 = (content) => {
|
|
|
12730
12889
|
}
|
|
12731
12890
|
};
|
|
12732
12891
|
var isNavigationItem = (item) => item !== void 0;
|
|
12733
|
-
var toPosixPath = (filePath) => filePath.split(
|
|
12892
|
+
var toPosixPath = (filePath) => filePath.split(path27.win32.sep).join(path27.posix.sep);
|
|
12734
12893
|
var NavigationResolver = class {
|
|
12735
12894
|
rootDir;
|
|
12736
12895
|
globPatterns;
|
|
@@ -12744,7 +12903,7 @@ var NavigationResolver = class {
|
|
|
12744
12903
|
}
|
|
12745
12904
|
async initialize() {
|
|
12746
12905
|
if (this.globFiles.length > 0) return;
|
|
12747
|
-
this.globFiles = await
|
|
12906
|
+
this.globFiles = await glob5(this.globPatterns, {
|
|
12748
12907
|
root: this.rootDir,
|
|
12749
12908
|
ignore: ["**/node_modules/**", "**/.git/**", "**/dist/**"]
|
|
12750
12909
|
}).then((files) => files.map(toPosixPath));
|
|
@@ -12863,13 +13022,13 @@ init_invariant();
|
|
|
12863
13022
|
|
|
12864
13023
|
// src/vite/debug.ts
|
|
12865
13024
|
import { mkdir as mkdir7, writeFile as writeFile9 } from "node:fs/promises";
|
|
12866
|
-
import
|
|
13025
|
+
import path28 from "node:path";
|
|
12867
13026
|
async function writePluginDebugCode(rootDir, pluginName, code, extension = "js") {
|
|
12868
13027
|
if (process.env.ZUDOKU_BUILD_DEBUG) {
|
|
12869
|
-
const debugDir =
|
|
13028
|
+
const debugDir = path28.join(rootDir, "dist", "debug");
|
|
12870
13029
|
await mkdir7(debugDir, { recursive: true });
|
|
12871
13030
|
await writeFile9(
|
|
12872
|
-
|
|
13031
|
+
path28.join(debugDir, `${pluginName}.${extension}`),
|
|
12873
13032
|
typeof code === "string" ? code : code.join("\n")
|
|
12874
13033
|
);
|
|
12875
13034
|
}
|
|
@@ -12978,7 +13137,7 @@ var viteConfigReloadPlugin = () => ({
|
|
|
12978
13137
|
reload(server);
|
|
12979
13138
|
logger.info(
|
|
12980
13139
|
colors7.blue(
|
|
12981
|
-
`Config ${
|
|
13140
|
+
`Config ${path29.basename(currentConfig.__meta.configPath)} changed. Reloading...`
|
|
12982
13141
|
),
|
|
12983
13142
|
{ timestamp: true }
|
|
12984
13143
|
);
|
|
@@ -12992,11 +13151,11 @@ var viteApiPlugin = async () => {
|
|
|
12992
13151
|
const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
|
|
12993
13152
|
const initialConfig = getCurrentConfig();
|
|
12994
13153
|
const zuploProcessors = ZuploEnv.isZuplo ? await runnerImport3(
|
|
12995
|
-
|
|
13154
|
+
path30.resolve(getZudokuRootDir(), "src/zuplo/with-zuplo-processors.ts")
|
|
12996
13155
|
).then((m) => m.module.default(initialConfig.__meta.rootDir)) : [];
|
|
12997
13156
|
const buildConfig = await getBuildConfig();
|
|
12998
13157
|
const buildProcessors = buildConfig?.processors ?? [];
|
|
12999
|
-
const tmpStoreDir =
|
|
13158
|
+
const tmpStoreDir = path30.posix.join(
|
|
13000
13159
|
initialConfig.__meta.rootDir,
|
|
13001
13160
|
"node_modules/.apitogo/processed"
|
|
13002
13161
|
);
|
|
@@ -13028,7 +13187,7 @@ var viteApiPlugin = async () => {
|
|
|
13028
13187
|
const inputPath = pathMap.get(req.url);
|
|
13029
13188
|
if (!inputPath) return next();
|
|
13030
13189
|
const content = await fs4.readFile(inputPath, "utf-8");
|
|
13031
|
-
const mimeType =
|
|
13190
|
+
const mimeType = path30.extname(inputPath).toLowerCase() === ".json" ? "application/json" : "application/x-yaml";
|
|
13032
13191
|
res.setHeader("Content-Type", `${mimeType}; charset=utf-8`);
|
|
13033
13192
|
return res.end(content);
|
|
13034
13193
|
});
|
|
@@ -13216,8 +13375,8 @@ var viteApiPlugin = async () => {
|
|
|
13216
13375
|
if (process.env.NODE_ENV !== "production") return;
|
|
13217
13376
|
for (const [urlPath, inputPath] of pathMap) {
|
|
13218
13377
|
const content = await fs4.readFile(inputPath, "utf-8");
|
|
13219
|
-
const outputPath =
|
|
13220
|
-
await fs4.mkdir(
|
|
13378
|
+
const outputPath = path30.join(config2.__meta.rootDir, "dist", urlPath);
|
|
13379
|
+
await fs4.mkdir(path30.dirname(outputPath), { recursive: true });
|
|
13221
13380
|
await fs4.writeFile(outputPath, content, "utf-8");
|
|
13222
13381
|
}
|
|
13223
13382
|
}
|
|
@@ -13260,7 +13419,7 @@ var plugin_auth_default = viteAuthPlugin;
|
|
|
13260
13419
|
|
|
13261
13420
|
// src/vite/plugin-component.ts
|
|
13262
13421
|
init_loader();
|
|
13263
|
-
import
|
|
13422
|
+
import path31 from "node:path";
|
|
13264
13423
|
var viteAliasPlugin = () => {
|
|
13265
13424
|
return {
|
|
13266
13425
|
name: "zudoku-component-plugin",
|
|
@@ -13288,7 +13447,7 @@ var viteAliasPlugin = () => {
|
|
|
13288
13447
|
];
|
|
13289
13448
|
const aliases = replacements.map(([find, replacement]) => ({
|
|
13290
13449
|
find,
|
|
13291
|
-
replacement:
|
|
13450
|
+
replacement: path31.posix.join(config2.__meta.moduleDir, replacement)
|
|
13292
13451
|
}));
|
|
13293
13452
|
return config2.__meta.mode === "internal" || config2.__meta.mode === "standalone" ? { resolve: { alias: aliases } } : void 0;
|
|
13294
13453
|
}
|
|
@@ -13299,11 +13458,11 @@ var plugin_component_default = viteAliasPlugin;
|
|
|
13299
13458
|
// src/vite/plugin-config.ts
|
|
13300
13459
|
init_package_json();
|
|
13301
13460
|
init_loader();
|
|
13302
|
-
import
|
|
13461
|
+
import path32 from "node:path";
|
|
13303
13462
|
import { normalizePath } from "vite";
|
|
13304
13463
|
var virtualModuleId3 = "virtual:zudoku-config";
|
|
13305
13464
|
var resolvedVirtualModuleId3 = `\0${virtualModuleId3}`;
|
|
13306
|
-
var browserConfigLoaderPath =
|
|
13465
|
+
var browserConfigLoaderPath = path32.join(
|
|
13307
13466
|
getZudokuRootDir(),
|
|
13308
13467
|
"src/config/apitogo-config-loader.browser.ts"
|
|
13309
13468
|
);
|
|
@@ -13437,7 +13596,7 @@ var plugin_custom_pages_default = viteCustomPagesPlugin;
|
|
|
13437
13596
|
|
|
13438
13597
|
// src/vite/plugin-doc-metadata.ts
|
|
13439
13598
|
init_loader();
|
|
13440
|
-
import { glob as
|
|
13599
|
+
import { glob as glob6 } from "glob";
|
|
13441
13600
|
var serializeMetadata = async (filePath) => {
|
|
13442
13601
|
const fm = await readFrontmatter(filePath);
|
|
13443
13602
|
const h1 = fm.content.match(/^#\s+(.*)$/m)?.[1];
|
|
@@ -13448,7 +13607,7 @@ var viteDocMetadataPlugin = () => ({
|
|
|
13448
13607
|
name: "zudoku-doc-metadata-plugin",
|
|
13449
13608
|
configureServer: async (server) => {
|
|
13450
13609
|
const config2 = getCurrentConfig();
|
|
13451
|
-
const files = await
|
|
13610
|
+
const files = await glob6("**/*.{md,mdx}", {
|
|
13452
13611
|
cwd: config2.__meta.rootDir,
|
|
13453
13612
|
ignore: ["node_modules", "dist"],
|
|
13454
13613
|
absolute: true
|
|
@@ -13474,9 +13633,9 @@ var viteDocMetadataPlugin = () => ({
|
|
|
13474
13633
|
|
|
13475
13634
|
// src/vite/plugin-docs.ts
|
|
13476
13635
|
init_loader();
|
|
13477
|
-
import
|
|
13478
|
-
import { glob as
|
|
13479
|
-
import
|
|
13636
|
+
import path33 from "node:path";
|
|
13637
|
+
import { glob as glob7 } from "glob";
|
|
13638
|
+
import globParent3 from "glob-parent";
|
|
13480
13639
|
init_ZudokuConfig();
|
|
13481
13640
|
|
|
13482
13641
|
// src/lib/components/navigation/utils.ts
|
|
@@ -13531,19 +13690,19 @@ var globMarkdownFiles = async (config2, options = { absolute: false }) => {
|
|
|
13531
13690
|
const docsConfig = DocsConfigSchema.parse(config2.docs ?? {});
|
|
13532
13691
|
const fileMapping = {};
|
|
13533
13692
|
for (const globPattern of docsConfig.files) {
|
|
13534
|
-
const globbedFiles = await
|
|
13693
|
+
const globbedFiles = await glob7(globPattern, {
|
|
13535
13694
|
root: config2.__meta.rootDir,
|
|
13536
13695
|
ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**"],
|
|
13537
13696
|
// Always glob with relative paths to avoid issues on different OS
|
|
13538
13697
|
absolute: false,
|
|
13539
13698
|
posix: true
|
|
13540
13699
|
});
|
|
13541
|
-
const parent =
|
|
13700
|
+
const parent = globParent3(globPattern).replace(/^\.?\//, "");
|
|
13542
13701
|
let draftFiles = /* @__PURE__ */ new Set();
|
|
13543
13702
|
if (process.env.NODE_ENV !== "development") {
|
|
13544
13703
|
const draftStatuses = await Promise.all(
|
|
13545
13704
|
globbedFiles.map(async (file) => {
|
|
13546
|
-
const absolutePath =
|
|
13705
|
+
const absolutePath = path33.resolve(config2.__meta.rootDir, file);
|
|
13547
13706
|
const { data } = await readFrontmatter(absolutePath);
|
|
13548
13707
|
return { file, isDraft: data.draft === true };
|
|
13549
13708
|
})
|
|
@@ -13556,9 +13715,9 @@ var globMarkdownFiles = async (config2, options = { absolute: false }) => {
|
|
|
13556
13715
|
if (draftFiles.has(file)) {
|
|
13557
13716
|
continue;
|
|
13558
13717
|
}
|
|
13559
|
-
const relativePath =
|
|
13718
|
+
const relativePath = path33.posix.relative(parent, file);
|
|
13560
13719
|
const routePath = ensureLeadingSlash(relativePath.replace(/\.mdx?$/, ""));
|
|
13561
|
-
const filePath = options.absolute ?
|
|
13720
|
+
const filePath = options.absolute ? path33.resolve(config2.__meta.rootDir, file) : file;
|
|
13562
13721
|
fileMapping[routePath] = filePath;
|
|
13563
13722
|
}
|
|
13564
13723
|
}
|
|
@@ -13622,7 +13781,7 @@ var viteDocsPlugin = () => {
|
|
|
13622
13781
|
const globbedDocuments = {};
|
|
13623
13782
|
for (const [routePath, file] of Object.entries(fileMapping)) {
|
|
13624
13783
|
const importPath = ensureLeadingSlash(
|
|
13625
|
-
|
|
13784
|
+
path33.posix.join(globImportBasePath, file)
|
|
13626
13785
|
);
|
|
13627
13786
|
globbedDocuments[routePath] = importPath;
|
|
13628
13787
|
}
|
|
@@ -13648,7 +13807,7 @@ var plugin_docs_default = viteDocsPlugin;
|
|
|
13648
13807
|
// src/vite/plugin-local-manifest.ts
|
|
13649
13808
|
init_apitogo_config_loader();
|
|
13650
13809
|
init_local_manifest();
|
|
13651
|
-
import
|
|
13810
|
+
import path34 from "node:path";
|
|
13652
13811
|
var APITOGO_LOCAL_MANIFEST_VIRTUAL_ID = "virtual:apitogo-local-manifest";
|
|
13653
13812
|
var resolvedVirtualModuleId4 = `\0${APITOGO_LOCAL_MANIFEST_VIRTUAL_ID}`;
|
|
13654
13813
|
var viteLocalManifestPlugin = () => {
|
|
@@ -13698,8 +13857,8 @@ var viteLocalManifestPlugin = () => {
|
|
|
13698
13857
|
server.watcher.add(watchPath);
|
|
13699
13858
|
}
|
|
13700
13859
|
server.watcher.on("change", async (changedPath) => {
|
|
13701
|
-
const resolvedChanged =
|
|
13702
|
-
if (!watchPaths.some((p) =>
|
|
13860
|
+
const resolvedChanged = path34.resolve(changedPath);
|
|
13861
|
+
if (!watchPaths.some((p) => path34.resolve(p) === resolvedChanged)) {
|
|
13703
13862
|
return;
|
|
13704
13863
|
}
|
|
13705
13864
|
const module = server.moduleGraph.getModuleById(
|
|
@@ -13726,7 +13885,7 @@ init_loader();
|
|
|
13726
13885
|
init_ProtectedRoutesSchema();
|
|
13727
13886
|
init_joinUrl();
|
|
13728
13887
|
import { mkdir as mkdir8, writeFile as writeFile10 } from "node:fs/promises";
|
|
13729
|
-
import
|
|
13888
|
+
import path35 from "node:path";
|
|
13730
13889
|
import { matchPath } from "react-router";
|
|
13731
13890
|
var processMarkdownFile = async (filePath) => {
|
|
13732
13891
|
const { content: markdownContent, data: frontmatter } = await readFrontmatter(filePath);
|
|
@@ -13814,7 +13973,7 @@ var viteMarkdownExportPlugin = () => {
|
|
|
13814
13973
|
if (process.env.NODE_ENV !== "production" || Object.keys(markdownFiles).length === 0 || !needsMdFiles) {
|
|
13815
13974
|
return;
|
|
13816
13975
|
}
|
|
13817
|
-
const distDir =
|
|
13976
|
+
const distDir = path35.join(
|
|
13818
13977
|
config2.__meta.rootDir,
|
|
13819
13978
|
"dist",
|
|
13820
13979
|
config2.basePath ?? ""
|
|
@@ -13835,15 +13994,15 @@ var viteMarkdownExportPlugin = () => {
|
|
|
13835
13994
|
content: finalMarkdown
|
|
13836
13995
|
});
|
|
13837
13996
|
const segments = routePath === "/" ? ["index"] : routePath.split("/").filter(Boolean);
|
|
13838
|
-
const outputPath = `${
|
|
13839
|
-
await mkdir8(
|
|
13997
|
+
const outputPath = `${path35.join(distDir, ...segments)}.md`;
|
|
13998
|
+
await mkdir8(path35.dirname(outputPath), { recursive: true });
|
|
13840
13999
|
await writeFile10(outputPath, finalMarkdown, "utf-8");
|
|
13841
14000
|
} catch (error) {
|
|
13842
14001
|
console.warn(`Failed to export markdown for ${routePath}:`, error);
|
|
13843
14002
|
}
|
|
13844
14003
|
}
|
|
13845
14004
|
if (config2.docs?.llms?.llmsTxt || config2.docs?.llms?.llmsTxtFull) {
|
|
13846
|
-
const markdownInfoPath =
|
|
14005
|
+
const markdownInfoPath = path35.join(
|
|
13847
14006
|
config2.__meta.rootDir,
|
|
13848
14007
|
"node_modules/.apitogo/markdown-info.json"
|
|
13849
14008
|
);
|
|
@@ -13995,9 +14154,9 @@ var remarkCodeTabs = () => (tree) => {
|
|
|
13995
14154
|
};
|
|
13996
14155
|
|
|
13997
14156
|
// src/vite/mdx/remark-inject-filepath.ts
|
|
13998
|
-
import
|
|
14157
|
+
import path36 from "node:path";
|
|
13999
14158
|
var remarkInjectFilepath = (rootDir) => (tree, vfile) => {
|
|
14000
|
-
const relativePath =
|
|
14159
|
+
const relativePath = path36.relative(rootDir, vfile.path).split(path36.sep).join(path36.posix.sep);
|
|
14001
14160
|
tree.children.unshift(exportMdxjsConst("__filepath", relativePath));
|
|
14002
14161
|
};
|
|
14003
14162
|
|
|
@@ -14084,18 +14243,18 @@ var remarkLastModified = () => {
|
|
|
14084
14243
|
};
|
|
14085
14244
|
|
|
14086
14245
|
// src/vite/mdx/remark-link-rewrite.ts
|
|
14087
|
-
import
|
|
14246
|
+
import path37 from "node:path";
|
|
14088
14247
|
import { visit as visit5 } from "unist-util-visit";
|
|
14089
14248
|
var remarkLinkRewrite = (basePath = "") => (tree) => {
|
|
14090
14249
|
visit5(tree, "link", (node) => {
|
|
14091
14250
|
if (!node.url) return;
|
|
14092
14251
|
if (node.url.startsWith("http") || node.url.startsWith("mailto:")) return;
|
|
14093
14252
|
node.url = node.url.replace(/\\/g, "/");
|
|
14094
|
-
const base =
|
|
14253
|
+
const base = path37.posix.join(basePath);
|
|
14095
14254
|
if (basePath && node.url.startsWith(base)) {
|
|
14096
14255
|
node.url = node.url.slice(base.length);
|
|
14097
14256
|
} else if (!node.url.startsWith("/") && !node.url.startsWith("#")) {
|
|
14098
|
-
node.url =
|
|
14257
|
+
node.url = path37.posix.join("..", node.url);
|
|
14099
14258
|
}
|
|
14100
14259
|
node.url = node.url.replace(/\.mdx?(#.*)?$/, "$1");
|
|
14101
14260
|
});
|
|
@@ -14315,14 +14474,14 @@ var plugin_mdx_default = viteMdxPlugin;
|
|
|
14315
14474
|
|
|
14316
14475
|
// src/vite/plugin-modules.ts
|
|
14317
14476
|
init_loader();
|
|
14318
|
-
import
|
|
14477
|
+
import path38 from "node:path";
|
|
14319
14478
|
import { normalizePath as normalizePath2 } from "vite";
|
|
14320
|
-
var getLandingModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(
|
|
14321
|
-
var getUserPanelModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(
|
|
14479
|
+
var getLandingModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path38.join(moduleDir, "../module-landing/src/index.tsx")) : "@lukoweb/apitogo-module-landing";
|
|
14480
|
+
var getUserPanelModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path38.join(moduleDir, "../module-user-panel/src/index.tsx")) : "@lukoweb/apitogo-module-user-panel";
|
|
14322
14481
|
var getBillingPluginImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(
|
|
14323
|
-
|
|
14482
|
+
path38.join(moduleDir, "../plugin-dev-portal-billing/src/index.ts")
|
|
14324
14483
|
) : "@lukoweb/apitogo-plugin-dev-portal-billing";
|
|
14325
|
-
var resolveProjectPageImport = (rootDir, pagePath) => normalizePath2(
|
|
14484
|
+
var resolveProjectPageImport = (rootDir, pagePath) => normalizePath2(path38.resolve(rootDir, pagePath));
|
|
14326
14485
|
var viteModulesPlugin = () => {
|
|
14327
14486
|
const virtualModuleId4 = "virtual:zudoku-modules-plugin";
|
|
14328
14487
|
const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
|
|
@@ -14464,17 +14623,17 @@ var plugin_modules_default = viteModulesPlugin;
|
|
|
14464
14623
|
|
|
14465
14624
|
// src/vite/plugin-offroot-resolve.ts
|
|
14466
14625
|
init_loader();
|
|
14467
|
-
import
|
|
14626
|
+
import path39 from "node:path";
|
|
14468
14627
|
function stripQuery(id) {
|
|
14469
14628
|
const query = id.indexOf("?");
|
|
14470
14629
|
return query === -1 ? id : id.slice(0, query);
|
|
14471
14630
|
}
|
|
14472
14631
|
function isInside(parent, child) {
|
|
14473
|
-
const relative =
|
|
14474
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
14632
|
+
const relative = path39.relative(path39.resolve(parent), path39.resolve(child));
|
|
14633
|
+
return relative === "" || !relative.startsWith("..") && !path39.isAbsolute(relative);
|
|
14475
14634
|
}
|
|
14476
14635
|
function isBareSpecifier(source) {
|
|
14477
|
-
return !source.startsWith("\0") && !source.startsWith(".") && !source.startsWith("/") && !
|
|
14636
|
+
return !source.startsWith("\0") && !source.startsWith(".") && !source.startsWith("/") && !path39.isAbsolute(source);
|
|
14478
14637
|
}
|
|
14479
14638
|
function isInsideNodeModules(filePath) {
|
|
14480
14639
|
return filePath.split(/[\\/]/).includes("node_modules");
|
|
@@ -14498,7 +14657,7 @@ function viteOffrootResolvePlugin() {
|
|
|
14498
14657
|
if (!shouldResolveFromSiteRoot(source, importer, rootDir)) {
|
|
14499
14658
|
return;
|
|
14500
14659
|
}
|
|
14501
|
-
return this.resolve(source,
|
|
14660
|
+
return this.resolve(source, path39.join(rootDir, "package.json"), {
|
|
14502
14661
|
...options,
|
|
14503
14662
|
skipSelf: true
|
|
14504
14663
|
});
|
|
@@ -14508,7 +14667,7 @@ function viteOffrootResolvePlugin() {
|
|
|
14508
14667
|
|
|
14509
14668
|
// src/vite/plugin-search.ts
|
|
14510
14669
|
init_loader();
|
|
14511
|
-
import
|
|
14670
|
+
import path40 from "node:path";
|
|
14512
14671
|
var viteSearchPlugin = () => {
|
|
14513
14672
|
const virtualModuleId4 = "virtual:zudoku-search-plugin";
|
|
14514
14673
|
const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
|
|
@@ -14526,7 +14685,7 @@ var viteSearchPlugin = () => {
|
|
|
14526
14685
|
return resolvedVirtualModuleId5;
|
|
14527
14686
|
}
|
|
14528
14687
|
if (id === "/pagefind/pagefind.js" && resolvedViteConfig?.publicDir) {
|
|
14529
|
-
return
|
|
14688
|
+
return path40.join(resolvedViteConfig.publicDir, "pagefind/pagefind.js");
|
|
14530
14689
|
}
|
|
14531
14690
|
},
|
|
14532
14691
|
async load(id) {
|
|
@@ -14667,27 +14826,27 @@ function vitePlugin() {
|
|
|
14667
14826
|
|
|
14668
14827
|
// src/vite/watch-ignore.ts
|
|
14669
14828
|
import { lstatSync, realpathSync } from "node:fs";
|
|
14670
|
-
import
|
|
14829
|
+
import path41 from "node:path";
|
|
14671
14830
|
var STATE_INSIDE_CONTENT = /[\\/]content[\\/](?:\.apitogo|apitogo[\\/]\.state)(?:[\\/]|$)/;
|
|
14672
14831
|
var within = (base, file) => {
|
|
14673
|
-
const resolvedBase =
|
|
14674
|
-
const resolvedFile =
|
|
14675
|
-
return resolvedFile === resolvedBase || resolvedFile.startsWith(resolvedBase +
|
|
14832
|
+
const resolvedBase = path41.resolve(base);
|
|
14833
|
+
const resolvedFile = path41.resolve(file);
|
|
14834
|
+
return resolvedFile === resolvedBase || resolvedFile.startsWith(resolvedBase + path41.sep);
|
|
14676
14835
|
};
|
|
14677
14836
|
var unique = (paths) => [...new Set(paths)];
|
|
14678
14837
|
function isWorkspace(root) {
|
|
14679
14838
|
try {
|
|
14680
|
-
return
|
|
14839
|
+
return path41.basename(root) === "generated" && lstatSync(path41.join(root, "content")).isSymbolicLink();
|
|
14681
14840
|
} catch {
|
|
14682
14841
|
return false;
|
|
14683
14842
|
}
|
|
14684
14843
|
}
|
|
14685
14844
|
function tenantDir(root) {
|
|
14686
|
-
return isWorkspace(root) ? realpathSync(
|
|
14845
|
+
return isWorkspace(root) ? realpathSync(path41.join(root, "content")) : void 0;
|
|
14687
14846
|
}
|
|
14688
14847
|
function stateIgnore(root) {
|
|
14689
14848
|
if (!isWorkspace(root)) return void 0;
|
|
14690
|
-
const state =
|
|
14849
|
+
const state = path41.dirname(root);
|
|
14691
14850
|
const states = unique([state, realpathSync(state)]);
|
|
14692
14851
|
const roots = unique([root, realpathSync(root)]);
|
|
14693
14852
|
return (file) => {
|
|
@@ -14698,17 +14857,17 @@ function stateIgnore(root) {
|
|
|
14698
14857
|
}
|
|
14699
14858
|
function devServerAllow(root, moduleDir) {
|
|
14700
14859
|
const tenant = tenantDir(root);
|
|
14701
|
-
return [root,
|
|
14860
|
+
return [root, path41.dirname(root), moduleDir, ...tenant ? [tenant] : []];
|
|
14702
14861
|
}
|
|
14703
14862
|
|
|
14704
14863
|
// src/vite/config.ts
|
|
14705
14864
|
var resolveMergedPublicDir = (rootDir, merged) => {
|
|
14706
14865
|
if (merged.publicDir === false) return void 0;
|
|
14707
14866
|
const rel2 = typeof merged.publicDir === "string" ? merged.publicDir : "public";
|
|
14708
|
-
return
|
|
14867
|
+
return path42.resolve(rootDir, rel2);
|
|
14709
14868
|
};
|
|
14710
|
-
var getAppClientEntryPath = () =>
|
|
14711
|
-
var getAppServerEntryPath = () =>
|
|
14869
|
+
var getAppClientEntryPath = () => path42.posix.join(getZudokuRootDir(), "src/app/entry.client.tsx");
|
|
14870
|
+
var getAppServerEntryPath = () => path42.posix.join(getZudokuRootDir(), "src/app/entry.server.tsx");
|
|
14712
14871
|
var hasLoggedCdnInfo = false;
|
|
14713
14872
|
var MEDIA_REGEX = /\.(a?png|jpe?g|gif|bmp|svg|webp|tiff|ico|webm|ogg|mp3|wav|m4a|avif|mp4)/i;
|
|
14714
14873
|
var defineEnvVars = (vars) => Object.fromEntries(
|
|
@@ -14739,7 +14898,7 @@ async function getViteConfig(dir, configEnv) {
|
|
|
14739
14898
|
const ignoreState = stateIgnore(dir);
|
|
14740
14899
|
if (ZuploEnv.isZuplo) {
|
|
14741
14900
|
dotenv.config({
|
|
14742
|
-
path:
|
|
14901
|
+
path: path42.resolve(config2.__meta.rootDir, "../.env.zuplo"),
|
|
14743
14902
|
quiet: true
|
|
14744
14903
|
});
|
|
14745
14904
|
}
|
|
@@ -14802,8 +14961,8 @@ async function getViteConfig(dir, configEnv) {
|
|
|
14802
14961
|
ssr: configEnv.isSsrBuild,
|
|
14803
14962
|
sourcemap: true,
|
|
14804
14963
|
target: "es2022",
|
|
14805
|
-
outDir:
|
|
14806
|
-
|
|
14964
|
+
outDir: path42.resolve(
|
|
14965
|
+
path42.join(
|
|
14807
14966
|
dir,
|
|
14808
14967
|
"dist",
|
|
14809
14968
|
config2.basePath ?? "",
|
|
@@ -14822,7 +14981,7 @@ async function getViteConfig(dir, configEnv) {
|
|
|
14822
14981
|
},
|
|
14823
14982
|
experimental: {
|
|
14824
14983
|
renderBuiltUrl(filename) {
|
|
14825
|
-
if (cdnUrl?.base && [".js", ".css"].includes(
|
|
14984
|
+
if (cdnUrl?.base && [".js", ".css"].includes(path42.extname(filename))) {
|
|
14826
14985
|
return joinUrl(cdnUrl.base, filename);
|
|
14827
14986
|
}
|
|
14828
14987
|
if (cdnUrl?.media && MEDIA_REGEX.test(filename)) {
|
|
@@ -14835,7 +14994,7 @@ async function getViteConfig(dir, configEnv) {
|
|
|
14835
14994
|
esbuildOptions: {
|
|
14836
14995
|
target: "es2022"
|
|
14837
14996
|
},
|
|
14838
|
-
entries: [
|
|
14997
|
+
entries: [path42.posix.join(getZudokuRootDir(), "src/{app,lib}/**")],
|
|
14839
14998
|
exclude: [
|
|
14840
14999
|
"@lukoweb/apitogo",
|
|
14841
15000
|
"@lukoweb/apitogo-plugin-dev-portal-billing"
|
|
@@ -14939,7 +15098,7 @@ init_package_json();
|
|
|
14939
15098
|
init_joinUrl();
|
|
14940
15099
|
import assert from "node:assert";
|
|
14941
15100
|
import { cp, mkdir as mkdir9, writeFile as writeFile11 } from "node:fs/promises";
|
|
14942
|
-
import
|
|
15101
|
+
import path43 from "node:path";
|
|
14943
15102
|
var pkgJson = getZudokuPackageJson();
|
|
14944
15103
|
function generateOutput({
|
|
14945
15104
|
config: config2,
|
|
@@ -14996,9 +15155,9 @@ async function writeOutput(dir, {
|
|
|
14996
15155
|
rewrites
|
|
14997
15156
|
}) {
|
|
14998
15157
|
const output4 = generateOutput({ config: config2, redirects, rewrites });
|
|
14999
|
-
const outputDir = process.env.VERCEL ?
|
|
15158
|
+
const outputDir = process.env.VERCEL ? path43.join(dir, ".vercel/output") : path43.join(dir, "dist/.output");
|
|
15000
15159
|
await mkdir9(outputDir, { recursive: true });
|
|
15001
|
-
const outputFile =
|
|
15160
|
+
const outputFile = path43.join(outputDir, "config.json");
|
|
15002
15161
|
await writeFile11(outputFile, JSON.stringify(output4, null, 2), "utf-8");
|
|
15003
15162
|
if (process.env.VERCEL) {
|
|
15004
15163
|
console.log("Wrote Vercel output to", outputDir);
|
|
@@ -15008,9 +15167,9 @@ async function writeOutput(dir, {
|
|
|
15008
15167
|
// src/vite/prerender/prerender.ts
|
|
15009
15168
|
init_logger();
|
|
15010
15169
|
init_file_exists();
|
|
15011
|
-
import { readFile as
|
|
15170
|
+
import { readFile as readFile11, rm as rm6 } from "node:fs/promises";
|
|
15012
15171
|
import os from "node:os";
|
|
15013
|
-
import
|
|
15172
|
+
import path46 from "node:path";
|
|
15014
15173
|
import { pathToFileURL } from "node:url";
|
|
15015
15174
|
import { createIndex } from "pagefind";
|
|
15016
15175
|
import colors11 from "picocolors";
|
|
@@ -15052,7 +15211,7 @@ function throttle(fn) {
|
|
|
15052
15211
|
init_joinUrl();
|
|
15053
15212
|
import { createWriteStream, existsSync as existsSync4 } from "node:fs";
|
|
15054
15213
|
import { mkdir as mkdir10 } from "node:fs/promises";
|
|
15055
|
-
import
|
|
15214
|
+
import path44 from "node:path";
|
|
15056
15215
|
import colors9 from "picocolors";
|
|
15057
15216
|
import { SitemapStream } from "sitemap";
|
|
15058
15217
|
async function generateSitemap({
|
|
@@ -15066,11 +15225,11 @@ async function generateSitemap({
|
|
|
15066
15225
|
return;
|
|
15067
15226
|
}
|
|
15068
15227
|
const sitemap = new SitemapStream({ hostname: config2.siteUrl });
|
|
15069
|
-
const outputDir =
|
|
15228
|
+
const outputDir = path44.resolve(baseOutputDir, config2.outDir ?? "");
|
|
15070
15229
|
if (!existsSync4(outputDir)) {
|
|
15071
15230
|
await mkdir10(outputDir, { recursive: true });
|
|
15072
15231
|
}
|
|
15073
|
-
const sitemapOutputPath =
|
|
15232
|
+
const sitemapOutputPath = path44.join(outputDir, "sitemap.xml");
|
|
15074
15233
|
const writeStream = createWriteStream(sitemapOutputPath);
|
|
15075
15234
|
sitemap.pipe(writeStream);
|
|
15076
15235
|
let lastmod;
|
|
@@ -15100,14 +15259,14 @@ async function generateSitemap({
|
|
|
15100
15259
|
|
|
15101
15260
|
// src/vite/prerender/utils.ts
|
|
15102
15261
|
init_joinUrl();
|
|
15103
|
-
var resolveRoutePath = (
|
|
15104
|
-
const segments =
|
|
15262
|
+
var resolveRoutePath = (path97) => {
|
|
15263
|
+
const segments = path97.split("/");
|
|
15105
15264
|
if (segments.some((s) => s.startsWith(":") && !s.endsWith("?"))) {
|
|
15106
15265
|
return void 0;
|
|
15107
15266
|
}
|
|
15108
15267
|
return segments.filter((s) => !s.startsWith(":")).join("/") || void 0;
|
|
15109
15268
|
};
|
|
15110
|
-
var isSkipped = (
|
|
15269
|
+
var isSkipped = (path97) => path97.includes("*") || /^\d+$/.test(path97);
|
|
15111
15270
|
var resolveRoutes = (routes, parentPath = "") => routes.flatMap((route) => {
|
|
15112
15271
|
if (route.path && isSkipped(route.path)) return [];
|
|
15113
15272
|
const routePath = route.path ? resolveRoutePath(route.path) : void 0;
|
|
@@ -15156,12 +15315,12 @@ var prerender = async ({
|
|
|
15156
15315
|
serverConfigFilename,
|
|
15157
15316
|
writeRedirects = true
|
|
15158
15317
|
}) => {
|
|
15159
|
-
const distDir =
|
|
15318
|
+
const distDir = path46.join(dir, "dist", basePath);
|
|
15160
15319
|
const serverConfigPath = pathToFileURL(
|
|
15161
|
-
|
|
15320
|
+
path46.join(distDir, "server", serverConfigFilename)
|
|
15162
15321
|
).href;
|
|
15163
15322
|
const entryServerPath = pathToFileURL(
|
|
15164
|
-
|
|
15323
|
+
path46.join(distDir, "server/entry.server.js")
|
|
15165
15324
|
).href;
|
|
15166
15325
|
const rawConfig = await import(serverConfigPath).then(
|
|
15167
15326
|
(m) => m.default
|
|
@@ -15246,7 +15405,7 @@ var prerender = async ({
|
|
|
15246
15405
|
})
|
|
15247
15406
|
);
|
|
15248
15407
|
const pagefindWriteResult = await pagefindIndex?.writeFiles({
|
|
15249
|
-
outputPath:
|
|
15408
|
+
outputPath: path46.join(distDir, "pagefind")
|
|
15250
15409
|
});
|
|
15251
15410
|
const seconds = ((performance.now() - start) / 1e3).toFixed(1);
|
|
15252
15411
|
const message = `\u2713 finished prerendering ${paths.length} routes in ${seconds} seconds using ${maxThreads} workers`;
|
|
@@ -15278,13 +15437,13 @@ var prerender = async ({
|
|
|
15278
15437
|
const { generateLlmsTxtFiles: generateLlmsTxtFiles2 } = await Promise.resolve().then(() => (init_llms(), llms_exports));
|
|
15279
15438
|
const docsConfig = DocsConfigSchema2.parse(config2.docs);
|
|
15280
15439
|
const llmsConfig = docsConfig.llms ?? {};
|
|
15281
|
-
const markdownInfoPath =
|
|
15440
|
+
const markdownInfoPath = path46.join(
|
|
15282
15441
|
dir,
|
|
15283
15442
|
"node_modules/.apitogo/markdown-info.json"
|
|
15284
15443
|
);
|
|
15285
15444
|
let markdownFileInfos = [];
|
|
15286
15445
|
if (await fileExists(markdownInfoPath)) {
|
|
15287
|
-
const markdownInfoContent = await
|
|
15446
|
+
const markdownInfoContent = await readFile11(markdownInfoPath, "utf-8");
|
|
15288
15447
|
markdownFileInfos = JSON.parse(markdownInfoContent);
|
|
15289
15448
|
}
|
|
15290
15449
|
if (llmsConfig.llmsTxt || llmsConfig.llmsTxtFull) {
|
|
@@ -15369,7 +15528,7 @@ async function runBuild(options) {
|
|
|
15369
15528
|
html,
|
|
15370
15529
|
basePath: config2.basePath
|
|
15371
15530
|
});
|
|
15372
|
-
await rm7(
|
|
15531
|
+
await rm7(path47.join(clientOutDir, "index.html"), { force: true });
|
|
15373
15532
|
} else {
|
|
15374
15533
|
await runPrerender({
|
|
15375
15534
|
dir,
|
|
@@ -15393,7 +15552,7 @@ var runPrerender = async (options) => {
|
|
|
15393
15552
|
serverConfigFilename,
|
|
15394
15553
|
writeRedirects: process.env.VERCEL === void 0
|
|
15395
15554
|
});
|
|
15396
|
-
const indexHtml =
|
|
15555
|
+
const indexHtml = path47.join(clientOutDir, "index.html");
|
|
15397
15556
|
if (!workerResults.find((r) => r.outputPath === indexHtml)) {
|
|
15398
15557
|
await writeFile13(indexHtml, html, "utf-8");
|
|
15399
15558
|
}
|
|
@@ -15403,15 +15562,15 @@ var runPrerender = async (options) => {
|
|
|
15403
15562
|
for (const statusPage of statusPages) {
|
|
15404
15563
|
await rename5(
|
|
15405
15564
|
statusPage,
|
|
15406
|
-
|
|
15565
|
+
path47.join(dir, DIST_DIR, path47.basename(statusPage))
|
|
15407
15566
|
);
|
|
15408
15567
|
}
|
|
15409
15568
|
await rm7(serverOutDir, { recursive: true, force: true });
|
|
15410
15569
|
if (process.env.VERCEL) {
|
|
15411
|
-
await mkdir11(
|
|
15570
|
+
await mkdir11(path47.join(dir, ".vercel/output/static"), { recursive: true });
|
|
15412
15571
|
await rename5(
|
|
15413
|
-
|
|
15414
|
-
|
|
15572
|
+
path47.join(dir, DIST_DIR),
|
|
15573
|
+
path47.join(dir, ".vercel/output/static")
|
|
15415
15574
|
);
|
|
15416
15575
|
}
|
|
15417
15576
|
await writeOutput(dir, {
|
|
@@ -15421,7 +15580,7 @@ var runPrerender = async (options) => {
|
|
|
15421
15580
|
});
|
|
15422
15581
|
if (ZuploEnv.isZuplo && issuer) {
|
|
15423
15582
|
await writeFile13(
|
|
15424
|
-
|
|
15583
|
+
path47.join(dir, DIST_DIR, ".output/zuplo.json"),
|
|
15425
15584
|
JSON.stringify({ issuer }, null, 2),
|
|
15426
15585
|
"utf-8"
|
|
15427
15586
|
);
|
|
@@ -15433,10 +15592,10 @@ var runPrerender = async (options) => {
|
|
|
15433
15592
|
};
|
|
15434
15593
|
var bundleSSREntry = async (options) => {
|
|
15435
15594
|
const { dir, adapter, serverOutDir, serverConfigFilename, html, basePath } = options;
|
|
15436
|
-
const tempEntryPath =
|
|
15595
|
+
const tempEntryPath = path47.join(dir, "__ssr-entry.ts");
|
|
15437
15596
|
const packageRoot = getZudokuRootDir();
|
|
15438
|
-
const templateContent = await
|
|
15439
|
-
|
|
15597
|
+
const templateContent = await readFile12(
|
|
15598
|
+
path47.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
|
|
15440
15599
|
"utf-8"
|
|
15441
15600
|
);
|
|
15442
15601
|
const entryContent = templateContent.replace('"__TEMPLATE__"', JSON.stringify(html)).replace('"__CONFIG_FILE__"', JSON.stringify(`./${serverConfigFilename}`)).replace(
|
|
@@ -15451,9 +15610,9 @@ var bundleSSREntry = async (options) => {
|
|
|
15451
15610
|
platform: adapter === "node" ? "node" : "neutral",
|
|
15452
15611
|
target: "es2022",
|
|
15453
15612
|
format: "esm",
|
|
15454
|
-
outfile:
|
|
15613
|
+
outfile: path47.join(serverOutDir, "entry.js"),
|
|
15455
15614
|
external: ["./entry.server.js", `./${serverConfigFilename}`],
|
|
15456
|
-
nodePaths: [
|
|
15615
|
+
nodePaths: [path47.join(packageRoot, "node_modules")],
|
|
15457
15616
|
banner: { js: "// Bundled SSR entry" }
|
|
15458
15617
|
});
|
|
15459
15618
|
} finally {
|
|
@@ -15466,8 +15625,8 @@ init_package_json();
|
|
|
15466
15625
|
|
|
15467
15626
|
// src/cli/init/v2-packages.ts
|
|
15468
15627
|
import { existsSync as existsSync5 } from "node:fs";
|
|
15469
|
-
import { readFile as
|
|
15470
|
-
import
|
|
15628
|
+
import { readFile as readFile13, writeFile as writeFile14 } from "node:fs/promises";
|
|
15629
|
+
import path48 from "node:path";
|
|
15471
15630
|
var CORE_PACKAGES = [
|
|
15472
15631
|
"@lukoweb/apitogo",
|
|
15473
15632
|
"react",
|
|
@@ -15484,7 +15643,7 @@ function packageNameFrom(name) {
|
|
|
15484
15643
|
return slug || "portal";
|
|
15485
15644
|
}
|
|
15486
15645
|
async function ensurePackageJson(dir, name) {
|
|
15487
|
-
const file =
|
|
15646
|
+
const file = path48.join(dir, "package.json");
|
|
15488
15647
|
if (existsSync5(file)) return false;
|
|
15489
15648
|
await writeFile14(
|
|
15490
15649
|
file,
|
|
@@ -15503,11 +15662,11 @@ async function ensurePackageJson(dir, name) {
|
|
|
15503
15662
|
return true;
|
|
15504
15663
|
}
|
|
15505
15664
|
function isPackageInstalled(startDir, name) {
|
|
15506
|
-
let dir =
|
|
15665
|
+
let dir = path48.resolve(startDir);
|
|
15507
15666
|
for (; ; ) {
|
|
15508
|
-
if (existsSync5(
|
|
15667
|
+
if (existsSync5(path48.join(dir, "node_modules", name, "package.json")))
|
|
15509
15668
|
return true;
|
|
15510
|
-
const parent =
|
|
15669
|
+
const parent = path48.dirname(dir);
|
|
15511
15670
|
if (parent === dir) return false;
|
|
15512
15671
|
dir = parent;
|
|
15513
15672
|
}
|
|
@@ -15563,7 +15722,7 @@ function portalBuildStep(context, options = {}, build2 = runBuild) {
|
|
|
15563
15722
|
return {
|
|
15564
15723
|
name: "build",
|
|
15565
15724
|
hash: () => hash2,
|
|
15566
|
-
stillValid: () => access4(
|
|
15725
|
+
stillValid: () => access4(path49.join(buildDir, "index.html")).then(
|
|
15567
15726
|
() => true,
|
|
15568
15727
|
() => false
|
|
15569
15728
|
),
|
|
@@ -15580,11 +15739,11 @@ function portalBuildStep(context, options = {}, build2 = runBuild) {
|
|
|
15580
15739
|
else process.env.NODE_ENV = originalNodeEnv;
|
|
15581
15740
|
}
|
|
15582
15741
|
await rm8(buildDir, { recursive: true, force: true });
|
|
15583
|
-
await mkdir12(
|
|
15584
|
-
await rename6(
|
|
15742
|
+
await mkdir12(path49.dirname(buildDir), { recursive: true });
|
|
15743
|
+
await rename6(path49.join(root, "dist"), buildDir);
|
|
15585
15744
|
if (prepared.publishedManifest) {
|
|
15586
15745
|
await writeFile15(
|
|
15587
|
-
|
|
15746
|
+
path49.join(buildDir, MANIFEST_FILE),
|
|
15588
15747
|
`${JSON.stringify(prepared.publishedManifest, null, 2)}
|
|
15589
15748
|
`
|
|
15590
15749
|
);
|
|
@@ -15613,17 +15772,17 @@ async function buildV2(options) {
|
|
|
15613
15772
|
}
|
|
15614
15773
|
|
|
15615
15774
|
// src/cli/check/gateway-online.ts
|
|
15616
|
-
import { readFile as
|
|
15775
|
+
import { readFile as readFile15 } from "node:fs/promises";
|
|
15617
15776
|
var SPEC_SEND_LIMIT = 5 * 1024 * 1024 + 64 * 1024;
|
|
15618
|
-
var issue2 = (code,
|
|
15777
|
+
var issue2 = (code, path97, message, hint) => ({ code, path: path97, message, hint });
|
|
15619
15778
|
function capabilityIssues(gateway, answer) {
|
|
15620
15779
|
const can = answer.capabilities;
|
|
15621
15780
|
const plan2 = `your ${answer.tier} plan`;
|
|
15622
15781
|
const found = [];
|
|
15623
|
-
const unsupported = (
|
|
15782
|
+
const unsupported = (path97, what, hint) => found.push(
|
|
15624
15783
|
issue2(
|
|
15625
15784
|
"GATEWAY_CAPABILITY_UNSUPPORTED",
|
|
15626
|
-
|
|
15785
|
+
path97,
|
|
15627
15786
|
`${what} is not available on ${plan2}.`,
|
|
15628
15787
|
hint
|
|
15629
15788
|
)
|
|
@@ -15677,7 +15836,7 @@ async function onlineGatewayRules(gateway, projectId, api, derivedCors = []) {
|
|
|
15677
15836
|
const specFile = gateway.specs[0];
|
|
15678
15837
|
if (specFile) {
|
|
15679
15838
|
try {
|
|
15680
|
-
const text = await
|
|
15839
|
+
const text = await readFile15(specFile, "utf8");
|
|
15681
15840
|
if (text.length <= SPEC_SEND_LIMIT) spec = text;
|
|
15682
15841
|
} catch {
|
|
15683
15842
|
}
|
|
@@ -15704,9 +15863,9 @@ async function onlineGatewayRules(gateway, projectId, api, derivedCors = []) {
|
|
|
15704
15863
|
}
|
|
15705
15864
|
|
|
15706
15865
|
// src/cli/deploy/plans-file.ts
|
|
15707
|
-
|
|
15708
|
-
import { readFile as readFile14 } from "node:fs/promises";
|
|
15866
|
+
import { readFile as readFile16 } from "node:fs/promises";
|
|
15709
15867
|
import { z as z14 } from "zod";
|
|
15868
|
+
init_invariant();
|
|
15710
15869
|
var PlansFileError = class extends ApitogoError {
|
|
15711
15870
|
constructor(code, message, developerHint) {
|
|
15712
15871
|
super(message, { developerHint, title: "Cannot read the plans file" });
|
|
@@ -15749,7 +15908,7 @@ var issuesOf = (error) => error.issues.map(
|
|
|
15749
15908
|
async function readPlansFile(file) {
|
|
15750
15909
|
let text;
|
|
15751
15910
|
try {
|
|
15752
|
-
text = await
|
|
15911
|
+
text = await readFile16(file, "utf8");
|
|
15753
15912
|
} catch {
|
|
15754
15913
|
throw new PlansFileError(
|
|
15755
15914
|
"PLANS_FILE_UNREADABLE",
|
|
@@ -15790,12 +15949,12 @@ async function readPlansFile(file) {
|
|
|
15790
15949
|
var BILLING_PERIOD = { month: "monthly", year: "annual" };
|
|
15791
15950
|
function toPlatformPlans(plans, options = {}) {
|
|
15792
15951
|
return plans.map((plan2, index) => {
|
|
15793
|
-
const paid =
|
|
15952
|
+
const paid = isPaidPlan(plan2);
|
|
15794
15953
|
if (paid && !options.billing)
|
|
15795
15954
|
throw new PlansFileError(
|
|
15796
15955
|
"PLANS_PAID_UNSUPPORTED",
|
|
15797
|
-
`The plan "${plan2.sku}" has a price,
|
|
15798
|
-
"
|
|
15956
|
+
`The plan "${plan2.sku}" has a price, but plans.billing.provider is "none", so nobody could pay for it.`,
|
|
15957
|
+
"Remove plans.billing.provider (Stripe is the provider; deploy asks for its key), or set priceAmount to 0 (or pricingModel to custom for a contact-us plan)."
|
|
15799
15958
|
);
|
|
15800
15959
|
const limits = plan2.limits ? {
|
|
15801
15960
|
...plan2.limits.rateLimit ? {
|
|
@@ -15827,9 +15986,9 @@ function toPlatformPlans(plans, options = {}) {
|
|
|
15827
15986
|
}
|
|
15828
15987
|
|
|
15829
15988
|
// src/cli/check/services-online.ts
|
|
15830
|
-
var issue3 = (code,
|
|
15989
|
+
var issue3 = (code, path97, message, hint) => ({
|
|
15831
15990
|
code,
|
|
15832
|
-
path:
|
|
15991
|
+
path: path97,
|
|
15833
15992
|
message,
|
|
15834
15993
|
hint
|
|
15835
15994
|
});
|
|
@@ -15940,7 +16099,7 @@ async function onlinePlansRules(resolved, projectId, api) {
|
|
|
15940
16099
|
async function isConfigV2(dir) {
|
|
15941
16100
|
try {
|
|
15942
16101
|
return /"version"\s*:\s*2\b/.test(
|
|
15943
|
-
await
|
|
16102
|
+
await readFile17(path50.join(dir, APITOGO_CONFIG_FILENAME), "utf8")
|
|
15944
16103
|
);
|
|
15945
16104
|
} catch {
|
|
15946
16105
|
return false;
|
|
@@ -16087,7 +16246,7 @@ async function validatePortalBuild(dir) {
|
|
|
16087
16246
|
}
|
|
16088
16247
|
}
|
|
16089
16248
|
async function runCheckV2(dir, args = {}, deps = {}) {
|
|
16090
|
-
const configPath =
|
|
16249
|
+
const configPath = path50.join(dir, APITOGO_CONFIG_FILENAME);
|
|
16091
16250
|
let report;
|
|
16092
16251
|
try {
|
|
16093
16252
|
const { config: config2, resolved } = loadConfigV2(dir);
|
|
@@ -16197,7 +16356,7 @@ async function checkV2(dir, args, deps = platformDependencies(args)) {
|
|
|
16197
16356
|
init_package_json();
|
|
16198
16357
|
|
|
16199
16358
|
// src/cli/init/v2-handler.ts
|
|
16200
|
-
import
|
|
16359
|
+
import path51 from "node:path";
|
|
16201
16360
|
import { createInterface } from "node:readline/promises";
|
|
16202
16361
|
function parseDocsFlag(value) {
|
|
16203
16362
|
if (value === void 0) return void 0;
|
|
@@ -16219,15 +16378,15 @@ async function ask(question) {
|
|
|
16219
16378
|
}
|
|
16220
16379
|
function describePlan(plan2) {
|
|
16221
16380
|
return {
|
|
16222
|
-
willCreate: plan2.entries.filter((entry) => !plan2.keep.includes(entry.path)).map((entry) =>
|
|
16223
|
-
willKeep: plan2.keep.map((target) =>
|
|
16381
|
+
willCreate: plan2.entries.filter((entry) => !plan2.keep.includes(entry.path)).map((entry) => path51.relative(plan2.dir, entry.path)),
|
|
16382
|
+
willKeep: plan2.keep.map((target) => path51.relative(plan2.dir, target)),
|
|
16224
16383
|
replacesConfig: plan2.replacesConfig
|
|
16225
16384
|
};
|
|
16226
16385
|
}
|
|
16227
16386
|
async function initV2(argv) {
|
|
16228
16387
|
const json = argv.json === true;
|
|
16229
16388
|
try {
|
|
16230
|
-
const dir =
|
|
16389
|
+
const dir = path51.resolve(process.cwd(), argv.dir ?? ".");
|
|
16231
16390
|
const plan2 = await planInit({
|
|
16232
16391
|
dir,
|
|
16233
16392
|
name: argv.name,
|
|
@@ -16268,8 +16427,8 @@ async function initV2(argv) {
|
|
|
16268
16427
|
status: "created",
|
|
16269
16428
|
dir,
|
|
16270
16429
|
...describePlan(plan2),
|
|
16271
|
-
created: result.created.map((p) =>
|
|
16272
|
-
kept: result.kept.map((p) =>
|
|
16430
|
+
created: result.created.map((p) => path51.relative(dir, p)),
|
|
16431
|
+
kept: result.kept.map((p) => path51.relative(dir, p))
|
|
16273
16432
|
},
|
|
16274
16433
|
null,
|
|
16275
16434
|
2
|
|
@@ -16278,7 +16437,7 @@ async function initV2(argv) {
|
|
|
16278
16437
|
return;
|
|
16279
16438
|
}
|
|
16280
16439
|
printResultToConsole(
|
|
16281
|
-
`Created ${
|
|
16440
|
+
`Created ${path51.basename(plan2.configPath)} (config version 2) in ${dir}.`
|
|
16282
16441
|
);
|
|
16283
16442
|
printHintToConsole(
|
|
16284
16443
|
"Next: add a service with `apitogo add <portal|gateway|identity|plans>`, or run `apitogo create` for a guided setup."
|
|
@@ -16306,7 +16465,7 @@ async function initV2(argv) {
|
|
|
16306
16465
|
// src/cli/services/packages.ts
|
|
16307
16466
|
import { spawn } from "node:child_process";
|
|
16308
16467
|
import { existsSync as existsSync6 } from "node:fs";
|
|
16309
|
-
import
|
|
16468
|
+
import path52 from "node:path";
|
|
16310
16469
|
var USER_PANEL_PACKAGE = "@lukoweb/apitogo-module-user-panel";
|
|
16311
16470
|
var BILLING_PLUGIN_PACKAGE = "@lukoweb/apitogo-plugin-dev-portal-billing";
|
|
16312
16471
|
var LANDING_PACKAGE = "@lukoweb/apitogo-module-landing";
|
|
@@ -16324,18 +16483,18 @@ function packagesForConfig(config2) {
|
|
|
16324
16483
|
];
|
|
16325
16484
|
}
|
|
16326
16485
|
function isInstalled(dir, name) {
|
|
16327
|
-
for (let current =
|
|
16328
|
-
if (existsSync6(
|
|
16486
|
+
for (let current = path52.resolve(dir); ; current = path52.dirname(current)) {
|
|
16487
|
+
if (existsSync6(path52.join(current, "node_modules", name, "package.json")))
|
|
16329
16488
|
return true;
|
|
16330
|
-
if (
|
|
16489
|
+
if (path52.dirname(current) === current) return false;
|
|
16331
16490
|
}
|
|
16332
16491
|
}
|
|
16333
16492
|
function missingPackages(dir, names) {
|
|
16334
16493
|
return names.filter((name) => !isInstalled(dir, name));
|
|
16335
16494
|
}
|
|
16336
16495
|
function detectPackageManager(dir) {
|
|
16337
|
-
if (existsSync6(
|
|
16338
|
-
if (existsSync6(
|
|
16496
|
+
if (existsSync6(path52.join(dir, "pnpm-lock.yaml"))) return "pnpm";
|
|
16497
|
+
if (existsSync6(path52.join(dir, "yarn.lock"))) return "yarn";
|
|
16339
16498
|
return "npm";
|
|
16340
16499
|
}
|
|
16341
16500
|
function installSpecsCommand(manager, specs) {
|
|
@@ -16394,7 +16553,7 @@ async function installMissingPackages(dir, config2, version, options) {
|
|
|
16394
16553
|
reason: "--no-install was given",
|
|
16395
16554
|
command: shown
|
|
16396
16555
|
};
|
|
16397
|
-
await ensurePackageJson(dir, config2.project?.name ??
|
|
16556
|
+
await ensurePackageJson(dir, config2.project?.name ?? path52.basename(dir));
|
|
16398
16557
|
await (options.installer ?? runInstaller)(dir, command2);
|
|
16399
16558
|
return { status: "installed", packages: missing, command: shown };
|
|
16400
16559
|
}
|
|
@@ -16457,7 +16616,7 @@ var list = (value) => {
|
|
|
16457
16616
|
return items.length > 0 ? items : void 0;
|
|
16458
16617
|
};
|
|
16459
16618
|
function addOptionsFromArguments(service, argv) {
|
|
16460
|
-
const dir =
|
|
16619
|
+
const dir = path53.resolve(process.cwd(), argv.dir ?? ".");
|
|
16461
16620
|
const issuers = list(argv.issuer);
|
|
16462
16621
|
return {
|
|
16463
16622
|
dir,
|
|
@@ -16502,8 +16661,7 @@ function addOptionsFromArguments(service, argv) {
|
|
|
16502
16661
|
} : void 0,
|
|
16503
16662
|
plans: service === "plans" ? {
|
|
16504
16663
|
file: argv.file,
|
|
16505
|
-
template: argv.template === "free" || argv.template === "tiered" ? argv.template : void 0
|
|
16506
|
-
billing: argv.billing
|
|
16664
|
+
template: argv.template === "free" || argv.template === "tiered" ? argv.template : void 0
|
|
16507
16665
|
} : void 0
|
|
16508
16666
|
};
|
|
16509
16667
|
}
|
|
@@ -16512,8 +16670,8 @@ function describe(edit, dir) {
|
|
|
16512
16670
|
return {
|
|
16513
16671
|
service: edit.service,
|
|
16514
16672
|
action: edit.action,
|
|
16515
|
-
willCreate: edit.files.map((file) =>
|
|
16516
|
-
keep: edit.keep.map((file) =>
|
|
16673
|
+
willCreate: edit.files.map((file) => path53.relative(dir, file.path)),
|
|
16674
|
+
keep: edit.keep.map((file) => path53.relative(dir, file)),
|
|
16517
16675
|
notes: edit.notes
|
|
16518
16676
|
};
|
|
16519
16677
|
}
|
|
@@ -16527,7 +16685,7 @@ async function run(action, argv, plan2, deps = {}) {
|
|
|
16527
16685
|
`Choose one of ${SERVICES.join(", ")}.`
|
|
16528
16686
|
);
|
|
16529
16687
|
}
|
|
16530
|
-
const dir =
|
|
16688
|
+
const dir = path53.resolve(process.cwd(), argv.dir ?? ".");
|
|
16531
16689
|
if (!await isConfigV2(dir)) {
|
|
16532
16690
|
throw new ServiceEditError(
|
|
16533
16691
|
`${action} works with a config version 2 project, and there is none in ${dir}.`,
|
|
@@ -16595,7 +16753,7 @@ async function run(action, argv, plan2, deps = {}) {
|
|
|
16595
16753
|
{
|
|
16596
16754
|
status: action === "add" ? "added" : "removed",
|
|
16597
16755
|
...describe(edit, dir),
|
|
16598
|
-
created: created.map((file) =>
|
|
16756
|
+
created: created.map((file) => path53.relative(dir, file)),
|
|
16599
16757
|
...install ? { packages: install } : {}
|
|
16600
16758
|
},
|
|
16601
16759
|
null,
|
|
@@ -16605,7 +16763,7 @@ async function run(action, argv, plan2, deps = {}) {
|
|
|
16605
16763
|
return;
|
|
16606
16764
|
}
|
|
16607
16765
|
printResultToConsole(
|
|
16608
|
-
`${action === "add" ? "Added" : "Removed"} ${edit.service} in ${
|
|
16766
|
+
`${action === "add" ? "Added" : "Removed"} ${edit.service} in ${path53.basename(edit.configPath)}.`
|
|
16609
16767
|
);
|
|
16610
16768
|
} catch (error) {
|
|
16611
16769
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -16666,7 +16824,7 @@ var removeService = (argv) => run(
|
|
|
16666
16824
|
"remove",
|
|
16667
16825
|
argv,
|
|
16668
16826
|
(service) => planRemoveService(service, {
|
|
16669
|
-
dir:
|
|
16827
|
+
dir: path53.resolve(process.cwd(), argv.dir ?? "."),
|
|
16670
16828
|
deleteFiles: argv.deleteFiles === true
|
|
16671
16829
|
})
|
|
16672
16830
|
);
|
|
@@ -16810,10 +16968,6 @@ var add_default = {
|
|
|
16810
16968
|
"none"
|
|
16811
16969
|
],
|
|
16812
16970
|
describe: "Content to create: blank (empty shell), starter (filled example) or full (starter plus a Node.js backend in server/). Plans also accept free, tiered and none; none is blank"
|
|
16813
|
-
}).option("billing", {
|
|
16814
|
-
type: "string",
|
|
16815
|
-
choices: ["stripe", "none"],
|
|
16816
|
-
describe: "plans: billing provider"
|
|
16817
16971
|
}),
|
|
16818
16972
|
handler: async (argv) => {
|
|
16819
16973
|
await captureEvent({ argv, event: "apitogo add" });
|
|
@@ -16822,16 +16976,16 @@ var add_default = {
|
|
|
16822
16976
|
};
|
|
16823
16977
|
|
|
16824
16978
|
// src/cli/build/handler.ts
|
|
16825
|
-
import
|
|
16979
|
+
import path55 from "node:path";
|
|
16826
16980
|
init_logger();
|
|
16827
16981
|
init_package_json();
|
|
16828
16982
|
|
|
16829
16983
|
// src/cli/preview/handler.ts
|
|
16830
|
-
import
|
|
16984
|
+
import path54 from "node:path";
|
|
16831
16985
|
import { preview as vitePreview } from "vite";
|
|
16832
16986
|
var DEFAULT_PREVIEW_PORT = 4e3;
|
|
16833
16987
|
async function preview(argv) {
|
|
16834
|
-
const dir =
|
|
16988
|
+
const dir = path54.resolve(process.cwd(), argv.dir);
|
|
16835
16989
|
const viteConfig = await getViteConfig(dir, {
|
|
16836
16990
|
command: "serve",
|
|
16837
16991
|
mode: "production",
|
|
@@ -16874,7 +17028,7 @@ async function build(argv) {
|
|
|
16874
17028
|
printDiagnosticsToConsole("");
|
|
16875
17029
|
printDiagnosticsToConsole("");
|
|
16876
17030
|
}
|
|
16877
|
-
const dir =
|
|
17031
|
+
const dir = path55.resolve(process.cwd(), argv.dir);
|
|
16878
17032
|
try {
|
|
16879
17033
|
if (await isConfigV2(dir)) {
|
|
16880
17034
|
const result = await buildV2({ dir, jsonOnly });
|
|
@@ -16939,10 +17093,10 @@ var build_default = {
|
|
|
16939
17093
|
};
|
|
16940
17094
|
|
|
16941
17095
|
// src/cli/check/handler.ts
|
|
16942
|
-
import
|
|
17096
|
+
import path61 from "node:path";
|
|
16943
17097
|
|
|
16944
17098
|
// src/cli/platform/tools/check-publish-readiness.ts
|
|
16945
|
-
import
|
|
17099
|
+
import path60 from "node:path";
|
|
16946
17100
|
|
|
16947
17101
|
// src/cli/platform/helpers/dev-portal-backend.ts
|
|
16948
17102
|
function deriveProvisioningState(backend) {
|
|
@@ -17026,8 +17180,8 @@ function formatDevPortalBackendResponse(projectId, backend) {
|
|
|
17026
17180
|
// src/cli/platform/helpers/dev-portal-manifest.ts
|
|
17027
17181
|
init_gateway_limits();
|
|
17028
17182
|
import { existsSync as existsSync7 } from "node:fs";
|
|
17029
|
-
import { access as access5, mkdir as mkdir13, readFile as
|
|
17030
|
-
import
|
|
17183
|
+
import { access as access5, mkdir as mkdir13, readFile as readFile18, writeFile as writeFile16 } from "node:fs/promises";
|
|
17184
|
+
import path56 from "node:path";
|
|
17031
17185
|
|
|
17032
17186
|
// src/cli/make-config/header-pricing-nav.ts
|
|
17033
17187
|
var HEADER_PRICING_PATH = "/pricing";
|
|
@@ -17149,7 +17303,7 @@ function isPlanFree(plan2) {
|
|
|
17149
17303
|
return (plan2.priceAmount ?? 0) <= 0;
|
|
17150
17304
|
}
|
|
17151
17305
|
function manifestFilePath(siteDirectory) {
|
|
17152
|
-
return
|
|
17306
|
+
return path56.join(path56.resolve(siteDirectory), APITOGO_CONFIG_FILENAME2);
|
|
17153
17307
|
}
|
|
17154
17308
|
var STORED_MANIFEST_KEYS = [
|
|
17155
17309
|
"authentication",
|
|
@@ -17573,23 +17727,23 @@ function resolveBackendSourceDirectory(siteDirectory, sourceDirectory) {
|
|
|
17573
17727
|
if (!trimmed) {
|
|
17574
17728
|
return void 0;
|
|
17575
17729
|
}
|
|
17576
|
-
return
|
|
17730
|
+
return path56.resolve(siteDirectory, trimmed);
|
|
17577
17731
|
}
|
|
17578
17732
|
function resolveBackendOpenApiPath(openApiPath, options) {
|
|
17579
17733
|
const trimmed = openApiPath?.trim();
|
|
17580
17734
|
if (!trimmed) {
|
|
17581
17735
|
return void 0;
|
|
17582
17736
|
}
|
|
17583
|
-
if (
|
|
17737
|
+
if (path56.isAbsolute(trimmed)) {
|
|
17584
17738
|
return trimmed;
|
|
17585
17739
|
}
|
|
17586
|
-
const siteResolved =
|
|
17740
|
+
const siteResolved = path56.resolve(options.siteDirectory, trimmed);
|
|
17587
17741
|
if (existsSync7(siteResolved)) {
|
|
17588
17742
|
return siteResolved;
|
|
17589
17743
|
}
|
|
17590
17744
|
const backendDir = options.backendSourceDirectory?.trim();
|
|
17591
17745
|
if (backendDir) {
|
|
17592
|
-
const backendResolved =
|
|
17746
|
+
const backendResolved = path56.resolve(backendDir, trimmed);
|
|
17593
17747
|
if (existsSync7(backendResolved)) {
|
|
17594
17748
|
return backendResolved;
|
|
17595
17749
|
}
|
|
@@ -17606,7 +17760,7 @@ function mergePublishPrerequisitesWithPlatformValidation(prerequisites, manifest
|
|
|
17606
17760
|
async function readManifest2(siteDirectory) {
|
|
17607
17761
|
const filePath = manifestFilePath(siteDirectory);
|
|
17608
17762
|
if (await pathExists(filePath)) {
|
|
17609
|
-
const raw = await
|
|
17763
|
+
const raw = await readFile18(filePath, "utf8");
|
|
17610
17764
|
const config2 = JSON.parse(raw);
|
|
17611
17765
|
return extractManifestFromConfig(config2);
|
|
17612
17766
|
}
|
|
@@ -17614,10 +17768,10 @@ async function readManifest2(siteDirectory) {
|
|
|
17614
17768
|
}
|
|
17615
17769
|
async function writeManifest2(siteDirectory, manifest) {
|
|
17616
17770
|
const filePath = manifestFilePath(siteDirectory);
|
|
17617
|
-
await mkdir13(
|
|
17771
|
+
await mkdir13(path56.dirname(filePath), { recursive: true });
|
|
17618
17772
|
let config2 = {};
|
|
17619
17773
|
if (await pathExists(filePath)) {
|
|
17620
|
-
const raw = await
|
|
17774
|
+
const raw = await readFile18(filePath, "utf8");
|
|
17621
17775
|
config2 = JSON.parse(raw);
|
|
17622
17776
|
}
|
|
17623
17777
|
const {
|
|
@@ -17636,11 +17790,11 @@ import {
|
|
|
17636
17790
|
access as access6,
|
|
17637
17791
|
appendFile,
|
|
17638
17792
|
mkdir as mkdir14,
|
|
17639
|
-
readFile as
|
|
17793
|
+
readFile as readFile19,
|
|
17640
17794
|
unlink,
|
|
17641
17795
|
writeFile as writeFile17
|
|
17642
17796
|
} from "node:fs/promises";
|
|
17643
|
-
import
|
|
17797
|
+
import path57 from "node:path";
|
|
17644
17798
|
var ENV_FILENAME = ".env";
|
|
17645
17799
|
var COLLAPSED_UPPERCASE_ALIASES2 = {
|
|
17646
17800
|
SECRETKEY: "secretKey",
|
|
@@ -17742,7 +17896,7 @@ function applyEnvOverrides2(config2, env) {
|
|
|
17742
17896
|
}
|
|
17743
17897
|
async function readEnvFile(filePath) {
|
|
17744
17898
|
try {
|
|
17745
|
-
const raw = await
|
|
17899
|
+
const raw = await readFile19(filePath, "utf8");
|
|
17746
17900
|
const env = {};
|
|
17747
17901
|
for (const line2 of raw.split("\n")) {
|
|
17748
17902
|
const trimmed = line2.trim();
|
|
@@ -17759,12 +17913,12 @@ async function readEnvFile(filePath) {
|
|
|
17759
17913
|
}
|
|
17760
17914
|
}
|
|
17761
17915
|
async function loadSiteEnv(siteDirectory) {
|
|
17762
|
-
const resolvedDirectory =
|
|
17916
|
+
const resolvedDirectory = path57.resolve(siteDirectory);
|
|
17763
17917
|
const merged = { ...process.env };
|
|
17764
17918
|
for (const fileName of [ENV_FILENAME, ".env.local"]) {
|
|
17765
17919
|
Object.assign(
|
|
17766
17920
|
merged,
|
|
17767
|
-
await readEnvFile(
|
|
17921
|
+
await readEnvFile(path57.join(resolvedDirectory, fileName))
|
|
17768
17922
|
);
|
|
17769
17923
|
}
|
|
17770
17924
|
return merged;
|
|
@@ -17801,7 +17955,7 @@ function buildAuthSecretsJson(secrets2, options) {
|
|
|
17801
17955
|
return payload;
|
|
17802
17956
|
}
|
|
17803
17957
|
function envFilePath(siteDirectory) {
|
|
17804
|
-
return
|
|
17958
|
+
return path57.join(path57.resolve(siteDirectory), ENV_FILENAME);
|
|
17805
17959
|
}
|
|
17806
17960
|
function getSecretsStatus(siteDirectory, manifest, secrets2, envExists) {
|
|
17807
17961
|
const providerSecretStatus = {};
|
|
@@ -17837,7 +17991,7 @@ function validateSecretsForPublish(manifest, secrets2, emailOptions) {
|
|
|
17837
17991
|
}
|
|
17838
17992
|
async function siteEnvFileHasEntries(siteDirectory) {
|
|
17839
17993
|
for (const fileName of [ENV_FILENAME, ".env.local"]) {
|
|
17840
|
-
const loaded = await readEnvFile(
|
|
17994
|
+
const loaded = await readEnvFile(path57.join(siteDirectory, fileName));
|
|
17841
17995
|
if (Object.keys(loaded).length > 0) {
|
|
17842
17996
|
return true;
|
|
17843
17997
|
}
|
|
@@ -17845,7 +17999,7 @@ async function siteEnvFileHasEntries(siteDirectory) {
|
|
|
17845
17999
|
return false;
|
|
17846
18000
|
}
|
|
17847
18001
|
async function resolvePublishConfig(siteDirectory, emailOptions) {
|
|
17848
|
-
const resolvedDirectory =
|
|
18002
|
+
const resolvedDirectory = path57.resolve(siteDirectory);
|
|
17849
18003
|
const manifestRaw = await readManifest2(resolvedDirectory);
|
|
17850
18004
|
if (!manifestRaw) {
|
|
17851
18005
|
throw new Error("apitogo.config.json not found in sourceDirectory.");
|
|
@@ -17875,13 +18029,13 @@ var SECRETS_COLLECTION_INSTRUCTION = "For go-live, plans must already be in apit
|
|
|
17875
18029
|
|
|
17876
18030
|
// src/cli/platform/helpers/dev-portal-site-validation.ts
|
|
17877
18031
|
init_gateway_limits();
|
|
17878
|
-
import { readFile as
|
|
18032
|
+
import { readFile as readFile20 } from "node:fs/promises";
|
|
17879
18033
|
import { createRequire as createRequire2 } from "node:module";
|
|
17880
|
-
import
|
|
18034
|
+
import path58 from "node:path";
|
|
17881
18035
|
var cachedFallbackTs;
|
|
17882
18036
|
async function loadTypeScriptForSite(sourceDirectory) {
|
|
17883
18037
|
const require2 = createRequire2(
|
|
17884
|
-
|
|
18038
|
+
path58.join(path58.resolve(sourceDirectory), "package.json")
|
|
17885
18039
|
);
|
|
17886
18040
|
try {
|
|
17887
18041
|
return require2("typescript");
|
|
@@ -17928,7 +18082,7 @@ async function referencedFileExists(sourceDirectory, reference) {
|
|
|
17928
18082
|
return true;
|
|
17929
18083
|
}
|
|
17930
18084
|
return pathExists(
|
|
17931
|
-
|
|
18085
|
+
path58.resolve(sourceDirectory, reference.replace(/^\.\//, ""))
|
|
17932
18086
|
);
|
|
17933
18087
|
}
|
|
17934
18088
|
async function validateSiteConfigStructure(config2, sourceDirectory) {
|
|
@@ -18043,17 +18197,17 @@ var DEFAULT_TSX_CANDIDATES = [
|
|
|
18043
18197
|
"landing/LandingPage.tsx"
|
|
18044
18198
|
];
|
|
18045
18199
|
async function validateDevPortalSiteConfig(sourceDirectory, options) {
|
|
18046
|
-
const resolvedDir =
|
|
18200
|
+
const resolvedDir = path58.resolve(sourceDirectory);
|
|
18047
18201
|
const issues = [];
|
|
18048
18202
|
const checkedFiles = [];
|
|
18049
18203
|
const skippedChecks = [];
|
|
18050
|
-
const jsonPath =
|
|
18204
|
+
const jsonPath = path58.join(resolvedDir, APITOGO_CONFIG_FILENAME2);
|
|
18051
18205
|
if (await pathExists(jsonPath)) {
|
|
18052
18206
|
checkedFiles.push(APITOGO_CONFIG_FILENAME2);
|
|
18053
18207
|
let parsed;
|
|
18054
18208
|
let parseFailed = false;
|
|
18055
18209
|
try {
|
|
18056
|
-
parsed = JSON.parse(await
|
|
18210
|
+
parsed = JSON.parse(await readFile20(jsonPath, "utf8"));
|
|
18057
18211
|
} catch (error) {
|
|
18058
18212
|
parseFailed = true;
|
|
18059
18213
|
issues.push({
|
|
@@ -18079,7 +18233,7 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
|
|
|
18079
18233
|
);
|
|
18080
18234
|
const existingTsxFiles = [];
|
|
18081
18235
|
for (const relativeFile of tsxFiles) {
|
|
18082
|
-
if (await pathExists(
|
|
18236
|
+
if (await pathExists(path58.join(resolvedDir, relativeFile))) {
|
|
18083
18237
|
existingTsxFiles.push(relativeFile);
|
|
18084
18238
|
}
|
|
18085
18239
|
}
|
|
@@ -18092,8 +18246,8 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
|
|
|
18092
18246
|
} else {
|
|
18093
18247
|
for (const relativeFile of existingTsxFiles) {
|
|
18094
18248
|
checkedFiles.push(relativeFile);
|
|
18095
|
-
const content = await
|
|
18096
|
-
|
|
18249
|
+
const content = await readFile20(
|
|
18250
|
+
path58.join(resolvedDir, relativeFile),
|
|
18097
18251
|
"utf8"
|
|
18098
18252
|
);
|
|
18099
18253
|
issues.push(
|
|
@@ -18115,8 +18269,8 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
|
|
|
18115
18269
|
|
|
18116
18270
|
// src/cli/platform/helpers/npm-build.ts
|
|
18117
18271
|
import { spawn as spawn2 } from "node:child_process";
|
|
18118
|
-
import { access as access7, readFile as
|
|
18119
|
-
import
|
|
18272
|
+
import { access as access7, readFile as readFile21 } from "node:fs/promises";
|
|
18273
|
+
import path59 from "node:path";
|
|
18120
18274
|
var BUILD_LOG_TAIL_BYTES = 8192;
|
|
18121
18275
|
var MIN_NODE_MAJOR = 20;
|
|
18122
18276
|
var NpmBuildError = class extends Error {
|
|
@@ -18183,13 +18337,13 @@ function runCommand(command2, args, cwd, env) {
|
|
|
18183
18337
|
}
|
|
18184
18338
|
async function runNpmInstall(sourceDirectory, options) {
|
|
18185
18339
|
assertNodeVersion(options?.nodeVersion);
|
|
18186
|
-
const cwd =
|
|
18187
|
-
const packageJsonPath =
|
|
18340
|
+
const cwd = path59.resolve(sourceDirectory);
|
|
18341
|
+
const packageJsonPath = path59.join(cwd, "package.json");
|
|
18188
18342
|
if (!await pathExists2(packageJsonPath)) {
|
|
18189
18343
|
throw new Error(`package.json not found in sourceDirectory: ${cwd}`);
|
|
18190
18344
|
}
|
|
18191
18345
|
const startedAt = Date.now();
|
|
18192
|
-
const lockPath =
|
|
18346
|
+
const lockPath = path59.join(cwd, "package-lock.json");
|
|
18193
18347
|
const installArgs = await pathExists2(lockPath) ? ["ci"] : ["install"];
|
|
18194
18348
|
const install = await runCommand("npm", installArgs, cwd);
|
|
18195
18349
|
const installLog = install.output;
|
|
@@ -18207,8 +18361,8 @@ async function runNpmInstall(sourceDirectory, options) {
|
|
|
18207
18361
|
}
|
|
18208
18362
|
async function runNpmBuild(sourceDirectory, options) {
|
|
18209
18363
|
assertNodeVersion(options?.nodeVersion);
|
|
18210
|
-
const cwd =
|
|
18211
|
-
const packageJsonPath =
|
|
18364
|
+
const cwd = path59.resolve(sourceDirectory);
|
|
18365
|
+
const packageJsonPath = path59.join(cwd, "package.json");
|
|
18212
18366
|
if (!await pathExists2(packageJsonPath)) {
|
|
18213
18367
|
throw new Error(`package.json not found in sourceDirectory: ${cwd}`);
|
|
18214
18368
|
}
|
|
@@ -18225,8 +18379,8 @@ async function runNpmBuild(sourceDirectory, options) {
|
|
|
18225
18379
|
build2.exitCode
|
|
18226
18380
|
);
|
|
18227
18381
|
}
|
|
18228
|
-
const distPath =
|
|
18229
|
-
const indexPath =
|
|
18382
|
+
const distPath = path59.join(cwd, "dist");
|
|
18383
|
+
const indexPath = path59.join(distPath, "index.html");
|
|
18230
18384
|
if (!await pathExists2(indexPath)) {
|
|
18231
18385
|
throw new NpmBuildError(
|
|
18232
18386
|
`Build completed but dist/index.html was not found at ${indexPath}`,
|
|
@@ -18610,7 +18764,7 @@ function validateManifestForPlatformPublish(manifest) {
|
|
|
18610
18764
|
|
|
18611
18765
|
// src/cli/platform/tools/check-publish-readiness.ts
|
|
18612
18766
|
async function checkPublishReadiness(client, _config, args) {
|
|
18613
|
-
const sourceDirectory =
|
|
18767
|
+
const sourceDirectory = path60.resolve(args.sourceDirectory);
|
|
18614
18768
|
const manifest = await readManifest2(sourceDirectory) ?? createScaffoldManifest();
|
|
18615
18769
|
const emailOptions = await resolveEmailOptionsForPublish(
|
|
18616
18770
|
client,
|
|
@@ -18688,7 +18842,7 @@ async function checkPublishReadiness(client, _config, args) {
|
|
|
18688
18842
|
|
|
18689
18843
|
// src/cli/check/handler.ts
|
|
18690
18844
|
async function check(argv) {
|
|
18691
|
-
const sourceDirectory =
|
|
18845
|
+
const sourceDirectory = path61.resolve(process.cwd(), argv.dir);
|
|
18692
18846
|
if (await isConfigV2(sourceDirectory)) {
|
|
18693
18847
|
await checkV2(sourceDirectory, argv);
|
|
18694
18848
|
return;
|
|
@@ -18752,7 +18906,7 @@ var check_default = {
|
|
|
18752
18906
|
|
|
18753
18907
|
// src/cli/make-config/handler.ts
|
|
18754
18908
|
init_invariant();
|
|
18755
|
-
import
|
|
18909
|
+
import path63 from "node:path";
|
|
18756
18910
|
import { stdin as input2 } from "node:process";
|
|
18757
18911
|
|
|
18758
18912
|
// src/cli/make-config/interactive.ts
|
|
@@ -18761,9 +18915,9 @@ import { createInterface as createInterface3 } from "node:readline/promises";
|
|
|
18761
18915
|
|
|
18762
18916
|
// src/cli/make-config/v2-edits.ts
|
|
18763
18917
|
init_apitogo_config_core();
|
|
18764
|
-
import { access as access8, mkdir as mkdir15, readFile as
|
|
18765
|
-
import
|
|
18766
|
-
import { glob as
|
|
18918
|
+
import { access as access8, mkdir as mkdir15, readFile as readFile22, writeFile as writeFile18 } from "node:fs/promises";
|
|
18919
|
+
import path62 from "node:path";
|
|
18920
|
+
import { glob as glob8 } from "glob";
|
|
18767
18921
|
init_invariant();
|
|
18768
18922
|
var ConfigEditError = class extends ApitogoError {
|
|
18769
18923
|
constructor(message, developerHint) {
|
|
@@ -18775,10 +18929,10 @@ var exists4 = (target) => access8(target).then(
|
|
|
18775
18929
|
() => true,
|
|
18776
18930
|
() => false
|
|
18777
18931
|
);
|
|
18778
|
-
var toPosix2 = (value) => value.split(
|
|
18779
|
-
var relativeToConfig = (project, target) => toPosix2(
|
|
18932
|
+
var toPosix2 = (value) => value.split(path62.sep).join("/");
|
|
18933
|
+
var relativeToConfig = (project, target) => toPosix2(path62.relative(project.resolved.configDir, target)) || ".";
|
|
18780
18934
|
async function openConfigProject(dir) {
|
|
18781
|
-
const configPath =
|
|
18935
|
+
const configPath = path62.join(dir, APITOGO_CONFIG_FILENAME);
|
|
18782
18936
|
if (!await exists4(configPath)) {
|
|
18783
18937
|
throw new ConfigEditError(
|
|
18784
18938
|
`There is no ${APITOGO_CONFIG_FILENAME} in ${dir}.`,
|
|
@@ -18843,7 +18997,7 @@ function setPortalName(project, name) {
|
|
|
18843
18997
|
}
|
|
18844
18998
|
async function addGatewaySpec(project, specPath) {
|
|
18845
18999
|
const gateway = requireGateway(project);
|
|
18846
|
-
const absolute =
|
|
19000
|
+
const absolute = path62.resolve(project.dir, specPath);
|
|
18847
19001
|
if (!await exists4(absolute)) {
|
|
18848
19002
|
throw new ConfigEditError(`The OpenAPI file ${specPath} does not exist.`);
|
|
18849
19003
|
}
|
|
@@ -18887,7 +19041,7 @@ function parseBackendInput(input5) {
|
|
|
18887
19041
|
}
|
|
18888
19042
|
async function setGatewayOrigin(project, backend) {
|
|
18889
19043
|
const gateway = requireGateway(project);
|
|
18890
|
-
const source =
|
|
19044
|
+
const source = path62.resolve(project.dir, backend.source);
|
|
18891
19045
|
if (!await exists4(source)) {
|
|
18892
19046
|
throw new ConfigEditError(
|
|
18893
19047
|
`The API source folder ${backend.source} does not exist.`
|
|
@@ -18925,6 +19079,33 @@ title: ${JSON.stringify(title)}
|
|
|
18925
19079
|
${body}
|
|
18926
19080
|
`;
|
|
18927
19081
|
}
|
|
19082
|
+
function pageComponentName(slug) {
|
|
19083
|
+
const name = slug.split(/[^A-Za-z0-9]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
19084
|
+
return `${/^[0-9]/.test(name) ? "Page" : ""}${name || "Docs"}Page`;
|
|
19085
|
+
}
|
|
19086
|
+
function buildTsxDocsPage(slug, title, file, content) {
|
|
19087
|
+
const text = content?.trim() ? `{${JSON.stringify(content.trim())}}` : "This page is a React component. Change it like any other component: add state, fetch data, or use the portal's components.";
|
|
19088
|
+
return `import { Callout, Heading, Typography } from "@lukoweb/apitogo/components";
|
|
19089
|
+
|
|
19090
|
+
/** The page's label in the sidebar. */
|
|
19091
|
+
export const title = ${JSON.stringify(title)};
|
|
19092
|
+
|
|
19093
|
+
export default function ${pageComponentName(slug)}() {
|
|
19094
|
+
return (
|
|
19095
|
+
<section className="mx-auto max-w-screen-lg px-4 py-12 pt-(--padding-content-top)">
|
|
19096
|
+
<Typography>
|
|
19097
|
+
<Heading level={1}>{title}</Heading>
|
|
19098
|
+
<p>${text}</p>
|
|
19099
|
+
<Callout type="info" title="Where this page lives">
|
|
19100
|
+
Edit <code>${file}</code>. Files whose name starts with <code>_</code> are not pages, so you can keep shared
|
|
19101
|
+
components next to your pages.
|
|
19102
|
+
</Callout>
|
|
19103
|
+
</Typography>
|
|
19104
|
+
</section>
|
|
19105
|
+
);
|
|
19106
|
+
}
|
|
19107
|
+
`;
|
|
19108
|
+
}
|
|
18928
19109
|
async function writeDocsPage(project, input5) {
|
|
18929
19110
|
requirePortal(project);
|
|
18930
19111
|
if (/^[A-Za-z]:[\\/]/.test(input5.slug.trim())) {
|
|
@@ -18942,29 +19123,36 @@ async function writeDocsPage(project, input5) {
|
|
|
18942
19123
|
}
|
|
18943
19124
|
const slug = normalizeDocsSlug(input5.slug);
|
|
18944
19125
|
if (!slug) throw new ConfigEditError("The page path must not be empty.");
|
|
18945
|
-
const base =
|
|
19126
|
+
const base = path62.join(portal.dir, "pages", ...slug.split("/"));
|
|
18946
19127
|
const existing = (await Promise.all(
|
|
18947
|
-
[`${base}.mdx`, `${base}.md`].map(
|
|
19128
|
+
[`${base}.tsx`, `${base}.mdx`, `${base}.md`].map(
|
|
18948
19129
|
async (file2) => await exists4(file2) ? file2 : null
|
|
18949
19130
|
)
|
|
18950
19131
|
)).find((file2) => file2 !== null);
|
|
19132
|
+
const relative = (file2) => toPosix2(path62.relative(project.dir, file2));
|
|
19133
|
+
const write = (file2, title) => writeFile18(
|
|
19134
|
+
file2,
|
|
19135
|
+
file2.endsWith(".tsx") ? buildTsxDocsPage(slug, title, relative(file2), input5.content) : buildDocsPage(title, input5.content),
|
|
19136
|
+
"utf8"
|
|
19137
|
+
);
|
|
18951
19138
|
let file;
|
|
18952
19139
|
let action;
|
|
18953
19140
|
if (input5.update) {
|
|
18954
19141
|
if (!existing) {
|
|
18955
19142
|
throw new ConfigEditError(
|
|
18956
|
-
`There is no page at ${
|
|
19143
|
+
`There is no page at ${relative(`${base}.${input5.format ?? "tsx"}`)}.`,
|
|
18957
19144
|
"Leave out --page-update to add it."
|
|
18958
19145
|
);
|
|
18959
19146
|
}
|
|
18960
|
-
const
|
|
19147
|
+
const source = await readFile22(existing, "utf8");
|
|
19148
|
+
const title = input5.title?.trim() || (existing.endsWith(".tsx") ? tsxPageLabel(source, existing) : titleOf(source));
|
|
18961
19149
|
file = existing;
|
|
18962
19150
|
action = "updated";
|
|
18963
|
-
await
|
|
19151
|
+
await write(file, title ?? slug);
|
|
18964
19152
|
} else {
|
|
18965
19153
|
if (existing) {
|
|
18966
19154
|
throw new ConfigEditError(
|
|
18967
|
-
`A page already exists at ${
|
|
19155
|
+
`A page already exists at ${relative(existing)}.`,
|
|
18968
19156
|
"Pass --page-update to change it."
|
|
18969
19157
|
);
|
|
18970
19158
|
}
|
|
@@ -18972,20 +19160,19 @@ async function writeDocsPage(project, input5) {
|
|
|
18972
19160
|
if (!title) {
|
|
18973
19161
|
throw new ConfigEditError("A new page needs a title (--page-title).");
|
|
18974
19162
|
}
|
|
18975
|
-
file = `${base}.
|
|
19163
|
+
file = `${base}.${input5.format ?? "tsx"}`;
|
|
18976
19164
|
action = "added";
|
|
18977
|
-
await mkdir15(
|
|
18978
|
-
await
|
|
19165
|
+
await mkdir15(path62.dirname(file), { recursive: true });
|
|
19166
|
+
await write(file, title);
|
|
18979
19167
|
}
|
|
18980
|
-
const
|
|
18981
|
-
const inPortal =
|
|
18982
|
-
(match) => path61.resolve(match) === path61.resolve(file)
|
|
18983
|
-
);
|
|
19168
|
+
const same = (match) => path62.resolve(match) === path62.resolve(file);
|
|
19169
|
+
const inPortal = file.endsWith(".tsx") ? (await findTsxPages(portal.docs.content)).some((page) => same(page.file)) : (await glob8(portal.docs.content, { absolute: true })).some(same);
|
|
18984
19170
|
return {
|
|
18985
19171
|
action,
|
|
18986
19172
|
slug,
|
|
18987
19173
|
route: `/${slug}`,
|
|
18988
|
-
file:
|
|
19174
|
+
file: relative(file),
|
|
19175
|
+
format: path62.extname(file).slice(1),
|
|
18989
19176
|
inPortal
|
|
18990
19177
|
};
|
|
18991
19178
|
}
|
|
@@ -19046,7 +19233,7 @@ async function upsertPlan(project, plan2) {
|
|
|
19046
19233
|
if (await exists4(plans.file)) {
|
|
19047
19234
|
let raw;
|
|
19048
19235
|
try {
|
|
19049
|
-
raw = JSON.parse(await
|
|
19236
|
+
raw = JSON.parse(await readFile22(plans.file, "utf8"));
|
|
19050
19237
|
} catch (error) {
|
|
19051
19238
|
throw new ConfigEditError(
|
|
19052
19239
|
`${relativeToConfig(project, plans.file)} is not valid JSON (${error.message}).`
|
|
@@ -19066,18 +19253,18 @@ async function upsertPlan(project, plan2) {
|
|
|
19066
19253
|
const next = [...catalog.plans];
|
|
19067
19254
|
if (index === -1) next.push(plan2);
|
|
19068
19255
|
else next[index] = plan2;
|
|
19069
|
-
await mkdir15(
|
|
19256
|
+
await mkdir15(path62.dirname(plans.file), { recursive: true });
|
|
19070
19257
|
await writeFile18(
|
|
19071
19258
|
plans.file,
|
|
19072
19259
|
`${JSON.stringify({ ...catalog, plans: next }, null, 2)}
|
|
19073
19260
|
`,
|
|
19074
19261
|
"utf8"
|
|
19075
19262
|
);
|
|
19076
|
-
const paid =
|
|
19263
|
+
const paid = isPaidPlan(plan2);
|
|
19077
19264
|
return {
|
|
19078
19265
|
action: index === -1 ? "added" : "updated",
|
|
19079
19266
|
sku: plan2.sku,
|
|
19080
|
-
file: toPosix2(
|
|
19267
|
+
file: toPosix2(path62.relative(project.dir, plans.file)),
|
|
19081
19268
|
paid,
|
|
19082
19269
|
needsBilling: paid && plans.billing.provider !== "stripe"
|
|
19083
19270
|
};
|
|
@@ -19105,7 +19292,7 @@ function printPageResult(page) {
|
|
|
19105
19292
|
);
|
|
19106
19293
|
if (page.inPortal) {
|
|
19107
19294
|
printHintToConsole(
|
|
19108
|
-
"The sidebar is built from the pages folder, so the config does not change. Edit the file to change the content."
|
|
19295
|
+
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."
|
|
19109
19296
|
);
|
|
19110
19297
|
} else {
|
|
19111
19298
|
printWarningToConsole(
|
|
@@ -19117,7 +19304,12 @@ function printPlanResult(plan2) {
|
|
|
19117
19304
|
printSuccessToConsole(`Plan "${plan2.sku}" ${plan2.action} in ${plan2.file}.`);
|
|
19118
19305
|
if (plan2.needsBilling) {
|
|
19119
19306
|
printWarningToConsole(
|
|
19120
|
-
|
|
19307
|
+
'This plan has a price, but plans.billing.provider is "none", so deploy will refuse it. Remove plans.billing.provider (Stripe is the provider), or make the plan free or custom.'
|
|
19308
|
+
);
|
|
19309
|
+
}
|
|
19310
|
+
if (plan2.paid && !plan2.needsBilling) {
|
|
19311
|
+
printHintToConsole(
|
|
19312
|
+
"Payments go through Stripe: apitogo deploy asks for your Stripe secret key if the project has none yet."
|
|
19121
19313
|
);
|
|
19122
19314
|
}
|
|
19123
19315
|
if (plan2.paid) printPaidPlanPlatformWarning();
|
|
@@ -19346,7 +19538,7 @@ async function applyConfigFlags(project, argv, changes) {
|
|
|
19346
19538
|
return { project: next, openApi };
|
|
19347
19539
|
}
|
|
19348
19540
|
async function makeConfig(argv) {
|
|
19349
|
-
const dir =
|
|
19541
|
+
const dir = path63.resolve(process.cwd(), argv.dir);
|
|
19350
19542
|
const interactive = shouldRunInteractive(argv);
|
|
19351
19543
|
const json = argv.json === true;
|
|
19352
19544
|
const changes = [];
|
|
@@ -19393,7 +19585,8 @@ async function makeConfig(argv) {
|
|
|
19393
19585
|
slug: argv.pageSlug,
|
|
19394
19586
|
title: argv.pageTitle,
|
|
19395
19587
|
content: argv.pageContent,
|
|
19396
|
-
update: argv.pageUpdate === true
|
|
19588
|
+
update: argv.pageUpdate === true,
|
|
19589
|
+
format: argv.pageFormat
|
|
19397
19590
|
});
|
|
19398
19591
|
changes.push(page.action === "added" ? "page_add" : "page_update");
|
|
19399
19592
|
}
|
|
@@ -19480,13 +19673,17 @@ function addConfigOptions(yargs2) {
|
|
|
19480
19673
|
describe: "Runtime version of --source, for example NODE_22_LTS"
|
|
19481
19674
|
}).option("page-slug", {
|
|
19482
19675
|
type: "string",
|
|
19483
|
-
describe: "Add or update a docs page at <portal>/pages/<slug>.
|
|
19676
|
+
describe: "Add or update a docs page at <portal>/pages/<slug>.tsx (for example guides/quickstart)"
|
|
19484
19677
|
}).option("page-title", {
|
|
19485
19678
|
type: "string",
|
|
19486
19679
|
describe: "Title of --page-slug (required when adding)"
|
|
19487
19680
|
}).option("page-content", {
|
|
19488
19681
|
type: "string",
|
|
19489
|
-
describe: "
|
|
19682
|
+
describe: "Text of --page-slug (Markdown for an .mdx page)"
|
|
19683
|
+
}).option("page-format", {
|
|
19684
|
+
type: "string",
|
|
19685
|
+
choices: ["tsx", "mdx"],
|
|
19686
|
+
describe: "Format of a new page: tsx (a React component, the default) or mdx (Markdown)"
|
|
19490
19687
|
}).option("page-update", {
|
|
19491
19688
|
type: "boolean",
|
|
19492
19689
|
default: false,
|
|
@@ -19512,15 +19709,15 @@ var config_default = {
|
|
|
19512
19709
|
// src/cli/create/handler.ts
|
|
19513
19710
|
init_apitogo_config_core();
|
|
19514
19711
|
import { execFile } from "node:child_process";
|
|
19515
|
-
import { readFile as
|
|
19516
|
-
import
|
|
19712
|
+
import { readFile as readFile23 } from "node:fs/promises";
|
|
19713
|
+
import path64 from "node:path";
|
|
19517
19714
|
import { promisify } from "node:util";
|
|
19518
19715
|
var execFileAsync = promisify(execFile);
|
|
19519
19716
|
function nextStepHint(dir) {
|
|
19520
19717
|
const linked = loadConfigV2(dir).resolved.project.id;
|
|
19521
|
-
const cd =
|
|
19718
|
+
const cd = path64.resolve(dir) === path64.resolve(process.cwd());
|
|
19522
19719
|
const steps = linked ? "apitogo deploy" : "apitogo project create, then apitogo deploy";
|
|
19523
|
-
return cd ? `Next: ${steps}` : `Next: cd ${JSON.stringify(
|
|
19720
|
+
return cd ? `Next: ${steps}` : `Next: cd ${JSON.stringify(path64.relative(process.cwd(), dir))}, then ${steps}`;
|
|
19524
19721
|
}
|
|
19525
19722
|
function projectFolderName(name) {
|
|
19526
19723
|
return name.trim().replace(/[<>:"/\\|?*\s]+/g, "-").replace(/^[-.]+|[-.]+$/g, "") || "apitogo-project";
|
|
@@ -19546,13 +19743,13 @@ async function gitHasUncommittedChanges(dir) {
|
|
|
19546
19743
|
async function defaultName(dir) {
|
|
19547
19744
|
try {
|
|
19548
19745
|
const parsed = JSON.parse(
|
|
19549
|
-
await
|
|
19746
|
+
await readFile23(path64.join(dir, "package.json"), "utf8")
|
|
19550
19747
|
);
|
|
19551
19748
|
if (typeof parsed.name === "string" && parsed.name.trim())
|
|
19552
19749
|
return parsed.name.replace(/^@[^/]+\//, "");
|
|
19553
19750
|
} catch {
|
|
19554
19751
|
}
|
|
19555
|
-
return
|
|
19752
|
+
return path64.basename(dir);
|
|
19556
19753
|
}
|
|
19557
19754
|
function parseServicesFlag(value) {
|
|
19558
19755
|
const names = (value ?? "").split(",").map((name) => name.trim()).filter(Boolean);
|
|
@@ -19578,7 +19775,7 @@ async function createProject(argv, deps = {}) {
|
|
|
19578
19775
|
if (!json) printDiagnosticsToConsole(line2);
|
|
19579
19776
|
};
|
|
19580
19777
|
try {
|
|
19581
|
-
const base =
|
|
19778
|
+
const base = path64.resolve(process.cwd(), argv.dir ?? ".");
|
|
19582
19779
|
let dir = base;
|
|
19583
19780
|
let requested = parseServicesFlag(argv.services);
|
|
19584
19781
|
let template = argv.template;
|
|
@@ -19601,8 +19798,8 @@ async function createProject(argv, deps = {}) {
|
|
|
19601
19798
|
default: await defaultName(base)
|
|
19602
19799
|
}) : await defaultName(base));
|
|
19603
19800
|
const folder = projectFolderName(name);
|
|
19604
|
-
if (argv.dir === void 0 && folder !==
|
|
19605
|
-
dir =
|
|
19801
|
+
if (argv.dir === void 0 && folder !== path64.basename(base))
|
|
19802
|
+
dir = path64.join(base, folder);
|
|
19606
19803
|
}
|
|
19607
19804
|
if (await (deps.hasUncommittedChanges ?? gitHasUncommittedChanges)(dir))
|
|
19608
19805
|
say(
|
|
@@ -19629,7 +19826,7 @@ async function createProject(argv, deps = {}) {
|
|
|
19629
19826
|
}
|
|
19630
19827
|
await applyInitPlan(plan2);
|
|
19631
19828
|
say(
|
|
19632
|
-
dir === base ? `Created ${APITOGO_CONFIG_FILENAME}.` : `Created ${
|
|
19829
|
+
dir === base ? `Created ${APITOGO_CONFIG_FILENAME}.` : `Created ${path64.relative(base, dir)}${path64.sep}${APITOGO_CONFIG_FILENAME}.`
|
|
19633
19830
|
);
|
|
19634
19831
|
} else {
|
|
19635
19832
|
say(`${APITOGO_CONFIG_FILENAME} exists: continuing from it.`);
|
|
@@ -19772,10 +19969,10 @@ var create_default = {
|
|
|
19772
19969
|
};
|
|
19773
19970
|
|
|
19774
19971
|
// src/cli/cmds/deploy.ts
|
|
19775
|
-
import
|
|
19972
|
+
import path82 from "node:path";
|
|
19776
19973
|
|
|
19777
19974
|
// src/cli/apply/handler.ts
|
|
19778
|
-
import
|
|
19975
|
+
import path76 from "node:path";
|
|
19779
19976
|
|
|
19780
19977
|
// src/cli/platform/helpers/gateway-plan-validation.ts
|
|
19781
19978
|
init_gateway_limits();
|
|
@@ -19984,11 +20181,11 @@ init_gateway_limits();
|
|
|
19984
20181
|
// src/cli/platform/helpers/deploy-artifact-hash.ts
|
|
19985
20182
|
import { createHash as createHash3 } from "node:crypto";
|
|
19986
20183
|
import { createReadStream, promises as fs6 } from "node:fs";
|
|
19987
|
-
import
|
|
20184
|
+
import path66 from "node:path";
|
|
19988
20185
|
|
|
19989
20186
|
// src/cli/platform/helpers/package-files.ts
|
|
19990
20187
|
import { promises as fs5 } from "node:fs";
|
|
19991
|
-
import
|
|
20188
|
+
import path65 from "node:path";
|
|
19992
20189
|
import ignore from "ignore";
|
|
19993
20190
|
var DEFAULT_EXCLUDES = /* @__PURE__ */ new Set([
|
|
19994
20191
|
"node_modules",
|
|
@@ -20002,7 +20199,7 @@ async function loadGitignore(rootDir, extraExcludes = []) {
|
|
|
20002
20199
|
const ig = ignore();
|
|
20003
20200
|
ig.add(["node_modules/", ".git/", "dist/", "bin/", "obj/"]);
|
|
20004
20201
|
if (extraExcludes.length > 0) ig.add([...extraExcludes]);
|
|
20005
|
-
const gitignorePath =
|
|
20202
|
+
const gitignorePath = path65.join(rootDir, ".gitignore");
|
|
20006
20203
|
try {
|
|
20007
20204
|
const content = await fs5.readFile(gitignorePath, "utf8");
|
|
20008
20205
|
ig.add(content);
|
|
@@ -20011,11 +20208,11 @@ async function loadGitignore(rootDir, extraExcludes = []) {
|
|
|
20011
20208
|
return ig;
|
|
20012
20209
|
}
|
|
20013
20210
|
async function collectFiles(rootDir, relativeDir, ig, files) {
|
|
20014
|
-
const absDir =
|
|
20211
|
+
const absDir = path65.join(rootDir, relativeDir);
|
|
20015
20212
|
const entries = await fs5.readdir(absDir, { withFileTypes: true });
|
|
20016
20213
|
for (const entry of entries) {
|
|
20017
|
-
const rel2 = relativeDir ?
|
|
20018
|
-
const relPosix = rel2.split(
|
|
20214
|
+
const rel2 = relativeDir ? path65.join(relativeDir, entry.name) : entry.name;
|
|
20215
|
+
const relPosix = rel2.split(path65.sep).join("/");
|
|
20019
20216
|
if (DEFAULT_EXCLUDES.has(entry.name) && !relativeDir) {
|
|
20020
20217
|
continue;
|
|
20021
20218
|
}
|
|
@@ -20030,7 +20227,7 @@ async function collectFiles(rootDir, relativeDir, ig, files) {
|
|
|
20030
20227
|
}
|
|
20031
20228
|
}
|
|
20032
20229
|
async function collectPackageableFiles(sourceDirectory, extraExcludes = []) {
|
|
20033
|
-
const resolved =
|
|
20230
|
+
const resolved = path65.resolve(sourceDirectory);
|
|
20034
20231
|
const stat7 = await fs5.stat(resolved).catch(() => null);
|
|
20035
20232
|
if (!stat7?.isDirectory()) {
|
|
20036
20233
|
throw new Error(`sourceDirectory is not a directory: ${resolved}`);
|
|
@@ -20056,7 +20253,7 @@ async function sha256File(filePath) {
|
|
|
20056
20253
|
return hash2.digest("hex");
|
|
20057
20254
|
}
|
|
20058
20255
|
async function hashDirectoryContents(rootDirectory, extraExcludes = []) {
|
|
20059
|
-
const resolved =
|
|
20256
|
+
const resolved = path66.resolve(rootDirectory);
|
|
20060
20257
|
const files = (await collectPackageableFiles(resolved, extraExcludes)).sort(
|
|
20061
20258
|
(a, b) => a.localeCompare(b)
|
|
20062
20259
|
);
|
|
@@ -20064,13 +20261,13 @@ async function hashDirectoryContents(rootDirectory, extraExcludes = []) {
|
|
|
20064
20261
|
for (const rel2 of files) {
|
|
20065
20262
|
hash2.update(rel2);
|
|
20066
20263
|
hash2.update("\0");
|
|
20067
|
-
hash2.update(await fs6.readFile(
|
|
20264
|
+
hash2.update(await fs6.readFile(path66.join(resolved, rel2)));
|
|
20068
20265
|
hash2.update("\0");
|
|
20069
20266
|
}
|
|
20070
20267
|
return hash2.digest("hex");
|
|
20071
20268
|
}
|
|
20072
20269
|
async function hashDevPortalSiteSources(siteDirectory, options) {
|
|
20073
|
-
const resolved =
|
|
20270
|
+
const resolved = path66.resolve(siteDirectory);
|
|
20074
20271
|
const hash2 = createHash3("sha256");
|
|
20075
20272
|
const candidates = [
|
|
20076
20273
|
"apitogo.config.json",
|
|
@@ -20080,7 +20277,7 @@ async function hashDevPortalSiteSources(siteDirectory, options) {
|
|
|
20080
20277
|
"zudoku.config.tsx"
|
|
20081
20278
|
];
|
|
20082
20279
|
for (const name of candidates) {
|
|
20083
|
-
const full =
|
|
20280
|
+
const full = path66.join(resolved, name);
|
|
20084
20281
|
try {
|
|
20085
20282
|
hash2.update(name);
|
|
20086
20283
|
hash2.update("\0");
|
|
@@ -20090,7 +20287,7 @@ async function hashDevPortalSiteSources(siteDirectory, options) {
|
|
|
20090
20287
|
}
|
|
20091
20288
|
}
|
|
20092
20289
|
for (const dir of ["pages", "landing", "src"]) {
|
|
20093
|
-
const full =
|
|
20290
|
+
const full = path66.join(resolved, dir);
|
|
20094
20291
|
try {
|
|
20095
20292
|
const st = await fs6.stat(full);
|
|
20096
20293
|
if (!st.isDirectory()) continue;
|
|
@@ -20319,8 +20516,8 @@ function normalizeActionKey(actionKey2) {
|
|
|
20319
20516
|
const trimmed = actionKey2.trim();
|
|
20320
20517
|
if (trimmed.includes(":")) {
|
|
20321
20518
|
const [method2, ...pathParts] = trimmed.split(":");
|
|
20322
|
-
const
|
|
20323
|
-
return `${method2?.toLowerCase()}:${
|
|
20519
|
+
const path98 = pathParts.join(":").trim();
|
|
20520
|
+
return `${method2?.toLowerCase()}:${path98.startsWith("/") ? path98 : `/${path98}`}`;
|
|
20324
20521
|
}
|
|
20325
20522
|
const spaceIndex = trimmed.indexOf(" ");
|
|
20326
20523
|
if (spaceIndex <= 0) {
|
|
@@ -20329,8 +20526,8 @@ function normalizeActionKey(actionKey2) {
|
|
|
20329
20526
|
);
|
|
20330
20527
|
}
|
|
20331
20528
|
const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
|
|
20332
|
-
const
|
|
20333
|
-
return `${method}:${
|
|
20529
|
+
const path97 = trimmed.slice(spaceIndex + 1).trim();
|
|
20530
|
+
return `${method}:${path97.startsWith("/") ? path97 : `/${path97}`}`;
|
|
20334
20531
|
}
|
|
20335
20532
|
async function applyGatewayPublicRoutes(client, projectId, routes, options) {
|
|
20336
20533
|
const applied = [];
|
|
@@ -20808,8 +21005,8 @@ async function upsertGatewayPlansFromManifest(client, config2, projectId, plans,
|
|
|
20808
21005
|
}
|
|
20809
21006
|
|
|
20810
21007
|
// src/cli/platform/helpers/openapi-gateway-servers.ts
|
|
20811
|
-
import { mkdir as mkdir16, readFile as
|
|
20812
|
-
import
|
|
21008
|
+
import { mkdir as mkdir16, readFile as readFile24, writeFile as writeFile19 } from "node:fs/promises";
|
|
21009
|
+
import path67 from "node:path";
|
|
20813
21010
|
import YAML from "yaml";
|
|
20814
21011
|
var GATEWAY_URL_ENV_KEY = "APITOGO_GATEWAY_URL";
|
|
20815
21012
|
var PUBLISH_OPENAPI_RELATIVE = ".apitogo/openapi-publish.json";
|
|
@@ -20840,8 +21037,8 @@ async function resolveProjectGatewayUrl(client, projectId) {
|
|
|
20840
21037
|
return null;
|
|
20841
21038
|
}
|
|
20842
21039
|
async function readOpenApiDocument(filePath) {
|
|
20843
|
-
const content = await
|
|
20844
|
-
const ext =
|
|
21040
|
+
const content = await readFile24(filePath, "utf8");
|
|
21041
|
+
const ext = path67.extname(filePath).toLowerCase();
|
|
20845
21042
|
const parsed = ext === ".json" ? JSON.parse(content) : YAML.parse(content);
|
|
20846
21043
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
20847
21044
|
throw new Error(`OpenAPI document must be an object: ${filePath}`);
|
|
@@ -20849,13 +21046,13 @@ async function readOpenApiDocument(filePath) {
|
|
|
20849
21046
|
return parsed;
|
|
20850
21047
|
}
|
|
20851
21048
|
async function materializePublishOpenApiWithGateway(siteDirectory, sourceOpenApiPath, gatewayUrl) {
|
|
20852
|
-
const site =
|
|
20853
|
-
const source =
|
|
21049
|
+
const site = path67.resolve(siteDirectory);
|
|
21050
|
+
const source = path67.resolve(sourceOpenApiPath);
|
|
20854
21051
|
const relativeInput = PUBLISH_OPENAPI_RELATIVE;
|
|
20855
|
-
const outputPath =
|
|
21052
|
+
const outputPath = path67.join(site, ...relativeInput.split("/"));
|
|
20856
21053
|
const doc = await readOpenApiDocument(source);
|
|
20857
21054
|
const rewritten = withGatewayServers(doc, gatewayUrl);
|
|
20858
|
-
await mkdir16(
|
|
21055
|
+
await mkdir16(path67.dirname(outputPath), { recursive: true });
|
|
20859
21056
|
await writeFile19(
|
|
20860
21057
|
outputPath,
|
|
20861
21058
|
`${JSON.stringify(rewritten, null, 2)}
|
|
@@ -20865,11 +21062,11 @@ async function materializePublishOpenApiWithGateway(siteDirectory, sourceOpenApi
|
|
|
20865
21062
|
return { outputPath, relativeInput };
|
|
20866
21063
|
}
|
|
20867
21064
|
async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
|
|
20868
|
-
const configPath =
|
|
20869
|
-
|
|
21065
|
+
const configPath = path67.join(
|
|
21066
|
+
path67.resolve(siteDirectory),
|
|
20870
21067
|
APITOGO_CONFIG_FILENAME2
|
|
20871
21068
|
);
|
|
20872
|
-
const raw = await
|
|
21069
|
+
const raw = await readFile24(configPath, "utf8");
|
|
20873
21070
|
const config2 = JSON.parse(raw);
|
|
20874
21071
|
const previousApis = config2.apis;
|
|
20875
21072
|
const previousBackend = config2.backend;
|
|
@@ -20886,7 +21083,7 @@ async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
|
|
|
20886
21083
|
`, "utf8");
|
|
20887
21084
|
return {
|
|
20888
21085
|
restore: async () => {
|
|
20889
|
-
const currentRaw = await
|
|
21086
|
+
const currentRaw = await readFile24(configPath, "utf8");
|
|
20890
21087
|
const current = JSON.parse(currentRaw);
|
|
20891
21088
|
if (previousApis === void 0) {
|
|
20892
21089
|
delete current.apis;
|
|
@@ -20908,7 +21105,7 @@ async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
|
|
|
20908
21105
|
};
|
|
20909
21106
|
}
|
|
20910
21107
|
async function prepareOpenApiServersForGatewayBuild(options) {
|
|
20911
|
-
const siteDirectory =
|
|
21108
|
+
const siteDirectory = path67.resolve(options.siteDirectory);
|
|
20912
21109
|
let openApiPath = resolveBackendOpenApiPath(
|
|
20913
21110
|
options.manifest?.backend?.openApiPath,
|
|
20914
21111
|
{
|
|
@@ -20921,8 +21118,8 @@ async function prepareOpenApiServersForGatewayBuild(options) {
|
|
|
20921
21118
|
);
|
|
20922
21119
|
if (!openApiPath) {
|
|
20923
21120
|
try {
|
|
20924
|
-
const raw = await
|
|
20925
|
-
|
|
21121
|
+
const raw = await readFile24(
|
|
21122
|
+
path67.join(siteDirectory, APITOGO_CONFIG_FILENAME2),
|
|
20926
21123
|
"utf8"
|
|
20927
21124
|
);
|
|
20928
21125
|
const config2 = JSON.parse(raw);
|
|
@@ -20951,8 +21148,8 @@ function normalizeActionKeyFormat(actionKey2) {
|
|
|
20951
21148
|
const trimmed = actionKey2.trim();
|
|
20952
21149
|
if (trimmed.includes(":")) {
|
|
20953
21150
|
const [method2, ...pathParts] = trimmed.split(":");
|
|
20954
|
-
const
|
|
20955
|
-
return `${method2.toLowerCase()}:${
|
|
21151
|
+
const path98 = pathParts.join(":").trim();
|
|
21152
|
+
return `${method2.toLowerCase()}:${path98.startsWith("/") ? path98 : `/${path98}`}`;
|
|
20956
21153
|
}
|
|
20957
21154
|
const spaceIndex = trimmed.indexOf(" ");
|
|
20958
21155
|
if (spaceIndex <= 0) {
|
|
@@ -20961,8 +21158,8 @@ function normalizeActionKeyFormat(actionKey2) {
|
|
|
20961
21158
|
);
|
|
20962
21159
|
}
|
|
20963
21160
|
const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
|
|
20964
|
-
const
|
|
20965
|
-
return `${method}:${
|
|
21161
|
+
const path97 = trimmed.slice(spaceIndex + 1).trim();
|
|
21162
|
+
return `${method}:${path97.startsWith("/") ? path97 : `/${path97}`}`;
|
|
20966
21163
|
}
|
|
20967
21164
|
function normalizePublicRoute(route) {
|
|
20968
21165
|
const trimmed = route.trim();
|
|
@@ -20995,16 +21192,16 @@ function collectManifestPublicActionKeys(gateway) {
|
|
|
20995
21192
|
}
|
|
20996
21193
|
|
|
20997
21194
|
// src/cli/platform/helpers/publish-ledger.ts
|
|
20998
|
-
import { mkdir as mkdir17, readFile as
|
|
20999
|
-
import
|
|
21195
|
+
import { mkdir as mkdir17, readFile as readFile25, writeFile as writeFile20 } from "node:fs/promises";
|
|
21196
|
+
import path68 from "node:path";
|
|
21000
21197
|
var PUBLISH_LEDGER_RELATIVE_PATH = ".apitogo/publish-state.json";
|
|
21001
21198
|
function publishLedgerPath(siteDirectory) {
|
|
21002
|
-
return
|
|
21199
|
+
return path68.join(path68.resolve(siteDirectory), PUBLISH_LEDGER_RELATIVE_PATH);
|
|
21003
21200
|
}
|
|
21004
21201
|
async function readPublishLedger(siteDirectory) {
|
|
21005
21202
|
const filePath = publishLedgerPath(siteDirectory);
|
|
21006
21203
|
try {
|
|
21007
|
-
const raw = await
|
|
21204
|
+
const raw = await readFile25(filePath, "utf8");
|
|
21008
21205
|
const parsed = JSON.parse(raw);
|
|
21009
21206
|
if (parsed?.version !== 1 || !Array.isArray(parsed.steps)) {
|
|
21010
21207
|
return null;
|
|
@@ -21016,7 +21213,7 @@ async function readPublishLedger(siteDirectory) {
|
|
|
21016
21213
|
}
|
|
21017
21214
|
async function writePublishLedger(siteDirectory, ledger) {
|
|
21018
21215
|
const filePath = publishLedgerPath(siteDirectory);
|
|
21019
|
-
await mkdir17(
|
|
21216
|
+
await mkdir17(path68.dirname(filePath), { recursive: true });
|
|
21020
21217
|
const next = {
|
|
21021
21218
|
...ledger,
|
|
21022
21219
|
version: 1,
|
|
@@ -21538,7 +21735,7 @@ async function createProjectWithWarmPoolRetry(client, body, options) {
|
|
|
21538
21735
|
import { spawn as spawn3 } from "node:child_process";
|
|
21539
21736
|
import { mkdtemp, readdir as readdir4, rm as rm9 } from "node:fs/promises";
|
|
21540
21737
|
import { tmpdir } from "node:os";
|
|
21541
|
-
import
|
|
21738
|
+
import path69 from "node:path";
|
|
21542
21739
|
async function directoryHasRuntimeConfig(dir) {
|
|
21543
21740
|
if (!await pathExists(dir)) {
|
|
21544
21741
|
return false;
|
|
@@ -21581,20 +21778,20 @@ function runDotnetPublish(projectDir, outputDir) {
|
|
|
21581
21778
|
async function findCsproj(projectDir) {
|
|
21582
21779
|
const entries = await readdir4(projectDir);
|
|
21583
21780
|
const csproj = entries.find((name) => name.endsWith(".csproj"));
|
|
21584
|
-
return csproj ?
|
|
21781
|
+
return csproj ? path69.join(projectDir, csproj) : null;
|
|
21585
21782
|
}
|
|
21586
21783
|
async function prepareBackendPackagingDirectory(args) {
|
|
21587
|
-
const sourceDirectory =
|
|
21784
|
+
const sourceDirectory = path69.resolve(args.sourceDirectory);
|
|
21588
21785
|
if (args.publishDirectory?.trim()) {
|
|
21589
21786
|
return {
|
|
21590
|
-
directory:
|
|
21787
|
+
directory: path69.resolve(args.publishDirectory),
|
|
21591
21788
|
packagingMode: "published"
|
|
21592
21789
|
};
|
|
21593
21790
|
}
|
|
21594
21791
|
if (await directoryHasRuntimeConfig(sourceDirectory)) {
|
|
21595
21792
|
return { directory: sourceDirectory, packagingMode: "published" };
|
|
21596
21793
|
}
|
|
21597
|
-
const publishSubdir =
|
|
21794
|
+
const publishSubdir = path69.join(sourceDirectory, "publish");
|
|
21598
21795
|
if (await directoryHasRuntimeConfig(publishSubdir)) {
|
|
21599
21796
|
return { directory: publishSubdir, packagingMode: "published" };
|
|
21600
21797
|
}
|
|
@@ -21606,9 +21803,9 @@ async function prepareBackendPackagingDirectory(args) {
|
|
|
21606
21803
|
return { directory: sourceDirectory, packagingMode: "source" };
|
|
21607
21804
|
}
|
|
21608
21805
|
const tempRoot = await mkdtemp(
|
|
21609
|
-
|
|
21806
|
+
path69.join(tmpdir(), "apitogo-dotnet-publish-")
|
|
21610
21807
|
);
|
|
21611
|
-
const outputDir =
|
|
21808
|
+
const outputDir = path69.join(tempRoot, "publish");
|
|
21612
21809
|
const result = await runDotnetPublish(sourceDirectory, outputDir);
|
|
21613
21810
|
if (result.exitCode !== 0) {
|
|
21614
21811
|
await rm9(tempRoot, { recursive: true, force: true });
|
|
@@ -21653,13 +21850,13 @@ function formatJobStatusResponse(options) {
|
|
|
21653
21850
|
|
|
21654
21851
|
// src/cli/platform/helpers/openapi.ts
|
|
21655
21852
|
import { promises as fs7 } from "node:fs";
|
|
21656
|
-
import
|
|
21853
|
+
import path70 from "node:path";
|
|
21657
21854
|
import SwaggerParser from "@apidevtools/swagger-parser";
|
|
21658
21855
|
import YAML2 from "yaml";
|
|
21659
21856
|
async function validateOpenApiFile(filePath) {
|
|
21660
|
-
const resolved =
|
|
21857
|
+
const resolved = path70.resolve(filePath);
|
|
21661
21858
|
const content = await fs7.readFile(resolved, "utf8");
|
|
21662
|
-
const ext =
|
|
21859
|
+
const ext = path70.extname(resolved).toLowerCase();
|
|
21663
21860
|
let parsed;
|
|
21664
21861
|
try {
|
|
21665
21862
|
parsed = ext === ".json" ? JSON.parse(content) : YAML2.parse(content);
|
|
@@ -21703,12 +21900,12 @@ async function validateOpenApiFile(filePath) {
|
|
|
21703
21900
|
// src/cli/platform/helpers/zip.ts
|
|
21704
21901
|
import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, promises as fs8 } from "node:fs";
|
|
21705
21902
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
21706
|
-
import
|
|
21903
|
+
import path71 from "node:path";
|
|
21707
21904
|
import { ZipArchive } from "archiver";
|
|
21708
21905
|
async function packageBackendDirectory(sourceDirectory, extraExcludes = []) {
|
|
21709
|
-
const resolved =
|
|
21906
|
+
const resolved = path71.resolve(sourceDirectory);
|
|
21710
21907
|
const files = await collectPackageableFiles(resolved, extraExcludes);
|
|
21711
|
-
const zipPath =
|
|
21908
|
+
const zipPath = path71.join(
|
|
21712
21909
|
tmpdir2(),
|
|
21713
21910
|
`apitogo-backend-${Date.now()}-${Math.random().toString(36).slice(2)}.zip`
|
|
21714
21911
|
);
|
|
@@ -21720,8 +21917,8 @@ async function packageBackendDirectory(sourceDirectory, extraExcludes = []) {
|
|
|
21720
21917
|
output4.on("error", reject);
|
|
21721
21918
|
archive.pipe(output4);
|
|
21722
21919
|
for (const rel2 of files) {
|
|
21723
|
-
archive.append(createReadStream2(
|
|
21724
|
-
name: rel2.split(
|
|
21920
|
+
archive.append(createReadStream2(path71.join(resolved, rel2)), {
|
|
21921
|
+
name: rel2.split(path71.sep).join("/")
|
|
21725
21922
|
});
|
|
21726
21923
|
}
|
|
21727
21924
|
void archive.finalize();
|
|
@@ -23272,11 +23469,11 @@ async function resolveProjectIdForPublish(client, config2, args, wait, progress,
|
|
|
23272
23469
|
}
|
|
23273
23470
|
|
|
23274
23471
|
// src/cli/platform/tools/dev-portal-site-build.ts
|
|
23275
|
-
import
|
|
23472
|
+
import path75 from "node:path";
|
|
23276
23473
|
|
|
23277
23474
|
// src/cli/platform/helpers/dev-portal-site-api-url.ts
|
|
23278
|
-
import { readdir as readdir5, readFile as
|
|
23279
|
-
import
|
|
23475
|
+
import { readdir as readdir5, readFile as readFile26, writeFile as writeFile21 } from "node:fs/promises";
|
|
23476
|
+
import path72 from "node:path";
|
|
23280
23477
|
var SITE_API_BASE_URL_ENV_KEY = "VITE_APITOGO_AUTHENTICATION_API_BASE_URL";
|
|
23281
23478
|
var PLACEHOLDER_HOST_MARKERS = [
|
|
23282
23479
|
"dp-example.azurecontainerapps.io",
|
|
@@ -23297,10 +23494,10 @@ function isPlaceholderDevPortalApiUrl(apiBaseUrl) {
|
|
|
23297
23494
|
return PLACEHOLDER_HOST_MARKERS.some((marker) => normalized.includes(marker));
|
|
23298
23495
|
}
|
|
23299
23496
|
async function readSiteApiBaseUrl(sourceDirectory) {
|
|
23300
|
-
const resolved =
|
|
23497
|
+
const resolved = path72.resolve(sourceDirectory);
|
|
23301
23498
|
for (const envFile of [".env", ".env.production"]) {
|
|
23302
23499
|
try {
|
|
23303
|
-
const content = await
|
|
23500
|
+
const content = await readFile26(path72.join(resolved, envFile), "utf8");
|
|
23304
23501
|
const lines = [...content.matchAll(ENV_LINE_GLOBAL_RE)];
|
|
23305
23502
|
if (lines.length === 0) {
|
|
23306
23503
|
continue;
|
|
@@ -23325,13 +23522,13 @@ async function readSiteApiBaseUrl(sourceDirectory) {
|
|
|
23325
23522
|
return null;
|
|
23326
23523
|
}
|
|
23327
23524
|
async function patchSiteApiBaseUrl(sourceDirectory, apiBaseUrl) {
|
|
23328
|
-
const resolved =
|
|
23525
|
+
const resolved = path72.resolve(sourceDirectory);
|
|
23329
23526
|
const line2 = `${SITE_API_BASE_URL_ENV_KEY}=${apiBaseUrl}`;
|
|
23330
23527
|
let patchedExisting = false;
|
|
23331
23528
|
for (const envFile of [".env.production", ".env"]) {
|
|
23332
|
-
const envPath =
|
|
23529
|
+
const envPath = path72.join(resolved, envFile);
|
|
23333
23530
|
try {
|
|
23334
|
-
const content = await
|
|
23531
|
+
const content = await readFile26(envPath, "utf8");
|
|
23335
23532
|
const withoutAssignments = content.replace(ENV_LINE_GLOBAL_RE, "").replace(/\n{3,}/g, "\n\n").trimEnd();
|
|
23336
23533
|
const patched = withoutAssignments ? `${withoutAssignments}
|
|
23337
23534
|
${line2}
|
|
@@ -23343,7 +23540,7 @@ ${line2}
|
|
|
23343
23540
|
}
|
|
23344
23541
|
}
|
|
23345
23542
|
if (!patchedExisting) {
|
|
23346
|
-
await writeFile21(
|
|
23543
|
+
await writeFile21(path72.join(resolved, ".env"), `${line2}
|
|
23347
23544
|
`);
|
|
23348
23545
|
}
|
|
23349
23546
|
}
|
|
@@ -23351,7 +23548,7 @@ function tryProjectId(explicit, manifestProjectId, config2) {
|
|
|
23351
23548
|
return explicit?.trim() || manifestProjectId?.trim() || config2.defaultProjectId?.trim() || void 0;
|
|
23352
23549
|
}
|
|
23353
23550
|
async function ensureLiveSiteApiBaseUrlForBuild(_client, config2, args, resolveFromProject) {
|
|
23354
|
-
const sourceDirectory =
|
|
23551
|
+
const sourceDirectory = path72.resolve(args.sourceDirectory);
|
|
23355
23552
|
const explicit = args.apiBaseUrl?.trim();
|
|
23356
23553
|
if (explicit && !isPlaceholderDevPortalApiUrl(explicit)) {
|
|
23357
23554
|
await patchSiteApiBaseUrl(sourceDirectory, explicit);
|
|
@@ -23387,7 +23584,7 @@ async function* walkFiles(root) {
|
|
|
23387
23584
|
return;
|
|
23388
23585
|
}
|
|
23389
23586
|
for (const entry of entries) {
|
|
23390
|
-
const full =
|
|
23587
|
+
const full = path72.join(root, entry.name);
|
|
23391
23588
|
if (entry.isDirectory()) {
|
|
23392
23589
|
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
23393
23590
|
continue;
|
|
@@ -23399,8 +23596,8 @@ async function* walkFiles(root) {
|
|
|
23399
23596
|
}
|
|
23400
23597
|
}
|
|
23401
23598
|
async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiBaseUrl) {
|
|
23402
|
-
const dist =
|
|
23403
|
-
const siteRoot =
|
|
23599
|
+
const dist = path72.resolve(distDirectory);
|
|
23600
|
+
const siteRoot = path72.dirname(dist);
|
|
23404
23601
|
const fromEnv = expectedApiBaseUrl?.trim() || await readSiteApiBaseUrl(siteRoot) || await readSiteApiBaseUrl(dist);
|
|
23405
23602
|
if (!fromEnv || isPlaceholderDevPortalApiUrl(fromEnv)) {
|
|
23406
23603
|
throw new Error(
|
|
@@ -23411,7 +23608,7 @@ async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiB
|
|
|
23411
23608
|
let found = false;
|
|
23412
23609
|
let foundPlaceholder = false;
|
|
23413
23610
|
for await (const file of walkFiles(dist)) {
|
|
23414
|
-
const content = await
|
|
23611
|
+
const content = await readFile26(file, "utf8");
|
|
23415
23612
|
if (content.includes(needle)) {
|
|
23416
23613
|
found = true;
|
|
23417
23614
|
}
|
|
@@ -23436,7 +23633,7 @@ async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiB
|
|
|
23436
23633
|
|
|
23437
23634
|
// src/cli/platform/tools/dev-portal.ts
|
|
23438
23635
|
import { promises as fs10 } from "node:fs";
|
|
23439
|
-
import
|
|
23636
|
+
import path74 from "node:path";
|
|
23440
23637
|
|
|
23441
23638
|
// src/cli/platform/helpers/dev-portal-backend-job.ts
|
|
23442
23639
|
var DEV_PORTAL_BACKEND_UPDATE_RESOURCE_TYPE = "DevPortalBackendUpdate";
|
|
@@ -23546,7 +23743,7 @@ async function snapshotBackendUpdateJobIds(client, projectId) {
|
|
|
23546
23743
|
// src/cli/platform/helpers/tarball.ts
|
|
23547
23744
|
import { createReadStream as createReadStream3, createWriteStream as createWriteStream3, promises as fs9 } from "node:fs";
|
|
23548
23745
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
23549
|
-
import
|
|
23746
|
+
import path73 from "node:path";
|
|
23550
23747
|
import { TarArchive } from "archiver";
|
|
23551
23748
|
var DEV_PORTAL_DEPLOY_ARCHIVE_ROOT = "dist";
|
|
23552
23749
|
function normalizeArchiveRoot(archiveRoot) {
|
|
@@ -23557,10 +23754,10 @@ function normalizeArchiveRoot(archiveRoot) {
|
|
|
23557
23754
|
return `${trimmed}/`;
|
|
23558
23755
|
}
|
|
23559
23756
|
async function packageDirectoryAsTarGz(sourceDirectory, options) {
|
|
23560
|
-
const resolved =
|
|
23757
|
+
const resolved = path73.resolve(sourceDirectory);
|
|
23561
23758
|
const files = await collectPackageableFiles(resolved);
|
|
23562
23759
|
const entryPrefix = options?.archiveRoot ? normalizeArchiveRoot(options.archiveRoot) : "";
|
|
23563
|
-
const archivePath =
|
|
23760
|
+
const archivePath = path73.join(
|
|
23564
23761
|
tmpdir3(),
|
|
23565
23762
|
`apitogo-docs-${Date.now()}-${Math.random().toString(36).slice(2)}.tgz`
|
|
23566
23763
|
);
|
|
@@ -23572,8 +23769,8 @@ async function packageDirectoryAsTarGz(sourceDirectory, options) {
|
|
|
23572
23769
|
output4.on("error", reject);
|
|
23573
23770
|
archive.pipe(output4);
|
|
23574
23771
|
for (const rel2 of files) {
|
|
23575
|
-
const entryName = entryPrefix + rel2.split(
|
|
23576
|
-
archive.append(createReadStream3(
|
|
23772
|
+
const entryName = entryPrefix + rel2.split(path73.sep).join("/");
|
|
23773
|
+
archive.append(createReadStream3(path73.join(resolved, rel2)), {
|
|
23577
23774
|
name: entryName
|
|
23578
23775
|
});
|
|
23579
23776
|
}
|
|
@@ -23815,7 +24012,7 @@ function validateDeployArchiveInput(args) {
|
|
|
23815
24012
|
async function resolveDevPortalArchive(args) {
|
|
23816
24013
|
validateDeployArchiveInput(args);
|
|
23817
24014
|
if (args.archivePath?.trim()) {
|
|
23818
|
-
const archivePath =
|
|
24015
|
+
const archivePath = path74.resolve(args.archivePath.trim());
|
|
23819
24016
|
const stat7 = await fs10.stat(archivePath).catch(() => null);
|
|
23820
24017
|
if (!stat7?.isFile()) {
|
|
23821
24018
|
throw new Error(`archivePath is not a file: ${archivePath}`);
|
|
@@ -23880,7 +24077,7 @@ async function handleDeployDevPortal(client, config2, args, progress) {
|
|
|
23880
24077
|
// src/cli/platform/tools/dev-portal-site-build.ts
|
|
23881
24078
|
async function handleBuildDevPortalSite(client, config2, args, progress) {
|
|
23882
24079
|
const buildProgress = progress?.child("Build dev portal site");
|
|
23883
|
-
const sourceDirectory =
|
|
24080
|
+
const sourceDirectory = path75.resolve(args.sourceDirectory);
|
|
23884
24081
|
await buildProgress?.onStep("Ensuring live portal API URL");
|
|
23885
24082
|
const apiBaseUrl = await ensureLiveSiteApiBaseUrlForBuild(
|
|
23886
24083
|
client,
|
|
@@ -25386,7 +25583,7 @@ function resultLooksFailed(payload) {
|
|
|
25386
25583
|
return parsed.status === "failed" || parsed.status === "blocked";
|
|
25387
25584
|
}
|
|
25388
25585
|
async function apply(argv) {
|
|
25389
|
-
const sourceDirectory =
|
|
25586
|
+
const sourceDirectory = path76.resolve(process.cwd(), argv.dir);
|
|
25390
25587
|
let config2;
|
|
25391
25588
|
try {
|
|
25392
25589
|
config2 = loadConfig();
|
|
@@ -25456,7 +25653,7 @@ async function apply(argv) {
|
|
|
25456
25653
|
if (canPromptInteractively && parsed?.status === "blocked" && parsed.reason === "project_not_found") {
|
|
25457
25654
|
const resolution = await resolveProjectNotFoundInteractively(
|
|
25458
25655
|
parsed,
|
|
25459
|
-
|
|
25656
|
+
path76.basename(sourceDirectory)
|
|
25460
25657
|
);
|
|
25461
25658
|
if (resolution) {
|
|
25462
25659
|
effectiveProjectId = void 0;
|
|
@@ -25476,7 +25673,7 @@ async function apply(argv) {
|
|
|
25476
25673
|
while (canPromptInteractively && parsed?.status === "blocked" && parsed.reason === "project_name_exists") {
|
|
25477
25674
|
const resolution = await resolveProjectNameExistsInteractively(
|
|
25478
25675
|
parsed,
|
|
25479
|
-
effectiveProjectName ??
|
|
25676
|
+
effectiveProjectName ?? path76.basename(sourceDirectory)
|
|
25480
25677
|
);
|
|
25481
25678
|
if (!resolution) {
|
|
25482
25679
|
break;
|
|
@@ -25547,11 +25744,11 @@ async function apply(argv) {
|
|
|
25547
25744
|
}
|
|
25548
25745
|
|
|
25549
25746
|
// src/cli/deploy/command.ts
|
|
25550
|
-
import
|
|
25747
|
+
import path81 from "node:path";
|
|
25551
25748
|
init_invariant();
|
|
25552
25749
|
|
|
25553
25750
|
// src/cli/project/create-handler.ts
|
|
25554
|
-
import
|
|
25751
|
+
import path77 from "node:path";
|
|
25555
25752
|
import open2 from "open";
|
|
25556
25753
|
init_invariant();
|
|
25557
25754
|
|
|
@@ -25855,7 +26052,7 @@ async function createLinkedProject(argv, dir, options = {}) {
|
|
|
25855
26052
|
}
|
|
25856
26053
|
}
|
|
25857
26054
|
async function createProject2(argv) {
|
|
25858
|
-
const dir =
|
|
26055
|
+
const dir = path77.resolve(process.cwd(), argv.dir ?? ".");
|
|
25859
26056
|
if (await isConfigV2(dir)) {
|
|
25860
26057
|
await createLinkedProject(argv, dir);
|
|
25861
26058
|
return;
|
|
@@ -25914,17 +26111,129 @@ async function createProject2(argv) {
|
|
|
25914
26111
|
}
|
|
25915
26112
|
}
|
|
25916
26113
|
|
|
26114
|
+
// src/cli/secrets/input.ts
|
|
26115
|
+
import { createInterface as createInterface6 } from "node:readline/promises";
|
|
26116
|
+
var CTRL_C = "";
|
|
26117
|
+
var CTRL_D = "";
|
|
26118
|
+
function readHidden(prompt, input5 = process.stdin, output4 = process.stdout) {
|
|
26119
|
+
return new Promise((resolve, reject) => {
|
|
26120
|
+
if (!input5.isTTY || !input5.setRawMode) {
|
|
26121
|
+
reject(new Error("A hidden prompt needs an interactive terminal."));
|
|
26122
|
+
return;
|
|
26123
|
+
}
|
|
26124
|
+
let value = "";
|
|
26125
|
+
output4.write(prompt);
|
|
26126
|
+
input5.setRawMode(true);
|
|
26127
|
+
input5.resume();
|
|
26128
|
+
const finish = (action) => {
|
|
26129
|
+
input5.removeListener("data", onData);
|
|
26130
|
+
input5.setRawMode?.(false);
|
|
26131
|
+
input5.pause();
|
|
26132
|
+
output4.write("\n");
|
|
26133
|
+
action();
|
|
26134
|
+
};
|
|
26135
|
+
const onData = (chunk) => {
|
|
26136
|
+
for (const char of chunk.toString("utf8")) {
|
|
26137
|
+
if (char === CTRL_C)
|
|
26138
|
+
return finish(() => reject(new Error("Cancelled.")));
|
|
26139
|
+
if (char === "\r" || char === "\n" || char === CTRL_D)
|
|
26140
|
+
return finish(() => resolve(value));
|
|
26141
|
+
if (char === "\x7F" || char === "\b") value = value.slice(0, -1);
|
|
26142
|
+
else value += char;
|
|
26143
|
+
}
|
|
26144
|
+
};
|
|
26145
|
+
input5.on("data", onData);
|
|
26146
|
+
});
|
|
26147
|
+
}
|
|
26148
|
+
async function readStdin(input5 = process.stdin) {
|
|
26149
|
+
const chunks = [];
|
|
26150
|
+
for await (const chunk of input5) {
|
|
26151
|
+
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
26152
|
+
}
|
|
26153
|
+
return Buffer.concat(chunks).toString("utf8").replace(/\r?\n$/, "");
|
|
26154
|
+
}
|
|
26155
|
+
async function confirm(question) {
|
|
26156
|
+
const rl = createInterface6({ input: process.stdin, output: process.stdout });
|
|
26157
|
+
try {
|
|
26158
|
+
const answer = (await rl.question(question)).trim().toLowerCase();
|
|
26159
|
+
return answer === "y" || answer === "yes";
|
|
26160
|
+
} finally {
|
|
26161
|
+
rl.close();
|
|
26162
|
+
}
|
|
26163
|
+
}
|
|
26164
|
+
|
|
26165
|
+
// src/cli/deploy/stripe-key.ts
|
|
26166
|
+
import path78 from "node:path";
|
|
26167
|
+
init_invariant();
|
|
26168
|
+
var StripeKeyError = class extends ApitogoError {
|
|
26169
|
+
constructor(message, developerHint) {
|
|
26170
|
+
super(message, { developerHint, title: "Stripe key needed" });
|
|
26171
|
+
this.name = "StripeKeyError";
|
|
26172
|
+
}
|
|
26173
|
+
};
|
|
26174
|
+
var STRIPE_KEY = /^(sk|rk)_(test|live)_[A-Za-z0-9]+$/;
|
|
26175
|
+
var wantsPlans = (only) => {
|
|
26176
|
+
if (only === void 0) return true;
|
|
26177
|
+
const names = (Array.isArray(only) ? only : only.split(",")).map((name) => name.trim()).filter(Boolean);
|
|
26178
|
+
return names.length === 0 || names.includes("plans");
|
|
26179
|
+
};
|
|
26180
|
+
async function ensureStripeKey(argv, deps) {
|
|
26181
|
+
if (!wantsPlans(argv.only)) return { status: "not-needed" };
|
|
26182
|
+
let resolved;
|
|
26183
|
+
try {
|
|
26184
|
+
resolved = loadConfigV2(path78.resolve(process.cwd(), argv.dir)).resolved;
|
|
26185
|
+
} catch {
|
|
26186
|
+
return { status: "not-needed" };
|
|
26187
|
+
}
|
|
26188
|
+
if (!resolved.plans?.enabled || resolved.plans.billing.provider !== "stripe")
|
|
26189
|
+
return { status: "not-needed" };
|
|
26190
|
+
const paid = await paidPlanSkus(resolved);
|
|
26191
|
+
if (paid.length === 0) return { status: "not-needed" };
|
|
26192
|
+
const projectId = argv.projectId?.trim() || resolved.project.id || deps.envProjectId?.trim();
|
|
26193
|
+
if (!projectId) return { status: "not-needed" };
|
|
26194
|
+
const name = stripeKeySecretName(resolved);
|
|
26195
|
+
const client = deps.client();
|
|
26196
|
+
const { secrets: secrets2 } = await client.listSecrets(projectId);
|
|
26197
|
+
if (secrets2.some((secret) => secret.name === name))
|
|
26198
|
+
return { status: "present", name };
|
|
26199
|
+
const reason = `The plan${paid.length > 1 ? "s" : ""} ${paid.join(", ")} ${paid.length > 1 ? "have" : "has"} a price, so payments go through Stripe, and this project has no Stripe key yet.`;
|
|
26200
|
+
if (!deps.interactive) {
|
|
26201
|
+
throw new StripeKeyError(
|
|
26202
|
+
reason,
|
|
26203
|
+
`Store it with \`apitogo secrets set ${name}\`, then deploy again. Or make the plans free.`
|
|
26204
|
+
);
|
|
26205
|
+
}
|
|
26206
|
+
deps.print(reason);
|
|
26207
|
+
deps.print(
|
|
26208
|
+
"Paste your Stripe secret key (starts with sk_ or rk_; use an sk_test_ key to try it out). It is stored as a project secret, not in your files."
|
|
26209
|
+
);
|
|
26210
|
+
const key = (await deps.askHidden("Stripe secret key (hidden): ")).trim();
|
|
26211
|
+
if (!key)
|
|
26212
|
+
throw new StripeKeyError(
|
|
26213
|
+
"No key was entered. Nothing was deployed.",
|
|
26214
|
+
`Run \`apitogo secrets set ${name}\` when you have it, then deploy again.`
|
|
26215
|
+
);
|
|
26216
|
+
if (!STRIPE_KEY.test(key))
|
|
26217
|
+
throw new StripeKeyError(
|
|
26218
|
+
"That is not a Stripe secret key. Nothing was deployed.",
|
|
26219
|
+
"A Stripe secret key starts with sk_test_, sk_live_, rk_test_ or rk_live_. Find it in Stripe under Developers > API keys."
|
|
26220
|
+
);
|
|
26221
|
+
await client.setSecret(projectId, name, key);
|
|
26222
|
+
deps.print(`Stripe key saved as the project secret ${name}.`);
|
|
26223
|
+
return { status: "saved", name };
|
|
26224
|
+
}
|
|
26225
|
+
|
|
25917
26226
|
// src/cli/deploy/v2.ts
|
|
25918
26227
|
import { rm as rm10 } from "node:fs/promises";
|
|
25919
26228
|
init_invariant();
|
|
25920
26229
|
|
|
25921
26230
|
// src/cli/portal/report.ts
|
|
25922
26231
|
import { access as access9 } from "node:fs/promises";
|
|
25923
|
-
import
|
|
26232
|
+
import path79 from "node:path";
|
|
25924
26233
|
|
|
25925
26234
|
// src/cli/deploy/gateway.ts
|
|
25926
26235
|
import { createHash as createHash4 } from "node:crypto";
|
|
25927
|
-
import { readFile as
|
|
26236
|
+
import { readFile as readFile27 } from "node:fs/promises";
|
|
25928
26237
|
init_invariant();
|
|
25929
26238
|
var GatewayDeployError = class extends ApitogoError {
|
|
25930
26239
|
constructor(code, message, developerHint) {
|
|
@@ -25962,7 +26271,7 @@ async function readSpec(gateway) {
|
|
|
25962
26271
|
"Add one to gateway.specs in the config."
|
|
25963
26272
|
);
|
|
25964
26273
|
try {
|
|
25965
|
-
return await
|
|
26274
|
+
return await readFile27(file);
|
|
25966
26275
|
} catch {
|
|
25967
26276
|
throw new GatewayDeployError(
|
|
25968
26277
|
"GATEWAY_SPEC_UNREADABLE",
|
|
@@ -26722,12 +27031,13 @@ async function plansInputs(resolved, projectId) {
|
|
|
26722
27031
|
const plans = resolved.plans;
|
|
26723
27032
|
if (!plans) throw new Error("plans is not in the config.");
|
|
26724
27033
|
const billing = plans.billing;
|
|
26725
|
-
const
|
|
27034
|
+
const filePlans = await readPlansFile(plans.file);
|
|
27035
|
+
const wanted = toPlatformPlans(filePlans, {
|
|
26726
27036
|
billing: billing.provider === "stripe"
|
|
26727
27037
|
});
|
|
26728
27038
|
const manifest = await readManifest(resolved.state);
|
|
26729
27039
|
const ledger = await readLedger(resolved.state);
|
|
26730
|
-
const billingOn = billing.provider === "stripe";
|
|
27040
|
+
const billingOn = billing.provider === "stripe" && filePlans.some((plan2) => isPaidPlan(plan2));
|
|
26731
27041
|
const billingStep = billingOn || stepOf(ledger, "plans", "billing") !== void 0;
|
|
26732
27042
|
const identity = manifest?.services.identity;
|
|
26733
27043
|
const ownIdentity = Boolean(
|
|
@@ -26739,11 +27049,12 @@ async function plansInputs(resolved, projectId) {
|
|
|
26739
27049
|
ownIdentity,
|
|
26740
27050
|
catalogHash: stableJson({ projectId, plans: wanted }),
|
|
26741
27051
|
backendHash: stableJson({ projectId }),
|
|
27052
|
+
billingOn,
|
|
26742
27053
|
billingStep,
|
|
26743
27054
|
// Only the references to the project's secrets: a rotated value is applied with --force.
|
|
26744
27055
|
billingHash: stableJson({
|
|
26745
27056
|
projectId,
|
|
26746
|
-
provider:
|
|
27057
|
+
provider: billingOn ? "stripe" : "none",
|
|
26747
27058
|
apiKey: billingOn ? billing.apiKey : void 0,
|
|
26748
27059
|
webhookSecret: billingOn ? billing.webhookSecret : void 0,
|
|
26749
27060
|
successUrl: billingOn ? billing.successUrl : void 0,
|
|
@@ -26809,6 +27120,7 @@ async function deployPlans(resolved, projectId, deps, options = {}) {
|
|
|
26809
27120
|
wanted,
|
|
26810
27121
|
manifest,
|
|
26811
27122
|
ownIdentity,
|
|
27123
|
+
billingOn,
|
|
26812
27124
|
billingStep,
|
|
26813
27125
|
billingHash,
|
|
26814
27126
|
catalogHash,
|
|
@@ -26968,7 +27280,7 @@ async function deployPlans(resolved, projectId, deps, options = {}) {
|
|
|
26968
27280
|
name: "billing",
|
|
26969
27281
|
hash: () => billingHash,
|
|
26970
27282
|
run: async () => {
|
|
26971
|
-
const body =
|
|
27283
|
+
const body = billingOn ? {
|
|
26972
27284
|
provider: "stripe",
|
|
26973
27285
|
apiKey: plans.billing.apiKey,
|
|
26974
27286
|
webhookSecret: plans.billing.webhookSecret,
|
|
@@ -26985,8 +27297,7 @@ async function deployPlans(resolved, projectId, deps, options = {}) {
|
|
|
26985
27297
|
code: "PLANS_BILLING",
|
|
26986
27298
|
text: "the billing settings"
|
|
26987
27299
|
});
|
|
26988
|
-
if (
|
|
26989
|
-
billingNote = billingNotes(queued);
|
|
27300
|
+
if (billingOn) billingNote = billingNotes(queued);
|
|
26990
27301
|
return { ...done, mode: queued.mode };
|
|
26991
27302
|
}
|
|
26992
27303
|
};
|
|
@@ -27029,9 +27340,9 @@ async function deployPlans(resolved, projectId, deps, options = {}) {
|
|
|
27029
27340
|
projectId,
|
|
27030
27341
|
projectName: resolved.project.name,
|
|
27031
27342
|
apiBaseUrl,
|
|
27032
|
-
billing:
|
|
27343
|
+
billing: billingOn ? "stripe" : "none",
|
|
27033
27344
|
catalogRevision: catalog && !catalog.skipped ? previous + 1 : Math.max(previous, 1),
|
|
27034
|
-
capabilities:
|
|
27345
|
+
capabilities: billingOn ? { ...PLANS_CAPABILITIES, checkout: true } : PLANS_CAPABILITIES
|
|
27035
27346
|
})
|
|
27036
27347
|
);
|
|
27037
27348
|
}
|
|
@@ -27190,7 +27501,7 @@ async function planPlansService(resolved, ledger, plansRemote2) {
|
|
|
27190
27501
|
),
|
|
27191
27502
|
inputs.ownIdentity ? "sign-in: the project's identity will be applied to the plans backend" : "sign-in: no identity of the platform deployed, so nothing is applied to the plans backend",
|
|
27192
27503
|
...inputs.billingStep ? [
|
|
27193
|
-
|
|
27504
|
+
inputs.billingOn ? "billing: a plan has a price, so the Stripe key and webhook secret of the project's secrets will be applied to the plans backend" : "billing: no plan has a price, so the stored Stripe settings will be removed from the plans backend"
|
|
27194
27505
|
] : [],
|
|
27195
27506
|
...steps.map(
|
|
27196
27507
|
(name) => `step ${name}: ${stepState(stepOf(ledger, "plans", name), hashes[name])}`
|
|
@@ -27384,7 +27695,7 @@ async function planPortalService(resolved, ledger) {
|
|
|
27384
27695
|
const hash2 = await portalBuildHash(resolved, prepared);
|
|
27385
27696
|
const previous = stepOf(ledger, "portal", "build");
|
|
27386
27697
|
const built = await exists5(
|
|
27387
|
-
|
|
27698
|
+
path79.join(resolved.state.buildDir, "index.html")
|
|
27388
27699
|
);
|
|
27389
27700
|
if (previous?.status === "succeeded" && previous.hash === hash2 && built) {
|
|
27390
27701
|
return {
|
|
@@ -27743,7 +28054,7 @@ async function statusV2(dir, only, options = {}) {
|
|
|
27743
28054
|
if (service === "portal") {
|
|
27744
28055
|
const build2 = stepOf(ledger, "portal", "build");
|
|
27745
28056
|
const built = await exists5(
|
|
27746
|
-
|
|
28057
|
+
path79.join(resolved.state.buildDir, "index.html")
|
|
27747
28058
|
);
|
|
27748
28059
|
const state = build2?.status === "failed" ? "build-failed" : build2?.status === "succeeded" && built ? "built" : "not-built";
|
|
27749
28060
|
services.push({
|
|
@@ -27754,7 +28065,7 @@ async function statusV2(dir, only, options = {}) {
|
|
|
27754
28065
|
...build2?.finishedAt ? [`last build: ${build2.finishedAt}`] : [],
|
|
27755
28066
|
...build2?.status === "failed" ? [`error: ${build2.error ?? "unknown"}`] : [],
|
|
27756
28067
|
...state === "built" ? [
|
|
27757
|
-
`output: ${
|
|
28068
|
+
`output: ${path79.relative(resolved.configDir, resolved.state.buildDir)}`
|
|
27758
28069
|
] : [],
|
|
27759
28070
|
...url2 ? [`url: ${url2}`] : ["url: not known (portal is not deployed yet)"],
|
|
27760
28071
|
...await hostingLine(resolved, manifest, options.hostingRemote)
|
|
@@ -27821,7 +28132,7 @@ function formatStatus(output4) {
|
|
|
27821
28132
|
|
|
27822
28133
|
// src/cli/deploy/static-web-config.ts
|
|
27823
28134
|
import { access as access10, writeFile as writeFile22 } from "node:fs/promises";
|
|
27824
|
-
import
|
|
28135
|
+
import path80 from "node:path";
|
|
27825
28136
|
var STATIC_WEB_CONFIG_FILE = "staticwebapp.config.json";
|
|
27826
28137
|
var STATIC_WEB_CONFIG_VERSION = 3;
|
|
27827
28138
|
var CLIENT_ONLY_ROUTES = [
|
|
@@ -27839,7 +28150,7 @@ var DEFAULT_STATIC_WEB_CONFIG = {
|
|
|
27839
28150
|
}
|
|
27840
28151
|
};
|
|
27841
28152
|
async function ensureStaticWebConfig(buildDir) {
|
|
27842
|
-
const file =
|
|
28153
|
+
const file = path80.join(buildDir, STATIC_WEB_CONFIG_FILE);
|
|
27843
28154
|
try {
|
|
27844
28155
|
await access10(file);
|
|
27845
28156
|
return false;
|
|
@@ -28190,7 +28501,7 @@ function formatDeploy(output4) {
|
|
|
28190
28501
|
// src/cli/deploy/command.ts
|
|
28191
28502
|
async function ensureLinkedProject(argv, deps) {
|
|
28192
28503
|
if (argv.projectId?.trim() || deps.envProjectId?.trim()) return true;
|
|
28193
|
-
const dir =
|
|
28504
|
+
const dir = path81.resolve(process.cwd(), argv.dir);
|
|
28194
28505
|
let linked;
|
|
28195
28506
|
try {
|
|
28196
28507
|
linked = Boolean(loadConfigV2(dir).resolved.project.id);
|
|
@@ -28220,6 +28531,18 @@ async function deployProject(argv) {
|
|
|
28220
28531
|
createProject: (dir) => createLinkedProject({ dir }, dir, { continuingDeploy: true })
|
|
28221
28532
|
});
|
|
28222
28533
|
if (!ready) return;
|
|
28534
|
+
try {
|
|
28535
|
+
await ensureStripeKey(argv, {
|
|
28536
|
+
client: () => new PlatformApiClient(loadConfig()),
|
|
28537
|
+
envProjectId: process.env.APITOGO_DEFAULT_PROJECT_ID,
|
|
28538
|
+
interactive,
|
|
28539
|
+
askHidden: (prompt) => readHidden(prompt),
|
|
28540
|
+
print: printDiagnosticsToConsole
|
|
28541
|
+
});
|
|
28542
|
+
} catch (error) {
|
|
28543
|
+
await reportFailure(error, json);
|
|
28544
|
+
return;
|
|
28545
|
+
}
|
|
28223
28546
|
const quiet = json || argv.verbose !== true;
|
|
28224
28547
|
if (quiet) applyJsonOnlyDeployQuietMode();
|
|
28225
28548
|
if (!json && quiet)
|
|
@@ -28230,7 +28553,7 @@ async function deployProject(argv) {
|
|
|
28230
28553
|
const config2 = loadConfig();
|
|
28231
28554
|
const output4 = await deployV2(
|
|
28232
28555
|
{
|
|
28233
|
-
dir:
|
|
28556
|
+
dir: path81.resolve(process.cwd(), argv.dir),
|
|
28234
28557
|
only: Array.isArray(argv.only) ? argv.only.join(",") : argv.only,
|
|
28235
28558
|
projectId: argv.projectId,
|
|
28236
28559
|
env: argv.env,
|
|
@@ -28250,23 +28573,26 @@ async function deployProject(argv) {
|
|
|
28250
28573
|
for (const line2 of formatDeploy(output4)) printDiagnosticsToConsole(line2);
|
|
28251
28574
|
printResultToConsole("Deploy finished.");
|
|
28252
28575
|
} catch (error) {
|
|
28253
|
-
|
|
28254
|
-
|
|
28255
|
-
|
|
28256
|
-
|
|
28257
|
-
|
|
28258
|
-
|
|
28259
|
-
|
|
28260
|
-
|
|
28261
|
-
|
|
28262
|
-
|
|
28263
|
-
|
|
28264
|
-
|
|
28265
|
-
|
|
28266
|
-
await printCriticalFailureToConsoleAndExit(
|
|
28267
|
-
hint ? `${message} ${hint}` : message
|
|
28576
|
+
await reportFailure(error, json);
|
|
28577
|
+
}
|
|
28578
|
+
}
|
|
28579
|
+
async function reportFailure(error, json) {
|
|
28580
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
28581
|
+
const hint = error instanceof ApitogoError ? error.developerHint : void 0;
|
|
28582
|
+
if (json) {
|
|
28583
|
+
console.log(
|
|
28584
|
+
JSON.stringify({
|
|
28585
|
+
status: "failed",
|
|
28586
|
+
error: message,
|
|
28587
|
+
hint: hint ?? null
|
|
28588
|
+
})
|
|
28268
28589
|
);
|
|
28590
|
+
process.exitCode = 1;
|
|
28591
|
+
return;
|
|
28269
28592
|
}
|
|
28593
|
+
await printCriticalFailureToConsoleAndExit(
|
|
28594
|
+
hint ? `${message} ${hint}` : message
|
|
28595
|
+
);
|
|
28270
28596
|
}
|
|
28271
28597
|
|
|
28272
28598
|
// src/cli/cmds/deploy.ts
|
|
@@ -28321,7 +28647,7 @@ var deploy_default = {
|
|
|
28321
28647
|
}),
|
|
28322
28648
|
handler: async (argv) => {
|
|
28323
28649
|
await captureEvent({ argv, event: "apitogo deploy" });
|
|
28324
|
-
if (await isConfigV2(
|
|
28650
|
+
if (await isConfigV2(path82.resolve(process.cwd(), argv.dir))) {
|
|
28325
28651
|
await deployProject(argv);
|
|
28326
28652
|
return;
|
|
28327
28653
|
}
|
|
@@ -28331,7 +28657,7 @@ var deploy_default = {
|
|
|
28331
28657
|
|
|
28332
28658
|
// src/cli/export/handler.ts
|
|
28333
28659
|
import { mkdir as mkdir18, writeFile as writeFile23 } from "node:fs/promises";
|
|
28334
|
-
import
|
|
28660
|
+
import path83 from "node:path";
|
|
28335
28661
|
init_invariant();
|
|
28336
28662
|
var ExportError = class extends ApitogoError {
|
|
28337
28663
|
constructor(message, developerHint) {
|
|
@@ -28345,7 +28671,7 @@ async function exportOpenApi(args, deps) {
|
|
|
28345
28671
|
`Cannot export "${args.target}".`,
|
|
28346
28672
|
"Only `apitogo export openapi` exists."
|
|
28347
28673
|
);
|
|
28348
|
-
const dir =
|
|
28674
|
+
const dir = path83.resolve(process.cwd(), args.dir ?? ".");
|
|
28349
28675
|
if (!await isConfigV2(dir))
|
|
28350
28676
|
throw new ExportError(
|
|
28351
28677
|
"This command needs a config version 2 project.",
|
|
@@ -28370,8 +28696,8 @@ async function exportOpenApi(args, deps) {
|
|
|
28370
28696
|
throw error;
|
|
28371
28697
|
}
|
|
28372
28698
|
if (!args.out) return { text };
|
|
28373
|
-
const file =
|
|
28374
|
-
await mkdir18(
|
|
28699
|
+
const file = path83.resolve(process.cwd(), args.out);
|
|
28700
|
+
await mkdir18(path83.dirname(file), { recursive: true });
|
|
28375
28701
|
await writeFile23(file, text);
|
|
28376
28702
|
return { text, file };
|
|
28377
28703
|
}
|
|
@@ -28464,8 +28790,8 @@ import open3 from "open";
|
|
|
28464
28790
|
import colors14 from "picocolors";
|
|
28465
28791
|
|
|
28466
28792
|
// src/cli/platform/device-auth.ts
|
|
28467
|
-
function url(apiUrl,
|
|
28468
|
-
return `${apiUrl}${
|
|
28793
|
+
function url(apiUrl, path97) {
|
|
28794
|
+
return `${apiUrl}${path97.startsWith("/") ? path97 : `/${path97}`}`;
|
|
28469
28795
|
}
|
|
28470
28796
|
async function requestDeviceCode(apiUrl) {
|
|
28471
28797
|
const response = await fetchWithRetry(
|
|
@@ -28647,7 +28973,7 @@ var logout_default = {
|
|
|
28647
28973
|
};
|
|
28648
28974
|
|
|
28649
28975
|
// src/cli/portal/commands.ts
|
|
28650
|
-
import
|
|
28976
|
+
import path84 from "node:path";
|
|
28651
28977
|
init_invariant();
|
|
28652
28978
|
function parseOnly(value) {
|
|
28653
28979
|
if (value === void 0) return void 0;
|
|
@@ -28664,7 +28990,7 @@ function parseOnly(value) {
|
|
|
28664
28990
|
async function run2(command2, argv, compute, format) {
|
|
28665
28991
|
const json = argv.json === true;
|
|
28666
28992
|
try {
|
|
28667
|
-
const dir =
|
|
28993
|
+
const dir = path84.resolve(process.cwd(), argv.dir ?? ".");
|
|
28668
28994
|
if (!await isConfigV2(dir)) {
|
|
28669
28995
|
throw new ServiceEditError(
|
|
28670
28996
|
`${command2} works with a config version 2 project, and there is none in ${dir}.`,
|
|
@@ -28880,14 +29206,14 @@ var remove_default = {
|
|
|
28880
29206
|
|
|
28881
29207
|
// src/cli/dev/handler.ts
|
|
28882
29208
|
init_joinUrl();
|
|
28883
|
-
import
|
|
29209
|
+
import path87 from "node:path";
|
|
28884
29210
|
|
|
28885
29211
|
// src/vite/dev-server.ts
|
|
28886
29212
|
init_logger();
|
|
28887
29213
|
import fs11 from "node:fs/promises";
|
|
28888
29214
|
import http from "node:http";
|
|
28889
29215
|
import https from "node:https";
|
|
28890
|
-
import
|
|
29216
|
+
import path86 from "node:path";
|
|
28891
29217
|
import { createHttpTerminator } from "http-terminator";
|
|
28892
29218
|
import {
|
|
28893
29219
|
createServer as createViteServer,
|
|
@@ -28920,7 +29246,7 @@ init_loader();
|
|
|
28920
29246
|
// src/vite/pagefind-dev-index.ts
|
|
28921
29247
|
init_invariant();
|
|
28922
29248
|
init_joinUrl();
|
|
28923
|
-
import
|
|
29249
|
+
import path85 from "node:path";
|
|
28924
29250
|
import { createIndex as createIndex2 } from "pagefind";
|
|
28925
29251
|
import { isRunnableDevEnvironment } from "vite";
|
|
28926
29252
|
async function* buildPagefindDevIndex(vite, config2) {
|
|
@@ -28973,7 +29299,7 @@ async function* buildPagefindDevIndex(vite, config2) {
|
|
|
28973
29299
|
path: urlPath
|
|
28974
29300
|
};
|
|
28975
29301
|
}
|
|
28976
|
-
const outputPath =
|
|
29302
|
+
const outputPath = path85.join(vite.config.publicDir, "pagefind");
|
|
28977
29303
|
await pagefindIndex.writeFiles({ outputPath });
|
|
28978
29304
|
yield { type: "complete", success: true, indexed };
|
|
28979
29305
|
}
|
|
@@ -28992,9 +29318,9 @@ var DevServer = class {
|
|
|
28992
29318
|
this.protocol = "https";
|
|
28993
29319
|
const { dir } = this.options;
|
|
28994
29320
|
const [key, cert, ca] = await Promise.all([
|
|
28995
|
-
fs11.readFile(
|
|
28996
|
-
fs11.readFile(
|
|
28997
|
-
config2.https.ca ? fs11.readFile(
|
|
29321
|
+
fs11.readFile(path86.resolve(dir, config2.https.key)),
|
|
29322
|
+
fs11.readFile(path86.resolve(dir, config2.https.cert)),
|
|
29323
|
+
config2.https.ca ? fs11.readFile(path86.resolve(dir, config2.https.ca)) : void 0
|
|
28998
29324
|
]);
|
|
28999
29325
|
return https.createServer({ key, cert, ca });
|
|
29000
29326
|
}
|
|
@@ -29011,7 +29337,7 @@ var DevServer = class {
|
|
|
29011
29337
|
);
|
|
29012
29338
|
const server = await this.createNodeServer(config2);
|
|
29013
29339
|
if (config2.search?.type === "pagefind" && viteConfig.publicDir !== false) {
|
|
29014
|
-
const publicRoot =
|
|
29340
|
+
const publicRoot = path86.resolve(
|
|
29015
29341
|
this.options.dir,
|
|
29016
29342
|
typeof viteConfig.publicDir === "string" ? viteConfig.publicDir : "public"
|
|
29017
29343
|
);
|
|
@@ -29028,7 +29354,7 @@ var DevServer = class {
|
|
|
29028
29354
|
// built-in transform middleware which would treat the path as a static asset.
|
|
29029
29355
|
name: "apitogo:entry-client",
|
|
29030
29356
|
configureServer(server2) {
|
|
29031
|
-
const entryPath =
|
|
29357
|
+
const entryPath = path86.posix.join(
|
|
29032
29358
|
server2.config.base,
|
|
29033
29359
|
"/__z/entry.client.tsx"
|
|
29034
29360
|
);
|
|
@@ -29193,7 +29519,7 @@ init_package_json();
|
|
|
29193
29519
|
async function dev(argv) {
|
|
29194
29520
|
const packageJson3 = getZudokuPackageJson();
|
|
29195
29521
|
process.env.NODE_ENV = "development";
|
|
29196
|
-
let dir =
|
|
29522
|
+
let dir = path87.resolve(process.cwd(), argv.dir);
|
|
29197
29523
|
if (await isConfigV2(dir)) {
|
|
29198
29524
|
const { root, prepared } = await preparePortalWorkspace(dir, "development");
|
|
29199
29525
|
dir = root;
|
|
@@ -29292,61 +29618,8 @@ var run_default = {
|
|
|
29292
29618
|
};
|
|
29293
29619
|
|
|
29294
29620
|
// src/cli/secrets/handler.ts
|
|
29295
|
-
import
|
|
29621
|
+
import path88 from "node:path";
|
|
29296
29622
|
init_invariant();
|
|
29297
|
-
|
|
29298
|
-
// src/cli/secrets/input.ts
|
|
29299
|
-
import { createInterface as createInterface6 } from "node:readline/promises";
|
|
29300
|
-
var CTRL_C = "";
|
|
29301
|
-
var CTRL_D = "";
|
|
29302
|
-
function readHidden(prompt, input5 = process.stdin, output4 = process.stdout) {
|
|
29303
|
-
return new Promise((resolve, reject) => {
|
|
29304
|
-
if (!input5.isTTY || !input5.setRawMode) {
|
|
29305
|
-
reject(new Error("A hidden prompt needs an interactive terminal."));
|
|
29306
|
-
return;
|
|
29307
|
-
}
|
|
29308
|
-
let value = "";
|
|
29309
|
-
output4.write(prompt);
|
|
29310
|
-
input5.setRawMode(true);
|
|
29311
|
-
input5.resume();
|
|
29312
|
-
const finish = (action) => {
|
|
29313
|
-
input5.removeListener("data", onData);
|
|
29314
|
-
input5.setRawMode?.(false);
|
|
29315
|
-
input5.pause();
|
|
29316
|
-
output4.write("\n");
|
|
29317
|
-
action();
|
|
29318
|
-
};
|
|
29319
|
-
const onData = (chunk) => {
|
|
29320
|
-
for (const char of chunk.toString("utf8")) {
|
|
29321
|
-
if (char === CTRL_C)
|
|
29322
|
-
return finish(() => reject(new Error("Cancelled.")));
|
|
29323
|
-
if (char === "\r" || char === "\n" || char === CTRL_D)
|
|
29324
|
-
return finish(() => resolve(value));
|
|
29325
|
-
if (char === "\x7F" || char === "\b") value = value.slice(0, -1);
|
|
29326
|
-
else value += char;
|
|
29327
|
-
}
|
|
29328
|
-
};
|
|
29329
|
-
input5.on("data", onData);
|
|
29330
|
-
});
|
|
29331
|
-
}
|
|
29332
|
-
async function readStdin(input5 = process.stdin) {
|
|
29333
|
-
const chunks = [];
|
|
29334
|
-
for await (const chunk of input5) {
|
|
29335
|
-
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
29336
|
-
}
|
|
29337
|
-
return Buffer.concat(chunks).toString("utf8").replace(/\r?\n$/, "");
|
|
29338
|
-
}
|
|
29339
|
-
async function confirm(question) {
|
|
29340
|
-
const rl = createInterface6({ input: process.stdin, output: process.stdout });
|
|
29341
|
-
try {
|
|
29342
|
-
const answer = (await rl.question(question)).trim().toLowerCase();
|
|
29343
|
-
return answer === "y" || answer === "yes";
|
|
29344
|
-
} finally {
|
|
29345
|
-
rl.close();
|
|
29346
|
-
}
|
|
29347
|
-
}
|
|
29348
|
-
|
|
29349
|
-
// src/cli/secrets/handler.ts
|
|
29350
29623
|
var SECRET_NAME = /^[A-Za-z_][A-Za-z0-9_]{0,127}$/;
|
|
29351
29624
|
var SecretsError = class extends ApitogoError {
|
|
29352
29625
|
constructor(message, developerHint) {
|
|
@@ -29357,7 +29630,7 @@ var SecretsError = class extends ApitogoError {
|
|
|
29357
29630
|
async function resolveProjectId2(argv, deps) {
|
|
29358
29631
|
const explicit = argv.projectId?.trim();
|
|
29359
29632
|
if (explicit) return explicit;
|
|
29360
|
-
const dir =
|
|
29633
|
+
const dir = path88.resolve(process.cwd(), argv.dir ?? ".");
|
|
29361
29634
|
if (await isConfigV2(dir)) {
|
|
29362
29635
|
const id = loadConfigV2(dir).resolved.project.id;
|
|
29363
29636
|
if (id) return id;
|
|
@@ -29517,12 +29790,12 @@ var secrets_default = {
|
|
|
29517
29790
|
};
|
|
29518
29791
|
|
|
29519
29792
|
// src/cli/cmds/status.ts
|
|
29520
|
-
import
|
|
29793
|
+
import path90 from "node:path";
|
|
29521
29794
|
|
|
29522
29795
|
// src/cli/status/handler.ts
|
|
29523
|
-
import
|
|
29796
|
+
import path89 from "node:path";
|
|
29524
29797
|
async function status(argv) {
|
|
29525
|
-
const sourceDirectory =
|
|
29798
|
+
const sourceDirectory = path89.resolve(process.cwd(), argv.dir);
|
|
29526
29799
|
let config2;
|
|
29527
29800
|
try {
|
|
29528
29801
|
config2 = loadConfig();
|
|
@@ -29620,7 +29893,7 @@ var status_default = {
|
|
|
29620
29893
|
}),
|
|
29621
29894
|
handler: async (argv) => {
|
|
29622
29895
|
await captureEvent({ argv, event: "apitogo status" });
|
|
29623
|
-
if (await isConfigV2(
|
|
29896
|
+
if (await isConfigV2(path90.resolve(process.cwd(), argv.dir))) {
|
|
29624
29897
|
await statusOfProject(argv);
|
|
29625
29898
|
return;
|
|
29626
29899
|
}
|
|
@@ -29629,11 +29902,11 @@ var status_default = {
|
|
|
29629
29902
|
};
|
|
29630
29903
|
|
|
29631
29904
|
// src/cli/cmds/teardown.ts
|
|
29632
|
-
import
|
|
29905
|
+
import path93 from "node:path";
|
|
29633
29906
|
|
|
29634
29907
|
// src/cli/teardown/command.ts
|
|
29635
29908
|
init_invariant();
|
|
29636
|
-
import
|
|
29909
|
+
import path91 from "node:path";
|
|
29637
29910
|
import { createInterface as createInterface7 } from "node:readline/promises";
|
|
29638
29911
|
|
|
29639
29912
|
// src/cli/teardown/v2.ts
|
|
@@ -29994,7 +30267,7 @@ async function teardownProject(argv) {
|
|
|
29994
30267
|
const progress = createConsoleProgressReporter();
|
|
29995
30268
|
const result = await teardownV2(
|
|
29996
30269
|
{
|
|
29997
|
-
dir:
|
|
30270
|
+
dir: path91.resolve(process.cwd(), argv.dir),
|
|
29998
30271
|
projectId: argv.projectId,
|
|
29999
30272
|
only: Array.isArray(argv.only) ? argv.only.join(",") : argv.only,
|
|
30000
30273
|
yes: argv.yes === true,
|
|
@@ -30053,7 +30326,7 @@ async function teardownProject(argv) {
|
|
|
30053
30326
|
}
|
|
30054
30327
|
|
|
30055
30328
|
// src/cli/teardown/handler.ts
|
|
30056
|
-
import
|
|
30329
|
+
import path92 from "node:path";
|
|
30057
30330
|
function resultLooksFailed3(payload) {
|
|
30058
30331
|
try {
|
|
30059
30332
|
const parsed = JSON.parse(payload);
|
|
@@ -30069,7 +30342,7 @@ async function teardown(argv) {
|
|
|
30069
30342
|
);
|
|
30070
30343
|
return;
|
|
30071
30344
|
}
|
|
30072
|
-
const sourceDirectory =
|
|
30345
|
+
const sourceDirectory = path92.resolve(process.cwd(), argv.dir);
|
|
30073
30346
|
let config2;
|
|
30074
30347
|
try {
|
|
30075
30348
|
config2 = loadConfig();
|
|
@@ -30147,7 +30420,7 @@ var teardown_default = {
|
|
|
30147
30420
|
}),
|
|
30148
30421
|
handler: async (argv) => {
|
|
30149
30422
|
await captureEvent({ argv, event: "apitogo teardown" });
|
|
30150
|
-
if (await isConfigV2(
|
|
30423
|
+
if (await isConfigV2(path93.resolve(process.cwd(), argv.dir))) {
|
|
30151
30424
|
await teardownProject(argv);
|
|
30152
30425
|
return;
|
|
30153
30426
|
}
|
|
@@ -30157,7 +30430,7 @@ var teardown_default = {
|
|
|
30157
30430
|
|
|
30158
30431
|
// src/cli/teardown/reset-command.ts
|
|
30159
30432
|
init_invariant();
|
|
30160
|
-
import
|
|
30433
|
+
import path94 from "node:path";
|
|
30161
30434
|
|
|
30162
30435
|
// src/cli/teardown/reset.ts
|
|
30163
30436
|
init_invariant();
|
|
@@ -30280,7 +30553,7 @@ async function resetProject(argv) {
|
|
|
30280
30553
|
const config2 = loadConfig();
|
|
30281
30554
|
const result = await resetProjectV2(
|
|
30282
30555
|
{
|
|
30283
|
-
dir:
|
|
30556
|
+
dir: path94.resolve(process.cwd(), argv.dir),
|
|
30284
30557
|
projectId: argv.projectId,
|
|
30285
30558
|
yes: argv.yes === true
|
|
30286
30559
|
},
|
|
@@ -30344,7 +30617,7 @@ var test_reset_default = {
|
|
|
30344
30617
|
};
|
|
30345
30618
|
|
|
30346
30619
|
// src/cli/test-sign-in/handler.ts
|
|
30347
|
-
import
|
|
30620
|
+
import path95 from "node:path";
|
|
30348
30621
|
init_invariant();
|
|
30349
30622
|
var TestSignInError = class extends ApitogoError {
|
|
30350
30623
|
constructor(message, developerHint) {
|
|
@@ -30355,7 +30628,7 @@ var TestSignInError = class extends ApitogoError {
|
|
|
30355
30628
|
async function resolveProjectId3(argv) {
|
|
30356
30629
|
const explicit = argv.projectId?.trim();
|
|
30357
30630
|
if (explicit) return explicit;
|
|
30358
|
-
const dir =
|
|
30631
|
+
const dir = path95.resolve(process.cwd(), argv.dir ?? ".");
|
|
30359
30632
|
if (await isConfigV2(dir)) {
|
|
30360
30633
|
const id = loadConfigV2(dir).resolved.project.id;
|
|
30361
30634
|
if (id) return id;
|
|
@@ -30495,36 +30768,36 @@ function createApitogoCli(argv) {
|
|
|
30495
30768
|
// src/cli/local-handoff.ts
|
|
30496
30769
|
import { spawn as spawn4 } from "node:child_process";
|
|
30497
30770
|
import { existsSync as existsSync8, realpathSync as realpathSync2 } from "node:fs";
|
|
30498
|
-
import
|
|
30771
|
+
import path96 from "node:path";
|
|
30499
30772
|
var LOCAL_HANDOFF_ENV = "APITOGO_LOCAL_CLI";
|
|
30500
30773
|
var PACKAGE_NAME = "@lukoweb/apitogo";
|
|
30501
30774
|
var resolveProjectDir = (argv, cwd) => {
|
|
30502
30775
|
for (let i = 0; i < argv.length; i++) {
|
|
30503
30776
|
const arg = argv[i];
|
|
30504
30777
|
const next = argv[i + 1];
|
|
30505
|
-
if (arg === "--dir" && next) return
|
|
30778
|
+
if (arg === "--dir" && next) return path96.resolve(cwd, next);
|
|
30506
30779
|
if (arg?.startsWith("--dir=")) {
|
|
30507
|
-
return
|
|
30780
|
+
return path96.resolve(cwd, arg.slice("--dir=".length));
|
|
30508
30781
|
}
|
|
30509
30782
|
}
|
|
30510
30783
|
return cwd;
|
|
30511
30784
|
};
|
|
30512
30785
|
var findLocalCli = (projectDir, runningRoot) => {
|
|
30513
|
-
let dir =
|
|
30786
|
+
let dir = path96.resolve(projectDir);
|
|
30514
30787
|
let localPackageRoot;
|
|
30515
30788
|
while (!localPackageRoot) {
|
|
30516
|
-
const candidate =
|
|
30517
|
-
if (existsSync8(
|
|
30789
|
+
const candidate = path96.join(dir, "node_modules", PACKAGE_NAME);
|
|
30790
|
+
if (existsSync8(path96.join(candidate, "package.json"))) {
|
|
30518
30791
|
localPackageRoot = candidate;
|
|
30519
|
-
} else if (dir ===
|
|
30792
|
+
} else if (dir === path96.dirname(dir)) {
|
|
30520
30793
|
return void 0;
|
|
30521
30794
|
} else {
|
|
30522
|
-
dir =
|
|
30795
|
+
dir = path96.dirname(dir);
|
|
30523
30796
|
}
|
|
30524
30797
|
}
|
|
30525
30798
|
const localRoot = realpathSync2(localPackageRoot);
|
|
30526
30799
|
if (localRoot === realpathSync2(runningRoot)) return void 0;
|
|
30527
|
-
return
|
|
30800
|
+
return path96.join(localRoot, "cli.js");
|
|
30528
30801
|
};
|
|
30529
30802
|
var handoffToLocalCli = async (argv, runningRoot) => {
|
|
30530
30803
|
if (process.env[LOCAL_HANDOFF_ENV] || process.env.ZUDOKU_ENV === "internal") {
|
|
@@ -30536,7 +30809,7 @@ var handoffToLocalCli = async (argv, runningRoot) => {
|
|
|
30536
30809
|
);
|
|
30537
30810
|
if (!localCli) return void 0;
|
|
30538
30811
|
printDiagnosticsToConsole(
|
|
30539
|
-
`Using the project's local ${PACKAGE_NAME} (${
|
|
30812
|
+
`Using the project's local ${PACKAGE_NAME} (${path96.dirname(localCli)})`
|
|
30540
30813
|
);
|
|
30541
30814
|
const child = spawn4(process.execPath, [localCli, ...argv], {
|
|
30542
30815
|
stdio: "inherit",
|