@lukoweb/apitogo 0.2.31 → 0.2.35
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 +440 -153
- package/dist/declarations/app/entry.server.d.ts +2 -2
- package/dist/declarations/app/main.d.ts +3 -1
- package/dist/declarations/cli/platform/client/platform-api.d.ts +0 -4
- package/dist/declarations/cli/platform/helpers/deploy-artifact-hash.d.ts +1 -1
- package/dist/declarations/cli/platform/helpers/package-files.d.ts +1 -1
- package/dist/declarations/cli/platform/helpers/zip.d.ts +1 -1
- package/dist/declarations/cli/platform/tools/infrastructure.d.ts +0 -4
- package/dist/declarations/config/effective-redirects.d.ts +6 -0
- package/dist/declarations/config/header-navigation-guard.d.ts +2 -0
- package/dist/declarations/config/resolve-modules.d.ts +1 -4
- package/dist/declarations/config/validators/HeaderNavigationSchema.d.ts +1 -2
- package/docs/cli/commands.md +19 -0
- package/docs/configuration/gateway.md +52 -0
- package/docs/guides/customer-account.md +11 -1
- package/docs/mcp/tools.md +101 -102
- package/package.json +2 -1
- package/src/app/demo.tsx +78 -77
- package/src/app/entry.client.tsx +115 -107
- package/src/app/entry.server.tsx +164 -160
- package/src/app/main.tsx +175 -167
- package/src/app/standalone.tsx +61 -60
- package/src/config/effective-redirects.ts +31 -0
- package/src/config/header-navigation-guard.ts +13 -0
- package/src/config/resolve-modules.ts +331 -354
- package/src/config/v2/home-redirect.ts +104 -98
- package/src/config/v2/index.ts +127 -126
- package/src/config/v2/ledger.ts +242 -235
- package/src/config/v2/resolve.ts +12 -4
- package/src/config/v2/rules.ts +716 -714
- package/src/config/v2/services.ts +799 -663
- package/src/config/v2/workspace.ts +17 -1
- package/src/config/validators/HeaderNavigationSchema.ts +42 -44
- package/src/lib/assets/powered-by-icon.png +0 -0
- package/src/lib/authentication/providers/dev-portal-auth-pages.tsx +667 -602
- package/src/lib/authentication/providers/dev-portal.tsx +476 -448
- package/src/lib/components/HeaderNavigation.tsx +176 -176
- package/src/lib/components/MobileTopNavigation.tsx +283 -283
- package/src/lib/components/navigation/PoweredByZudoku.tsx +42 -39
- package/src/vite/plugin-offroot-resolve.ts +68 -67
- package/src/vite/prerender/prerender.ts +242 -242
package/dist/cli/cli.js
CHANGED
|
@@ -5267,7 +5267,7 @@ var llms_exports = {};
|
|
|
5267
5267
|
__export(llms_exports, {
|
|
5268
5268
|
generateLlmsTxtFiles: () => generateLlmsTxtFiles
|
|
5269
5269
|
});
|
|
5270
|
-
import { writeFile as
|
|
5270
|
+
import { writeFile as writeFile12 } from "node:fs/promises";
|
|
5271
5271
|
import path44 from "node:path";
|
|
5272
5272
|
import colors10 from "picocolors";
|
|
5273
5273
|
async function generateLlmsTxtFiles({
|
|
@@ -5303,7 +5303,7 @@ async function generateLlmsTxtFiles({
|
|
|
5303
5303
|
}
|
|
5304
5304
|
}
|
|
5305
5305
|
const llmsTxt2 = llmsTxtParts.join("\n");
|
|
5306
|
-
await
|
|
5306
|
+
await writeFile12(path44.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
|
}
|
|
@@ -5330,7 +5330,7 @@ ${info.content}
|
|
|
5330
5330
|
`);
|
|
5331
5331
|
}
|
|
5332
5332
|
const llmsFull = llmsFullParts.join("\n");
|
|
5333
|
-
await
|
|
5333
|
+
await writeFile12(
|
|
5334
5334
|
path44.join(baseOutputDir, "llms-full.txt"),
|
|
5335
5335
|
llmsFull,
|
|
5336
5336
|
"utf-8"
|
|
@@ -5811,7 +5811,6 @@ import yargs from "yargs/yargs";
|
|
|
5811
5811
|
|
|
5812
5812
|
// src/cli/services/handler.ts
|
|
5813
5813
|
import path53 from "node:path";
|
|
5814
|
-
import { createInterface as createInterface2 } from "node:readline/promises";
|
|
5815
5814
|
|
|
5816
5815
|
// src/config/v2/errors.ts
|
|
5817
5816
|
init_invariant();
|
|
@@ -6540,8 +6539,11 @@ import path8 from "node:path";
|
|
|
6540
6539
|
|
|
6541
6540
|
// src/config/v2/resolve.ts
|
|
6542
6541
|
import path7 from "node:path";
|
|
6542
|
+
function toGlobPath(value) {
|
|
6543
|
+
return value.split(path7.sep).join("/");
|
|
6544
|
+
}
|
|
6543
6545
|
function fromConfig(configDir, value) {
|
|
6544
|
-
return value.startsWith("!") ? `!${path7.resolve(configDir, value.slice(1))}` : path7.resolve(configDir, value);
|
|
6546
|
+
return value.startsWith("!") ? `!${toGlobPath(path7.resolve(configDir, value.slice(1)))}` : toGlobPath(path7.resolve(configDir, value));
|
|
6545
6547
|
}
|
|
6546
6548
|
function resolveConfigV2(config2, configPath) {
|
|
6547
6549
|
const absoluteConfigPath = path7.resolve(configPath);
|
|
@@ -6569,7 +6571,7 @@ function resolveConfigV2(config2, configPath) {
|
|
|
6569
6571
|
docs: {
|
|
6570
6572
|
enabled: portal.docs?.enabled ?? true,
|
|
6571
6573
|
provider,
|
|
6572
|
-
content: provider === "external" ? [] : portal.docs?.content ? portal.docs.content.map((glob9) => fromConfig(configDir, glob9)) : [path7.join(dir, "pages", "**", "*.{md,mdx}")],
|
|
6574
|
+
content: provider === "external" ? [] : portal.docs?.content ? portal.docs.content.map((glob9) => fromConfig(configDir, glob9)) : [toGlobPath(path7.join(dir, "pages", "**", "*.{md,mdx}"))],
|
|
6573
6575
|
url: portal.docs?.url
|
|
6574
6576
|
},
|
|
6575
6577
|
console: { enabled: portal.console?.enabled ?? true },
|
|
@@ -6815,8 +6817,9 @@ async function portalRules(config2, resolved, out) {
|
|
|
6815
6817
|
}
|
|
6816
6818
|
}
|
|
6817
6819
|
async function docsContentRule(config2, patterns, resolved, out) {
|
|
6818
|
-
const
|
|
6819
|
-
const
|
|
6820
|
+
const globs = patterns.map(toGlobPath);
|
|
6821
|
+
const include = globs.filter((pattern) => !pattern.startsWith("!"));
|
|
6822
|
+
const ignore2 = globs.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1));
|
|
6820
6823
|
const matches = include.length > 0 ? await glob(include, { nodir: true, ignore: ignore2, absolute: true }) : [];
|
|
6821
6824
|
if (matches.length > 0) return;
|
|
6822
6825
|
const shown = config2.portal?.docs?.content ?? [
|
|
@@ -7835,8 +7838,9 @@ var readFrontmatter = async (filePath) => {
|
|
|
7835
7838
|
// src/config/v2/home-redirect.ts
|
|
7836
7839
|
var IGNORED = ["**/node_modules/**", "**/dist/**", "**/.git/**"];
|
|
7837
7840
|
async function docRoutes(patterns, options = {}) {
|
|
7838
|
-
const
|
|
7839
|
-
const
|
|
7841
|
+
const globs = patterns.map(toGlobPath);
|
|
7842
|
+
const excluded = globs.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1));
|
|
7843
|
+
const included = globs.filter((pattern) => !pattern.startsWith("!"));
|
|
7840
7844
|
const routes = await Promise.all(
|
|
7841
7845
|
included.map(async (pattern) => {
|
|
7842
7846
|
const files = await glob2(pattern, {
|
|
@@ -7852,7 +7856,7 @@ async function docRoutes(patterns, options = {}) {
|
|
|
7852
7856
|
}))
|
|
7853
7857
|
)).filter(({ draft }) => !draft).map(({ file }) => file);
|
|
7854
7858
|
return published.map(
|
|
7855
|
-
(file) => `/${path11.posix.relative(parent, file).replace(/\.mdx?$/, "")}`
|
|
7859
|
+
(file) => `/${path11.posix.relative(parent, file.replace(/^\/\/\?\//, "")).replace(/\.mdx?$/, "")}`
|
|
7856
7860
|
);
|
|
7857
7861
|
})
|
|
7858
7862
|
);
|
|
@@ -8223,7 +8227,7 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
|
|
|
8223
8227
|
|
|
8224
8228
|
// src/config/v2/workspace.ts
|
|
8225
8229
|
import { createHash as createHash2 } from "node:crypto";
|
|
8226
|
-
import { access as access2, lstat, readFile as readFile7, rm as rm3 } from "node:fs/promises";
|
|
8230
|
+
import { access as access2, lstat, readFile as readFile7, rm as rm3, writeFile as writeFile6 } from "node:fs/promises";
|
|
8227
8231
|
import path13 from "node:path";
|
|
8228
8232
|
import { glob as glob3 } from "glob";
|
|
8229
8233
|
|
|
@@ -8256,9 +8260,17 @@ async function relink(target, link) {
|
|
|
8256
8260
|
await rm3(link, { recursive: true, force: true });
|
|
8257
8261
|
await linkDirectory(target, link);
|
|
8258
8262
|
}
|
|
8263
|
+
var GENERATED_PACKAGE_JSON = '{\n "private": true,\n "type": "module"\n}\n';
|
|
8264
|
+
async function writeGeneratedPackageJson(root) {
|
|
8265
|
+
const file = path13.join(root, "package.json");
|
|
8266
|
+
const current = await readFile7(file, "utf8").catch(() => void 0);
|
|
8267
|
+
if (current !== GENERATED_PACKAGE_JSON)
|
|
8268
|
+
await writeFile6(file, GENERATED_PACKAGE_JSON, "utf8");
|
|
8269
|
+
}
|
|
8259
8270
|
async function materializeWorkspace(resolved, prepared) {
|
|
8260
8271
|
const root = path13.dirname(prepared.wrapperPath);
|
|
8261
8272
|
await ensureStateDir(resolved.state);
|
|
8273
|
+
await writeGeneratedPackageJson(root);
|
|
8262
8274
|
await relink(resolved.configDir, path13.join(root, CONTENT_LINK));
|
|
8263
8275
|
const publicDir = resolved.portal && path13.join(resolved.portal.dir, "public");
|
|
8264
8276
|
const publicLink = path13.join(root, "public");
|
|
@@ -8326,15 +8338,22 @@ async function portalArtifactHash(resolved, manifestText, cliVersion, wrapper =
|
|
|
8326
8338
|
|
|
8327
8339
|
// src/config/v2/services.ts
|
|
8328
8340
|
init_invariant();
|
|
8329
|
-
import { access as access3, mkdir as mkdir5, rename as rename3, rm as rm4, stat as stat3, writeFile as
|
|
8341
|
+
import { access as access3, mkdir as mkdir5, rename as rename3, rm as rm4, stat as stat3, writeFile as writeFile7 } from "node:fs/promises";
|
|
8330
8342
|
import path14 from "node:path";
|
|
8331
8343
|
var SERVICES = ["portal", "gateway", "identity", "plans"];
|
|
8332
8344
|
var ServiceEditError = class extends ApitogoError {
|
|
8333
|
-
constructor(message, developerHint) {
|
|
8345
|
+
constructor(message, developerHint, missingServices = []) {
|
|
8334
8346
|
super(message, { developerHint, title: "Cannot change the services" });
|
|
8347
|
+
this.missingServices = missingServices;
|
|
8335
8348
|
this.name = "ServiceEditError";
|
|
8336
8349
|
}
|
|
8337
8350
|
};
|
|
8351
|
+
var httpsProblem = (value) => /^https:\/\/\S+$/i.test(value) ? void 0 : "The address must start with https://";
|
|
8352
|
+
var DEFAULT_RUNTIME_VERSION = {
|
|
8353
|
+
nodejs: "NODE_22_LTS",
|
|
8354
|
+
python: "PYTHON_312",
|
|
8355
|
+
dotnet: "DOTNET_8"
|
|
8356
|
+
};
|
|
8338
8357
|
function isServiceName(value) {
|
|
8339
8358
|
return SERVICES.includes(value);
|
|
8340
8359
|
}
|
|
@@ -8430,7 +8449,10 @@ async function buildPortal(context) {
|
|
|
8430
8449
|
if (!external && o.docsUrl) {
|
|
8431
8450
|
throw new ServiceEditError("--docs-url needs --docs-provider external.");
|
|
8432
8451
|
}
|
|
8433
|
-
|
|
8452
|
+
const docsUrl = o.docsUrl ?? (external && options.ask ? await options.ask.text("HTTPS address of your docs site", {
|
|
8453
|
+
validate: httpsProblem
|
|
8454
|
+
}) : void 0);
|
|
8455
|
+
if (external && !docsUrl) {
|
|
8434
8456
|
throw new ServiceEditError(
|
|
8435
8457
|
"--docs-provider external needs --docs-url <https url>."
|
|
8436
8458
|
);
|
|
@@ -8444,6 +8466,13 @@ async function buildPortal(context) {
|
|
|
8444
8466
|
const candidates = await detectExistingDocs(dir);
|
|
8445
8467
|
if (candidates.length === 1 || candidates.length > 1 && options.acceptAllDocs) {
|
|
8446
8468
|
content = candidates.map((candidate) => candidate.glob);
|
|
8469
|
+
} else if (candidates.length > 1 && options.ask) {
|
|
8470
|
+
const places = candidates.map((c) => c.path).join(", ");
|
|
8471
|
+
if (await options.ask.confirm(
|
|
8472
|
+
`Several places with documentation were found (${places}). Include all of them?`,
|
|
8473
|
+
true
|
|
8474
|
+
))
|
|
8475
|
+
content = candidates.map((candidate) => candidate.glob);
|
|
8447
8476
|
} else if (candidates.length > 1) {
|
|
8448
8477
|
throw new ServiceEditError(
|
|
8449
8478
|
`Several places with documentation were found (${candidates.map((c) => c.path).join(", ")}).`,
|
|
@@ -8462,7 +8491,7 @@ async function buildPortal(context) {
|
|
|
8462
8491
|
return {
|
|
8463
8492
|
...options.disabled ? { enabled: false } : {},
|
|
8464
8493
|
name,
|
|
8465
|
-
...external ? { docs: { provider: "external", url:
|
|
8494
|
+
...external ? { docs: { provider: "external", url: docsUrl } } : content.length > 0 ? { docs: { content } } : {},
|
|
8466
8495
|
...o.noConsole ? { console: { enabled: false } } : {},
|
|
8467
8496
|
...o.requireAuth ? { requireAuth: true } : {},
|
|
8468
8497
|
...o.search && !external ? { search: o.search } : {}
|
|
@@ -8471,7 +8500,20 @@ async function buildPortal(context) {
|
|
|
8471
8500
|
async function buildGateway(context) {
|
|
8472
8501
|
const { options, dir, resolved } = context;
|
|
8473
8502
|
const o = options.gateway ?? {};
|
|
8474
|
-
const
|
|
8503
|
+
const ask4 = options.ask;
|
|
8504
|
+
let mode = o.origin ?? (o.url ? "proxy" : o.source || o.runtime ? "managed" : void 0);
|
|
8505
|
+
if (!mode && ask4) {
|
|
8506
|
+
mode = await ask4.choose("How does the gateway reach your API?", [
|
|
8507
|
+
{
|
|
8508
|
+
value: "proxy",
|
|
8509
|
+
label: "My API runs somewhere else: the gateway forwards calls to its https address"
|
|
8510
|
+
},
|
|
8511
|
+
{
|
|
8512
|
+
value: "managed",
|
|
8513
|
+
label: "The platform runs my code (nodejs, python or dotnet)"
|
|
8514
|
+
}
|
|
8515
|
+
]);
|
|
8516
|
+
}
|
|
8475
8517
|
if (!mode) {
|
|
8476
8518
|
throw new ServiceEditError(
|
|
8477
8519
|
"The gateway needs an origin: say how it reaches your API.",
|
|
@@ -8480,11 +8522,25 @@ async function buildGateway(context) {
|
|
|
8480
8522
|
}
|
|
8481
8523
|
let origin;
|
|
8482
8524
|
if (mode === "proxy") {
|
|
8483
|
-
|
|
8525
|
+
const url2 = o.url ?? (ask4 ? await ask4.text("https address of your API", {
|
|
8526
|
+
validate: httpsProblem
|
|
8527
|
+
}) : void 0);
|
|
8528
|
+
if (!url2)
|
|
8484
8529
|
throw new ServiceEditError("--origin proxy needs --url <https url>.");
|
|
8485
|
-
origin = { mode, url:
|
|
8530
|
+
origin = { mode, url: url2 };
|
|
8486
8531
|
} else {
|
|
8487
|
-
|
|
8532
|
+
const source = o.source ?? (ask4 ? await ask4.text("Folder with your code, relative to the project", {
|
|
8533
|
+
default: "server"
|
|
8534
|
+
}) : void 0);
|
|
8535
|
+
const runtime = o.runtime ?? (ask4 ? await ask4.choose("Runtime of your code", [
|
|
8536
|
+
{ value: "nodejs", label: "Node.js" },
|
|
8537
|
+
{ value: "python", label: "Python" },
|
|
8538
|
+
{ value: "dotnet", label: ".NET" }
|
|
8539
|
+
]) : void 0);
|
|
8540
|
+
const runtimeVersion = o.runtimeVersion ?? (ask4 && runtime ? await ask4.text("Runtime version", {
|
|
8541
|
+
default: DEFAULT_RUNTIME_VERSION[runtime]
|
|
8542
|
+
}) : void 0);
|
|
8543
|
+
if (!source || !runtime || !runtimeVersion) {
|
|
8488
8544
|
throw new ServiceEditError(
|
|
8489
8545
|
"--origin managed needs --source, --runtime and --runtime-version.",
|
|
8490
8546
|
"For example: --source server --runtime nodejs --runtime-version NODE_22_LTS."
|
|
@@ -8492,16 +8548,29 @@ async function buildGateway(context) {
|
|
|
8492
8548
|
}
|
|
8493
8549
|
origin = {
|
|
8494
8550
|
mode,
|
|
8495
|
-
source: insideProject(dir,
|
|
8496
|
-
runtime
|
|
8497
|
-
runtimeVersion
|
|
8551
|
+
source: insideProject(dir, source, "Source folder"),
|
|
8552
|
+
runtime,
|
|
8553
|
+
runtimeVersion,
|
|
8498
8554
|
...o.exclude?.length ? { exclude: o.exclude } : {}
|
|
8499
8555
|
};
|
|
8500
8556
|
}
|
|
8501
8557
|
let specs;
|
|
8502
|
-
|
|
8558
|
+
let requestedSpecs = o.spec ?? [];
|
|
8559
|
+
let createSpec = o.createSpec === true;
|
|
8560
|
+
if (requestedSpecs.length === 0 && !createSpec && ask4) {
|
|
8561
|
+
const answer = await ask4.choose("OpenAPI file of your API", [
|
|
8562
|
+
{ value: "create", label: "Start from a small file the command creates" },
|
|
8563
|
+
{ value: "existing", label: "Use a file I already have" }
|
|
8564
|
+
]);
|
|
8565
|
+
if (answer === "create") createSpec = true;
|
|
8566
|
+
else
|
|
8567
|
+
requestedSpecs = [
|
|
8568
|
+
await ask4.text("Path of your OpenAPI file, relative to the project")
|
|
8569
|
+
];
|
|
8570
|
+
}
|
|
8571
|
+
if (requestedSpecs.length > 0) {
|
|
8503
8572
|
specs = [];
|
|
8504
|
-
for (const requested of
|
|
8573
|
+
for (const requested of requestedSpecs) {
|
|
8505
8574
|
const relative = insideProject(dir, requested, "OpenAPI file");
|
|
8506
8575
|
if (!await stat3(path14.join(dir, relative)).then(
|
|
8507
8576
|
(s) => s.isFile(),
|
|
@@ -8513,7 +8582,7 @@ async function buildGateway(context) {
|
|
|
8513
8582
|
}
|
|
8514
8583
|
specs.push(relative);
|
|
8515
8584
|
}
|
|
8516
|
-
} else if (
|
|
8585
|
+
} else if (createSpec) {
|
|
8517
8586
|
const target = path14.join(resolved.apisDir, "openapi.yaml");
|
|
8518
8587
|
await addFile(context, target, STARTER_SPEC(resolved.project.name));
|
|
8519
8588
|
specs = [rel(dir, target)];
|
|
@@ -8545,12 +8614,15 @@ async function buildGateway(context) {
|
|
|
8545
8614
|
...Object.keys(policies).length > 0 ? { policies } : {}
|
|
8546
8615
|
};
|
|
8547
8616
|
}
|
|
8548
|
-
function buildIdentity(context) {
|
|
8617
|
+
async function buildIdentity(context) {
|
|
8549
8618
|
const { options } = context;
|
|
8550
8619
|
const o = options.identity ?? {};
|
|
8551
8620
|
const provider = o.provider ?? "apitogo";
|
|
8552
8621
|
if (provider === "oidc") {
|
|
8553
|
-
|
|
8622
|
+
const issuer = o.issuer ?? (options.ask ? await options.ask.text("https address of your OIDC issuer", {
|
|
8623
|
+
validate: httpsProblem
|
|
8624
|
+
}) : void 0);
|
|
8625
|
+
if (!issuer)
|
|
8554
8626
|
throw new ServiceEditError("--provider oidc needs --issuer <https url>.");
|
|
8555
8627
|
if (o.connection || o.native === false) {
|
|
8556
8628
|
throw new ServiceEditError(
|
|
@@ -8560,7 +8632,7 @@ function buildIdentity(context) {
|
|
|
8560
8632
|
return {
|
|
8561
8633
|
...options.disabled ? { enabled: false } : {},
|
|
8562
8634
|
provider,
|
|
8563
|
-
issuer
|
|
8635
|
+
issuer,
|
|
8564
8636
|
...o.clientId ? { clientId: o.clientId } : {}
|
|
8565
8637
|
};
|
|
8566
8638
|
}
|
|
@@ -8634,6 +8706,15 @@ async function buildPlans(context) {
|
|
|
8634
8706
|
function reparse(configPath, raw) {
|
|
8635
8707
|
return parseConfigV2(JSON.parse(JSON.stringify(raw)), configPath);
|
|
8636
8708
|
}
|
|
8709
|
+
function missingServicesOf(issues) {
|
|
8710
|
+
const missing = /* @__PURE__ */ new Set();
|
|
8711
|
+
for (const { code } of issues) {
|
|
8712
|
+
if (code === "PLANS_GATEWAY_REQUIRED") missing.add("gateway");
|
|
8713
|
+
if (code === "PLANS_IDENTITY_REQUIRED" || code === "PORTAL_CAPABILITY_MISSING")
|
|
8714
|
+
missing.add("identity");
|
|
8715
|
+
}
|
|
8716
|
+
return [...missing];
|
|
8717
|
+
}
|
|
8637
8718
|
function dependencyProblems(config2, configPath) {
|
|
8638
8719
|
return checkDependencies(config2, resolveConfigV2(config2, configPath));
|
|
8639
8720
|
}
|
|
@@ -8655,7 +8736,7 @@ async function planAddService(service, options) {
|
|
|
8655
8736
|
keep: [],
|
|
8656
8737
|
notes: []
|
|
8657
8738
|
};
|
|
8658
|
-
const section = service === "portal" ? await buildPortal(context) : service === "gateway" ? await buildGateway(context) : service === "identity" ? buildIdentity(context) : await buildPlans(context);
|
|
8739
|
+
const section = service === "portal" ? await buildPortal(context) : service === "gateway" ? await buildGateway(context) : service === "identity" ? await buildIdentity(context) : await buildPlans(context);
|
|
8659
8740
|
const next = reparse(resolved.configPath, { ...config2, [service]: section });
|
|
8660
8741
|
if (!options.disabled) {
|
|
8661
8742
|
const before = new Set(
|
|
@@ -8669,7 +8750,8 @@ async function planAddService(service, options) {
|
|
|
8669
8750
|
if (added.length > 0) {
|
|
8670
8751
|
throw new ServiceEditError(
|
|
8671
8752
|
added.map((issue4) => issue4.message).join(" "),
|
|
8672
|
-
added.map((issue4) => issue4.hint).filter(Boolean).join(" ") || "Add the missing service first."
|
|
8753
|
+
added.map((issue4) => issue4.hint).filter(Boolean).join(" ") || "Add the missing service first.",
|
|
8754
|
+
missingServicesOf(added)
|
|
8673
8755
|
);
|
|
8674
8756
|
}
|
|
8675
8757
|
}
|
|
@@ -8727,7 +8809,7 @@ async function planRemoveService(service, options) {
|
|
|
8727
8809
|
async function writeConfig(configPath, config2) {
|
|
8728
8810
|
const temporary = `${configPath}.${process.pid}.tmp`;
|
|
8729
8811
|
try {
|
|
8730
|
-
await
|
|
8812
|
+
await writeFile7(temporary, `${JSON.stringify(config2, null, 2)}
|
|
8731
8813
|
`, "utf8");
|
|
8732
8814
|
await rename3(temporary, configPath);
|
|
8733
8815
|
} catch (error) {
|
|
@@ -8740,7 +8822,7 @@ async function applyServiceEdit(edit) {
|
|
|
8740
8822
|
for (const file of edit.files) {
|
|
8741
8823
|
await mkdir5(path14.dirname(file.path), { recursive: true });
|
|
8742
8824
|
try {
|
|
8743
|
-
await
|
|
8825
|
+
await writeFile7(file.path, file.content, { flag: "wx" });
|
|
8744
8826
|
created.push(file.path);
|
|
8745
8827
|
} catch (error) {
|
|
8746
8828
|
if (error.code !== "EEXIST") throw error;
|
|
@@ -8788,7 +8870,7 @@ async function clearProjectId(dir, projectId) {
|
|
|
8788
8870
|
|
|
8789
8871
|
// src/config/v2/ledger.ts
|
|
8790
8872
|
init_invariant();
|
|
8791
|
-
import { mkdir as mkdir6, readFile as readFile8, rename as rename4, rm as rm5, writeFile as
|
|
8873
|
+
import { mkdir as mkdir6, readFile as readFile8, rename as rename4, rm as rm5, writeFile as writeFile8 } from "node:fs/promises";
|
|
8792
8874
|
import path15 from "node:path";
|
|
8793
8875
|
var LEDGER_VERSION = 1;
|
|
8794
8876
|
var LedgerError = class extends ApitogoError {
|
|
@@ -8847,7 +8929,7 @@ async function writeLedger(state, ledger) {
|
|
|
8847
8929
|
await mkdir6(path15.dirname(state.file), { recursive: true });
|
|
8848
8930
|
const temporary = `${state.file}.${process.pid}.tmp`;
|
|
8849
8931
|
try {
|
|
8850
|
-
await
|
|
8932
|
+
await writeFile8(temporary, `${JSON.stringify(ledger, null, 2)}
|
|
8851
8933
|
`, "utf8");
|
|
8852
8934
|
await rename4(temporary, state.file);
|
|
8853
8935
|
} catch (error) {
|
|
@@ -8928,6 +9010,10 @@ async function clearServices(state, services) {
|
|
|
8928
9010
|
);
|
|
8929
9011
|
if (Object.keys(remaining).length === Object.keys(ledger.services).length)
|
|
8930
9012
|
return;
|
|
9013
|
+
if (Object.keys(remaining).length === 0) {
|
|
9014
|
+
await rm5(state.file, { force: true });
|
|
9015
|
+
return;
|
|
9016
|
+
}
|
|
8931
9017
|
await writeLedger(state, { ...ledger, services: remaining });
|
|
8932
9018
|
}
|
|
8933
9019
|
|
|
@@ -9164,13 +9250,6 @@ var PlatformApiClient = class {
|
|
|
9164
9250
|
`/api/v1/projects/${projectId}/infrastructure/provisioning-jobs`
|
|
9165
9251
|
);
|
|
9166
9252
|
}
|
|
9167
|
-
getDeploymentToken(projectId, regenerate = false) {
|
|
9168
|
-
const query = regenerate ? "?regenerate=true" : "";
|
|
9169
|
-
return this.request(
|
|
9170
|
-
"POST",
|
|
9171
|
-
`/api/v1/projects/${projectId}/infrastructure/deployment-token${query}`
|
|
9172
|
-
);
|
|
9173
|
-
}
|
|
9174
9253
|
/**
|
|
9175
9254
|
* Publishes a built portal (.tgz, root folder `dist`). The platform holds the deploy server key and the project's
|
|
9176
9255
|
* deployment token, so the CLI only needs its own login. `env` falls back to the platform default.
|
|
@@ -9843,12 +9922,12 @@ import {
|
|
|
9843
9922
|
readFile as readFile12,
|
|
9844
9923
|
rename as rename6,
|
|
9845
9924
|
rm as rm8,
|
|
9846
|
-
writeFile as
|
|
9925
|
+
writeFile as writeFile15
|
|
9847
9926
|
} from "node:fs/promises";
|
|
9848
9927
|
import path48 from "node:path";
|
|
9849
9928
|
|
|
9850
9929
|
// src/vite/build.ts
|
|
9851
|
-
import { mkdir as mkdir11, readFile as readFile10, rename as rename5, rm as rm7, writeFile as
|
|
9930
|
+
import { mkdir as mkdir11, readFile as readFile10, rename as rename5, rm as rm7, writeFile as writeFile13 } from "node:fs/promises";
|
|
9852
9931
|
import path46 from "node:path";
|
|
9853
9932
|
import { build as esbuild } from "esbuild";
|
|
9854
9933
|
import { build as viteBuild, mergeConfig as mergeConfig3 } from "vite";
|
|
@@ -9996,7 +10075,7 @@ import {
|
|
|
9996
10075
|
// package.json
|
|
9997
10076
|
var package_default = {
|
|
9998
10077
|
name: "@lukoweb/apitogo",
|
|
9999
|
-
version: "0.2.
|
|
10078
|
+
version: "0.2.35",
|
|
10000
10079
|
type: "module",
|
|
10001
10080
|
sideEffects: [
|
|
10002
10081
|
"**/*.css",
|
|
@@ -10074,6 +10153,7 @@ var package_default = {
|
|
|
10074
10153
|
build: "esbuild src/cli/cli.ts src/vite/prerender/worker.ts --outdir=dist/cli --entry-names=[name] --bundle --format=esm --packages=external --target=node20 --platform=node --log-level=error",
|
|
10075
10154
|
postbuild: "tsx scripts/check-external-deps.ts",
|
|
10076
10155
|
typecheck: "tsc --project tsconfig.app.json --noEmit",
|
|
10156
|
+
"test:e2e": "vitest run --config vitest.e2e.config.ts",
|
|
10077
10157
|
"generate:types": "tsx scripts/generate-types.js && tsx scripts/generate-flat-config.js",
|
|
10078
10158
|
"build:standalone": "vite build --mode standalone --config vite.standalone.config.ts --log-level=error",
|
|
10079
10159
|
prepack: "npm run build && tsx scripts/generate-publish-exports.ts",
|
|
@@ -12245,13 +12325,13 @@ var NavigationResolver = class {
|
|
|
12245
12325
|
init_invariant();
|
|
12246
12326
|
|
|
12247
12327
|
// src/vite/debug.ts
|
|
12248
|
-
import { mkdir as mkdir7, writeFile as
|
|
12328
|
+
import { mkdir as mkdir7, writeFile as writeFile9 } from "node:fs/promises";
|
|
12249
12329
|
import path27 from "node:path";
|
|
12250
12330
|
async function writePluginDebugCode(rootDir, pluginName, code, extension = "js") {
|
|
12251
12331
|
if (process.env.ZUDOKU_BUILD_DEBUG) {
|
|
12252
12332
|
const debugDir = path27.join(rootDir, "dist", "debug");
|
|
12253
12333
|
await mkdir7(debugDir, { recursive: true });
|
|
12254
|
-
await
|
|
12334
|
+
await writeFile9(
|
|
12255
12335
|
path27.join(debugDir, `${pluginName}.${extension}`),
|
|
12256
12336
|
typeof code === "string" ? code : code.join("\n")
|
|
12257
12337
|
);
|
|
@@ -13108,7 +13188,7 @@ var plugin_local_manifest_default = viteLocalManifestPlugin;
|
|
|
13108
13188
|
init_loader();
|
|
13109
13189
|
init_ProtectedRoutesSchema();
|
|
13110
13190
|
init_joinUrl();
|
|
13111
|
-
import { mkdir as mkdir8, writeFile as
|
|
13191
|
+
import { mkdir as mkdir8, writeFile as writeFile10 } from "node:fs/promises";
|
|
13112
13192
|
import path34 from "node:path";
|
|
13113
13193
|
import { matchPath } from "react-router";
|
|
13114
13194
|
var processMarkdownFile = async (filePath) => {
|
|
@@ -13220,7 +13300,7 @@ var viteMarkdownExportPlugin = () => {
|
|
|
13220
13300
|
const segments = routePath === "/" ? ["index"] : routePath.split("/").filter(Boolean);
|
|
13221
13301
|
const outputPath = `${path34.join(distDir, ...segments)}.md`;
|
|
13222
13302
|
await mkdir8(path34.dirname(outputPath), { recursive: true });
|
|
13223
|
-
await
|
|
13303
|
+
await writeFile10(outputPath, finalMarkdown, "utf-8");
|
|
13224
13304
|
} catch (error) {
|
|
13225
13305
|
console.warn(`Failed to export markdown for ${routePath}:`, error);
|
|
13226
13306
|
}
|
|
@@ -13230,7 +13310,7 @@ var viteMarkdownExportPlugin = () => {
|
|
|
13230
13310
|
config2.__meta.rootDir,
|
|
13231
13311
|
"node_modules/.apitogo/markdown-info.json"
|
|
13232
13312
|
);
|
|
13233
|
-
await
|
|
13313
|
+
await writeFile10(
|
|
13234
13314
|
markdownInfoPath,
|
|
13235
13315
|
JSON.stringify(markdownFileInfos, null, 2),
|
|
13236
13316
|
"utf-8"
|
|
@@ -13858,7 +13938,7 @@ function isBareSpecifier(source) {
|
|
|
13858
13938
|
return !source.startsWith("\0") && !source.startsWith(".") && !source.startsWith("/") && !path38.isAbsolute(source);
|
|
13859
13939
|
}
|
|
13860
13940
|
function isInsideNodeModules(filePath) {
|
|
13861
|
-
return filePath.split(
|
|
13941
|
+
return filePath.split(/[\\/]/).includes("node_modules");
|
|
13862
13942
|
}
|
|
13863
13943
|
function shouldResolveFromSiteRoot(source, importer, rootDir) {
|
|
13864
13944
|
if (!importer || !isBareSpecifier(source)) {
|
|
@@ -14315,7 +14395,7 @@ ${cssLinks}
|
|
|
14315
14395
|
init_package_json();
|
|
14316
14396
|
init_joinUrl();
|
|
14317
14397
|
import assert from "node:assert";
|
|
14318
|
-
import { cp, mkdir as mkdir9, writeFile as
|
|
14398
|
+
import { cp, mkdir as mkdir9, writeFile as writeFile11 } from "node:fs/promises";
|
|
14319
14399
|
import path42 from "node:path";
|
|
14320
14400
|
var pkgJson = getZudokuPackageJson();
|
|
14321
14401
|
function generateOutput({
|
|
@@ -14376,7 +14456,7 @@ async function writeOutput(dir, {
|
|
|
14376
14456
|
const outputDir = process.env.VERCEL ? path42.join(dir, ".vercel/output") : path42.join(dir, "dist/.output");
|
|
14377
14457
|
await mkdir9(outputDir, { recursive: true });
|
|
14378
14458
|
const outputFile = path42.join(outputDir, "config.json");
|
|
14379
|
-
await
|
|
14459
|
+
await writeFile11(outputFile, JSON.stringify(output4, null, 2), "utf-8");
|
|
14380
14460
|
if (process.env.VERCEL) {
|
|
14381
14461
|
console.log("Wrote Vercel output to", outputDir);
|
|
14382
14462
|
}
|
|
@@ -14772,7 +14852,7 @@ var runPrerender = async (options) => {
|
|
|
14772
14852
|
});
|
|
14773
14853
|
const indexHtml = path46.join(clientOutDir, "index.html");
|
|
14774
14854
|
if (!workerResults.find((r) => r.outputPath === indexHtml)) {
|
|
14775
|
-
await
|
|
14855
|
+
await writeFile13(indexHtml, html, "utf-8");
|
|
14776
14856
|
}
|
|
14777
14857
|
const statusPages = workerResults.flatMap(
|
|
14778
14858
|
(r) => /400|404|500\.html$/.test(r.outputPath) ? r.outputPath : []
|
|
@@ -14797,7 +14877,7 @@ var runPrerender = async (options) => {
|
|
|
14797
14877
|
rewrites
|
|
14798
14878
|
});
|
|
14799
14879
|
if (ZuploEnv.isZuplo && issuer) {
|
|
14800
|
-
await
|
|
14880
|
+
await writeFile13(
|
|
14801
14881
|
path46.join(dir, DIST_DIR, ".output/zuplo.json"),
|
|
14802
14882
|
JSON.stringify({ issuer }, null, 2),
|
|
14803
14883
|
"utf-8"
|
|
@@ -14820,7 +14900,7 @@ var bundleSSREntry = async (options) => {
|
|
|
14820
14900
|
'"__BASE_PATH__"',
|
|
14821
14901
|
basePath ? JSON.stringify(basePath) : "undefined"
|
|
14822
14902
|
);
|
|
14823
|
-
await
|
|
14903
|
+
await writeFile13(tempEntryPath, entryContent, "utf-8");
|
|
14824
14904
|
try {
|
|
14825
14905
|
await esbuild({
|
|
14826
14906
|
entryPoints: [tempEntryPath],
|
|
@@ -14843,7 +14923,7 @@ init_package_json();
|
|
|
14843
14923
|
|
|
14844
14924
|
// src/cli/init/v2-packages.ts
|
|
14845
14925
|
import { existsSync as existsSync5 } from "node:fs";
|
|
14846
|
-
import { readFile as readFile11, writeFile as
|
|
14926
|
+
import { readFile as readFile11, writeFile as writeFile14 } from "node:fs/promises";
|
|
14847
14927
|
import path47 from "node:path";
|
|
14848
14928
|
var CORE_PACKAGES = [
|
|
14849
14929
|
"@lukoweb/apitogo",
|
|
@@ -14863,7 +14943,7 @@ function packageNameFrom(name) {
|
|
|
14863
14943
|
async function ensurePackageJson(dir, name) {
|
|
14864
14944
|
const file = path47.join(dir, "package.json");
|
|
14865
14945
|
if (existsSync5(file)) return false;
|
|
14866
|
-
await
|
|
14946
|
+
await writeFile14(
|
|
14867
14947
|
file,
|
|
14868
14948
|
`${JSON.stringify(
|
|
14869
14949
|
{
|
|
@@ -14946,17 +15026,21 @@ function portalBuildStep(context, options = {}, build2 = runBuild) {
|
|
|
14946
15026
|
),
|
|
14947
15027
|
run: async () => {
|
|
14948
15028
|
const originalCwd = process.cwd();
|
|
15029
|
+
const originalNodeEnv = process.env.NODE_ENV;
|
|
15030
|
+
process.env.NODE_ENV = "production";
|
|
14949
15031
|
process.chdir(root);
|
|
14950
15032
|
try {
|
|
14951
15033
|
await build2({ dir: root, jsonOnly: options.jsonOnly });
|
|
14952
15034
|
} finally {
|
|
14953
15035
|
process.chdir(originalCwd);
|
|
15036
|
+
if (originalNodeEnv === void 0) delete process.env.NODE_ENV;
|
|
15037
|
+
else process.env.NODE_ENV = originalNodeEnv;
|
|
14954
15038
|
}
|
|
14955
15039
|
await rm8(buildDir, { recursive: true, force: true });
|
|
14956
15040
|
await mkdir12(path48.dirname(buildDir), { recursive: true });
|
|
14957
15041
|
await rename6(path48.join(root, "dist"), buildDir);
|
|
14958
15042
|
if (prepared.publishedManifest) {
|
|
14959
|
-
await
|
|
15043
|
+
await writeFile15(
|
|
14960
15044
|
path48.join(buildDir, MANIFEST_FILE),
|
|
14961
15045
|
`${JSON.stringify(prepared.publishedManifest, null, 2)}
|
|
14962
15046
|
`
|
|
@@ -15970,6 +16054,56 @@ async function installMissingPackages(dir, config2, version, options) {
|
|
|
15970
16054
|
return { status: "installed", packages: missing, command: shown };
|
|
15971
16055
|
}
|
|
15972
16056
|
|
|
16057
|
+
// src/cli/services/prompter.ts
|
|
16058
|
+
import { createInterface as createInterface2 } from "node:readline/promises";
|
|
16059
|
+
var terminalQuestion = async (prompt) => {
|
|
16060
|
+
const rl = createInterface2({ input: process.stdin, output: process.stdout });
|
|
16061
|
+
try {
|
|
16062
|
+
return await rl.question(prompt);
|
|
16063
|
+
} finally {
|
|
16064
|
+
rl.close();
|
|
16065
|
+
}
|
|
16066
|
+
};
|
|
16067
|
+
function createAsker(question = terminalQuestion, say = (line2) => console.log(line2)) {
|
|
16068
|
+
return {
|
|
16069
|
+
async text(prompt, options) {
|
|
16070
|
+
for (; ; ) {
|
|
16071
|
+
const suffix = options?.default ? ` [${options.default}]` : "";
|
|
16072
|
+
const answer = (await question(`${prompt}${suffix}: `)).trim();
|
|
16073
|
+
const value = answer || options?.default || "";
|
|
16074
|
+
if (!value) {
|
|
16075
|
+
say("A value is needed.");
|
|
16076
|
+
continue;
|
|
16077
|
+
}
|
|
16078
|
+
const problem = options?.validate?.(value);
|
|
16079
|
+
if (problem) {
|
|
16080
|
+
say(problem);
|
|
16081
|
+
continue;
|
|
16082
|
+
}
|
|
16083
|
+
return value;
|
|
16084
|
+
}
|
|
16085
|
+
},
|
|
16086
|
+
async choose(prompt, choices) {
|
|
16087
|
+
say(prompt);
|
|
16088
|
+
choices.forEach((choice, index) => {
|
|
16089
|
+
say(` ${index + 1}) ${choice.label}`);
|
|
16090
|
+
});
|
|
16091
|
+
for (; ; ) {
|
|
16092
|
+
const answer = (await question(`Choose 1-${choices.length} [1]: `)).trim();
|
|
16093
|
+
const index = Number(answer || "1");
|
|
16094
|
+
const chosen = Number.isInteger(index) && index >= 1 && index <= choices.length ? choices[index - 1] : choices.find((choice) => choice.value === answer);
|
|
16095
|
+
if (chosen) return chosen.value;
|
|
16096
|
+
say(`Pick a number from 1 to ${choices.length}.`);
|
|
16097
|
+
}
|
|
16098
|
+
},
|
|
16099
|
+
async confirm(prompt, defaultYes = false) {
|
|
16100
|
+
const answer = (await question(`${prompt} (${defaultYes ? "Y/n" : "y/N"}) `)).trim().toLowerCase();
|
|
16101
|
+
if (!answer) return defaultYes;
|
|
16102
|
+
return answer === "y" || answer === "yes";
|
|
16103
|
+
}
|
|
16104
|
+
};
|
|
16105
|
+
}
|
|
16106
|
+
|
|
15973
16107
|
// src/cli/services/handler.ts
|
|
15974
16108
|
var list = (value) => {
|
|
15975
16109
|
const items = (Array.isArray(value) ? value : value === void 0 ? [] : [value]).filter(
|
|
@@ -16024,15 +16158,6 @@ function addOptionsFromArguments(service, argv) {
|
|
|
16024
16158
|
};
|
|
16025
16159
|
}
|
|
16026
16160
|
var canPrompt2 = (json) => !json && process.stdin.isTTY === true && process.stdout.isTTY === true;
|
|
16027
|
-
async function confirm(question) {
|
|
16028
|
-
const rl = createInterface2({ input: process.stdin, output: process.stdout });
|
|
16029
|
-
try {
|
|
16030
|
-
const answer = (await rl.question(question)).trim().toLowerCase();
|
|
16031
|
-
return answer === "y" || answer === "yes";
|
|
16032
|
-
} finally {
|
|
16033
|
-
rl.close();
|
|
16034
|
-
}
|
|
16035
|
-
}
|
|
16036
16161
|
function describe(edit, dir) {
|
|
16037
16162
|
return {
|
|
16038
16163
|
service: edit.service,
|
|
@@ -16044,6 +16169,7 @@ function describe(edit, dir) {
|
|
|
16044
16169
|
}
|
|
16045
16170
|
async function run(action, argv, plan2, deps = {}) {
|
|
16046
16171
|
const json = argv.json === true;
|
|
16172
|
+
const asker = argv.yes === true ? void 0 : deps.asker ?? (canPrompt2(json) ? createAsker() : void 0);
|
|
16047
16173
|
try {
|
|
16048
16174
|
if (!isServiceName(argv.service)) {
|
|
16049
16175
|
throw new ServiceEditError(
|
|
@@ -16058,7 +16184,28 @@ async function run(action, argv, plan2, deps = {}) {
|
|
|
16058
16184
|
"Create one with `apitogo init`."
|
|
16059
16185
|
);
|
|
16060
16186
|
}
|
|
16061
|
-
const
|
|
16187
|
+
const service = argv.service;
|
|
16188
|
+
let edit;
|
|
16189
|
+
for (let attempt = 0; edit === void 0; attempt++) {
|
|
16190
|
+
try {
|
|
16191
|
+
edit = await plan2(service, asker);
|
|
16192
|
+
} catch (error) {
|
|
16193
|
+
const missing = action === "add" && error instanceof ServiceEditError ? error.missingServices : [];
|
|
16194
|
+
if (missing.length === 0 || !asker || argv.dryRun || attempt >= 3)
|
|
16195
|
+
throw error;
|
|
16196
|
+
for (const needed2 of missing) {
|
|
16197
|
+
if (!await asker.confirm(
|
|
16198
|
+
`${service} needs ${needed2}. Add ${needed2} now?`,
|
|
16199
|
+
true
|
|
16200
|
+
))
|
|
16201
|
+
throw error;
|
|
16202
|
+
await addService(
|
|
16203
|
+
{ service: needed2, dir: argv.dir, install: argv.install },
|
|
16204
|
+
deps
|
|
16205
|
+
);
|
|
16206
|
+
}
|
|
16207
|
+
}
|
|
16208
|
+
}
|
|
16062
16209
|
const needed = action === "add" ? missingPackages(dir, packagesForConfig(edit.config)) : [];
|
|
16063
16210
|
if (!json) {
|
|
16064
16211
|
for (const line2 of formatServiceEdit(edit))
|
|
@@ -16079,13 +16226,13 @@ async function run(action, argv, plan2, deps = {}) {
|
|
|
16079
16226
|
return;
|
|
16080
16227
|
}
|
|
16081
16228
|
if (argv.yes !== true) {
|
|
16082
|
-
if (!
|
|
16229
|
+
if (!asker) {
|
|
16083
16230
|
throw new ServiceEditError(
|
|
16084
16231
|
"This is not an interactive terminal.",
|
|
16085
16232
|
"Pass --yes to apply the change, or --dry-run to only see it."
|
|
16086
16233
|
);
|
|
16087
16234
|
}
|
|
16088
|
-
if (!await confirm("Apply this change?
|
|
16235
|
+
if (!await asker.confirm("Apply this change?")) {
|
|
16089
16236
|
printResultToConsole("Cancelled. Nothing was written.");
|
|
16090
16237
|
return;
|
|
16091
16238
|
}
|
|
@@ -16159,7 +16306,10 @@ async function installPackages(dir, edit, argv, deps, json) {
|
|
|
16159
16306
|
var addService = (argv, deps = {}) => run(
|
|
16160
16307
|
"add",
|
|
16161
16308
|
argv,
|
|
16162
|
-
(service) => planAddService(service,
|
|
16309
|
+
(service, ask4) => planAddService(service, {
|
|
16310
|
+
...addOptionsFromArguments(service, argv),
|
|
16311
|
+
ask: ask4
|
|
16312
|
+
}),
|
|
16163
16313
|
deps
|
|
16164
16314
|
);
|
|
16165
16315
|
var removeService = (argv) => run(
|
|
@@ -16518,7 +16668,7 @@ function formatDevPortalBackendResponse(projectId, backend) {
|
|
|
16518
16668
|
// src/cli/platform/helpers/dev-portal-manifest.ts
|
|
16519
16669
|
init_gateway_limits();
|
|
16520
16670
|
import { existsSync as existsSync7 } from "node:fs";
|
|
16521
|
-
import { access as access6, mkdir as mkdir13, readFile as readFile17, writeFile as
|
|
16671
|
+
import { access as access6, mkdir as mkdir13, readFile as readFile17, writeFile as writeFile16 } from "node:fs/promises";
|
|
16522
16672
|
import path57 from "node:path";
|
|
16523
16673
|
|
|
16524
16674
|
// src/cli/make-config/json-config.ts
|
|
@@ -17838,7 +17988,7 @@ async function writeManifest2(siteDirectory, manifest) {
|
|
|
17838
17988
|
...safeManifest
|
|
17839
17989
|
} = manifest;
|
|
17840
17990
|
config2 = applyManifestToConfig(config2, safeManifest);
|
|
17841
|
-
await
|
|
17991
|
+
await writeFile16(filePath, `${JSON.stringify(config2, null, 2)}
|
|
17842
17992
|
`, "utf8");
|
|
17843
17993
|
return filePath;
|
|
17844
17994
|
}
|
|
@@ -17850,7 +18000,7 @@ import {
|
|
|
17850
18000
|
mkdir as mkdir14,
|
|
17851
18001
|
readFile as readFile18,
|
|
17852
18002
|
unlink,
|
|
17853
|
-
writeFile as
|
|
18003
|
+
writeFile as writeFile17
|
|
17854
18004
|
} from "node:fs/promises";
|
|
17855
18005
|
import path58 from "node:path";
|
|
17856
18006
|
var ENV_FILENAME = ".env";
|
|
@@ -18125,7 +18275,7 @@ async function writeScaffoldEnv(siteDirectory) {
|
|
|
18125
18275
|
await access7(envPath);
|
|
18126
18276
|
} catch {
|
|
18127
18277
|
await mkdir14(resolvedDirectory, { recursive: true });
|
|
18128
|
-
await
|
|
18278
|
+
await writeFile17(envPath, createEnvContent(), "utf8");
|
|
18129
18279
|
filesWritten.push(ENV_FILENAME);
|
|
18130
18280
|
}
|
|
18131
18281
|
for (const legacyName of [".env.example"]) {
|
|
@@ -18154,7 +18304,7 @@ async function writeScaffoldEnv(siteDirectory) {
|
|
|
18154
18304
|
if (!hasEntry) {
|
|
18155
18305
|
const suffix = gitignore.length === 0 ? "" : gitignore.endsWith("\n") ? "" : "\n";
|
|
18156
18306
|
if (gitignore.length === 0) {
|
|
18157
|
-
await
|
|
18307
|
+
await writeFile17(gitignorePath, `${entry}
|
|
18158
18308
|
`, "utf8");
|
|
18159
18309
|
} else {
|
|
18160
18310
|
await appendFile(gitignorePath, `${suffix}${entry}
|
|
@@ -18938,7 +19088,7 @@ var check_default = {
|
|
|
18938
19088
|
|
|
18939
19089
|
// src/cli/make-config/handler.ts
|
|
18940
19090
|
import { constants as constants2 } from "node:fs";
|
|
18941
|
-
import { access as access12, mkdir as mkdir17, readFile as readFile24, writeFile as
|
|
19091
|
+
import { access as access12, mkdir as mkdir17, readFile as readFile24, writeFile as writeFile22 } from "node:fs/promises";
|
|
18942
19092
|
import path71 from "node:path";
|
|
18943
19093
|
import { stdin as input2 } from "node:process";
|
|
18944
19094
|
import { glob as glob8 } from "glob";
|
|
@@ -19078,12 +19228,12 @@ function withDefaultIncludedActionKeys(plan2, actionKeys) {
|
|
|
19078
19228
|
}
|
|
19079
19229
|
|
|
19080
19230
|
// src/cli/scaffold/dev-portal-config-pages.ts
|
|
19081
|
-
import { access as access8, readFile as readFile20, rename as rename7, rm as rm9, writeFile as
|
|
19231
|
+
import { access as access8, readFile as readFile20, rename as rename7, rm as rm9, writeFile as writeFile18 } from "node:fs/promises";
|
|
19082
19232
|
import path63 from "node:path";
|
|
19083
19233
|
async function writeConfigAtomically(filePath, content) {
|
|
19084
19234
|
const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
19085
19235
|
try {
|
|
19086
|
-
await
|
|
19236
|
+
await writeFile18(temporaryPath, content, "utf8");
|
|
19087
19237
|
await rename7(temporaryPath, filePath);
|
|
19088
19238
|
} catch (error) {
|
|
19089
19239
|
await rm9(temporaryPath, { force: true });
|
|
@@ -19855,7 +20005,7 @@ async function wireNewDevPortalPageInConfig(sourceDirectory, slug, label2) {
|
|
|
19855
20005
|
}
|
|
19856
20006
|
|
|
19857
20007
|
// src/cli/scaffold/wire-openapi.ts
|
|
19858
|
-
import { access as access10, readFile as readFile22, writeFile as
|
|
20008
|
+
import { access as access10, readFile as readFile22, writeFile as writeFile20 } from "node:fs/promises";
|
|
19859
20009
|
import path68 from "node:path";
|
|
19860
20010
|
|
|
19861
20011
|
// src/cli/platform/helpers/openapi.ts
|
|
@@ -20059,7 +20209,7 @@ async function validateOpenApiFile(filePath) {
|
|
|
20059
20209
|
}
|
|
20060
20210
|
|
|
20061
20211
|
// src/cli/scaffold/scaffold-dev-portal-site.ts
|
|
20062
|
-
import { mkdir as mkdir15, readFile as readFile21, writeFile as
|
|
20212
|
+
import { mkdir as mkdir15, readFile as readFile21, writeFile as writeFile19 } from "node:fs/promises";
|
|
20063
20213
|
import path67 from "node:path";
|
|
20064
20214
|
|
|
20065
20215
|
// src/cli/scaffold/apitogo-npm-packages.ts
|
|
@@ -20471,7 +20621,7 @@ async function ensureAccountPlansPage(outputDirectory) {
|
|
|
20471
20621
|
return void 0;
|
|
20472
20622
|
} catch {
|
|
20473
20623
|
await mkdir15(path67.dirname(pagePath), { recursive: true });
|
|
20474
|
-
await
|
|
20624
|
+
await writeFile19(pagePath, ACCOUNT_PLANS_PAGE);
|
|
20475
20625
|
return ACCOUNT_PLANS_PAGE_PATH;
|
|
20476
20626
|
}
|
|
20477
20627
|
}
|
|
@@ -20482,7 +20632,7 @@ async function ensureDashboardPage(outputDirectory) {
|
|
|
20482
20632
|
return void 0;
|
|
20483
20633
|
} catch {
|
|
20484
20634
|
await mkdir15(path67.dirname(pagePath), { recursive: true });
|
|
20485
|
-
await
|
|
20635
|
+
await writeFile19(pagePath, DASHBOARD_PAGE);
|
|
20486
20636
|
return DASHBOARD_PAGE_PATH;
|
|
20487
20637
|
}
|
|
20488
20638
|
}
|
|
@@ -20541,7 +20691,7 @@ async function patchScaffoldedSite(outputDirectory, options) {
|
|
|
20541
20691
|
const packageJsonPath = path67.join(outputDirectory, "package.json");
|
|
20542
20692
|
if (options.patchPackageJson !== false) {
|
|
20543
20693
|
const packageJson3 = await readFile21(packageJsonPath, "utf8");
|
|
20544
|
-
await
|
|
20694
|
+
await writeFile19(
|
|
20545
20695
|
packageJsonPath,
|
|
20546
20696
|
rewritePackageJson(packageJson3, {
|
|
20547
20697
|
siteName: options.siteName,
|
|
@@ -20553,7 +20703,7 @@ async function patchScaffoldedSite(outputDirectory, options) {
|
|
|
20553
20703
|
}
|
|
20554
20704
|
const configPath = path67.join(outputDirectory, "apitogo.config.tsx");
|
|
20555
20705
|
const configContent = await readFile21(configPath, "utf8");
|
|
20556
|
-
await
|
|
20706
|
+
await writeFile19(
|
|
20557
20707
|
configPath,
|
|
20558
20708
|
patchDashboardPageConfig(
|
|
20559
20709
|
patchAccountPlansPageConfig(
|
|
@@ -20665,7 +20815,7 @@ async function wireDevPortalOpenApi(sourceDirectory, openApiPath) {
|
|
|
20665
20815
|
input: input5,
|
|
20666
20816
|
apiPath: "api"
|
|
20667
20817
|
});
|
|
20668
|
-
await
|
|
20818
|
+
await writeFile20(
|
|
20669
20819
|
jsonConfigPath,
|
|
20670
20820
|
`${JSON.stringify(updated, null, 2)}
|
|
20671
20821
|
`,
|
|
@@ -20676,7 +20826,7 @@ async function wireDevPortalOpenApi(sourceDirectory, openApiPath) {
|
|
|
20676
20826
|
const configContent = await readFile22(tsxConfigPath, "utf8");
|
|
20677
20827
|
try {
|
|
20678
20828
|
const patched = patchApitogoConfigOpenApiToFile(configContent, input5);
|
|
20679
|
-
await
|
|
20829
|
+
await writeFile20(tsxConfigPath, patched);
|
|
20680
20830
|
} catch (error) {
|
|
20681
20831
|
return {
|
|
20682
20832
|
status: "failed",
|
|
@@ -21029,7 +21179,7 @@ export default function ${componentName}() {
|
|
|
21029
21179
|
// src/cli/make-config/scaffold-project.ts
|
|
21030
21180
|
init_package_json();
|
|
21031
21181
|
import { constants } from "node:fs";
|
|
21032
|
-
import { access as access11, mkdir as mkdir16, readFile as readFile23, writeFile as
|
|
21182
|
+
import { access as access11, mkdir as mkdir16, readFile as readFile23, writeFile as writeFile21 } from "node:fs/promises";
|
|
21033
21183
|
import path70 from "node:path";
|
|
21034
21184
|
import { glob as glob7 } from "glob";
|
|
21035
21185
|
|
|
@@ -21107,7 +21257,7 @@ async function ensurePackageJson2(dir) {
|
|
|
21107
21257
|
typescript: "^5"
|
|
21108
21258
|
}
|
|
21109
21259
|
};
|
|
21110
|
-
await
|
|
21260
|
+
await writeFile21(pkgPath, `${JSON.stringify(pkg2, null, 2)}
|
|
21111
21261
|
`, "utf8");
|
|
21112
21262
|
return true;
|
|
21113
21263
|
}
|
|
@@ -21134,7 +21284,7 @@ async function ensurePackageJson2(dir) {
|
|
|
21134
21284
|
for (const [k, v] of Object.entries(baseDeps)) {
|
|
21135
21285
|
if (!deps[k]) deps[k] = v;
|
|
21136
21286
|
}
|
|
21137
|
-
await
|
|
21287
|
+
await writeFile21(pkgPath, `${JSON.stringify(pkg, null, 2)}
|
|
21138
21288
|
`, "utf8");
|
|
21139
21289
|
return false;
|
|
21140
21290
|
}
|
|
@@ -21169,7 +21319,7 @@ async function ensureTsconfigJson(dir) {
|
|
|
21169
21319
|
"user-panel"
|
|
21170
21320
|
]
|
|
21171
21321
|
};
|
|
21172
|
-
await
|
|
21322
|
+
await writeFile21(tsPath, `${JSON.stringify(tsconfig, null, 2)}
|
|
21173
21323
|
`, "utf8");
|
|
21174
21324
|
return true;
|
|
21175
21325
|
}
|
|
@@ -21191,17 +21341,17 @@ async function ensurePortalStubFiles(dir) {
|
|
|
21191
21341
|
const landingPath = path70.join(dir, "landing", "LandingPage.tsx");
|
|
21192
21342
|
if (!await fileExists2(landingPath)) {
|
|
21193
21343
|
await mkdir16(path70.join(dir, "landing"), { recursive: true });
|
|
21194
|
-
await
|
|
21344
|
+
await writeFile21(landingPath, LANDING_PAGE_SOURCE, "utf8");
|
|
21195
21345
|
}
|
|
21196
21346
|
const plansPath = path70.join(dir, "user-panel", "AccountPlansPage.tsx");
|
|
21197
21347
|
if (!await fileExists2(plansPath)) {
|
|
21198
21348
|
await mkdir16(path70.join(dir, "user-panel"), { recursive: true });
|
|
21199
|
-
await
|
|
21349
|
+
await writeFile21(plansPath, ACCOUNT_PLANS_PAGE_SOURCE, "utf8");
|
|
21200
21350
|
}
|
|
21201
21351
|
const dashboardPath = path70.join(dir, "user-panel", "DashboardPage.tsx");
|
|
21202
21352
|
if (!await fileExists2(dashboardPath)) {
|
|
21203
21353
|
await mkdir16(path70.join(dir, "user-panel"), { recursive: true });
|
|
21204
|
-
await
|
|
21354
|
+
await writeFile21(dashboardPath, DASHBOARD_PAGE_SOURCE, "utf8");
|
|
21205
21355
|
}
|
|
21206
21356
|
await ensurePublicBrandingFiles(dir);
|
|
21207
21357
|
}
|
|
@@ -21213,11 +21363,11 @@ async function ensurePublicBrandingFiles(dir) {
|
|
|
21213
21363
|
if (await fileExists2(dest)) {
|
|
21214
21364
|
continue;
|
|
21215
21365
|
}
|
|
21216
|
-
await
|
|
21366
|
+
await writeFile21(dest, content, "utf8");
|
|
21217
21367
|
}
|
|
21218
21368
|
const faviconDest = path70.join(destDir, "Icon.png");
|
|
21219
21369
|
if (!await fileExists2(faviconDest)) {
|
|
21220
|
-
await
|
|
21370
|
+
await writeFile21(faviconDest, Buffer.from(FAVICON_PNG_BASE64, "base64"));
|
|
21221
21371
|
}
|
|
21222
21372
|
}
|
|
21223
21373
|
async function ensureThinConfigTsx(dir) {
|
|
@@ -21225,7 +21375,7 @@ async function ensureThinConfigTsx(dir) {
|
|
|
21225
21375
|
if (await fileExists2(tsxPath)) {
|
|
21226
21376
|
return false;
|
|
21227
21377
|
}
|
|
21228
|
-
await
|
|
21378
|
+
await writeFile21(tsxPath, THIN_WRAPPER_SOURCE, "utf8");
|
|
21229
21379
|
return true;
|
|
21230
21380
|
}
|
|
21231
21381
|
|
|
@@ -21286,13 +21436,13 @@ async function persistConfig(config2, ctx) {
|
|
|
21286
21436
|
force: ctx.force
|
|
21287
21437
|
})
|
|
21288
21438
|
};
|
|
21289
|
-
await
|
|
21439
|
+
await writeFile22(ctx.jsonPath, `${JSON.stringify(next, null, 2)}
|
|
21290
21440
|
`, "utf8");
|
|
21291
21441
|
const tsxPath = path71.join(ctx.dir, "apitogo.config.tsx");
|
|
21292
21442
|
if (await fileExists3(tsxPath) && tsxRoutes.length > 0) {
|
|
21293
21443
|
const tsxSource = await readFile24(tsxPath, "utf8");
|
|
21294
21444
|
if (isManagedConfigWrapper(tsxSource)) {
|
|
21295
|
-
await
|
|
21445
|
+
await writeFile22(
|
|
21296
21446
|
tsxPath,
|
|
21297
21447
|
buildThinWrapperWithCustomPages(tsxRoutes),
|
|
21298
21448
|
"utf8"
|
|
@@ -21396,7 +21546,7 @@ async function makeConfig(argv) {
|
|
|
21396
21546
|
if (action2.kind === "page") {
|
|
21397
21547
|
const pagePath = path71.join(dir, action2.page.relativePath);
|
|
21398
21548
|
await mkdir17(path71.dirname(pagePath), { recursive: true });
|
|
21399
|
-
await
|
|
21549
|
+
await writeFile22(
|
|
21400
21550
|
pagePath,
|
|
21401
21551
|
buildStarterDocsPageTsx(action2.page.slug, action2.page.title),
|
|
21402
21552
|
"utf8"
|
|
@@ -21505,7 +21655,7 @@ async function makeConfig(argv) {
|
|
|
21505
21655
|
argv.pageContent,
|
|
21506
21656
|
pageTemplate
|
|
21507
21657
|
);
|
|
21508
|
-
await
|
|
21658
|
+
await writeFile22(filePath, tsx, "utf8");
|
|
21509
21659
|
pageResult = {
|
|
21510
21660
|
action: "updated",
|
|
21511
21661
|
slug,
|
|
@@ -21525,7 +21675,7 @@ async function makeConfig(argv) {
|
|
|
21525
21675
|
pageTemplate
|
|
21526
21676
|
);
|
|
21527
21677
|
await mkdir17(path71.dirname(filePath), { recursive: true });
|
|
21528
|
-
await
|
|
21678
|
+
await writeFile22(filePath, tsx, "utf8");
|
|
21529
21679
|
const configResult = await wireNewDevPortalPageInConfig(
|
|
21530
21680
|
dir,
|
|
21531
21681
|
slug,
|
|
@@ -21874,9 +22024,10 @@ var DEFAULT_EXCLUDES = /* @__PURE__ */ new Set([
|
|
|
21874
22024
|
"bin",
|
|
21875
22025
|
"obj"
|
|
21876
22026
|
]);
|
|
21877
|
-
async function loadGitignore(rootDir) {
|
|
22027
|
+
async function loadGitignore(rootDir, extraExcludes = []) {
|
|
21878
22028
|
const ig = ignore();
|
|
21879
22029
|
ig.add(["node_modules/", ".git/", "dist/", "bin/", "obj/"]);
|
|
22030
|
+
if (extraExcludes.length > 0) ig.add([...extraExcludes]);
|
|
21880
22031
|
const gitignorePath = path72.join(rootDir, ".gitignore");
|
|
21881
22032
|
try {
|
|
21882
22033
|
const content = await fs7.readFile(gitignorePath, "utf8");
|
|
@@ -21904,13 +22055,13 @@ async function collectFiles(rootDir, relativeDir, ig, files) {
|
|
|
21904
22055
|
}
|
|
21905
22056
|
}
|
|
21906
22057
|
}
|
|
21907
|
-
async function collectPackageableFiles(sourceDirectory) {
|
|
22058
|
+
async function collectPackageableFiles(sourceDirectory, extraExcludes = []) {
|
|
21908
22059
|
const resolved = path72.resolve(sourceDirectory);
|
|
21909
22060
|
const stat7 = await fs7.stat(resolved).catch(() => null);
|
|
21910
22061
|
if (!stat7?.isDirectory()) {
|
|
21911
22062
|
throw new Error(`sourceDirectory is not a directory: ${resolved}`);
|
|
21912
22063
|
}
|
|
21913
|
-
const ig = await loadGitignore(resolved);
|
|
22064
|
+
const ig = await loadGitignore(resolved, extraExcludes);
|
|
21914
22065
|
const files = [];
|
|
21915
22066
|
await collectFiles(resolved, "", ig, files);
|
|
21916
22067
|
if (files.length === 0) {
|
|
@@ -21930,9 +22081,9 @@ async function sha256File(filePath) {
|
|
|
21930
22081
|
});
|
|
21931
22082
|
return hash2.digest("hex");
|
|
21932
22083
|
}
|
|
21933
|
-
async function hashDirectoryContents(rootDirectory) {
|
|
22084
|
+
async function hashDirectoryContents(rootDirectory, extraExcludes = []) {
|
|
21934
22085
|
const resolved = path73.resolve(rootDirectory);
|
|
21935
|
-
const files = (await collectPackageableFiles(resolved)).sort(
|
|
22086
|
+
const files = (await collectPackageableFiles(resolved, extraExcludes)).sort(
|
|
21936
22087
|
(a, b) => a.localeCompare(b)
|
|
21937
22088
|
);
|
|
21938
22089
|
const hash2 = createHash3("sha256");
|
|
@@ -22683,7 +22834,7 @@ async function upsertGatewayPlansFromManifest(client, config2, projectId, plans,
|
|
|
22683
22834
|
}
|
|
22684
22835
|
|
|
22685
22836
|
// src/cli/platform/helpers/openapi-gateway-servers.ts
|
|
22686
|
-
import { mkdir as mkdir18, readFile as readFile25, writeFile as
|
|
22837
|
+
import { mkdir as mkdir18, readFile as readFile25, writeFile as writeFile23 } from "node:fs/promises";
|
|
22687
22838
|
import path74 from "node:path";
|
|
22688
22839
|
import YAML3 from "yaml";
|
|
22689
22840
|
var GATEWAY_URL_ENV_KEY = "APITOGO_GATEWAY_URL";
|
|
@@ -22731,7 +22882,7 @@ async function materializePublishOpenApiWithGateway(siteDirectory, sourceOpenApi
|
|
|
22731
22882
|
const doc = await readOpenApiDocument(source);
|
|
22732
22883
|
const rewritten = withGatewayServers(doc, gatewayUrl);
|
|
22733
22884
|
await mkdir18(path74.dirname(outputPath), { recursive: true });
|
|
22734
|
-
await
|
|
22885
|
+
await writeFile23(
|
|
22735
22886
|
outputPath,
|
|
22736
22887
|
`${JSON.stringify(rewritten, null, 2)}
|
|
22737
22888
|
`,
|
|
@@ -22757,7 +22908,7 @@ async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
|
|
|
22757
22908
|
const backend = config2.backend && typeof config2.backend === "object" ? { ...config2.backend } : {};
|
|
22758
22909
|
backend.openApiPath = relativeInput;
|
|
22759
22910
|
config2.backend = backend;
|
|
22760
|
-
await
|
|
22911
|
+
await writeFile23(configPath, `${JSON.stringify(config2, null, 2)}
|
|
22761
22912
|
`, "utf8");
|
|
22762
22913
|
return {
|
|
22763
22914
|
restore: async () => {
|
|
@@ -22773,7 +22924,7 @@ async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
|
|
|
22773
22924
|
} else {
|
|
22774
22925
|
current.backend = previousBackend;
|
|
22775
22926
|
}
|
|
22776
|
-
await
|
|
22927
|
+
await writeFile23(
|
|
22777
22928
|
configPath,
|
|
22778
22929
|
`${JSON.stringify(current, null, 2)}
|
|
22779
22930
|
`,
|
|
@@ -22870,7 +23021,7 @@ function collectManifestPublicActionKeys(gateway) {
|
|
|
22870
23021
|
}
|
|
22871
23022
|
|
|
22872
23023
|
// src/cli/platform/helpers/publish-ledger.ts
|
|
22873
|
-
import { mkdir as mkdir19, readFile as readFile26, writeFile as
|
|
23024
|
+
import { mkdir as mkdir19, readFile as readFile26, writeFile as writeFile24 } from "node:fs/promises";
|
|
22874
23025
|
import path75 from "node:path";
|
|
22875
23026
|
var PUBLISH_LEDGER_RELATIVE_PATH = ".apitogo/publish-state.json";
|
|
22876
23027
|
function publishLedgerPath(siteDirectory) {
|
|
@@ -22897,7 +23048,7 @@ async function writePublishLedger(siteDirectory, ledger) {
|
|
|
22897
23048
|
version: 1,
|
|
22898
23049
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
22899
23050
|
};
|
|
22900
|
-
await
|
|
23051
|
+
await writeFile24(filePath, `${JSON.stringify(next, null, 2)}
|
|
22901
23052
|
`, "utf8");
|
|
22902
23053
|
return filePath;
|
|
22903
23054
|
}
|
|
@@ -23531,9 +23682,9 @@ import { createReadStream as createReadStream2, createWriteStream as createWrite
|
|
|
23531
23682
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
23532
23683
|
import path77 from "node:path";
|
|
23533
23684
|
import { ZipArchive } from "archiver";
|
|
23534
|
-
async function packageBackendDirectory(sourceDirectory) {
|
|
23685
|
+
async function packageBackendDirectory(sourceDirectory, extraExcludes = []) {
|
|
23535
23686
|
const resolved = path77.resolve(sourceDirectory);
|
|
23536
|
-
const files = await collectPackageableFiles(resolved);
|
|
23687
|
+
const files = await collectPackageableFiles(resolved, extraExcludes);
|
|
23537
23688
|
const zipPath = path77.join(
|
|
23538
23689
|
tmpdir2(),
|
|
23539
23690
|
`apitogo-backend-${Date.now()}-${Math.random().toString(36).slice(2)}.zip`
|
|
@@ -25058,7 +25209,7 @@ async function resolveProjectIdForPublish(client, config2, args, wait, progress,
|
|
|
25058
25209
|
import path81 from "node:path";
|
|
25059
25210
|
|
|
25060
25211
|
// src/cli/platform/helpers/dev-portal-site-api-url.ts
|
|
25061
|
-
import { readdir as readdir3, readFile as readFile27, writeFile as
|
|
25212
|
+
import { readdir as readdir3, readFile as readFile27, writeFile as writeFile25 } from "node:fs/promises";
|
|
25062
25213
|
import path78 from "node:path";
|
|
25063
25214
|
var SITE_API_BASE_URL_ENV_KEY = "VITE_APITOGO_AUTHENTICATION_API_BASE_URL";
|
|
25064
25215
|
var PLACEHOLDER_HOST_MARKERS = [
|
|
@@ -25120,13 +25271,13 @@ async function patchSiteApiBaseUrl(sourceDirectory, apiBaseUrl) {
|
|
|
25120
25271
|
${line2}
|
|
25121
25272
|
` : `${line2}
|
|
25122
25273
|
`;
|
|
25123
|
-
await
|
|
25274
|
+
await writeFile25(envPath, patched);
|
|
25124
25275
|
patchedExisting = true;
|
|
25125
25276
|
} catch {
|
|
25126
25277
|
}
|
|
25127
25278
|
}
|
|
25128
25279
|
if (!patchedExisting) {
|
|
25129
|
-
await
|
|
25280
|
+
await writeFile25(path78.join(resolved, ".env"), `${line2}
|
|
25130
25281
|
`);
|
|
25131
25282
|
}
|
|
25132
25283
|
}
|
|
@@ -27344,19 +27495,11 @@ var GatewayDeployError = class extends ApitogoError {
|
|
|
27344
27495
|
};
|
|
27345
27496
|
var sha256 = (text) => createHash4("sha256").update(text).digest("hex");
|
|
27346
27497
|
function gatewayNotDeployableReason(gateway) {
|
|
27347
|
-
if (gateway.origin.mode === "managed")
|
|
27348
|
-
return "a managed origin cannot be deployed from this CLI version yet; use origin.mode proxy";
|
|
27349
27498
|
if (gateway.specs.length > 1)
|
|
27350
27499
|
return "the platform takes one OpenAPI file per gateway, but the config lists several";
|
|
27351
27500
|
return void 0;
|
|
27352
27501
|
}
|
|
27353
27502
|
function assertDeployable(gateway) {
|
|
27354
|
-
if (gateway.origin.mode === "managed")
|
|
27355
|
-
throw new GatewayDeployError(
|
|
27356
|
-
"GATEWAY_MANAGED_ORIGIN_UNSUPPORTED",
|
|
27357
|
-
"A managed origin cannot be deployed from this CLI version yet.",
|
|
27358
|
-
'Set gateway.origin.mode to "proxy" and point gateway.origin.url at your API.'
|
|
27359
|
-
);
|
|
27360
27503
|
if (gateway.specs.length > 1)
|
|
27361
27504
|
throw new GatewayDeployError(
|
|
27362
27505
|
"GATEWAY_MULTIPLE_SPECS",
|
|
@@ -27403,6 +27546,37 @@ async function gatewayDeployInputs(resolved, projectId) {
|
|
|
27403
27546
|
};
|
|
27404
27547
|
}
|
|
27405
27548
|
var defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
27549
|
+
async function backendDeployInputs(gateway, projectId) {
|
|
27550
|
+
const { origin } = gateway;
|
|
27551
|
+
if (origin.mode !== "managed" || !origin.source || !origin.runtime || !origin.runtimeVersion)
|
|
27552
|
+
return void 0;
|
|
27553
|
+
const runtime = normalizeRuntime(origin.runtime);
|
|
27554
|
+
const runtimeVersion = normalizeRuntimeVersionSlug(
|
|
27555
|
+
runtime,
|
|
27556
|
+
origin.runtimeVersion
|
|
27557
|
+
);
|
|
27558
|
+
const exclude = origin.exclude ?? [];
|
|
27559
|
+
let tree;
|
|
27560
|
+
try {
|
|
27561
|
+
tree = await hashDirectoryContents(origin.source, exclude);
|
|
27562
|
+
} catch (error) {
|
|
27563
|
+
throw new GatewayDeployError(
|
|
27564
|
+
"GATEWAY_BACKEND_UNREADABLE",
|
|
27565
|
+
`Cannot read the backend source ${origin.source}: ${error instanceof Error ? error.message : String(error)}`,
|
|
27566
|
+
"Check gateway.origin.source in the config. It must be a folder with your API's code."
|
|
27567
|
+
);
|
|
27568
|
+
}
|
|
27569
|
+
return {
|
|
27570
|
+
source: origin.source,
|
|
27571
|
+
runtime,
|
|
27572
|
+
runtimeVersion,
|
|
27573
|
+
exclude,
|
|
27574
|
+
healthPath: origin.healthPath,
|
|
27575
|
+
hash: sha256(
|
|
27576
|
+
`${projectId}|${runtime}|${runtimeVersion}|${origin.healthPath ?? ""}|${stableJson(exclude)}|${tree}`
|
|
27577
|
+
)
|
|
27578
|
+
};
|
|
27579
|
+
}
|
|
27406
27580
|
function describePlatformProblem(error) {
|
|
27407
27581
|
if (!(error instanceof PlatformApiError) || !error.problem) return [];
|
|
27408
27582
|
const errors = error.problem.errors;
|
|
@@ -27438,11 +27612,73 @@ function rejected(what, error) {
|
|
|
27438
27612
|
async function deployGateway(resolved, projectId, deps, options = {}) {
|
|
27439
27613
|
const { gateway, spec, body, specHash, configHash } = await gatewayDeployInputs(resolved, projectId);
|
|
27440
27614
|
assertDeployable(gateway);
|
|
27615
|
+
const backend = await backendDeployInputs(gateway, projectId);
|
|
27441
27616
|
const client = deps.client;
|
|
27442
27617
|
const sleep5 = deps.sleep ?? defaultSleep;
|
|
27443
27618
|
const now = deps.now ?? Date.now;
|
|
27444
27619
|
const timeoutMs = deps.reconcileTimeoutMs ?? 18e4;
|
|
27620
|
+
const backendTimeoutMs = deps.backendTimeoutMs ?? 20 * 6e4;
|
|
27445
27621
|
const intervalMs = deps.pollIntervalMs ?? 2e3;
|
|
27622
|
+
const backendStep = {
|
|
27623
|
+
name: "backend",
|
|
27624
|
+
hash: () => backend?.hash ?? "",
|
|
27625
|
+
run: async () => {
|
|
27626
|
+
if (!backend) throw new Error("gateway.origin is not a managed origin");
|
|
27627
|
+
const prepared = await prepareBackendPackagingDirectory({
|
|
27628
|
+
sourceDirectory: backend.source,
|
|
27629
|
+
runtime: backend.runtime
|
|
27630
|
+
});
|
|
27631
|
+
let zipPath;
|
|
27632
|
+
try {
|
|
27633
|
+
const packaged = await packageBackendDirectory(
|
|
27634
|
+
prepared.directory,
|
|
27635
|
+
backend.exclude
|
|
27636
|
+
);
|
|
27637
|
+
zipPath = packaged.zipPath;
|
|
27638
|
+
let started;
|
|
27639
|
+
try {
|
|
27640
|
+
started = await client.deployBackend(projectId, {
|
|
27641
|
+
archivePath: packaged.zipPath,
|
|
27642
|
+
runtime: backend.runtime,
|
|
27643
|
+
runtimeVersion: backend.runtimeVersion,
|
|
27644
|
+
healthCheckPath: backend.healthPath
|
|
27645
|
+
});
|
|
27646
|
+
} catch (error) {
|
|
27647
|
+
return rejected("backend upload", error);
|
|
27648
|
+
}
|
|
27649
|
+
if (!started.reused) {
|
|
27650
|
+
const deadline = now() + backendTimeoutMs;
|
|
27651
|
+
for (; ; ) {
|
|
27652
|
+
const state = await client.getDeploymentStatus(
|
|
27653
|
+
projectId,
|
|
27654
|
+
started.deploymentId
|
|
27655
|
+
);
|
|
27656
|
+
if (state.status.toLowerCase() === "healthy") break;
|
|
27657
|
+
if (isTerminalDeploymentStatus(state.status))
|
|
27658
|
+
throw new GatewayDeployError(
|
|
27659
|
+
"GATEWAY_BACKEND_FAILED",
|
|
27660
|
+
`The platform could not deploy your backend (${state.status}): ${state.error ?? state.messages.at(-1)?.message ?? "no reason given"}.`,
|
|
27661
|
+
"Fix the cause and run deploy again; the backend is uploaded again."
|
|
27662
|
+
);
|
|
27663
|
+
if (now() >= deadline)
|
|
27664
|
+
throw new GatewayDeployError(
|
|
27665
|
+
"GATEWAY_BACKEND_TIMEOUT",
|
|
27666
|
+
`Your backend was not ready within ${Math.round(backendTimeoutMs / 6e4)} minutes (state: ${state.status}).`,
|
|
27667
|
+
"Run deploy again to keep waiting."
|
|
27668
|
+
);
|
|
27669
|
+
await sleep5(intervalMs);
|
|
27670
|
+
}
|
|
27671
|
+
}
|
|
27672
|
+
return {
|
|
27673
|
+
deploymentId: started.deploymentId,
|
|
27674
|
+
...started.artifactContentSha256 ? { artifactSha256: started.artifactContentSha256 } : {}
|
|
27675
|
+
};
|
|
27676
|
+
} finally {
|
|
27677
|
+
if (zipPath) await cleanupZip(zipPath);
|
|
27678
|
+
await prepared.cleanup?.();
|
|
27679
|
+
}
|
|
27680
|
+
}
|
|
27681
|
+
};
|
|
27446
27682
|
const specStep = {
|
|
27447
27683
|
name: "spec",
|
|
27448
27684
|
hash: () => specHash,
|
|
@@ -27522,12 +27758,30 @@ async function deployGateway(resolved, projectId, deps, options = {}) {
|
|
|
27522
27758
|
};
|
|
27523
27759
|
}
|
|
27524
27760
|
};
|
|
27525
|
-
|
|
27526
|
-
|
|
27527
|
-
|
|
27528
|
-
|
|
27529
|
-
|
|
27530
|
-
|
|
27761
|
+
let outcomes;
|
|
27762
|
+
if (backend) {
|
|
27763
|
+
const head = await runPipeline(
|
|
27764
|
+
resolved.state,
|
|
27765
|
+
"gateway",
|
|
27766
|
+
[specStep, configStep],
|
|
27767
|
+
{ force: options.force }
|
|
27768
|
+
);
|
|
27769
|
+
const middle = await runPipeline(resolved.state, "gateway", [backendStep], {
|
|
27770
|
+
force: options.force
|
|
27771
|
+
});
|
|
27772
|
+
const changed = [...head, ...middle].some((outcome) => !outcome.skipped);
|
|
27773
|
+
const tail = await runPipeline(resolved.state, "gateway", [reconcileStep], {
|
|
27774
|
+
force: options.force || changed
|
|
27775
|
+
});
|
|
27776
|
+
outcomes = [...head, ...middle, ...tail];
|
|
27777
|
+
} else {
|
|
27778
|
+
outcomes = await runPipeline(
|
|
27779
|
+
resolved.state,
|
|
27780
|
+
"gateway",
|
|
27781
|
+
[specStep, configStep, reconcileStep],
|
|
27782
|
+
{ force: options.force }
|
|
27783
|
+
);
|
|
27784
|
+
}
|
|
27531
27785
|
const reconcile = outcomes.find((outcome) => outcome.step === "reconcile");
|
|
27532
27786
|
const ran = reconcile !== void 0 && !reconcile.skipped;
|
|
27533
27787
|
const known = (await readManifest(resolved.state))?.services.gateway;
|
|
@@ -28642,7 +28896,7 @@ async function planGatewayService(resolved, ledger, dryRun) {
|
|
|
28642
28896
|
details: []
|
|
28643
28897
|
};
|
|
28644
28898
|
const details = [
|
|
28645
|
-
`origin: proxy ${gateway.origin.url ?? "(no url set)"}`,
|
|
28899
|
+
gateway.origin.mode === "managed" ? `origin: managed (${gateway.origin.runtime ?? "no runtime"} from ${gateway.origin.source ?? "no source folder"})` : `origin: proxy ${gateway.origin.url ?? "(no url set)"}`,
|
|
28646
28900
|
...gateway.auth ? [`auth: ${gateway.auth.mode}`] : ["auth: none"],
|
|
28647
28901
|
...describePolicies(gateway)
|
|
28648
28902
|
];
|
|
@@ -28695,8 +28949,27 @@ async function planGatewayService(resolved, ledger, dryRun) {
|
|
|
28695
28949
|
);
|
|
28696
28950
|
}
|
|
28697
28951
|
}
|
|
28952
|
+
let backendHash;
|
|
28953
|
+
try {
|
|
28954
|
+
backendHash = (await backendDeployInputs(gateway, resolved.project.id ?? ""))?.hash;
|
|
28955
|
+
} catch (error) {
|
|
28956
|
+
return {
|
|
28957
|
+
...base,
|
|
28958
|
+
action: "blocked",
|
|
28959
|
+
reason: "cannot deploy until this is fixed",
|
|
28960
|
+
details,
|
|
28961
|
+
issues: [
|
|
28962
|
+
{
|
|
28963
|
+
code: "GATEWAY_BACKEND_UNREADABLE",
|
|
28964
|
+
path: "gateway.origin.source",
|
|
28965
|
+
message: error instanceof Error ? error.message : String(error)
|
|
28966
|
+
}
|
|
28967
|
+
]
|
|
28968
|
+
};
|
|
28969
|
+
}
|
|
28698
28970
|
const step2 = (name) => stepOf(ledger, "gateway", name);
|
|
28699
28971
|
const hashes = {
|
|
28972
|
+
backend: backendHash ?? "",
|
|
28700
28973
|
spec: inputs.specHash,
|
|
28701
28974
|
config: inputs.configHash,
|
|
28702
28975
|
reconcile: inputs.configHash
|
|
@@ -28712,9 +28985,10 @@ async function planGatewayService(resolved, ledger, dryRun) {
|
|
|
28712
28985
|
const lines = [
|
|
28713
28986
|
`step spec (upload the OpenAPI file): ${state("spec")}`,
|
|
28714
28987
|
`step config (send the wanted state): ${state("config")}`,
|
|
28988
|
+
...backendHash ? [`step backend (upload and start your code): ${state("backend")}`] : [],
|
|
28715
28989
|
`step reconcile (wait until the platform applied it): ${state("reconcile")}`
|
|
28716
28990
|
];
|
|
28717
|
-
const allDone = step2("spec")?.status === "succeeded" && step2("spec")?.hash === hashes.spec && step2("config")?.status === "succeeded" && step2("config")?.hash === hashes.config && step2("reconcile")?.status === "succeeded" && step2("reconcile")?.hash === hashes.reconcile;
|
|
28991
|
+
const allDone = (!backendHash || step2("backend")?.status === "succeeded" && step2("backend")?.hash === hashes.backend) && step2("spec")?.status === "succeeded" && step2("spec")?.hash === hashes.spec && step2("config")?.status === "succeeded" && step2("config")?.hash === hashes.config && step2("reconcile")?.status === "succeeded" && step2("reconcile")?.hash === hashes.reconcile;
|
|
28718
28992
|
if (issues.length > 0)
|
|
28719
28993
|
return {
|
|
28720
28994
|
...base,
|
|
@@ -28795,7 +29069,7 @@ function corsLines(platform) {
|
|
|
28795
29069
|
];
|
|
28796
29070
|
}
|
|
28797
29071
|
async function gatewayStatus(resolved, ledger, manifest, remote) {
|
|
28798
|
-
const steps = ["spec", "config", "reconcile"].map((name) => ({
|
|
29072
|
+
const steps = ["spec", "config", "backend", "reconcile"].map((name) => ({
|
|
28799
29073
|
name,
|
|
28800
29074
|
record: stepOf(ledger, "gateway", name)
|
|
28801
29075
|
}));
|
|
@@ -28813,6 +29087,14 @@ async function gatewayStatus(resolved, ledger, manifest, remote) {
|
|
|
28813
29087
|
if (remote && projectId) {
|
|
28814
29088
|
try {
|
|
28815
29089
|
const platform = await remote(projectId);
|
|
29090
|
+
if (platform.status === "Released") {
|
|
29091
|
+
details.length = 0;
|
|
29092
|
+
details.push(
|
|
29093
|
+
"platform state: Released (the gateway was removed; deploy makes a new one)"
|
|
29094
|
+
);
|
|
29095
|
+
state = "not-deployed";
|
|
29096
|
+
return { service: "gateway", state, details: [...details, ...local] };
|
|
29097
|
+
}
|
|
28816
29098
|
details.push(
|
|
28817
29099
|
`platform state: ${platform.status}`,
|
|
28818
29100
|
platform.inSync ? "drift: none (the real gateway matches the config)" : `drift: the real gateway does not match the config yet (wanted ${platform.desiredHash?.slice(0, 12) ?? "none"}, real ${platform.observedHash?.slice(0, 12) ?? "none"})`,
|
|
@@ -28950,7 +29232,7 @@ function formatStatus(output4) {
|
|
|
28950
29232
|
}
|
|
28951
29233
|
|
|
28952
29234
|
// src/cli/deploy/static-web-config.ts
|
|
28953
|
-
import { access as access14, writeFile as
|
|
29235
|
+
import { access as access14, writeFile as writeFile26 } from "node:fs/promises";
|
|
28954
29236
|
import path84 from "node:path";
|
|
28955
29237
|
var STATIC_WEB_CONFIG_FILE = "staticwebapp.config.json";
|
|
28956
29238
|
var STATIC_WEB_CONFIG_VERSION = 1;
|
|
@@ -28969,7 +29251,7 @@ async function ensureStaticWebConfig(buildDir) {
|
|
|
28969
29251
|
await access14(file);
|
|
28970
29252
|
return false;
|
|
28971
29253
|
} catch {
|
|
28972
|
-
await
|
|
29254
|
+
await writeFile26(
|
|
28973
29255
|
file,
|
|
28974
29256
|
`${JSON.stringify(DEFAULT_STATIC_WEB_CONFIG, null, 2)}
|
|
28975
29257
|
`,
|
|
@@ -29118,7 +29400,7 @@ async function deployGatewayService(options, deps, projectId, named) {
|
|
|
29118
29400
|
return { service: "gateway", status: "skipped", reason: why, steps: [] };
|
|
29119
29401
|
}
|
|
29120
29402
|
const client = deps.client;
|
|
29121
|
-
if (!client.putGatewaySpec || !client.putGatewayConfig || !client.getGatewayReconciliation || !client.getGatewayStatus || !client.getGatewayCapabilities)
|
|
29403
|
+
if (!client.putGatewaySpec || !client.putGatewayConfig || !client.getGatewayReconciliation || !client.getGatewayStatus || !client.getGatewayCapabilities || gateway?.origin.mode === "managed" && (!client.deployBackend || !client.getDeploymentStatus))
|
|
29122
29404
|
throw new Error("The platform client has no gateway calls.");
|
|
29123
29405
|
const result = await deployGateway(
|
|
29124
29406
|
resolved,
|
|
@@ -29366,7 +29648,7 @@ var deploy_default = {
|
|
|
29366
29648
|
};
|
|
29367
29649
|
|
|
29368
29650
|
// src/cli/export/handler.ts
|
|
29369
|
-
import { mkdir as mkdir20, writeFile as
|
|
29651
|
+
import { mkdir as mkdir20, writeFile as writeFile27 } from "node:fs/promises";
|
|
29370
29652
|
import path87 from "node:path";
|
|
29371
29653
|
init_invariant();
|
|
29372
29654
|
var ExportError = class extends ApitogoError {
|
|
@@ -29408,7 +29690,7 @@ async function exportOpenApi(args, deps) {
|
|
|
29408
29690
|
if (!args.out) return { text };
|
|
29409
29691
|
const file = path87.resolve(process.cwd(), args.out);
|
|
29410
29692
|
await mkdir20(path87.dirname(file), { recursive: true });
|
|
29411
|
-
await
|
|
29693
|
+
await writeFile27(file, text);
|
|
29412
29694
|
return { text, file };
|
|
29413
29695
|
}
|
|
29414
29696
|
async function exportCommand(args) {
|
|
@@ -29461,13 +29743,13 @@ var export_default = {
|
|
|
29461
29743
|
import path91 from "node:path";
|
|
29462
29744
|
|
|
29463
29745
|
// src/cli/scaffold/run-scaffold-discovery.ts
|
|
29464
|
-
import { access as access16, readFile as readFile31, writeFile as
|
|
29746
|
+
import { access as access16, readFile as readFile31, writeFile as writeFile29 } from "node:fs/promises";
|
|
29465
29747
|
import path90 from "node:path";
|
|
29466
29748
|
|
|
29467
29749
|
// src/cli/scaffold/detect-backend.ts
|
|
29468
29750
|
import { readdir as readdir4, readFile as readFile29 } from "node:fs/promises";
|
|
29469
29751
|
import path88 from "node:path";
|
|
29470
|
-
var
|
|
29752
|
+
var DEFAULT_RUNTIME_VERSION2 = {
|
|
29471
29753
|
dotnet: "DOTNET_10",
|
|
29472
29754
|
nodejs: "NODE_22_LTS",
|
|
29473
29755
|
python: "PYTHON_312"
|
|
@@ -29494,18 +29776,18 @@ function dotnetVersionFromCsproj(content) {
|
|
|
29494
29776
|
if (major === "8" || major === "9" || major === "10") {
|
|
29495
29777
|
return `DOTNET_${major}`;
|
|
29496
29778
|
}
|
|
29497
|
-
return
|
|
29779
|
+
return DEFAULT_RUNTIME_VERSION2.dotnet;
|
|
29498
29780
|
}
|
|
29499
29781
|
function nodeVersionFromEngines(engines) {
|
|
29500
29782
|
const range = engines && typeof engines === "object" && !Array.isArray(engines) ? engines.node : void 0;
|
|
29501
29783
|
if (typeof range === "string" && /(^|[^\d])24/.test(range)) {
|
|
29502
29784
|
return "NODE_24_LTS";
|
|
29503
29785
|
}
|
|
29504
|
-
return
|
|
29786
|
+
return DEFAULT_RUNTIME_VERSION2.nodejs;
|
|
29505
29787
|
}
|
|
29506
29788
|
function pythonVersionFromText(content) {
|
|
29507
29789
|
const match = content?.match(/3\.(1[0-4])/);
|
|
29508
|
-
return match ? `PYTHON_3${match[1]}` :
|
|
29790
|
+
return match ? `PYTHON_3${match[1]}` : DEFAULT_RUNTIME_VERSION2.python;
|
|
29509
29791
|
}
|
|
29510
29792
|
function isRunnableNodePackage(pkg) {
|
|
29511
29793
|
const scripts = pkg.scripts && typeof pkg.scripts === "object" ? pkg.scripts : {};
|
|
@@ -29572,7 +29854,7 @@ import {
|
|
|
29572
29854
|
readFile as readFile30,
|
|
29573
29855
|
readlink,
|
|
29574
29856
|
symlink as symlink2,
|
|
29575
|
-
writeFile as
|
|
29857
|
+
writeFile as writeFile28
|
|
29576
29858
|
} from "node:fs/promises";
|
|
29577
29859
|
import path89 from "node:path";
|
|
29578
29860
|
var DOCS_DIR_WHITELIST = [
|
|
@@ -29809,7 +30091,7 @@ async function applyDocsNavigation(siteDirectory, routes) {
|
|
|
29809
30091
|
force: false
|
|
29810
30092
|
});
|
|
29811
30093
|
const updated = ensureHeaderDocsNavigation(parsed, routes);
|
|
29812
|
-
await
|
|
30094
|
+
await writeFile28(configPath, `${JSON.stringify(updated, null, 2)}
|
|
29813
30095
|
`, "utf8");
|
|
29814
30096
|
}
|
|
29815
30097
|
async function discoverAndWireDocs(siteDirectory) {
|
|
@@ -29993,7 +30275,7 @@ async function wireOpenApiIntoJsonConfig(siteDirectory, openApiPath) {
|
|
|
29993
30275
|
});
|
|
29994
30276
|
const backend = updated.backend && typeof updated.backend === "object" && !Array.isArray(updated.backend) ? { ...updated.backend } : {};
|
|
29995
30277
|
updated.backend = { ...backend, openApiPath: input5 };
|
|
29996
|
-
await
|
|
30278
|
+
await writeFile29(
|
|
29997
30279
|
jsonConfigPath,
|
|
29998
30280
|
`${JSON.stringify(updated, null, 2)}
|
|
29999
30281
|
`,
|
|
@@ -30113,7 +30395,7 @@ async function discoverAndWireBackend(siteDirectory, mode) {
|
|
|
30113
30395
|
runtime: detected.runtime,
|
|
30114
30396
|
runtimeVersion: detected.runtimeVersion
|
|
30115
30397
|
};
|
|
30116
|
-
await
|
|
30398
|
+
await writeFile29(
|
|
30117
30399
|
jsonConfigPath,
|
|
30118
30400
|
`${JSON.stringify(siteConfig, null, 2)}
|
|
30119
30401
|
`,
|
|
@@ -30678,7 +30960,12 @@ var ProjectCreateError = class extends ApitogoError {
|
|
|
30678
30960
|
}
|
|
30679
30961
|
};
|
|
30680
30962
|
function modulesForConfig(config2) {
|
|
30681
|
-
|
|
30963
|
+
const modules = [];
|
|
30964
|
+
if (config2.portal && config2.portal.enabled !== false)
|
|
30965
|
+
modules.push("dev-portal");
|
|
30966
|
+
if (config2.gateway && config2.gateway.enabled !== false && config2.gateway.origin?.mode === "managed")
|
|
30967
|
+
modules.push("apihub");
|
|
30968
|
+
return modules;
|
|
30682
30969
|
}
|
|
30683
30970
|
var hostsAnything = (config2) => config2.portal && config2.portal.enabled !== false || config2.gateway && config2.gateway.enabled !== false;
|
|
30684
30971
|
async function createProjectV2(options, deps) {
|
|
@@ -31535,7 +31822,7 @@ async function readStdin(input5 = process.stdin) {
|
|
|
31535
31822
|
}
|
|
31536
31823
|
return Buffer.concat(chunks).toString("utf8").replace(/\r?\n$/, "");
|
|
31537
31824
|
}
|
|
31538
|
-
async function
|
|
31825
|
+
async function confirm(question) {
|
|
31539
31826
|
const rl = createInterface6({ input: process.stdin, output: process.stdout });
|
|
31540
31827
|
try {
|
|
31541
31828
|
const answer = (await rl.question(question)).trim().toLowerCase();
|
|
@@ -31651,7 +31938,7 @@ async function secrets(argv) {
|
|
|
31651
31938
|
isTerminal: process.stdin.isTTY === true && !json,
|
|
31652
31939
|
askValue: (prompt) => readHidden(prompt),
|
|
31653
31940
|
readPiped: () => readStdin(),
|
|
31654
|
-
confirm
|
|
31941
|
+
confirm
|
|
31655
31942
|
});
|
|
31656
31943
|
if (json) {
|
|
31657
31944
|
console.log(JSON.stringify({ status: "succeeded", ...result }, null, 2));
|