@lukoweb/apitogo 0.2.10 → 0.2.12
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 +323 -96
- package/package.json +1 -1
- package/src/config/v2/gateway-reference.ts +220 -0
- package/src/config/v2/index.ts +8 -0
- package/src/config/v2/wrapper.ts +81 -3
package/dist/cli/cli.js
CHANGED
|
@@ -7489,6 +7489,157 @@ async function removeServicesFromManifest(state, names) {
|
|
|
7489
7489
|
await writeManifest(state, { ...existing, services });
|
|
7490
7490
|
}
|
|
7491
7491
|
|
|
7492
|
+
// src/config/v2/gateway-reference.ts
|
|
7493
|
+
import { readFile as readFile4 } from "node:fs/promises";
|
|
7494
|
+
import { parse } from "yaml";
|
|
7495
|
+
var DEFAULT_KEY_HEADER = "Ocp-Apim-Subscription-Key";
|
|
7496
|
+
var METHODS = [
|
|
7497
|
+
"get",
|
|
7498
|
+
"put",
|
|
7499
|
+
"post",
|
|
7500
|
+
"delete",
|
|
7501
|
+
"options",
|
|
7502
|
+
"head",
|
|
7503
|
+
"patch",
|
|
7504
|
+
"trace"
|
|
7505
|
+
];
|
|
7506
|
+
var isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7507
|
+
function actionKey(method, path100) {
|
|
7508
|
+
const trimmed = path100.trim();
|
|
7509
|
+
const withSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
7510
|
+
const normalized = withSlash.length > 1 ? withSlash.replace(/\/+$/, "") || "/" : withSlash;
|
|
7511
|
+
return `${method.trim().toLowerCase()}:${normalized}`;
|
|
7512
|
+
}
|
|
7513
|
+
function configActionKey(entry) {
|
|
7514
|
+
const match = /^\s*([A-Za-z]+)\s+(\S+)\s*$/.exec(entry);
|
|
7515
|
+
return match?.[1] && match[2] ? actionKey(match[1], match[2]) : void 0;
|
|
7516
|
+
}
|
|
7517
|
+
function referenceOptions(gateway, gatewayBaseUrl, keyHeaderName) {
|
|
7518
|
+
const access16 = gateway.policies.access;
|
|
7519
|
+
const jwt = access16?.jwt ?? gateway.auth !== void 0;
|
|
7520
|
+
const keys = (list2) => new Set(
|
|
7521
|
+
(list2 ?? []).flatMap((entry) => {
|
|
7522
|
+
const key = configActionKey(entry);
|
|
7523
|
+
return key ? [key] : [];
|
|
7524
|
+
})
|
|
7525
|
+
);
|
|
7526
|
+
return {
|
|
7527
|
+
gatewayBaseUrl,
|
|
7528
|
+
originUrl: gateway.origin.url,
|
|
7529
|
+
jwtRequired: jwt && gateway.auth !== void 0,
|
|
7530
|
+
oidcMetadataUrl: jwt ? gateway.auth?.metadataUrl : void 0,
|
|
7531
|
+
apiKeyRequired: access16?.apiKey ?? true,
|
|
7532
|
+
apiKeyHeader: keyHeaderName ?? access16?.apiKeyHeader ?? DEFAULT_KEY_HEADER,
|
|
7533
|
+
publicOperations: keys(gateway.policies.operations?.public),
|
|
7534
|
+
deniedOperations: keys(gateway.policies.operations?.deny)
|
|
7535
|
+
};
|
|
7536
|
+
}
|
|
7537
|
+
var ReferenceSpecError = class extends Error {
|
|
7538
|
+
constructor(message) {
|
|
7539
|
+
super(message);
|
|
7540
|
+
this.name = "ReferenceSpecError";
|
|
7541
|
+
}
|
|
7542
|
+
};
|
|
7543
|
+
function operationsOf(paths) {
|
|
7544
|
+
return Object.entries(paths).flatMap(
|
|
7545
|
+
([path100, item]) => isObject(item) ? METHODS.filter((method) => isObject(item[method])).map(
|
|
7546
|
+
(method) => [path100, item, method]
|
|
7547
|
+
) : []
|
|
7548
|
+
);
|
|
7549
|
+
}
|
|
7550
|
+
function buildReferenceSpec(specText, options) {
|
|
7551
|
+
let root;
|
|
7552
|
+
try {
|
|
7553
|
+
root = parse(specText);
|
|
7554
|
+
} catch {
|
|
7555
|
+
throw new ReferenceSpecError("The OpenAPI file could not be read.");
|
|
7556
|
+
}
|
|
7557
|
+
if (!isObject(root) || typeof root.openapi !== "string")
|
|
7558
|
+
throw new ReferenceSpecError("The OpenAPI file could not be read.");
|
|
7559
|
+
const doc = structuredClone(root);
|
|
7560
|
+
const paths = isObject(doc.paths) ? doc.paths : {};
|
|
7561
|
+
for (const [path100, item, method] of operationsOf(paths))
|
|
7562
|
+
if (options.deniedOperations.has(actionKey(method, path100)))
|
|
7563
|
+
delete item[method];
|
|
7564
|
+
for (const [path100, item] of Object.entries(paths))
|
|
7565
|
+
if (!isObject(item) || !METHODS.some((method) => method in item))
|
|
7566
|
+
delete paths[path100];
|
|
7567
|
+
for (const [path100, item, method] of operationsOf(paths))
|
|
7568
|
+
if (options.publicOperations.has(actionKey(method, path100)))
|
|
7569
|
+
item[method].security = [];
|
|
7570
|
+
doc.servers = [{ url: options.gatewayBaseUrl.replace(/\/+$/, "") }];
|
|
7571
|
+
for (const item of Object.values(paths)) {
|
|
7572
|
+
if (!isObject(item)) continue;
|
|
7573
|
+
delete item.servers;
|
|
7574
|
+
for (const method of METHODS) {
|
|
7575
|
+
const operation = item[method];
|
|
7576
|
+
if (isObject(operation)) delete operation.servers;
|
|
7577
|
+
}
|
|
7578
|
+
}
|
|
7579
|
+
const schemes = {};
|
|
7580
|
+
const requirement = {};
|
|
7581
|
+
if (options.jwtRequired) {
|
|
7582
|
+
schemes.bearerAuth = {
|
|
7583
|
+
type: "http",
|
|
7584
|
+
scheme: "bearer",
|
|
7585
|
+
bearerFormat: "JWT"
|
|
7586
|
+
};
|
|
7587
|
+
requirement.bearerAuth = [];
|
|
7588
|
+
}
|
|
7589
|
+
if (options.oidcMetadataUrl)
|
|
7590
|
+
schemes.openIdAuth = {
|
|
7591
|
+
type: "openIdConnect",
|
|
7592
|
+
openIdConnectUrl: options.oidcMetadataUrl
|
|
7593
|
+
};
|
|
7594
|
+
if (options.apiKeyRequired) {
|
|
7595
|
+
schemes.apiKeyAuth = {
|
|
7596
|
+
type: "apiKey",
|
|
7597
|
+
in: "header",
|
|
7598
|
+
name: options.apiKeyHeader
|
|
7599
|
+
};
|
|
7600
|
+
requirement.apiKeyAuth = [];
|
|
7601
|
+
}
|
|
7602
|
+
const components = isObject(doc.components) ? doc.components : {};
|
|
7603
|
+
if (Object.keys(schemes).length > 0) components.securitySchemes = schemes;
|
|
7604
|
+
else delete components.securitySchemes;
|
|
7605
|
+
if (Object.keys(components).length > 0) doc.components = components;
|
|
7606
|
+
else delete doc.components;
|
|
7607
|
+
doc.security = Object.keys(requirement).length > 0 ? [requirement] : [];
|
|
7608
|
+
for (const [, item, method] of operationsOf(paths)) {
|
|
7609
|
+
const operation = item[method];
|
|
7610
|
+
if (Array.isArray(operation.security) && operation.security.length > 0)
|
|
7611
|
+
delete operation.security;
|
|
7612
|
+
}
|
|
7613
|
+
return JSON.parse(hideOrigin(JSON.stringify(doc), options));
|
|
7614
|
+
}
|
|
7615
|
+
function hideOrigin(text, options) {
|
|
7616
|
+
const origin = options.originUrl?.trim().replace(/\/+$/, "");
|
|
7617
|
+
if (!origin) return text;
|
|
7618
|
+
const gateway = options.gatewayBaseUrl.trim().replace(/\/+$/, "");
|
|
7619
|
+
const pattern = new RegExp(
|
|
7620
|
+
origin.replace(/[.*+?^${}()|[\]\\/]/g, "\\$&"),
|
|
7621
|
+
"gi"
|
|
7622
|
+
);
|
|
7623
|
+
return text.replace(pattern, () => gateway);
|
|
7624
|
+
}
|
|
7625
|
+
async function renderReferenceSpec(gateway, gatewayBaseUrl, keyHeaderName) {
|
|
7626
|
+
const file = gateway.specs[0];
|
|
7627
|
+
if (!file)
|
|
7628
|
+
throw new ReferenceSpecError("gateway.specs lists no OpenAPI file.");
|
|
7629
|
+
let text;
|
|
7630
|
+
try {
|
|
7631
|
+
text = await readFile4(file, "utf8");
|
|
7632
|
+
} catch {
|
|
7633
|
+
throw new ReferenceSpecError(`Cannot read the OpenAPI file ${file}.`);
|
|
7634
|
+
}
|
|
7635
|
+
const spec = buildReferenceSpec(
|
|
7636
|
+
text,
|
|
7637
|
+
referenceOptions(gateway, gatewayBaseUrl, keyHeaderName)
|
|
7638
|
+
);
|
|
7639
|
+
return `${JSON.stringify(spec, null, 2)}
|
|
7640
|
+
`;
|
|
7641
|
+
}
|
|
7642
|
+
|
|
7492
7643
|
// src/config/v2/gateway-request.ts
|
|
7493
7644
|
function derivedCorsSites(sites) {
|
|
7494
7645
|
const originOf = (url2) => {
|
|
@@ -7548,7 +7699,7 @@ function stableJson(value) {
|
|
|
7548
7699
|
}
|
|
7549
7700
|
|
|
7550
7701
|
// src/config/v2/wrapper.ts
|
|
7551
|
-
import { mkdir as mkdir4, readFile as
|
|
7702
|
+
import { mkdir as mkdir4, readFile as readFile5, rename as rename2, rm as rm2, writeFile as writeFile5 } from "node:fs/promises";
|
|
7552
7703
|
import path11 from "node:path";
|
|
7553
7704
|
var WRAPPER_FILE = "apitogo.config.tsx";
|
|
7554
7705
|
var CONTENT_LINK = "content";
|
|
@@ -7613,16 +7764,30 @@ var DEFAULT_SCOPES = ["openid", "profile", "email"];
|
|
|
7613
7764
|
function planPortal(profile, manifest) {
|
|
7614
7765
|
const skipped = [];
|
|
7615
7766
|
const skip = (piece, reason) => void skipped.push({ piece, reason });
|
|
7616
|
-
const { identity, plans } = manifest.services;
|
|
7767
|
+
const { identity, plans, gateway } = manifest.services;
|
|
7617
7768
|
const plan2 = {
|
|
7618
7769
|
docs: profile.modules.docs,
|
|
7619
|
-
apiReference:
|
|
7770
|
+
apiReference: false,
|
|
7620
7771
|
userPanel: false,
|
|
7621
7772
|
signup: false,
|
|
7622
7773
|
skipped,
|
|
7623
7774
|
preview: manifest.preview === true
|
|
7624
7775
|
};
|
|
7625
7776
|
if (!profile.enabled) return plan2;
|
|
7777
|
+
if (profile.pipelines.openapi) {
|
|
7778
|
+
if (!gateway) skip("api reference", "services.json has no gateway entry");
|
|
7779
|
+
else if (!serviceReady(gateway))
|
|
7780
|
+
skip("api reference", `gateway is ${gateway.status}, not ready`);
|
|
7781
|
+
else if (!gateway.baseUrl)
|
|
7782
|
+
skip("api reference", "the gateway entry has no base URL yet");
|
|
7783
|
+
else {
|
|
7784
|
+
plan2.apiReference = true;
|
|
7785
|
+
plan2.gatewayReference = {
|
|
7786
|
+
baseUrl: gateway.baseUrl,
|
|
7787
|
+
keyHeaderName: gateway.keyHeaderName
|
|
7788
|
+
};
|
|
7789
|
+
}
|
|
7790
|
+
}
|
|
7626
7791
|
if (!profile.console.enabled) {
|
|
7627
7792
|
skip("console", "portal.console.enabled is false");
|
|
7628
7793
|
return plan2;
|
|
@@ -7663,6 +7828,8 @@ function planPortal(profile, manifest) {
|
|
|
7663
7828
|
return plan2;
|
|
7664
7829
|
}
|
|
7665
7830
|
var SITE_CONFIG_FILE = "apitogo.config.json";
|
|
7831
|
+
var REFERENCE_SPEC_FILE = "openapi/gateway.json";
|
|
7832
|
+
var API_REFERENCE_PATH = "api";
|
|
7666
7833
|
function buildSiteConfig(resolved, plan2, theme) {
|
|
7667
7834
|
const portal = resolved.portal;
|
|
7668
7835
|
return {
|
|
@@ -7681,6 +7848,22 @@ function buildSiteConfig(resolved, plan2, theme) {
|
|
|
7681
7848
|
)
|
|
7682
7849
|
}
|
|
7683
7850
|
} : {},
|
|
7851
|
+
...plan2.apiReference ? {
|
|
7852
|
+
apis: [
|
|
7853
|
+
{
|
|
7854
|
+
type: "file",
|
|
7855
|
+
input: `./${REFERENCE_SPEC_FILE}`,
|
|
7856
|
+
path: API_REFERENCE_PATH
|
|
7857
|
+
}
|
|
7858
|
+
],
|
|
7859
|
+
navigation: [
|
|
7860
|
+
{
|
|
7861
|
+
type: "link",
|
|
7862
|
+
to: `/${API_REFERENCE_PATH}`,
|
|
7863
|
+
label: "API Reference"
|
|
7864
|
+
}
|
|
7865
|
+
]
|
|
7866
|
+
} : {},
|
|
7684
7867
|
...theme !== void 0 ? { theme } : {},
|
|
7685
7868
|
...plan2.auth ? { authentication: { type: "openid", ...plan2.auth } } : {},
|
|
7686
7869
|
...plan2.preview ? { preview: true } : {}
|
|
@@ -7714,7 +7897,7 @@ async function readTheme(resolved) {
|
|
|
7714
7897
|
const file = resolved.portal?.theme;
|
|
7715
7898
|
if (!file) return void 0;
|
|
7716
7899
|
try {
|
|
7717
|
-
return JSON.parse(await
|
|
7900
|
+
return JSON.parse(await readFile5(file, "utf8"));
|
|
7718
7901
|
} catch {
|
|
7719
7902
|
return void 0;
|
|
7720
7903
|
}
|
|
@@ -7754,6 +7937,24 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
|
|
|
7754
7937
|
effective = { ...effective, preview: void 0, services: {} };
|
|
7755
7938
|
}
|
|
7756
7939
|
const plan2 = planPortal(profile, effective);
|
|
7940
|
+
let referenceSpec;
|
|
7941
|
+
if (plan2.apiReference && plan2.gatewayReference && resolved.gateway) {
|
|
7942
|
+
try {
|
|
7943
|
+
referenceSpec = await renderReferenceSpec(
|
|
7944
|
+
resolved.gateway,
|
|
7945
|
+
plan2.gatewayReference.baseUrl,
|
|
7946
|
+
plan2.gatewayReference.keyHeaderName
|
|
7947
|
+
);
|
|
7948
|
+
} catch (error) {
|
|
7949
|
+
if (!(error instanceof ReferenceSpecError)) throw error;
|
|
7950
|
+
plan2.apiReference = false;
|
|
7951
|
+
plan2.gatewayReference = void 0;
|
|
7952
|
+
plan2.skipped.push({
|
|
7953
|
+
piece: "api reference",
|
|
7954
|
+
reason: `${error.message} The API page is left out.`
|
|
7955
|
+
});
|
|
7956
|
+
}
|
|
7957
|
+
}
|
|
7757
7958
|
const siteConfig = buildSiteConfig(resolved, plan2, await readTheme(resolved));
|
|
7758
7959
|
const wrapper = renderWrapper(plan2);
|
|
7759
7960
|
const wrapperPath = path11.join(resolved.state.generatedDir, WRAPPER_FILE);
|
|
@@ -7764,6 +7965,16 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
|
|
|
7764
7965
|
`${JSON.stringify(siteConfig, null, 2)}
|
|
7765
7966
|
`
|
|
7766
7967
|
);
|
|
7968
|
+
const referenceFile = path11.join(
|
|
7969
|
+
path11.dirname(wrapperPath),
|
|
7970
|
+
REFERENCE_SPEC_FILE
|
|
7971
|
+
);
|
|
7972
|
+
if (referenceSpec !== void 0) {
|
|
7973
|
+
await mkdir4(path11.dirname(referenceFile), { recursive: true });
|
|
7974
|
+
await writeFile5(referenceFile, referenceSpec);
|
|
7975
|
+
} else {
|
|
7976
|
+
await rm2(referenceFile, { force: true });
|
|
7977
|
+
}
|
|
7767
7978
|
const temporary = `${wrapperPath}.${process.pid}.tmp`;
|
|
7768
7979
|
try {
|
|
7769
7980
|
await writeFile5(temporary, wrapper, "utf8");
|
|
@@ -7778,6 +7989,7 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
|
|
|
7778
7989
|
plan: plan2,
|
|
7779
7990
|
wrapper,
|
|
7780
7991
|
siteConfig,
|
|
7992
|
+
referenceSpec,
|
|
7781
7993
|
// Without a console there are no console links to offer, so a docs-only portal ships no manifest.
|
|
7782
7994
|
publishedManifest: manifestSource === "file" && profile.console.enabled ? publishedManifest(effective, plan2) : void 0,
|
|
7783
7995
|
wrapperPath,
|
|
@@ -7787,7 +7999,7 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
|
|
|
7787
7999
|
|
|
7788
8000
|
// src/config/v2/workspace.ts
|
|
7789
8001
|
import { createHash as createHash2 } from "node:crypto";
|
|
7790
|
-
import { access as access2, lstat, readFile as
|
|
8002
|
+
import { access as access2, lstat, readFile as readFile6, rm as rm3, symlink } from "node:fs/promises";
|
|
7791
8003
|
import path12 from "node:path";
|
|
7792
8004
|
import { glob as glob2 } from "glob";
|
|
7793
8005
|
var exists2 = (file) => access2(file).then(
|
|
@@ -7816,7 +8028,7 @@ async function materializeWorkspace(resolved, prepared) {
|
|
|
7816
8028
|
return root;
|
|
7817
8029
|
}
|
|
7818
8030
|
async function configFingerprint(configPath) {
|
|
7819
|
-
const text = await
|
|
8031
|
+
const text = await readFile6(configPath, "utf8");
|
|
7820
8032
|
try {
|
|
7821
8033
|
const raw = JSON.parse(text);
|
|
7822
8034
|
if (raw.project) {
|
|
@@ -7865,7 +8077,7 @@ async function portalArtifactHash(resolved, manifestText, cliVersion, wrapper =
|
|
|
7865
8077
|
for (const file of files) {
|
|
7866
8078
|
hash2.update(`file:${path12.relative(resolved.configDir, file)}
|
|
7867
8079
|
`);
|
|
7868
|
-
hash2.update(await
|
|
8080
|
+
hash2.update(await readFile6(file));
|
|
7869
8081
|
}
|
|
7870
8082
|
return hash2.digest("hex");
|
|
7871
8083
|
}
|
|
@@ -8332,7 +8544,7 @@ async function clearProjectId(dir, projectId) {
|
|
|
8332
8544
|
|
|
8333
8545
|
// src/config/v2/ledger.ts
|
|
8334
8546
|
init_invariant();
|
|
8335
|
-
import { mkdir as mkdir6, readFile as
|
|
8547
|
+
import { mkdir as mkdir6, readFile as readFile7, rename as rename4, rm as rm5, writeFile as writeFile7 } from "node:fs/promises";
|
|
8336
8548
|
import path14 from "node:path";
|
|
8337
8549
|
var LEDGER_VERSION = 1;
|
|
8338
8550
|
var LedgerError = class extends ApitogoError {
|
|
@@ -8349,7 +8561,7 @@ var emptyLedger = () => ({
|
|
|
8349
8561
|
async function readLedger(state) {
|
|
8350
8562
|
let text;
|
|
8351
8563
|
try {
|
|
8352
|
-
text = await
|
|
8564
|
+
text = await readFile7(state.file, "utf8");
|
|
8353
8565
|
} catch (error) {
|
|
8354
8566
|
if (error.code === "ENOENT")
|
|
8355
8567
|
return emptyLedger();
|
|
@@ -8480,7 +8692,7 @@ init_invariant();
|
|
|
8480
8692
|
|
|
8481
8693
|
// src/cli/check/v2.ts
|
|
8482
8694
|
init_apitogo_config_core();
|
|
8483
|
-
import { readFile as
|
|
8695
|
+
import { readFile as readFile13 } from "node:fs/promises";
|
|
8484
8696
|
import path46 from "node:path";
|
|
8485
8697
|
|
|
8486
8698
|
// src/cli/platform/client/platform-api.ts
|
|
@@ -9164,8 +9376,8 @@ var PlatformApiClient = class {
|
|
|
9164
9376
|
`/api/v1/projects/${projectId}/gateway/actions?${query.toString()}`
|
|
9165
9377
|
);
|
|
9166
9378
|
}
|
|
9167
|
-
setGatewayActionPublic(projectId,
|
|
9168
|
-
const encodedKey = encodeURIComponent(
|
|
9379
|
+
setGatewayActionPublic(projectId, actionKey2, isPublic) {
|
|
9380
|
+
const encodedKey = encodeURIComponent(actionKey2);
|
|
9169
9381
|
return this.request(
|
|
9170
9382
|
"PATCH",
|
|
9171
9383
|
`/api/v1/projects/${projectId}/gateway/actions/${encodedKey}`,
|
|
@@ -9196,8 +9408,8 @@ var PlatformApiClient = class {
|
|
|
9196
9408
|
}
|
|
9197
9409
|
};
|
|
9198
9410
|
async function readFileBytes(filePath) {
|
|
9199
|
-
const { readFile:
|
|
9200
|
-
const buffer = await
|
|
9411
|
+
const { readFile: readFile30 } = await import("node:fs/promises");
|
|
9412
|
+
const buffer = await readFile30(filePath);
|
|
9201
9413
|
const arrayBuffer = new ArrayBuffer(buffer.byteLength);
|
|
9202
9414
|
new Uint8Array(arrayBuffer).set(buffer);
|
|
9203
9415
|
return arrayBuffer;
|
|
@@ -9294,7 +9506,7 @@ function resolveProjectId(explicit, config2) {
|
|
|
9294
9506
|
import {
|
|
9295
9507
|
access as access4,
|
|
9296
9508
|
mkdir as mkdir12,
|
|
9297
|
-
readFile as
|
|
9509
|
+
readFile as readFile11,
|
|
9298
9510
|
rename as rename6,
|
|
9299
9511
|
rm as rm8,
|
|
9300
9512
|
writeFile as writeFile13
|
|
@@ -9303,7 +9515,7 @@ import { createRequire as createRequire2 } from "node:module";
|
|
|
9303
9515
|
import path45 from "node:path";
|
|
9304
9516
|
|
|
9305
9517
|
// src/vite/build.ts
|
|
9306
|
-
import { mkdir as mkdir11, readFile as
|
|
9518
|
+
import { mkdir as mkdir11, readFile as readFile10, rename as rename5, rm as rm7, writeFile as writeFile12 } from "node:fs/promises";
|
|
9307
9519
|
import path44 from "node:path";
|
|
9308
9520
|
import { build as esbuild } from "esbuild";
|
|
9309
9521
|
import { build as viteBuild, mergeConfig as mergeConfig3 } from "vite";
|
|
@@ -9451,7 +9663,7 @@ import {
|
|
|
9451
9663
|
// package.json
|
|
9452
9664
|
var package_default = {
|
|
9453
9665
|
name: "@lukoweb/apitogo",
|
|
9454
|
-
version: "0.2.
|
|
9666
|
+
version: "0.2.12",
|
|
9455
9667
|
type: "module",
|
|
9456
9668
|
sideEffects: [
|
|
9457
9669
|
"**/*.css",
|
|
@@ -11538,15 +11750,15 @@ import { mdxFromMarkdown } from "mdast-util-mdx";
|
|
|
11538
11750
|
import { mdxjs } from "micromark-extension-mdxjs";
|
|
11539
11751
|
|
|
11540
11752
|
// src/lib/util/readFrontmatter.ts
|
|
11541
|
-
import { readFile as
|
|
11753
|
+
import { readFile as readFile8 } from "node:fs/promises";
|
|
11542
11754
|
import matter from "gray-matter";
|
|
11543
|
-
import { parse, stringify as stringify2 } from "yaml";
|
|
11755
|
+
import { parse as parse2, stringify as stringify2 } from "yaml";
|
|
11544
11756
|
var yaml = {
|
|
11545
|
-
parse: (input5) =>
|
|
11757
|
+
parse: (input5) => parse2(input5) ?? {},
|
|
11546
11758
|
stringify: (obj) => stringify2(obj)
|
|
11547
11759
|
};
|
|
11548
11760
|
var readFrontmatter = async (filePath) => {
|
|
11549
|
-
const content = await
|
|
11761
|
+
const content = await readFile8(filePath, "utf-8");
|
|
11550
11762
|
const normalizedContent = content.replace(/\r\n/g, "\n");
|
|
11551
11763
|
return matter(normalizedContent, { engines: { yaml } });
|
|
11552
11764
|
};
|
|
@@ -12857,7 +13069,7 @@ var remarkInjectFilepath = (rootDir) => (tree, vfile) => {
|
|
|
12857
13069
|
import { spawnSync } from "node:child_process";
|
|
12858
13070
|
import { stat as stat6 } from "node:fs/promises";
|
|
12859
13071
|
import { visit as visit4 } from "unist-util-visit";
|
|
12860
|
-
import { parse as
|
|
13072
|
+
import { parse as parse3, stringify as stringify4 } from "yaml";
|
|
12861
13073
|
var isGitAvailable;
|
|
12862
13074
|
var hasWarnedShallowClone = false;
|
|
12863
13075
|
var checkGitAvailable = () => {
|
|
@@ -12920,7 +13132,7 @@ var remarkLastModified = () => {
|
|
|
12920
13132
|
let hasYaml = false;
|
|
12921
13133
|
visit4(tree, "yaml", (node) => {
|
|
12922
13134
|
hasYaml = true;
|
|
12923
|
-
const data =
|
|
13135
|
+
const data = parse3(node.value) ?? {};
|
|
12924
13136
|
if (!data.lastModifiedTime) {
|
|
12925
13137
|
data.lastModifiedTime = lastModifiedISO;
|
|
12926
13138
|
node.value = stringify4(data).trim();
|
|
@@ -13820,7 +14032,7 @@ async function writeOutput(dir, {
|
|
|
13820
14032
|
// src/vite/prerender/prerender.ts
|
|
13821
14033
|
init_logger();
|
|
13822
14034
|
init_file_exists();
|
|
13823
|
-
import { readFile as
|
|
14035
|
+
import { readFile as readFile9, rm as rm6 } from "node:fs/promises";
|
|
13824
14036
|
import os from "node:os";
|
|
13825
14037
|
import path43 from "node:path";
|
|
13826
14038
|
import { pathToFileURL } from "node:url";
|
|
@@ -14096,7 +14308,7 @@ var prerender = async ({
|
|
|
14096
14308
|
);
|
|
14097
14309
|
let markdownFileInfos = [];
|
|
14098
14310
|
if (await fileExists(markdownInfoPath)) {
|
|
14099
|
-
const markdownInfoContent = await
|
|
14311
|
+
const markdownInfoContent = await readFile9(markdownInfoPath, "utf-8");
|
|
14100
14312
|
markdownFileInfos = JSON.parse(markdownInfoContent);
|
|
14101
14313
|
}
|
|
14102
14314
|
if (llmsConfig.llmsTxt || llmsConfig.llmsTxtFull) {
|
|
@@ -14247,7 +14459,7 @@ var bundleSSREntry = async (options) => {
|
|
|
14247
14459
|
const { dir, adapter, serverOutDir, serverConfigFilename, html, basePath } = options;
|
|
14248
14460
|
const tempEntryPath = path44.join(dir, "__ssr-entry.ts");
|
|
14249
14461
|
const packageRoot = getZudokuRootDir();
|
|
14250
|
-
const templateContent = await
|
|
14462
|
+
const templateContent = await readFile10(
|
|
14251
14463
|
path44.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
|
|
14252
14464
|
"utf-8"
|
|
14253
14465
|
);
|
|
@@ -14314,7 +14526,7 @@ async function portalBuildHash(resolved, prepared) {
|
|
|
14314
14526
|
resolved,
|
|
14315
14527
|
void 0,
|
|
14316
14528
|
getZudokuPackageJson().version,
|
|
14317
|
-
prepared.wrapper + JSON.stringify(prepared.siteConfig) + JSON.stringify(prepared.publishedManifest ?? null)
|
|
14529
|
+
prepared.wrapper + JSON.stringify(prepared.siteConfig) + JSON.stringify(prepared.publishedManifest ?? null) + (prepared.referenceSpec ?? "")
|
|
14318
14530
|
);
|
|
14319
14531
|
}
|
|
14320
14532
|
function portalBuildStep(context, options = {}, build2 = runBuild) {
|
|
@@ -14369,7 +14581,7 @@ async function buildV2(options) {
|
|
|
14369
14581
|
}
|
|
14370
14582
|
|
|
14371
14583
|
// src/cli/check/gateway-online.ts
|
|
14372
|
-
import { readFile as
|
|
14584
|
+
import { readFile as readFile12 } from "node:fs/promises";
|
|
14373
14585
|
var SPEC_SEND_LIMIT = 5 * 1024 * 1024 + 64 * 1024;
|
|
14374
14586
|
var issue2 = (code, path100, message, hint) => ({ code, path: path100, message, hint });
|
|
14375
14587
|
function capabilityIssues(gateway, answer) {
|
|
@@ -14425,7 +14637,7 @@ async function onlineGatewayRules(gateway, projectId, api, derivedCors = []) {
|
|
|
14425
14637
|
const specFile = gateway.specs[0];
|
|
14426
14638
|
if (specFile) {
|
|
14427
14639
|
try {
|
|
14428
|
-
const text = await
|
|
14640
|
+
const text = await readFile12(specFile, "utf8");
|
|
14429
14641
|
if (text.length <= SPEC_SEND_LIMIT) spec = text;
|
|
14430
14642
|
} catch {
|
|
14431
14643
|
}
|
|
@@ -14455,7 +14667,7 @@ async function onlineGatewayRules(gateway, projectId, api, derivedCors = []) {
|
|
|
14455
14667
|
async function isConfigV2(dir) {
|
|
14456
14668
|
try {
|
|
14457
14669
|
return /"version"\s*:\s*2\b/.test(
|
|
14458
|
-
await
|
|
14670
|
+
await readFile13(path46.join(dir, APITOGO_CONFIG_FILENAME), "utf8")
|
|
14459
14671
|
);
|
|
14460
14672
|
} catch {
|
|
14461
14673
|
return false;
|
|
@@ -14514,6 +14726,19 @@ async function addGatewayOnlineRules(report, resolved, args, deps) {
|
|
|
14514
14726
|
"online rules ran for the gateway only; the other services have none yet"
|
|
14515
14727
|
);
|
|
14516
14728
|
}
|
|
14729
|
+
async function addApiReferenceWarning(report, resolved) {
|
|
14730
|
+
const portal = resolved.portal;
|
|
14731
|
+
if (!portal?.enabled || !portal.docs.enabled || portal.docs.provider !== "apitogo" || resolved.gateway?.enabled !== true)
|
|
14732
|
+
return;
|
|
14733
|
+
const entry = (await readManifest(resolved.state))?.services.gateway;
|
|
14734
|
+
if (entry?.baseUrl && (entry.status ?? "ready") === "ready") return;
|
|
14735
|
+
report.warnings.push({
|
|
14736
|
+
code: "PORTAL_API_REFERENCE_SKIPPED",
|
|
14737
|
+
path: "portal.docs",
|
|
14738
|
+
message: "the portal's API page is left out of the build because the gateway has no address yet.",
|
|
14739
|
+
hint: "Run `apitogo deploy --only gateway`, then build the portal again."
|
|
14740
|
+
});
|
|
14741
|
+
}
|
|
14517
14742
|
async function validatePortalBuild(dir) {
|
|
14518
14743
|
try {
|
|
14519
14744
|
await buildV2({ dir, force: true, jsonOnly: true });
|
|
@@ -14553,6 +14778,7 @@ async function runCheckV2(dir, args = {}, deps = {}) {
|
|
|
14553
14778
|
});
|
|
14554
14779
|
if (online.failure) report.skipped.push(online.failure);
|
|
14555
14780
|
await addGatewayOnlineRules(report, resolved, args, deps);
|
|
14781
|
+
await addApiReferenceWarning(report, resolved);
|
|
14556
14782
|
} catch (error) {
|
|
14557
14783
|
if (!(error instanceof ConfigError)) throw error;
|
|
14558
14784
|
report = {
|
|
@@ -15402,7 +15628,7 @@ function formatDevPortalBackendResponse(projectId, backend) {
|
|
|
15402
15628
|
// src/cli/platform/helpers/dev-portal-manifest.ts
|
|
15403
15629
|
init_gateway_limits();
|
|
15404
15630
|
import { existsSync as existsSync6 } from "node:fs";
|
|
15405
|
-
import { access as access5, mkdir as mkdir13, readFile as
|
|
15631
|
+
import { access as access5, mkdir as mkdir13, readFile as readFile14, writeFile as writeFile14 } from "node:fs/promises";
|
|
15406
15632
|
import path53 from "node:path";
|
|
15407
15633
|
|
|
15408
15634
|
// src/cli/make-config/json-config.ts
|
|
@@ -15455,7 +15681,7 @@ function ensureHeaderPricingNavigation(config2) {
|
|
|
15455
15681
|
// src/cli/make-config/json-config.ts
|
|
15456
15682
|
var APITOGO_JSON_FILENAME = "apitogo.config.json";
|
|
15457
15683
|
var DOCUMENTATION_NAV_LABEL = "Documentation";
|
|
15458
|
-
var
|
|
15684
|
+
var API_REFERENCE_PATH2 = "/api";
|
|
15459
15685
|
var API_REFERENCE_LABEL = "API Reference";
|
|
15460
15686
|
function isPlainObject3(value) {
|
|
15461
15687
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -15816,7 +16042,7 @@ function isDocumentationCategory(item) {
|
|
|
15816
16042
|
return typeof item === "object" && item.type === "category" && item.label === DOCUMENTATION_NAV_LABEL;
|
|
15817
16043
|
}
|
|
15818
16044
|
function isApiReferenceLink(item) {
|
|
15819
|
-
return typeof item === "object" && item.type === "link" && item.to ===
|
|
16045
|
+
return typeof item === "object" && item.type === "link" && item.to === API_REFERENCE_PATH2;
|
|
15820
16046
|
}
|
|
15821
16047
|
function mergeDocumentationNavigation(navigation, docRoutePaths, options) {
|
|
15822
16048
|
const existing = Array.isArray(navigation) ? navigation : [];
|
|
@@ -15858,14 +16084,14 @@ function applyOpenApiToJsonConfig(config2, input5) {
|
|
|
15858
16084
|
if (!navigation.some(isApiReferenceLink)) {
|
|
15859
16085
|
navigation.push({
|
|
15860
16086
|
type: "link",
|
|
15861
|
-
to:
|
|
16087
|
+
to: API_REFERENCE_PATH2,
|
|
15862
16088
|
label: API_REFERENCE_LABEL
|
|
15863
16089
|
});
|
|
15864
16090
|
}
|
|
15865
16091
|
next.navigation = navigation;
|
|
15866
16092
|
return ensureHeaderApiReferenceNavigation(
|
|
15867
16093
|
next,
|
|
15868
|
-
|
|
16094
|
+
API_REFERENCE_PATH2,
|
|
15869
16095
|
API_REFERENCE_LABEL
|
|
15870
16096
|
);
|
|
15871
16097
|
}
|
|
@@ -16702,7 +16928,7 @@ function applyOpenApiToSiteConfig(config2, options) {
|
|
|
16702
16928
|
async function readManifest2(siteDirectory) {
|
|
16703
16929
|
const filePath = manifestFilePath(siteDirectory);
|
|
16704
16930
|
if (await pathExists(filePath)) {
|
|
16705
|
-
const raw = await
|
|
16931
|
+
const raw = await readFile14(filePath, "utf8");
|
|
16706
16932
|
const config2 = JSON.parse(raw);
|
|
16707
16933
|
return extractManifestFromConfig(config2);
|
|
16708
16934
|
}
|
|
@@ -16713,7 +16939,7 @@ async function writeManifest2(siteDirectory, manifest) {
|
|
|
16713
16939
|
await mkdir13(path53.dirname(filePath), { recursive: true });
|
|
16714
16940
|
let config2 = {};
|
|
16715
16941
|
if (await pathExists(filePath)) {
|
|
16716
|
-
const raw = await
|
|
16942
|
+
const raw = await readFile14(filePath, "utf8");
|
|
16717
16943
|
config2 = JSON.parse(raw);
|
|
16718
16944
|
}
|
|
16719
16945
|
const {
|
|
@@ -16732,7 +16958,7 @@ import {
|
|
|
16732
16958
|
access as access6,
|
|
16733
16959
|
appendFile,
|
|
16734
16960
|
mkdir as mkdir14,
|
|
16735
|
-
readFile as
|
|
16961
|
+
readFile as readFile15,
|
|
16736
16962
|
unlink,
|
|
16737
16963
|
writeFile as writeFile15
|
|
16738
16964
|
} from "node:fs/promises";
|
|
@@ -16838,7 +17064,7 @@ function applyEnvOverrides2(config2, env) {
|
|
|
16838
17064
|
}
|
|
16839
17065
|
async function readEnvFile(filePath) {
|
|
16840
17066
|
try {
|
|
16841
|
-
const raw = await
|
|
17067
|
+
const raw = await readFile15(filePath, "utf8");
|
|
16842
17068
|
const env = {};
|
|
16843
17069
|
for (const line2 of raw.split("\n")) {
|
|
16844
17070
|
const trimmed = line2.trim();
|
|
@@ -17015,7 +17241,7 @@ async function writeScaffoldEnv(siteDirectory) {
|
|
|
17015
17241
|
for (const legacyName of [".env.example"]) {
|
|
17016
17242
|
const legacyPath = path54.join(resolvedDirectory, legacyName);
|
|
17017
17243
|
try {
|
|
17018
|
-
const legacy = await
|
|
17244
|
+
const legacy = await readFile15(legacyPath, "utf8");
|
|
17019
17245
|
if (!envFileHasActiveAssignments(legacy)) {
|
|
17020
17246
|
await unlink(legacyPath);
|
|
17021
17247
|
filesWritten.push(`removed:${legacyName}`);
|
|
@@ -17026,7 +17252,7 @@ async function writeScaffoldEnv(siteDirectory) {
|
|
|
17026
17252
|
const gitignorePath = path54.join(resolvedDirectory, ".gitignore");
|
|
17027
17253
|
let gitignore = "";
|
|
17028
17254
|
try {
|
|
17029
|
-
gitignore = await
|
|
17255
|
+
gitignore = await readFile15(gitignorePath, "utf8");
|
|
17030
17256
|
} catch {
|
|
17031
17257
|
gitignore = "";
|
|
17032
17258
|
}
|
|
@@ -17058,7 +17284,7 @@ var SECRETS_COLLECTION_INSTRUCTION = "For go-live, plans must already be in apit
|
|
|
17058
17284
|
|
|
17059
17285
|
// src/cli/platform/helpers/dev-portal-site-validation.ts
|
|
17060
17286
|
init_gateway_limits();
|
|
17061
|
-
import { readFile as
|
|
17287
|
+
import { readFile as readFile16 } from "node:fs/promises";
|
|
17062
17288
|
import { createRequire as createRequire3 } from "node:module";
|
|
17063
17289
|
import path55 from "node:path";
|
|
17064
17290
|
var cachedFallbackTs;
|
|
@@ -17236,7 +17462,7 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
|
|
|
17236
17462
|
let parsed;
|
|
17237
17463
|
let parseFailed = false;
|
|
17238
17464
|
try {
|
|
17239
|
-
parsed = JSON.parse(await
|
|
17465
|
+
parsed = JSON.parse(await readFile16(jsonPath, "utf8"));
|
|
17240
17466
|
} catch (error) {
|
|
17241
17467
|
parseFailed = true;
|
|
17242
17468
|
issues.push({
|
|
@@ -17275,7 +17501,7 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
|
|
|
17275
17501
|
} else {
|
|
17276
17502
|
for (const relativeFile of existingTsxFiles) {
|
|
17277
17503
|
checkedFiles.push(relativeFile);
|
|
17278
|
-
const content = await
|
|
17504
|
+
const content = await readFile16(
|
|
17279
17505
|
path55.join(resolvedDir, relativeFile),
|
|
17280
17506
|
"utf8"
|
|
17281
17507
|
);
|
|
@@ -17313,7 +17539,7 @@ function buildSiteValidationResponseFields(result) {
|
|
|
17313
17539
|
|
|
17314
17540
|
// src/cli/platform/helpers/npm-build.ts
|
|
17315
17541
|
import { spawn as spawn2 } from "node:child_process";
|
|
17316
|
-
import { access as access7, readFile as
|
|
17542
|
+
import { access as access7, readFile as readFile17 } from "node:fs/promises";
|
|
17317
17543
|
import path56 from "node:path";
|
|
17318
17544
|
var BUILD_LOG_TAIL_BYTES = 8192;
|
|
17319
17545
|
var MIN_NODE_MAJOR = 20;
|
|
@@ -17950,7 +18176,7 @@ var check_default = {
|
|
|
17950
18176
|
|
|
17951
18177
|
// src/cli/make-config/handler.ts
|
|
17952
18178
|
import { constants as constants2 } from "node:fs";
|
|
17953
|
-
import { access as access12, mkdir as mkdir17, readFile as
|
|
18179
|
+
import { access as access12, mkdir as mkdir17, readFile as readFile22, writeFile as writeFile20 } from "node:fs/promises";
|
|
17954
18180
|
import path68 from "node:path";
|
|
17955
18181
|
import { stdin as input2 } from "node:process";
|
|
17956
18182
|
import { glob as glob7 } from "glob";
|
|
@@ -18090,7 +18316,7 @@ function withDefaultIncludedActionKeys(plan2, actionKeys) {
|
|
|
18090
18316
|
}
|
|
18091
18317
|
|
|
18092
18318
|
// src/cli/scaffold/dev-portal-config-pages.ts
|
|
18093
|
-
import { access as access8, readFile as
|
|
18319
|
+
import { access as access8, readFile as readFile18, rename as rename7, rm as rm9, writeFile as writeFile16 } from "node:fs/promises";
|
|
18094
18320
|
import path60 from "node:path";
|
|
18095
18321
|
async function writeConfigAtomically(filePath, content) {
|
|
18096
18322
|
const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
@@ -18855,7 +19081,7 @@ async function wireNewDevPortalPageInConfig(sourceDirectory, slug, label) {
|
|
|
18855
19081
|
if (!configPath) {
|
|
18856
19082
|
return { updated: false };
|
|
18857
19083
|
}
|
|
18858
|
-
const original = await
|
|
19084
|
+
const original = await readFile18(configPath, "utf8");
|
|
18859
19085
|
const patched = patchApitogoConfigForNewPage(original, slug, label, {
|
|
18860
19086
|
typescript: configPath.endsWith(".tsx")
|
|
18861
19087
|
});
|
|
@@ -18867,7 +19093,7 @@ async function wireNewDevPortalPageInConfig(sourceDirectory, slug, label) {
|
|
|
18867
19093
|
}
|
|
18868
19094
|
|
|
18869
19095
|
// src/cli/scaffold/wire-openapi.ts
|
|
18870
|
-
import { access as access10, readFile as
|
|
19096
|
+
import { access as access10, readFile as readFile20, writeFile as writeFile18 } from "node:fs/promises";
|
|
18871
19097
|
import path65 from "node:path";
|
|
18872
19098
|
|
|
18873
19099
|
// src/cli/platform/helpers/openapi.ts
|
|
@@ -19071,7 +19297,7 @@ async function validateOpenApiFile(filePath) {
|
|
|
19071
19297
|
}
|
|
19072
19298
|
|
|
19073
19299
|
// src/cli/scaffold/scaffold-dev-portal-site.ts
|
|
19074
|
-
import { mkdir as mkdir15, readFile as
|
|
19300
|
+
import { mkdir as mkdir15, readFile as readFile19, writeFile as writeFile17 } from "node:fs/promises";
|
|
19075
19301
|
import path64 from "node:path";
|
|
19076
19302
|
|
|
19077
19303
|
// src/cli/scaffold/apitogo-npm-packages.ts
|
|
@@ -19479,7 +19705,7 @@ function patchDashboardPageConfig(content) {
|
|
|
19479
19705
|
async function ensureAccountPlansPage(outputDirectory) {
|
|
19480
19706
|
const pagePath = path64.join(outputDirectory, ACCOUNT_PLANS_PAGE_PATH);
|
|
19481
19707
|
try {
|
|
19482
|
-
await
|
|
19708
|
+
await readFile19(pagePath, "utf8");
|
|
19483
19709
|
return void 0;
|
|
19484
19710
|
} catch {
|
|
19485
19711
|
await mkdir15(path64.dirname(pagePath), { recursive: true });
|
|
@@ -19490,7 +19716,7 @@ async function ensureAccountPlansPage(outputDirectory) {
|
|
|
19490
19716
|
async function ensureDashboardPage(outputDirectory) {
|
|
19491
19717
|
const pagePath = path64.join(outputDirectory, DASHBOARD_PAGE_PATH);
|
|
19492
19718
|
try {
|
|
19493
|
-
await
|
|
19719
|
+
await readFile19(pagePath, "utf8");
|
|
19494
19720
|
return void 0;
|
|
19495
19721
|
} catch {
|
|
19496
19722
|
await mkdir15(path64.dirname(pagePath), { recursive: true });
|
|
@@ -19552,7 +19778,7 @@ async function patchScaffoldedSite(outputDirectory, options) {
|
|
|
19552
19778
|
const filesWritten = [];
|
|
19553
19779
|
const packageJsonPath = path64.join(outputDirectory, "package.json");
|
|
19554
19780
|
if (options.patchPackageJson !== false) {
|
|
19555
|
-
const packageJson3 = await
|
|
19781
|
+
const packageJson3 = await readFile19(packageJsonPath, "utf8");
|
|
19556
19782
|
await writeFile17(
|
|
19557
19783
|
packageJsonPath,
|
|
19558
19784
|
rewritePackageJson(packageJson3, {
|
|
@@ -19564,7 +19790,7 @@ async function patchScaffoldedSite(outputDirectory, options) {
|
|
|
19564
19790
|
filesWritten.push("package.json");
|
|
19565
19791
|
}
|
|
19566
19792
|
const configPath = path64.join(outputDirectory, "apitogo.config.tsx");
|
|
19567
|
-
const configContent = await
|
|
19793
|
+
const configContent = await readFile19(configPath, "utf8");
|
|
19568
19794
|
await writeFile17(
|
|
19569
19795
|
configPath,
|
|
19570
19796
|
patchDashboardPageConfig(
|
|
@@ -19671,7 +19897,7 @@ async function wireDevPortalOpenApi(sourceDirectory, openApiPath) {
|
|
|
19671
19897
|
}
|
|
19672
19898
|
const jsonConfigPath = manifestFilePath(resolvedSource);
|
|
19673
19899
|
if (await pathExists4(jsonConfigPath)) {
|
|
19674
|
-
const raw = await
|
|
19900
|
+
const raw = await readFile20(jsonConfigPath, "utf8");
|
|
19675
19901
|
const siteConfig = JSON.parse(raw);
|
|
19676
19902
|
const updated = applyOpenApiToSiteConfig(siteConfig, {
|
|
19677
19903
|
input: input5,
|
|
@@ -19685,7 +19911,7 @@ async function wireDevPortalOpenApi(sourceDirectory, openApiPath) {
|
|
|
19685
19911
|
);
|
|
19686
19912
|
} else {
|
|
19687
19913
|
const tsxConfigPath = path65.join(resolvedSource, "apitogo.config.tsx");
|
|
19688
|
-
const configContent = await
|
|
19914
|
+
const configContent = await readFile20(tsxConfigPath, "utf8");
|
|
19689
19915
|
try {
|
|
19690
19916
|
const patched = patchApitogoConfigOpenApiToFile(configContent, input5);
|
|
19691
19917
|
await writeFile18(tsxConfigPath, patched);
|
|
@@ -20041,7 +20267,7 @@ export default function ${componentName}() {
|
|
|
20041
20267
|
// src/cli/make-config/scaffold-project.ts
|
|
20042
20268
|
init_package_json();
|
|
20043
20269
|
import { constants } from "node:fs";
|
|
20044
|
-
import { access as access11, mkdir as mkdir16, readFile as
|
|
20270
|
+
import { access as access11, mkdir as mkdir16, readFile as readFile21, writeFile as writeFile19 } from "node:fs/promises";
|
|
20045
20271
|
import path67 from "node:path";
|
|
20046
20272
|
import { glob as glob6 } from "glob";
|
|
20047
20273
|
|
|
@@ -20123,7 +20349,7 @@ async function ensurePackageJson(dir) {
|
|
|
20123
20349
|
`, "utf8");
|
|
20124
20350
|
return true;
|
|
20125
20351
|
}
|
|
20126
|
-
const raw = await
|
|
20352
|
+
const raw = await readFile21(pkgPath, "utf8");
|
|
20127
20353
|
let pkg;
|
|
20128
20354
|
try {
|
|
20129
20355
|
pkg = JSON.parse(raw);
|
|
@@ -20252,7 +20478,7 @@ var fileExists3 = async (filePath) => {
|
|
|
20252
20478
|
}
|
|
20253
20479
|
};
|
|
20254
20480
|
var readJsonConfig = async (filePath) => {
|
|
20255
|
-
const raw = await
|
|
20481
|
+
const raw = await readFile22(filePath, "utf8");
|
|
20256
20482
|
const parsed = JSON.parse(raw);
|
|
20257
20483
|
if (!isPlainObject3(parsed)) {
|
|
20258
20484
|
throw new Error(`${APITOGO_JSON_FILENAME} must be a JSON object.`);
|
|
@@ -20302,7 +20528,7 @@ async function persistConfig(config2, ctx) {
|
|
|
20302
20528
|
`, "utf8");
|
|
20303
20529
|
const tsxPath = path68.join(ctx.dir, "apitogo.config.tsx");
|
|
20304
20530
|
if (await fileExists3(tsxPath) && tsxRoutes.length > 0) {
|
|
20305
|
-
const tsxSource = await
|
|
20531
|
+
const tsxSource = await readFile22(tsxPath, "utf8");
|
|
20306
20532
|
if (isManagedConfigWrapper(tsxSource)) {
|
|
20307
20533
|
await writeFile20(
|
|
20308
20534
|
tsxPath,
|
|
@@ -21202,8 +21428,8 @@ async function waitForGatewayEntraProvision(client, projectId, options) {
|
|
|
21202
21428
|
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
21203
21429
|
}
|
|
21204
21430
|
}
|
|
21205
|
-
function normalizeActionKey(
|
|
21206
|
-
const trimmed =
|
|
21431
|
+
function normalizeActionKey(actionKey2) {
|
|
21432
|
+
const trimmed = actionKey2.trim();
|
|
21207
21433
|
if (trimmed.includes(":")) {
|
|
21208
21434
|
const [method2, ...pathParts] = trimmed.split(":");
|
|
21209
21435
|
const path101 = pathParts.join(":").trim();
|
|
@@ -21244,10 +21470,10 @@ async function applyGatewayPublicRoutes(client, projectId, routes, options) {
|
|
|
21244
21470
|
}
|
|
21245
21471
|
}
|
|
21246
21472
|
for (const route of routes) {
|
|
21247
|
-
let
|
|
21473
|
+
let actionKey2;
|
|
21248
21474
|
try {
|
|
21249
21475
|
const trimmed = route.trim();
|
|
21250
|
-
|
|
21476
|
+
actionKey2 = trimmed.startsWith("/") ? normalizeActionKey(`GET ${trimmed}`) : normalizeActionKey(trimmed);
|
|
21251
21477
|
} catch (error) {
|
|
21252
21478
|
unresolved.push({
|
|
21253
21479
|
route,
|
|
@@ -21255,23 +21481,23 @@ async function applyGatewayPublicRoutes(client, projectId, routes, options) {
|
|
|
21255
21481
|
});
|
|
21256
21482
|
continue;
|
|
21257
21483
|
}
|
|
21258
|
-
if (knownKeys && !knownKeys.has(
|
|
21259
|
-
const message = `Action '${
|
|
21260
|
-
unresolved.push({ route, actionKey, error: message });
|
|
21484
|
+
if (knownKeys && !knownKeys.has(actionKey2.toLowerCase())) {
|
|
21485
|
+
const message = `Action '${actionKey2}' not found in gateway actions.`;
|
|
21486
|
+
unresolved.push({ route, actionKey: actionKey2, error: message });
|
|
21261
21487
|
warnings.push(message);
|
|
21262
21488
|
continue;
|
|
21263
21489
|
}
|
|
21264
21490
|
try {
|
|
21265
21491
|
const action = await client.setGatewayActionPublic(
|
|
21266
21492
|
projectId,
|
|
21267
|
-
|
|
21493
|
+
actionKey2,
|
|
21268
21494
|
true
|
|
21269
21495
|
);
|
|
21270
21496
|
applied.push(action);
|
|
21271
21497
|
} catch (error) {
|
|
21272
21498
|
const message = error instanceof Error ? error.message : String(error);
|
|
21273
|
-
unresolved.push({ route, actionKey, error: message });
|
|
21274
|
-
warnings.push(`Failed to set public for '${
|
|
21499
|
+
unresolved.push({ route, actionKey: actionKey2, error: message });
|
|
21500
|
+
warnings.push(`Failed to set public for '${actionKey2}': ${message}`);
|
|
21275
21501
|
}
|
|
21276
21502
|
}
|
|
21277
21503
|
return { applied, unresolved, warnings };
|
|
@@ -21695,7 +21921,7 @@ async function upsertGatewayPlansFromManifest(client, config2, projectId, plans,
|
|
|
21695
21921
|
}
|
|
21696
21922
|
|
|
21697
21923
|
// src/cli/platform/helpers/openapi-gateway-servers.ts
|
|
21698
|
-
import { mkdir as mkdir18, readFile as
|
|
21924
|
+
import { mkdir as mkdir18, readFile as readFile23, writeFile as writeFile21 } from "node:fs/promises";
|
|
21699
21925
|
import path71 from "node:path";
|
|
21700
21926
|
import YAML3 from "yaml";
|
|
21701
21927
|
var GATEWAY_URL_ENV_KEY = "APITOGO_GATEWAY_URL";
|
|
@@ -21727,7 +21953,7 @@ async function resolveProjectGatewayUrl(client, projectId) {
|
|
|
21727
21953
|
return null;
|
|
21728
21954
|
}
|
|
21729
21955
|
async function readOpenApiDocument(filePath) {
|
|
21730
|
-
const content = await
|
|
21956
|
+
const content = await readFile23(filePath, "utf8");
|
|
21731
21957
|
const ext = path71.extname(filePath).toLowerCase();
|
|
21732
21958
|
const parsed = ext === ".json" ? JSON.parse(content) : YAML3.parse(content);
|
|
21733
21959
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
@@ -21756,7 +21982,7 @@ async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
|
|
|
21756
21982
|
path71.resolve(siteDirectory),
|
|
21757
21983
|
APITOGO_CONFIG_FILENAME2
|
|
21758
21984
|
);
|
|
21759
|
-
const raw = await
|
|
21985
|
+
const raw = await readFile23(configPath, "utf8");
|
|
21760
21986
|
const config2 = JSON.parse(raw);
|
|
21761
21987
|
const previousApis = config2.apis;
|
|
21762
21988
|
const previousBackend = config2.backend;
|
|
@@ -21773,7 +21999,7 @@ async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
|
|
|
21773
21999
|
`, "utf8");
|
|
21774
22000
|
return {
|
|
21775
22001
|
restore: async () => {
|
|
21776
|
-
const currentRaw = await
|
|
22002
|
+
const currentRaw = await readFile23(configPath, "utf8");
|
|
21777
22003
|
const current = JSON.parse(currentRaw);
|
|
21778
22004
|
if (previousApis === void 0) {
|
|
21779
22005
|
delete current.apis;
|
|
@@ -21808,7 +22034,7 @@ async function prepareOpenApiServersForGatewayBuild(options) {
|
|
|
21808
22034
|
);
|
|
21809
22035
|
if (!openApiPath) {
|
|
21810
22036
|
try {
|
|
21811
|
-
const raw = await
|
|
22037
|
+
const raw = await readFile23(
|
|
21812
22038
|
path71.join(siteDirectory, APITOGO_CONFIG_FILENAME2),
|
|
21813
22039
|
"utf8"
|
|
21814
22040
|
);
|
|
@@ -21834,8 +22060,8 @@ async function prepareOpenApiServersForGatewayBuild(options) {
|
|
|
21834
22060
|
}
|
|
21835
22061
|
|
|
21836
22062
|
// src/cli/platform/helpers/public-routes.ts
|
|
21837
|
-
function normalizeActionKeyFormat(
|
|
21838
|
-
const trimmed =
|
|
22063
|
+
function normalizeActionKeyFormat(actionKey2) {
|
|
22064
|
+
const trimmed = actionKey2.trim();
|
|
21839
22065
|
if (trimmed.includes(":")) {
|
|
21840
22066
|
const [method2, ...pathParts] = trimmed.split(":");
|
|
21841
22067
|
const path101 = pathParts.join(":").trim();
|
|
@@ -21882,7 +22108,7 @@ function collectManifestPublicActionKeys(gateway) {
|
|
|
21882
22108
|
}
|
|
21883
22109
|
|
|
21884
22110
|
// src/cli/platform/helpers/publish-ledger.ts
|
|
21885
|
-
import { mkdir as mkdir19, readFile as
|
|
22111
|
+
import { mkdir as mkdir19, readFile as readFile24, writeFile as writeFile22 } from "node:fs/promises";
|
|
21886
22112
|
import path72 from "node:path";
|
|
21887
22113
|
var PUBLISH_LEDGER_RELATIVE_PATH = ".apitogo/publish-state.json";
|
|
21888
22114
|
function publishLedgerPath(siteDirectory) {
|
|
@@ -21891,7 +22117,7 @@ function publishLedgerPath(siteDirectory) {
|
|
|
21891
22117
|
async function readPublishLedger(siteDirectory) {
|
|
21892
22118
|
const filePath = publishLedgerPath(siteDirectory);
|
|
21893
22119
|
try {
|
|
21894
|
-
const raw = await
|
|
22120
|
+
const raw = await readFile24(filePath, "utf8");
|
|
21895
22121
|
const parsed = JSON.parse(raw);
|
|
21896
22122
|
if (parsed?.version !== 1 || !Array.isArray(parsed.steps)) {
|
|
21897
22123
|
return null;
|
|
@@ -24063,7 +24289,7 @@ async function resolveProjectIdForPublish(client, config2, args, wait, progress,
|
|
|
24063
24289
|
import path78 from "node:path";
|
|
24064
24290
|
|
|
24065
24291
|
// src/cli/platform/helpers/dev-portal-site-api-url.ts
|
|
24066
|
-
import { readdir as readdir3, readFile as
|
|
24292
|
+
import { readdir as readdir3, readFile as readFile25, writeFile as writeFile23 } from "node:fs/promises";
|
|
24067
24293
|
import path75 from "node:path";
|
|
24068
24294
|
var SITE_API_BASE_URL_ENV_KEY = "VITE_APITOGO_AUTHENTICATION_API_BASE_URL";
|
|
24069
24295
|
var PLACEHOLDER_HOST_MARKERS = [
|
|
@@ -24088,7 +24314,7 @@ async function readSiteApiBaseUrl(sourceDirectory) {
|
|
|
24088
24314
|
const resolved = path75.resolve(sourceDirectory);
|
|
24089
24315
|
for (const envFile of [".env", ".env.production"]) {
|
|
24090
24316
|
try {
|
|
24091
|
-
const content = await
|
|
24317
|
+
const content = await readFile25(path75.join(resolved, envFile), "utf8");
|
|
24092
24318
|
const lines = [...content.matchAll(ENV_LINE_GLOBAL_RE)];
|
|
24093
24319
|
if (lines.length === 0) {
|
|
24094
24320
|
continue;
|
|
@@ -24119,7 +24345,7 @@ async function patchSiteApiBaseUrl(sourceDirectory, apiBaseUrl) {
|
|
|
24119
24345
|
for (const envFile of [".env.production", ".env"]) {
|
|
24120
24346
|
const envPath = path75.join(resolved, envFile);
|
|
24121
24347
|
try {
|
|
24122
|
-
const content = await
|
|
24348
|
+
const content = await readFile25(envPath, "utf8");
|
|
24123
24349
|
const withoutAssignments = content.replace(ENV_LINE_GLOBAL_RE, "").replace(/\n{3,}/g, "\n\n").trimEnd();
|
|
24124
24350
|
const patched = withoutAssignments ? `${withoutAssignments}
|
|
24125
24351
|
${line2}
|
|
@@ -24199,7 +24425,7 @@ async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiB
|
|
|
24199
24425
|
let found = false;
|
|
24200
24426
|
let foundPlaceholder = false;
|
|
24201
24427
|
for await (const file of walkFiles(dist)) {
|
|
24202
|
-
const content = await
|
|
24428
|
+
const content = await readFile25(file, "utf8");
|
|
24203
24429
|
if (content.includes(needle)) {
|
|
24204
24430
|
found = true;
|
|
24205
24431
|
}
|
|
@@ -26338,7 +26564,7 @@ import path80 from "node:path";
|
|
|
26338
26564
|
|
|
26339
26565
|
// src/cli/deploy/gateway.ts
|
|
26340
26566
|
import { createHash as createHash4 } from "node:crypto";
|
|
26341
|
-
import { readFile as
|
|
26567
|
+
import { readFile as readFile26 } from "node:fs/promises";
|
|
26342
26568
|
init_invariant();
|
|
26343
26569
|
var GatewayDeployError = class extends ApitogoError {
|
|
26344
26570
|
constructor(code, message, developerHint) {
|
|
@@ -26378,7 +26604,7 @@ async function readSpec(gateway) {
|
|
|
26378
26604
|
"Add one to gateway.specs in the config."
|
|
26379
26605
|
);
|
|
26380
26606
|
try {
|
|
26381
|
-
return await
|
|
26607
|
+
return await readFile26(file);
|
|
26382
26608
|
} catch {
|
|
26383
26609
|
throw new GatewayDeployError(
|
|
26384
26610
|
"GATEWAY_SPEC_UNREADABLE",
|
|
@@ -27384,11 +27610,11 @@ var export_default = {
|
|
|
27384
27610
|
import path87 from "node:path";
|
|
27385
27611
|
|
|
27386
27612
|
// src/cli/scaffold/run-scaffold-discovery.ts
|
|
27387
|
-
import { access as access15, readFile as
|
|
27613
|
+
import { access as access15, readFile as readFile29, writeFile as writeFile26 } from "node:fs/promises";
|
|
27388
27614
|
import path86 from "node:path";
|
|
27389
27615
|
|
|
27390
27616
|
// src/cli/scaffold/detect-backend.ts
|
|
27391
|
-
import { readdir as readdir4, readFile as
|
|
27617
|
+
import { readdir as readdir4, readFile as readFile27 } from "node:fs/promises";
|
|
27392
27618
|
import path84 from "node:path";
|
|
27393
27619
|
var DEFAULT_RUNTIME_VERSION = {
|
|
27394
27620
|
dotnet: "DOTNET_10",
|
|
@@ -27406,7 +27632,7 @@ async function listFiles(directory) {
|
|
|
27406
27632
|
}
|
|
27407
27633
|
async function readText(filePath) {
|
|
27408
27634
|
try {
|
|
27409
|
-
return await
|
|
27635
|
+
return await readFile27(filePath, "utf8");
|
|
27410
27636
|
} catch {
|
|
27411
27637
|
return void 0;
|
|
27412
27638
|
}
|
|
@@ -27492,7 +27718,7 @@ import {
|
|
|
27492
27718
|
lstat as lstat2,
|
|
27493
27719
|
mkdir as mkdir21,
|
|
27494
27720
|
readdir as readdir5,
|
|
27495
|
-
readFile as
|
|
27721
|
+
readFile as readFile28,
|
|
27496
27722
|
readlink,
|
|
27497
27723
|
symlink as symlink2,
|
|
27498
27724
|
writeFile as writeFile25
|
|
@@ -27723,7 +27949,7 @@ async function applyDocsNavigation(siteDirectory, routes) {
|
|
|
27723
27949
|
if (!await pathExists5(configPath)) {
|
|
27724
27950
|
return;
|
|
27725
27951
|
}
|
|
27726
|
-
const raw = await
|
|
27952
|
+
const raw = await readFile28(configPath, "utf8");
|
|
27727
27953
|
const parsed = JSON.parse(raw);
|
|
27728
27954
|
if (!isPlainObject5(parsed)) {
|
|
27729
27955
|
return;
|
|
@@ -27908,7 +28134,7 @@ async function pathExists6(filePath) {
|
|
|
27908
28134
|
async function wireOpenApiIntoJsonConfig(siteDirectory, openApiPath) {
|
|
27909
28135
|
const input5 = toSiteRelativeOpenApiInput(siteDirectory, openApiPath);
|
|
27910
28136
|
const jsonConfigPath = path86.join(siteDirectory, "apitogo.config.json");
|
|
27911
|
-
const raw = await
|
|
28137
|
+
const raw = await readFile29(jsonConfigPath, "utf8");
|
|
27912
28138
|
const siteConfig = JSON.parse(raw);
|
|
27913
28139
|
const updated = applyOpenApiToSiteConfig(siteConfig, {
|
|
27914
28140
|
input: input5,
|
|
@@ -27935,7 +28161,7 @@ async function discoverAndWireOpenApiLite(siteDirectory, mode) {
|
|
|
27935
28161
|
const invalidCandidates = [];
|
|
27936
28162
|
let selected;
|
|
27937
28163
|
for (const candidate of search.candidates) {
|
|
27938
|
-
const content = await
|
|
28164
|
+
const content = await readFile29(candidate, "utf8");
|
|
27939
28165
|
const parsed = liteParseOpenApi(content, candidate);
|
|
27940
28166
|
if (parsed.valid) {
|
|
27941
28167
|
selected = {
|
|
@@ -28015,7 +28241,7 @@ async function discoverAndWireBackend(siteDirectory, mode) {
|
|
|
28015
28241
|
}
|
|
28016
28242
|
try {
|
|
28017
28243
|
const siteConfig = JSON.parse(
|
|
28018
|
-
await
|
|
28244
|
+
await readFile29(jsonConfigPath, "utf8")
|
|
28019
28245
|
);
|
|
28020
28246
|
const existing = siteConfig.backend && typeof siteConfig.backend === "object" && !Array.isArray(siteConfig.backend) ? siteConfig.backend : {};
|
|
28021
28247
|
if (typeof existing.sourceDirectory === "string" && existing.sourceDirectory.trim()) {
|
|
@@ -28595,7 +28821,7 @@ async function createProjectV2(options, deps) {
|
|
|
28595
28821
|
modules,
|
|
28596
28822
|
wait: options.wait !== false
|
|
28597
28823
|
});
|
|
28598
|
-
const outcome =
|
|
28824
|
+
const outcome = parse4(raw);
|
|
28599
28825
|
if (outcome.requiresPlatformPlanSelection) {
|
|
28600
28826
|
throw new ProjectCreateError(
|
|
28601
28827
|
"PLAN_NOT_SELECTED",
|
|
@@ -28626,7 +28852,7 @@ async function createProjectV2(options, deps) {
|
|
|
28626
28852
|
resumed: outcome.resumed === true
|
|
28627
28853
|
};
|
|
28628
28854
|
}
|
|
28629
|
-
function
|
|
28855
|
+
function parse4(raw) {
|
|
28630
28856
|
try {
|
|
28631
28857
|
return JSON.parse(raw);
|
|
28632
28858
|
} catch {
|
|
@@ -29774,6 +30000,7 @@ Type the project name to confirm: `
|
|
|
29774
30000
|
projectId,
|
|
29775
30001
|
projectName: name,
|
|
29776
30002
|
status: "removed",
|
|
30003
|
+
scope: "gateway",
|
|
29777
30004
|
cleared,
|
|
29778
30005
|
message: "The gateway was removed. The project and your local files are kept."
|
|
29779
30006
|
};
|
|
@@ -29827,7 +30054,7 @@ async function teardownProject(argv) {
|
|
|
29827
30054
|
return;
|
|
29828
30055
|
}
|
|
29829
30056
|
printDiagnosticsToConsole(
|
|
29830
|
-
`${result.status === "removed" ? "Deleted" : "Queued deletion of"} project ${result.projectName} (${result.projectId}).`
|
|
30057
|
+
result.scope === "gateway" ? `Removed the gateway of project ${result.projectName} (${result.projectId}).` : `${result.status === "removed" ? "Deleted" : "Queued deletion of"} project ${result.projectName} (${result.projectId}).`
|
|
29831
30058
|
);
|
|
29832
30059
|
if (result.cleared.length > 0)
|
|
29833
30060
|
printDiagnosticsToConsole(
|