@lukoweb/apitogo 0.2.53 → 0.2.54
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/README.md +15 -2
- package/dist/cli/cli.js +662 -403
- package/dist/cli/worker.js +7 -1
- package/dist/declarations/cli/common/spawn-command.d.ts +3 -0
- package/dist/declarations/cli/platform/helpers/progress.d.ts +4 -1
- package/dist/declarations/lib/components/SiteTitle.d.ts +1 -0
- package/package.json +1 -1
- package/src/config/v2/docs-navigation.ts +11 -3
- package/src/config/v2/full-server.ts +1 -1
- package/src/config/v2/home-redirect.ts +39 -6
- package/src/config/v2/page-order.ts +73 -0
- package/src/config/v2/services.ts +5 -0
- package/src/config/v2/tsx-pages.ts +10 -1
- package/src/config/v2/wrapper.ts +12 -2
- package/src/lib/authentication/providers/dev-portal-auth-pages.tsx +18 -1
- package/src/lib/components/SiteTitle.tsx +69 -58
- package/src/vite/prerender/worker.ts +132 -118
package/dist/cli/cli.js
CHANGED
|
@@ -837,7 +837,7 @@ import { stat as stat4 } from "node:fs/promises";
|
|
|
837
837
|
var fileExists;
|
|
838
838
|
var init_file_exists = __esm({
|
|
839
839
|
"src/config/file-exists.ts"() {
|
|
840
|
-
fileExists = (
|
|
840
|
+
fileExists = (path98) => stat4(path98).then(() => true).catch(() => false);
|
|
841
841
|
}
|
|
842
842
|
});
|
|
843
843
|
|
|
@@ -5523,10 +5523,10 @@ function createSpinner(initialText, { stream = process.stderr, silent = false }
|
|
|
5523
5523
|
stream.write(`${initialText}
|
|
5524
5524
|
`);
|
|
5525
5525
|
return {
|
|
5526
|
-
update(
|
|
5527
|
-
if (
|
|
5528
|
-
last =
|
|
5529
|
-
stream.write(`${
|
|
5526
|
+
update(text3) {
|
|
5527
|
+
if (text3 === last) return;
|
|
5528
|
+
last = text3;
|
|
5529
|
+
stream.write(`${text3}
|
|
5530
5530
|
`);
|
|
5531
5531
|
},
|
|
5532
5532
|
log: (line2) => void stream.write(`${line2}
|
|
@@ -5536,7 +5536,7 @@ function createSpinner(initialText, { stream = process.stderr, silent = false }
|
|
|
5536
5536
|
};
|
|
5537
5537
|
}
|
|
5538
5538
|
const startedAt = Date.now();
|
|
5539
|
-
let
|
|
5539
|
+
let text2 = initialText;
|
|
5540
5540
|
let frame = 0;
|
|
5541
5541
|
let timer;
|
|
5542
5542
|
const clear = () => stream.write("\r\x1B[K");
|
|
@@ -5547,7 +5547,7 @@ function createSpinner(initialText, { stream = process.stderr, silent = false }
|
|
|
5547
5547
|
10,
|
|
5548
5548
|
(stream.columns || 80) - 3 - ` (${formatElapsed(elapsed)})`.length
|
|
5549
5549
|
);
|
|
5550
|
-
const shown =
|
|
5550
|
+
const shown = text2.length > room ? `${text2.slice(0, room - 1)}\u2026` : text2;
|
|
5551
5551
|
stream.write(
|
|
5552
5552
|
`\r\x1B[K${colors.cyan(FRAMES[frame++ % FRAMES.length])} ${shown}${suffix}`
|
|
5553
5553
|
);
|
|
@@ -5560,7 +5560,7 @@ function createSpinner(initialText, { stream = process.stderr, silent = false }
|
|
|
5560
5560
|
timer.unref();
|
|
5561
5561
|
const spinner = {
|
|
5562
5562
|
update(next) {
|
|
5563
|
-
|
|
5563
|
+
text2 = next;
|
|
5564
5564
|
},
|
|
5565
5565
|
log(line2) {
|
|
5566
5566
|
if (!timer) {
|
|
@@ -5585,8 +5585,8 @@ function createSpinner(initialText, { stream = process.stderr, silent = false }
|
|
|
5585
5585
|
active.add(spinner);
|
|
5586
5586
|
return spinner;
|
|
5587
5587
|
}
|
|
5588
|
-
async function withSpinner(
|
|
5589
|
-
const spinner = createSpinner(
|
|
5588
|
+
async function withSpinner(text2, fn, options) {
|
|
5589
|
+
const spinner = createSpinner(text2, options);
|
|
5590
5590
|
try {
|
|
5591
5591
|
return await fn(spinner);
|
|
5592
5592
|
} finally {
|
|
@@ -5631,9 +5631,9 @@ function printBoxToConsole(message) {
|
|
|
5631
5631
|
}
|
|
5632
5632
|
async function printCriticalFailureToConsoleAndExit(message) {
|
|
5633
5633
|
stopAllSpinners();
|
|
5634
|
-
const
|
|
5634
|
+
const text2 = typeof message === "string" && message.trim() === "" ? "Command failed with no further details." : message;
|
|
5635
5635
|
console.error(
|
|
5636
|
-
`${colors2.bold(colors2.red(`${withSymbol(symbols.error, process.stderr.isTTY)}Error:`))} ${colors2.red(
|
|
5636
|
+
`${colors2.bold(colors2.red(`${withSymbol(symbols.error, process.stderr.isTTY)}Error:`))} ${colors2.red(text2)}`
|
|
5637
5637
|
);
|
|
5638
5638
|
await Sentry.close(MAX_WAIT_PENDING_TIME_MS).then(() => {
|
|
5639
5639
|
process.exit(1);
|
|
@@ -5872,8 +5872,8 @@ function formatConfigIssue(issue4) {
|
|
|
5872
5872
|
const hint = issue4.hint ? ` ${issue4.hint}` : "";
|
|
5873
5873
|
const rest = issue4.message.slice(issue4.path.length);
|
|
5874
5874
|
const startsWithPath = issue4.path !== "" && issue4.message.startsWith(issue4.path) && (rest === "" || /^[\s:]/.test(rest));
|
|
5875
|
-
const
|
|
5876
|
-
return `${
|
|
5875
|
+
const text2 = startsWithPath ? issue4.message : `${issue4.path === "" ? "(root)" : issue4.path}: ${issue4.message}`;
|
|
5876
|
+
return `${text2}${hint} [${issue4.code}]`;
|
|
5877
5877
|
}
|
|
5878
5878
|
var ConfigError = class extends ApitogoError {
|
|
5879
5879
|
issues;
|
|
@@ -6073,8 +6073,8 @@ var ConfigV2Schema = z.strictObject({
|
|
|
6073
6073
|
var REMOVED_KEYS = {
|
|
6074
6074
|
"plans.provider": "plans.provider was removed. Only plans.billing.provider (stripe or none) is selectable."
|
|
6075
6075
|
};
|
|
6076
|
-
function pathToString(
|
|
6077
|
-
return
|
|
6076
|
+
function pathToString(path98) {
|
|
6077
|
+
return path98.reduce(
|
|
6078
6078
|
(acc, segment) => typeof segment === "number" ? `${acc}[${segment}]` : acc === "" ? String(segment) : `${acc}.${String(segment)}`,
|
|
6079
6079
|
""
|
|
6080
6080
|
);
|
|
@@ -6094,9 +6094,9 @@ function step(schema2, segment) {
|
|
|
6094
6094
|
}
|
|
6095
6095
|
return void 0;
|
|
6096
6096
|
}
|
|
6097
|
-
function knownKeysAt(
|
|
6097
|
+
function knownKeysAt(path98) {
|
|
6098
6098
|
let current = ConfigV2Schema;
|
|
6099
|
-
for (const segment of
|
|
6099
|
+
for (const segment of path98) {
|
|
6100
6100
|
if (!current) return [];
|
|
6101
6101
|
current = step(current, segment);
|
|
6102
6102
|
}
|
|
@@ -6132,7 +6132,7 @@ function unknownKeyHint(fullPath, key, known) {
|
|
|
6132
6132
|
return known.length > 0 ? `Allowed keys: ${known.join(", ")}.` : void 0;
|
|
6133
6133
|
}
|
|
6134
6134
|
function mapIssue(issue4) {
|
|
6135
|
-
const
|
|
6135
|
+
const path98 = pathToString(issue4.path);
|
|
6136
6136
|
switch (issue4.code) {
|
|
6137
6137
|
case "unrecognized_keys":
|
|
6138
6138
|
return issue4.keys.map((key) => {
|
|
@@ -6148,20 +6148,20 @@ function mapIssue(issue4) {
|
|
|
6148
6148
|
return [
|
|
6149
6149
|
{
|
|
6150
6150
|
code: "CONFIG_INVALID_VALUE",
|
|
6151
|
-
path:
|
|
6151
|
+
path: path98,
|
|
6152
6152
|
message: `must be one of: ${issue4.values.map((v) => JSON.stringify(v)).join(", ")}.`
|
|
6153
6153
|
}
|
|
6154
6154
|
];
|
|
6155
6155
|
case "custom": {
|
|
6156
6156
|
const code = typeof issue4.params?.code === "string" ? issue4.params.code : "CONFIG_INVALID_VALUE";
|
|
6157
|
-
return [{ code, path:
|
|
6157
|
+
return [{ code, path: path98, message: issue4.message ?? "is invalid." }];
|
|
6158
6158
|
}
|
|
6159
6159
|
case "invalid_type":
|
|
6160
6160
|
return [
|
|
6161
|
-
/received undefined/.test(issue4.message) ? { code: "CONFIG_MISSING_FIELD", path:
|
|
6161
|
+
/received undefined/.test(issue4.message) ? { code: "CONFIG_MISSING_FIELD", path: path98, message: "is required." } : { code: "CONFIG_INVALID_VALUE", path: path98, message: issue4.message }
|
|
6162
6162
|
];
|
|
6163
6163
|
default:
|
|
6164
|
-
return [{ code: "CONFIG_INVALID_VALUE", path:
|
|
6164
|
+
return [{ code: "CONFIG_INVALID_VALUE", path: path98, message: issue4.message }];
|
|
6165
6165
|
}
|
|
6166
6166
|
}
|
|
6167
6167
|
function isRecord(value) {
|
|
@@ -6391,16 +6391,16 @@ var NOT_DOCS = /^(readme|license|licence|changelog)(\.|$)/i;
|
|
|
6391
6391
|
var DOCS_SEARCH_DEPTH = 2;
|
|
6392
6392
|
var OWN_PAGES_FOLDER = "portal/pages";
|
|
6393
6393
|
async function countDocs(dir) {
|
|
6394
|
-
let
|
|
6394
|
+
let count2 = 0;
|
|
6395
6395
|
for (const entry of await readEntries(dir)) {
|
|
6396
6396
|
if (entry.isDirectory()) {
|
|
6397
6397
|
if (!IGNORED_DIRS.has(entry.name))
|
|
6398
|
-
|
|
6398
|
+
count2 += await countDocs(path6.join(dir, entry.name));
|
|
6399
6399
|
} else if (entry.isFile() && DOCS_EXTENSIONS.has(path6.extname(entry.name))) {
|
|
6400
|
-
|
|
6400
|
+
count2 += 1;
|
|
6401
6401
|
}
|
|
6402
6402
|
}
|
|
6403
|
-
return
|
|
6403
|
+
return count2;
|
|
6404
6404
|
}
|
|
6405
6405
|
async function detectExistingDocs(dir) {
|
|
6406
6406
|
const candidates = [];
|
|
@@ -6562,14 +6562,14 @@ function resolveConfigV2(config2, configPath) {
|
|
|
6562
6562
|
}
|
|
6563
6563
|
|
|
6564
6564
|
// src/config/v2/load.ts
|
|
6565
|
-
function describeJsonError(error,
|
|
6565
|
+
function describeJsonError(error, text2) {
|
|
6566
6566
|
const message = error instanceof Error ? error.message : String(error);
|
|
6567
6567
|
const lineColumn = /line (\d+) column (\d+)/.exec(message);
|
|
6568
6568
|
if (lineColumn) return `${message}`;
|
|
6569
6569
|
const position = /position (\d+)/.exec(message);
|
|
6570
6570
|
if (!position) return message;
|
|
6571
6571
|
const offset = Number(position[1]);
|
|
6572
|
-
const before =
|
|
6572
|
+
const before = text2.slice(0, offset);
|
|
6573
6573
|
const line2 = before.split("\n").length;
|
|
6574
6574
|
const column = offset - before.lastIndexOf("\n");
|
|
6575
6575
|
return `${message} (line ${line2} column ${column})`;
|
|
@@ -6587,16 +6587,16 @@ function loadConfigV2(pathOrDir) {
|
|
|
6587
6587
|
}
|
|
6588
6588
|
]);
|
|
6589
6589
|
}
|
|
6590
|
-
const
|
|
6590
|
+
const text2 = readFileSync2(configPath, "utf8");
|
|
6591
6591
|
let raw;
|
|
6592
6592
|
try {
|
|
6593
|
-
raw = JSON.parse(
|
|
6593
|
+
raw = JSON.parse(text2);
|
|
6594
6594
|
} catch (error) {
|
|
6595
6595
|
throw new ConfigError(path8.basename(configPath), [
|
|
6596
6596
|
{
|
|
6597
6597
|
code: "CONFIG_INVALID_JSON",
|
|
6598
6598
|
path: "",
|
|
6599
|
-
message: describeJsonError(error,
|
|
6599
|
+
message: describeJsonError(error, text2),
|
|
6600
6600
|
hint: "Fix the JSON syntax; comments and trailing commas are not allowed."
|
|
6601
6601
|
}
|
|
6602
6602
|
]);
|
|
@@ -6617,6 +6617,47 @@ import path9 from "node:path";
|
|
|
6617
6617
|
import { glob } from "glob";
|
|
6618
6618
|
import globParent from "glob-parent";
|
|
6619
6619
|
|
|
6620
|
+
// src/config/v2/page-order.ts
|
|
6621
|
+
var FIRST_PAGE_NAMES = [
|
|
6622
|
+
"introduction",
|
|
6623
|
+
"intro",
|
|
6624
|
+
"welcome",
|
|
6625
|
+
"getting-started",
|
|
6626
|
+
"get-started",
|
|
6627
|
+
"overview",
|
|
6628
|
+
"quickstart",
|
|
6629
|
+
"quick-start"
|
|
6630
|
+
];
|
|
6631
|
+
var lastSegment = (route) => route.split("/").filter(Boolean).pop() ?? "";
|
|
6632
|
+
var rank = (route, orders) => {
|
|
6633
|
+
const name = lastSegment(route).toLowerCase();
|
|
6634
|
+
if (name === "index" || route === "/") return [0, 0];
|
|
6635
|
+
const order = orders.get(route);
|
|
6636
|
+
if (order !== void 0) return [1, order];
|
|
6637
|
+
const preferred = FIRST_PAGE_NAMES.indexOf(name);
|
|
6638
|
+
return [2, preferred === -1 ? FIRST_PAGE_NAMES.length : preferred];
|
|
6639
|
+
};
|
|
6640
|
+
function comparePages(a, b, orders = /* @__PURE__ */ new Map()) {
|
|
6641
|
+
const [groupA, valueA] = rank(a, orders);
|
|
6642
|
+
const [groupB, valueB] = rank(b, orders);
|
|
6643
|
+
return groupA - groupB || valueA - valueB || a.localeCompare(b);
|
|
6644
|
+
}
|
|
6645
|
+
function firstPage(routes, orders = /* @__PURE__ */ new Map()) {
|
|
6646
|
+
const depth = (route) => route.split("/").length;
|
|
6647
|
+
return [...routes].sort(
|
|
6648
|
+
(a, b) => depth(a) - depth(b) || comparePages(a, b, orders)
|
|
6649
|
+
)[0];
|
|
6650
|
+
}
|
|
6651
|
+
function orderValue(value) {
|
|
6652
|
+
const number = typeof value === "number" ? value : typeof value === "string" && value.trim() !== "" ? Number(value) : Number.NaN;
|
|
6653
|
+
return Number.isInteger(number) ? number : void 0;
|
|
6654
|
+
}
|
|
6655
|
+
var TSX_ORDER = /export\s+const\s+order\s*(?::\s*number\s*)?=\s*(-?\d+)/;
|
|
6656
|
+
function tsxPageOrder(source) {
|
|
6657
|
+
const match = TSX_ORDER.exec(source);
|
|
6658
|
+
return match?.[1] ? Number(match[1]) : void 0;
|
|
6659
|
+
}
|
|
6660
|
+
|
|
6620
6661
|
// src/config/v2/docs-navigation.ts
|
|
6621
6662
|
var DOCS_NAVIGATION_LABEL = "Documentation";
|
|
6622
6663
|
var emptyBranch = () => ({ pages: /* @__PURE__ */ new Map(), folders: /* @__PURE__ */ new Map() });
|
|
@@ -6625,9 +6666,9 @@ function folderLabel(name) {
|
|
|
6625
6666
|
return words.charAt(0).toUpperCase() + words.slice(1);
|
|
6626
6667
|
}
|
|
6627
6668
|
var byName = (a, b) => a.localeCompare(b);
|
|
6628
|
-
var toItems = (branch, prefix) => {
|
|
6669
|
+
var toItems = (branch, prefix, orders) => {
|
|
6629
6670
|
const names = [...branch.pages.keys()].sort(
|
|
6630
|
-
(a, b) => a
|
|
6671
|
+
(a, b) => comparePages(`/${prefix}${a}`, `/${prefix}${b}`, orders)
|
|
6631
6672
|
);
|
|
6632
6673
|
const folders = [...branch.folders.keys()].sort(byName);
|
|
6633
6674
|
const folderPath = prefix === "" ? "/" : `/${prefix.slice(0, -1)}`;
|
|
@@ -6653,7 +6694,8 @@ var toItems = (branch, prefix) => {
|
|
|
6653
6694
|
collapsed: false,
|
|
6654
6695
|
items: toItems(
|
|
6655
6696
|
branch.folders.get(folder) ?? emptyBranch(),
|
|
6656
|
-
`${prefix}${folder}
|
|
6697
|
+
`${prefix}${folder}/`,
|
|
6698
|
+
orders
|
|
6657
6699
|
)
|
|
6658
6700
|
})
|
|
6659
6701
|
)
|
|
@@ -6669,7 +6711,7 @@ var branchOf = (root, route) => {
|
|
|
6669
6711
|
}, root);
|
|
6670
6712
|
return { branch, page };
|
|
6671
6713
|
};
|
|
6672
|
-
function docsNavigation(routes, customPages = []) {
|
|
6714
|
+
function docsNavigation(routes, customPages = [], orders = /* @__PURE__ */ new Map()) {
|
|
6673
6715
|
const root = emptyBranch();
|
|
6674
6716
|
for (const route of routes) {
|
|
6675
6717
|
const { branch, page } = branchOf(root, route);
|
|
@@ -6680,7 +6722,7 @@ function docsNavigation(routes, customPages = []) {
|
|
|
6680
6722
|
if (page && !branch.pages.has(page))
|
|
6681
6723
|
branch.pages.set(page, { kind: "custom", ...custom });
|
|
6682
6724
|
}
|
|
6683
|
-
const items = toItems(root, "");
|
|
6725
|
+
const items = toItems(root, "", orders);
|
|
6684
6726
|
return items.length === 0 ? [] : [{ type: "category", label: DOCS_NAVIGATION_LABEL, items }];
|
|
6685
6727
|
}
|
|
6686
6728
|
|
|
@@ -6733,7 +6775,13 @@ async function findTsxPages(contentGlobs) {
|
|
|
6733
6775
|
const route = `/${relative.replace(/\.tsx$/, "")}`;
|
|
6734
6776
|
if (found.has(route)) continue;
|
|
6735
6777
|
const source = await readFile3(file, "utf8").catch(() => "");
|
|
6736
|
-
|
|
6778
|
+
const order = tsxPageOrder(source);
|
|
6779
|
+
found.set(route, {
|
|
6780
|
+
route,
|
|
6781
|
+
file,
|
|
6782
|
+
label: tsxPageLabel(source, file),
|
|
6783
|
+
...order !== void 0 ? { order } : {}
|
|
6784
|
+
});
|
|
6737
6785
|
}
|
|
6738
6786
|
}
|
|
6739
6787
|
return [...found.values()].sort((a, b) => a.route.localeCompare(b.route));
|
|
@@ -7087,8 +7135,8 @@ async function specRule(spec, index, resolved, out) {
|
|
|
7087
7135
|
}
|
|
7088
7136
|
let document;
|
|
7089
7137
|
try {
|
|
7090
|
-
const
|
|
7091
|
-
document = spec.toLowerCase().endsWith(".json") ? JSON.parse(
|
|
7138
|
+
const text2 = await readFile4(spec, "utf8");
|
|
7139
|
+
document = spec.toLowerCase().endsWith(".json") ? JSON.parse(text2) : parseYaml(text2);
|
|
7092
7140
|
} catch (error) {
|
|
7093
7141
|
out.error({
|
|
7094
7142
|
code: "GATEWAY_SPEC_INVALID",
|
|
@@ -7126,8 +7174,8 @@ function authRule(resolved, out) {
|
|
|
7126
7174
|
issuers: auth.issuers?.length ?? 0,
|
|
7127
7175
|
audiences: auth.audiences?.length ?? 0
|
|
7128
7176
|
};
|
|
7129
|
-
const present = Object.entries(parts).filter(([,
|
|
7130
|
-
const missing = Object.entries(parts).filter(([,
|
|
7177
|
+
const present = Object.entries(parts).filter(([, count2]) => count2 > 0).map(([name]) => name);
|
|
7178
|
+
const missing = Object.entries(parts).filter(([, count2]) => count2 === 0).map(([name]) => name);
|
|
7131
7179
|
if (missing.length === 0) return;
|
|
7132
7180
|
const blocked = "Token validation would be skipped, so deploy is blocked.";
|
|
7133
7181
|
if (present.length === 0) {
|
|
@@ -7407,7 +7455,7 @@ var ServiceManifestSchema = z3.looseObject({
|
|
|
7407
7455
|
}).optional()
|
|
7408
7456
|
}).default({})
|
|
7409
7457
|
});
|
|
7410
|
-
var issue = (code,
|
|
7458
|
+
var issue = (code, path98, message, hint) => ({ code, path: path98, message, hint });
|
|
7411
7459
|
function parseManifest(raw, file = "services.json") {
|
|
7412
7460
|
const version = typeof raw === "object" && raw !== null && "schemaVersion" in raw ? raw.schemaVersion : void 0;
|
|
7413
7461
|
if (typeof version === "number" && version > SUPPORTED_MANIFEST_SCHEMA) {
|
|
@@ -7438,15 +7486,15 @@ function parseManifest(raw, file = "services.json") {
|
|
|
7438
7486
|
}
|
|
7439
7487
|
async function readManifest(state) {
|
|
7440
7488
|
const file = manifestPathFor(state);
|
|
7441
|
-
let
|
|
7489
|
+
let text2;
|
|
7442
7490
|
try {
|
|
7443
|
-
|
|
7491
|
+
text2 = await readFile5(file, "utf8");
|
|
7444
7492
|
} catch (error) {
|
|
7445
7493
|
if (error.code === "ENOENT") return void 0;
|
|
7446
7494
|
throw error;
|
|
7447
7495
|
}
|
|
7448
7496
|
try {
|
|
7449
|
-
return parseManifest(JSON.parse(
|
|
7497
|
+
return parseManifest(JSON.parse(text2), file);
|
|
7450
7498
|
} catch (error) {
|
|
7451
7499
|
if (error instanceof SyntaxError) {
|
|
7452
7500
|
throw new ConfigError(file, [
|
|
@@ -7670,8 +7718,8 @@ var METHODS = [
|
|
|
7670
7718
|
"trace"
|
|
7671
7719
|
];
|
|
7672
7720
|
var isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7673
|
-
function actionKey(method,
|
|
7674
|
-
const trimmed =
|
|
7721
|
+
function actionKey(method, path98) {
|
|
7722
|
+
const trimmed = path98.trim();
|
|
7675
7723
|
const withSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
7676
7724
|
const normalized = withSlash.length > 1 ? withSlash.replace(/\/+$/, "") || "/" : withSlash;
|
|
7677
7725
|
return `${method.trim().toLowerCase()}:${normalized}`;
|
|
@@ -7708,8 +7756,8 @@ var ReferenceSpecError = class extends Error {
|
|
|
7708
7756
|
};
|
|
7709
7757
|
function operationsOf(paths) {
|
|
7710
7758
|
return Object.entries(paths).flatMap(
|
|
7711
|
-
([
|
|
7712
|
-
(method) => [
|
|
7759
|
+
([path98, item]) => isObject(item) ? METHODS.filter((method) => isObject(item[method])).map(
|
|
7760
|
+
(method) => [path98, item, method]
|
|
7713
7761
|
) : []
|
|
7714
7762
|
);
|
|
7715
7763
|
}
|
|
@@ -7724,14 +7772,14 @@ function buildReferenceSpec(specText, options) {
|
|
|
7724
7772
|
throw new ReferenceSpecError("The OpenAPI file could not be read.");
|
|
7725
7773
|
const doc = structuredClone(root);
|
|
7726
7774
|
const paths = isObject(doc.paths) ? doc.paths : {};
|
|
7727
|
-
for (const [
|
|
7728
|
-
if (options.deniedOperations.has(actionKey(method,
|
|
7775
|
+
for (const [path98, item, method] of operationsOf(paths))
|
|
7776
|
+
if (options.deniedOperations.has(actionKey(method, path98)))
|
|
7729
7777
|
delete item[method];
|
|
7730
|
-
for (const [
|
|
7778
|
+
for (const [path98, item] of Object.entries(paths))
|
|
7731
7779
|
if (!isObject(item) || !METHODS.some((method) => method in item))
|
|
7732
|
-
delete paths[
|
|
7733
|
-
for (const [
|
|
7734
|
-
if (options.publicOperations.has(actionKey(method,
|
|
7780
|
+
delete paths[path98];
|
|
7781
|
+
for (const [path98, item, method] of operationsOf(paths))
|
|
7782
|
+
if (options.publicOperations.has(actionKey(method, path98)))
|
|
7735
7783
|
item[method].security = [];
|
|
7736
7784
|
doc.servers = [{ url: options.gatewayBaseUrl.replace(/\/+$/, "") }];
|
|
7737
7785
|
for (const item of Object.values(paths)) {
|
|
@@ -7771,38 +7819,38 @@ function buildReferenceSpec(specText, options) {
|
|
|
7771
7819
|
if (Object.keys(components).length > 0) doc.components = components;
|
|
7772
7820
|
else delete doc.components;
|
|
7773
7821
|
doc.security = Object.keys(requirement).length > 0 ? [requirement] : [];
|
|
7774
|
-
for (const [
|
|
7822
|
+
for (const [path98, item, method] of operationsOf(paths)) {
|
|
7775
7823
|
const operation = item[method];
|
|
7776
7824
|
if (Array.isArray(operation.security) && operation.security.length > 0)
|
|
7777
7825
|
delete operation.security;
|
|
7778
|
-
if (options.apiKeyRequired && !options.publicOperations.has(actionKey(method,
|
|
7826
|
+
if (options.apiKeyRequired && !options.publicOperations.has(actionKey(method, path98)))
|
|
7779
7827
|
operation[KEY_HEADER_EXTENSION] = options.apiKeyHeader;
|
|
7780
7828
|
else delete operation[KEY_HEADER_EXTENSION];
|
|
7781
7829
|
}
|
|
7782
7830
|
return JSON.parse(hideOrigin(JSON.stringify(doc), options));
|
|
7783
7831
|
}
|
|
7784
|
-
function hideOrigin(
|
|
7832
|
+
function hideOrigin(text2, options) {
|
|
7785
7833
|
const origin = options.originUrl?.trim().replace(/\/+$/, "");
|
|
7786
|
-
if (!origin) return
|
|
7834
|
+
if (!origin) return text2;
|
|
7787
7835
|
const gateway = options.gatewayBaseUrl.trim().replace(/\/+$/, "");
|
|
7788
7836
|
const pattern = new RegExp(
|
|
7789
7837
|
origin.replace(/[.*+?^${}()|[\]\\/]/g, "\\$&"),
|
|
7790
7838
|
"gi"
|
|
7791
7839
|
);
|
|
7792
|
-
return
|
|
7840
|
+
return text2.replace(pattern, () => gateway);
|
|
7793
7841
|
}
|
|
7794
7842
|
async function renderReferenceSpec(gateway, gatewayBaseUrl, keyHeaderName) {
|
|
7795
7843
|
const file = gateway.specs[0];
|
|
7796
7844
|
if (!file)
|
|
7797
7845
|
throw new ReferenceSpecError("gateway.specs lists no OpenAPI file.");
|
|
7798
|
-
let
|
|
7846
|
+
let text2;
|
|
7799
7847
|
try {
|
|
7800
|
-
|
|
7848
|
+
text2 = await readFile6(file, "utf8");
|
|
7801
7849
|
} catch {
|
|
7802
7850
|
throw new ReferenceSpecError(`Cannot read the OpenAPI file ${file}.`);
|
|
7803
7851
|
}
|
|
7804
7852
|
const spec = buildReferenceSpec(
|
|
7805
|
-
|
|
7853
|
+
text2,
|
|
7806
7854
|
referenceOptions(gateway, gatewayBaseUrl, keyHeaderName)
|
|
7807
7855
|
);
|
|
7808
7856
|
return `${JSON.stringify(spec, null, 2)}
|
|
@@ -7917,17 +7965,34 @@ async function docRoutes(patterns, options = {}) {
|
|
|
7917
7965
|
);
|
|
7918
7966
|
return [...new Set(routes.flat())].sort();
|
|
7919
7967
|
}
|
|
7920
|
-
function pickLandingRoute(routes) {
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
|
|
7924
|
-
)
|
|
7968
|
+
function pickLandingRoute(routes, orders) {
|
|
7969
|
+
return firstPage(routes, orders);
|
|
7970
|
+
}
|
|
7971
|
+
async function docPageOrders(patterns) {
|
|
7972
|
+
const globs = patterns.map(toGlobPath);
|
|
7973
|
+
const excluded = globs.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1));
|
|
7974
|
+
const orders = /* @__PURE__ */ new Map();
|
|
7975
|
+
for (const pattern of globs.filter((p) => !p.startsWith("!"))) {
|
|
7976
|
+
const parent = globParent2(pattern);
|
|
7977
|
+
const files = await glob3(pattern, {
|
|
7978
|
+
absolute: true,
|
|
7979
|
+
posix: true,
|
|
7980
|
+
ignore: [...IGNORED2, ...excluded]
|
|
7981
|
+
});
|
|
7982
|
+
for (const raw of files) {
|
|
7983
|
+
const order = orderValue((await readFrontmatter(raw)).data.order);
|
|
7984
|
+
if (order === void 0) continue;
|
|
7985
|
+
const route = `/${path12.posix.relative(parent, raw.replace(/^\/\/\?\//, "")).replace(/\.mdx?$/, "")}`;
|
|
7986
|
+
if (!orders.has(route)) orders.set(route, order);
|
|
7987
|
+
}
|
|
7988
|
+
}
|
|
7989
|
+
return orders;
|
|
7925
7990
|
}
|
|
7926
7991
|
function homeRedirect(input5) {
|
|
7927
7992
|
if (input5.hostsDocs) {
|
|
7928
7993
|
if (input5.docRoutes.some((route) => route === "/" || route === "/index"))
|
|
7929
7994
|
return void 0;
|
|
7930
|
-
const landing = pickLandingRoute(input5.docRoutes);
|
|
7995
|
+
const landing = pickLandingRoute(input5.docRoutes, input5.pageOrders);
|
|
7931
7996
|
if (landing) return { from: "/", to: landing };
|
|
7932
7997
|
return input5.apiReferencePath ? { from: "/", to: input5.apiReferencePath } : void 0;
|
|
7933
7998
|
}
|
|
@@ -8349,10 +8414,14 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
|
|
|
8349
8414
|
const hostedDocRoutes = [
|
|
8350
8415
|
.../* @__PURE__ */ new Set([...markdownRoutes, ...tsxPages.map((page) => page.route)])
|
|
8351
8416
|
].sort();
|
|
8417
|
+
const pageOrders = plan2.docs ? await docPageOrders(profile.docs.content) : /* @__PURE__ */ new Map();
|
|
8418
|
+
for (const page of tsxPages)
|
|
8419
|
+
if (page.order !== void 0 && !pageOrders.has(page.route))
|
|
8420
|
+
pageOrders.set(page.route, page.order);
|
|
8352
8421
|
if (plan2.plansPlugin && plan2.docs) {
|
|
8353
8422
|
const landing = hostedDocRoutes.some(
|
|
8354
8423
|
(route) => route === "/" || route === "/index"
|
|
8355
|
-
) ? "/" : pickLandingRoute(hostedDocRoutes);
|
|
8424
|
+
) ? "/" : pickLandingRoute(hostedDocRoutes, pageOrders);
|
|
8356
8425
|
if (landing)
|
|
8357
8426
|
plan2.plansPlugin.links = { ...plan2.plansPlugin.links, docs: landing };
|
|
8358
8427
|
}
|
|
@@ -8362,7 +8431,8 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
|
|
|
8362
8431
|
externalDocsUrl: profile.docs.url,
|
|
8363
8432
|
apiReferencePath: plan2.apiReference ? `/${API_REFERENCE_PATH}` : void 0,
|
|
8364
8433
|
userPanel: plan2.userPanel,
|
|
8365
|
-
pricingPath: plan2.plansPlugin && hasCapability(effective.services.plans, "catalog") ? CONSOLE_ROUTES.pricing : void 0
|
|
8434
|
+
pricingPath: plan2.plansPlugin && hasCapability(effective.services.plans, "catalog") ? CONSOLE_ROUTES.pricing : void 0,
|
|
8435
|
+
pageOrders
|
|
8366
8436
|
});
|
|
8367
8437
|
const siteConfig = buildSiteConfig(
|
|
8368
8438
|
resolved,
|
|
@@ -8376,9 +8446,10 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
|
|
|
8376
8446
|
route: page.route,
|
|
8377
8447
|
label: page.label,
|
|
8378
8448
|
element: wrapperPages[index]?.id ?? ""
|
|
8379
|
-
}))
|
|
8449
|
+
})),
|
|
8450
|
+
pageOrders
|
|
8380
8451
|
),
|
|
8381
|
-
docsPath: pickLandingRoute(hostedDocRoutes),
|
|
8452
|
+
docsPath: pickLandingRoute(hostedDocRoutes, pageOrders),
|
|
8382
8453
|
demoPlans: plan2.demo && plan2.plansPlugin ? await readDemoPlans(resolved.plans?.file) : void 0,
|
|
8383
8454
|
protectedRoutes: protectedRoutesFor({
|
|
8384
8455
|
requireAuth: resolved.portal?.requireAuth,
|
|
@@ -8486,16 +8557,16 @@ async function materializeWorkspace(resolved, prepared) {
|
|
|
8486
8557
|
return root;
|
|
8487
8558
|
}
|
|
8488
8559
|
async function configFingerprint(configPath) {
|
|
8489
|
-
const
|
|
8560
|
+
const text2 = await readFile9(configPath, "utf8");
|
|
8490
8561
|
try {
|
|
8491
|
-
const raw = JSON.parse(
|
|
8562
|
+
const raw = JSON.parse(text2);
|
|
8492
8563
|
if (raw.project) {
|
|
8493
8564
|
delete raw.project.id;
|
|
8494
8565
|
if (Object.keys(raw.project).length === 0) delete raw.project;
|
|
8495
8566
|
}
|
|
8496
8567
|
return JSON.stringify(raw);
|
|
8497
8568
|
} catch {
|
|
8498
|
-
return
|
|
8569
|
+
return text2;
|
|
8499
8570
|
}
|
|
8500
8571
|
}
|
|
8501
8572
|
async function portalArtifactHash(resolved, manifestText, cliVersion, wrapper = "") {
|
|
@@ -8588,7 +8659,7 @@ const items = [
|
|
|
8588
8659
|
{ id: "3", name: "Third item" },
|
|
8589
8660
|
];
|
|
8590
8661
|
|
|
8591
|
-
// Lets the portal's API page call this server while you run it locally (\`apitogo
|
|
8662
|
+
// Lets the portal's API page call this server while you run it locally (\`apitogo run\`). Once deployed, the gateway
|
|
8592
8663
|
// answers browsers itself and keeps its own list of allowed sites.
|
|
8593
8664
|
const cors = {
|
|
8594
8665
|
"access-control-allow-origin": "*",
|
|
@@ -9282,7 +9353,10 @@ async function buildGateway(context) {
|
|
|
9282
9353
|
const policies = {
|
|
9283
9354
|
...rateLimit ? { rateLimit: { calls: rateLimit[0], periodSeconds: rateLimit[1] } } : {},
|
|
9284
9355
|
...quota ? { quota: { calls: quota[0], periodDays: quota[1] } } : {},
|
|
9285
|
-
...o.cors?.length ? { cors: o.cors } : {}
|
|
9356
|
+
...o.cors?.length ? { cors: o.cors } : {},
|
|
9357
|
+
// The sample server's health check needs no key: monitors and the platform call it, and it is not something a
|
|
9358
|
+
// plan sells, so it stays out of the plans' feature lists (API-126).
|
|
9359
|
+
...sampleServer ? { operations: { public: [`GET ${FULL_SERVER_HEALTH_PATH}`] } } : {}
|
|
9286
9360
|
};
|
|
9287
9361
|
return {
|
|
9288
9362
|
...options.disabled ? { enabled: false } : {},
|
|
@@ -9573,9 +9647,9 @@ var emptyLedger = () => ({
|
|
|
9573
9647
|
services: {}
|
|
9574
9648
|
});
|
|
9575
9649
|
async function readLedger(state) {
|
|
9576
|
-
let
|
|
9650
|
+
let text2;
|
|
9577
9651
|
try {
|
|
9578
|
-
|
|
9652
|
+
text2 = await readFile10(state.file, "utf8");
|
|
9579
9653
|
} catch (error) {
|
|
9580
9654
|
if (error.code === "ENOENT")
|
|
9581
9655
|
return emptyLedger();
|
|
@@ -9583,7 +9657,7 @@ async function readLedger(state) {
|
|
|
9583
9657
|
}
|
|
9584
9658
|
let raw;
|
|
9585
9659
|
try {
|
|
9586
|
-
raw = JSON.parse(
|
|
9660
|
+
raw = JSON.parse(text2);
|
|
9587
9661
|
} catch {
|
|
9588
9662
|
throw corrupt(state.file, "is not valid JSON");
|
|
9589
9663
|
}
|
|
@@ -9824,8 +9898,8 @@ var PlatformApiClient = class {
|
|
|
9824
9898
|
constructor(config2) {
|
|
9825
9899
|
this.config = config2;
|
|
9826
9900
|
}
|
|
9827
|
-
url(
|
|
9828
|
-
return `${this.config.apiUrl}${
|
|
9901
|
+
url(path98) {
|
|
9902
|
+
return `${this.config.apiUrl}${path98.startsWith("/") ? path98 : `/${path98}`}`;
|
|
9829
9903
|
}
|
|
9830
9904
|
headers(extra) {
|
|
9831
9905
|
return {
|
|
@@ -9835,9 +9909,9 @@ var PlatformApiClient = class {
|
|
|
9835
9909
|
...extra
|
|
9836
9910
|
};
|
|
9837
9911
|
}
|
|
9838
|
-
async request(method,
|
|
9912
|
+
async request(method, path98, init3) {
|
|
9839
9913
|
const response = await fetchWithRetry(
|
|
9840
|
-
this.url(
|
|
9914
|
+
this.url(path98),
|
|
9841
9915
|
{
|
|
9842
9916
|
method,
|
|
9843
9917
|
...init3,
|
|
@@ -10283,15 +10357,15 @@ var PlatformApiClient = class {
|
|
|
10283
10357
|
}
|
|
10284
10358
|
);
|
|
10285
10359
|
}
|
|
10286
|
-
deleteDevPortalPage(projectId,
|
|
10287
|
-
const query = new URLSearchParams({ path:
|
|
10360
|
+
deleteDevPortalPage(projectId, path98) {
|
|
10361
|
+
const query = new URLSearchParams({ path: path98 });
|
|
10288
10362
|
return this.request(
|
|
10289
10363
|
"DELETE",
|
|
10290
10364
|
`/api/v1/projects/${projectId}/dev-portal/pages/files?${query.toString()}`
|
|
10291
10365
|
);
|
|
10292
10366
|
}
|
|
10293
|
-
renameDevPortalPage(projectId,
|
|
10294
|
-
const query = new URLSearchParams({ path:
|
|
10367
|
+
renameDevPortalPage(projectId, path98, newName) {
|
|
10368
|
+
const query = new URLSearchParams({ path: path98 });
|
|
10295
10369
|
return this.request(
|
|
10296
10370
|
"POST",
|
|
10297
10371
|
`/api/v1/projects/${projectId}/dev-portal/pages/files/rename?${query.toString()}`,
|
|
@@ -10407,8 +10481,8 @@ var PlatformApiClient = class {
|
|
|
10407
10481
|
* the project-less endpoint is used; `planTier` overrides the tier used for paid-plan checks.
|
|
10408
10482
|
*/
|
|
10409
10483
|
validateGatewayPlans(plans, options = {}) {
|
|
10410
|
-
const
|
|
10411
|
-
return this.request("POST",
|
|
10484
|
+
const path98 = options.projectId ? `/api/v1/projects/${options.projectId}/gateway/plans/validate` : "/api/v1/gateway/plans/validate";
|
|
10485
|
+
return this.request("POST", path98, {
|
|
10412
10486
|
headers: { "Content-Type": "application/json" },
|
|
10413
10487
|
body: JSON.stringify({ plans, planTier: options.planTier })
|
|
10414
10488
|
});
|
|
@@ -10787,7 +10861,7 @@ import {
|
|
|
10787
10861
|
// package.json
|
|
10788
10862
|
var package_default = {
|
|
10789
10863
|
name: "@lukoweb/apitogo",
|
|
10790
|
-
version: "0.2.
|
|
10864
|
+
version: "0.2.54",
|
|
10791
10865
|
type: "module",
|
|
10792
10866
|
sideEffects: [
|
|
10793
10867
|
"**/*.css",
|
|
@@ -11505,9 +11579,9 @@ var slugifyWithCounter = () => {
|
|
|
11505
11579
|
const counts = /* @__PURE__ */ new Map();
|
|
11506
11580
|
return (str) => {
|
|
11507
11581
|
const base = slugify(str);
|
|
11508
|
-
const
|
|
11509
|
-
counts.set(base,
|
|
11510
|
-
return
|
|
11582
|
+
const count2 = counts.get(base) ?? 0;
|
|
11583
|
+
counts.set(base, count2 + 1);
|
|
11584
|
+
return count2 === 0 ? base : `${base}-${count2 + 1}`;
|
|
11511
11585
|
};
|
|
11512
11586
|
};
|
|
11513
11587
|
|
|
@@ -11572,14 +11646,14 @@ var flattenAllOf = (schema2) => {
|
|
|
11572
11646
|
};
|
|
11573
11647
|
|
|
11574
11648
|
// src/lib/util/traverse.ts
|
|
11575
|
-
var traverse = (specification, transform,
|
|
11576
|
-
const transformed = transform(specification,
|
|
11649
|
+
var traverse = (specification, transform, path98 = []) => {
|
|
11650
|
+
const transformed = transform(specification, path98);
|
|
11577
11651
|
if (typeof transformed !== "object" || transformed === null) {
|
|
11578
11652
|
return transformed;
|
|
11579
11653
|
}
|
|
11580
11654
|
const result = Array.isArray(transformed) ? [] : {};
|
|
11581
11655
|
for (const [key, value] of Object.entries(transformed)) {
|
|
11582
|
-
const currentPath = [...
|
|
11656
|
+
const currentPath = [...path98, key];
|
|
11583
11657
|
if (Array.isArray(value)) {
|
|
11584
11658
|
result[key] = value.map(
|
|
11585
11659
|
(item, index) => typeof item === "object" && item != null ? traverse(item, transform, [...currentPath, index.toString()]) : item
|
|
@@ -11607,9 +11681,9 @@ var resolveLocalRef = (schema2, ref) => {
|
|
|
11607
11681
|
if (schemaCache?.has(ref)) {
|
|
11608
11682
|
return schemaCache.get(ref);
|
|
11609
11683
|
}
|
|
11610
|
-
const
|
|
11684
|
+
const path98 = ref.split("/").slice(1);
|
|
11611
11685
|
let current = schema2;
|
|
11612
|
-
for (const segment of
|
|
11686
|
+
for (const segment of path98) {
|
|
11613
11687
|
if (!current || typeof current !== "object") {
|
|
11614
11688
|
current = null;
|
|
11615
11689
|
}
|
|
@@ -11628,7 +11702,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
11628
11702
|
}
|
|
11629
11703
|
const cloned = structuredClone(schema2);
|
|
11630
11704
|
const visited = /* @__PURE__ */ new Set();
|
|
11631
|
-
const resolve = async (current,
|
|
11705
|
+
const resolve = async (current, path98) => {
|
|
11632
11706
|
if (isIndexableObject(current)) {
|
|
11633
11707
|
if (visited.has(current)) {
|
|
11634
11708
|
return CIRCULAR_REF;
|
|
@@ -11636,7 +11710,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
11636
11710
|
visited.add(current);
|
|
11637
11711
|
if (Array.isArray(current)) {
|
|
11638
11712
|
for (let index = 0; index < current.length; index++) {
|
|
11639
|
-
current[index] = await resolve(current[index], `${
|
|
11713
|
+
current[index] = await resolve(current[index], `${path98}/${index}`);
|
|
11640
11714
|
}
|
|
11641
11715
|
} else {
|
|
11642
11716
|
if ("$ref" in current && typeof current.$ref === "string") {
|
|
@@ -11647,13 +11721,13 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
11647
11721
|
for (const resolver of resolvers) {
|
|
11648
11722
|
const resolved = await resolver($ref);
|
|
11649
11723
|
if (resolved) {
|
|
11650
|
-
result2 = await resolve(resolved,
|
|
11724
|
+
result2 = await resolve(resolved, path98);
|
|
11651
11725
|
break;
|
|
11652
11726
|
}
|
|
11653
11727
|
}
|
|
11654
11728
|
if (result2 === void 0) {
|
|
11655
11729
|
const resolved = await resolveLocalRef(cloned, $ref);
|
|
11656
|
-
result2 = await resolve(resolved,
|
|
11730
|
+
result2 = await resolve(resolved, path98);
|
|
11657
11731
|
}
|
|
11658
11732
|
if (hasSiblings) {
|
|
11659
11733
|
if (result2 === CIRCULAR_REF) {
|
|
@@ -11666,7 +11740,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
11666
11740
|
return result2;
|
|
11667
11741
|
}
|
|
11668
11742
|
for (const key in current) {
|
|
11669
|
-
current[key] = await resolve(current[key], `${
|
|
11743
|
+
current[key] = await resolve(current[key], `${path98}/${key}`);
|
|
11670
11744
|
}
|
|
11671
11745
|
}
|
|
11672
11746
|
visited.delete(current);
|
|
@@ -11705,9 +11779,9 @@ var upgradeSchema = (schema2) => {
|
|
|
11705
11779
|
}
|
|
11706
11780
|
return sub;
|
|
11707
11781
|
});
|
|
11708
|
-
schema2 = traverse(schema2, (sub,
|
|
11782
|
+
schema2 = traverse(schema2, (sub, path98) => {
|
|
11709
11783
|
if (sub.example !== void 0) {
|
|
11710
|
-
if (isSchemaPath(
|
|
11784
|
+
if (isSchemaPath(path98 ?? [])) {
|
|
11711
11785
|
sub.examples = [sub.example];
|
|
11712
11786
|
} else {
|
|
11713
11787
|
sub.examples = {
|
|
@@ -11720,11 +11794,11 @@ var upgradeSchema = (schema2) => {
|
|
|
11720
11794
|
}
|
|
11721
11795
|
return sub;
|
|
11722
11796
|
});
|
|
11723
|
-
schema2 = traverse(schema2, (schema3,
|
|
11797
|
+
schema2 = traverse(schema2, (schema3, path98) => {
|
|
11724
11798
|
if (schema3.type === "object" && schema3.properties !== void 0) {
|
|
11725
|
-
const parentPath =
|
|
11799
|
+
const parentPath = path98?.slice(0, -1);
|
|
11726
11800
|
const isMultipart = parentPath?.some((segment, index) => {
|
|
11727
|
-
return segment === "content" &&
|
|
11801
|
+
return segment === "content" && path98?.[index + 1] === "multipart/form-data";
|
|
11728
11802
|
});
|
|
11729
11803
|
if (isMultipart) {
|
|
11730
11804
|
const entries = Object.entries(schema3.properties);
|
|
@@ -11738,8 +11812,8 @@ var upgradeSchema = (schema2) => {
|
|
|
11738
11812
|
}
|
|
11739
11813
|
return schema3;
|
|
11740
11814
|
});
|
|
11741
|
-
schema2 = traverse(schema2, (schema3,
|
|
11742
|
-
if (
|
|
11815
|
+
schema2 = traverse(schema2, (schema3, path98) => {
|
|
11816
|
+
if (path98?.includes("content") && path98.includes("application/octet-stream")) {
|
|
11743
11817
|
return {};
|
|
11744
11818
|
}
|
|
11745
11819
|
if (schema3.type === "string" && schema3.format === "binary") {
|
|
@@ -11765,11 +11839,11 @@ var upgradeSchema = (schema2) => {
|
|
|
11765
11839
|
}
|
|
11766
11840
|
return sub;
|
|
11767
11841
|
});
|
|
11768
|
-
schema2 = traverse(schema2, (schema3,
|
|
11842
|
+
schema2 = traverse(schema2, (schema3, path98) => {
|
|
11769
11843
|
if (schema3.type === "string" && schema3.format === "byte") {
|
|
11770
|
-
const parentPath =
|
|
11844
|
+
const parentPath = path98?.slice(0, -1);
|
|
11771
11845
|
const contentMediaType = parentPath?.find(
|
|
11772
|
-
(_, index) =>
|
|
11846
|
+
(_, index) => path98?.[index - 1] === "content"
|
|
11773
11847
|
);
|
|
11774
11848
|
return {
|
|
11775
11849
|
type: "string",
|
|
@@ -11781,7 +11855,7 @@ var upgradeSchema = (schema2) => {
|
|
|
11781
11855
|
});
|
|
11782
11856
|
return schema2;
|
|
11783
11857
|
};
|
|
11784
|
-
function isSchemaPath(
|
|
11858
|
+
function isSchemaPath(path98) {
|
|
11785
11859
|
const schemaLocations = [
|
|
11786
11860
|
["components", "schemas"],
|
|
11787
11861
|
"properties",
|
|
@@ -11794,10 +11868,10 @@ function isSchemaPath(path97) {
|
|
|
11794
11868
|
];
|
|
11795
11869
|
return schemaLocations.some((location) => {
|
|
11796
11870
|
if (Array.isArray(location)) {
|
|
11797
|
-
return location.every((segment, index) =>
|
|
11871
|
+
return location.every((segment, index) => path98[index] === segment);
|
|
11798
11872
|
}
|
|
11799
|
-
return
|
|
11800
|
-
}) ||
|
|
11873
|
+
return path98.includes(location);
|
|
11874
|
+
}) || path98.includes("schema") || path98.some((segment) => segment.endsWith("Schema"));
|
|
11801
11875
|
}
|
|
11802
11876
|
|
|
11803
11877
|
// src/lib/oas/parser/index.ts
|
|
@@ -11879,13 +11953,13 @@ var OPENAPI_PROPS = /* @__PURE__ */ new Set([
|
|
|
11879
11953
|
"anyOf",
|
|
11880
11954
|
"oneOf"
|
|
11881
11955
|
]);
|
|
11882
|
-
var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(),
|
|
11956
|
+
var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path98 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
|
|
11883
11957
|
if (obj === null || typeof obj !== "object") return obj;
|
|
11884
11958
|
const refPath = obj.__$ref;
|
|
11885
11959
|
const isCircular = currentPath.has(obj) || typeof refPath === "string" && currentRefPaths.has(refPath);
|
|
11886
11960
|
if (isCircular) {
|
|
11887
11961
|
if (typeof refPath === "string") return SCHEMA_REF_PREFIX + refPath;
|
|
11888
|
-
const circularProp =
|
|
11962
|
+
const circularProp = path98.find((p) => !OPENAPI_PROPS.has(p)) || path98[0];
|
|
11889
11963
|
return [CIRCULAR_REF, circularProp].filter(Boolean).join(":");
|
|
11890
11964
|
}
|
|
11891
11965
|
if (refs.has(obj)) return refs.get(obj);
|
|
@@ -11895,7 +11969,7 @@ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs
|
|
|
11895
11969
|
value,
|
|
11896
11970
|
currentPath,
|
|
11897
11971
|
refs,
|
|
11898
|
-
[...
|
|
11972
|
+
[...path98, key],
|
|
11899
11973
|
currentRefPaths
|
|
11900
11974
|
);
|
|
11901
11975
|
const result = Array.isArray(obj) ? obj.map((item, i) => recurse(item, i.toString())) : Object.fromEntries(
|
|
@@ -11930,7 +12004,7 @@ var resolveExtensions = (obj) => Object.fromEntries(
|
|
|
11930
12004
|
var getAllTags = (schema2) => {
|
|
11931
12005
|
const rootTags = schema2.tags ?? [];
|
|
11932
12006
|
const operations = Object.values(schema2.paths ?? {}).flatMap(
|
|
11933
|
-
(
|
|
12007
|
+
(path98) => HttpMethods.map((k) => path98?.[k]).filter((op) => op != null)
|
|
11934
12008
|
);
|
|
11935
12009
|
const operationTags = new Set(operations.flatMap((op) => op.tags ?? []));
|
|
11936
12010
|
const hasUntaggedOperations = operations.some(
|
|
@@ -11985,7 +12059,7 @@ var getAllSlugs = (ops, schemaTags = []) => {
|
|
|
11985
12059
|
var getOperationSlugKey = (op) => [op.path, op.method, op.operationId, op.summary].filter(Boolean).join("-");
|
|
11986
12060
|
var getAllOperations = (paths) => {
|
|
11987
12061
|
const operations = Object.entries(paths ?? {}).flatMap(
|
|
11988
|
-
([
|
|
12062
|
+
([path98, value]) => HttpMethods.flatMap((method) => {
|
|
11989
12063
|
if (!value?.[method]) return [];
|
|
11990
12064
|
const operation = value[method];
|
|
11991
12065
|
const pathParameters = value.parameters ?? [];
|
|
@@ -12005,7 +12079,7 @@ var getAllOperations = (paths) => {
|
|
|
12005
12079
|
return {
|
|
12006
12080
|
...operation,
|
|
12007
12081
|
method,
|
|
12008
|
-
path:
|
|
12082
|
+
path: path98,
|
|
12009
12083
|
parameters,
|
|
12010
12084
|
servers,
|
|
12011
12085
|
tags: operation.tags ?? []
|
|
@@ -12363,8 +12437,8 @@ var Schema = builder.objectRef("Schema").implement({
|
|
|
12363
12437
|
}),
|
|
12364
12438
|
paths: t.field({
|
|
12365
12439
|
type: [PathItem],
|
|
12366
|
-
resolve: (root) => Object.entries(root.paths ?? {}).map(([
|
|
12367
|
-
path:
|
|
12440
|
+
resolve: (root) => Object.entries(root.paths ?? {}).map(([path98, value]) => ({
|
|
12441
|
+
path: path98,
|
|
12368
12442
|
// biome-ignore lint/style/noNonNullAssertion: value is guaranteed to be defined
|
|
12369
12443
|
methods: Object.keys(value)
|
|
12370
12444
|
}))
|
|
@@ -12529,7 +12603,7 @@ init_joinUrl();
|
|
|
12529
12603
|
|
|
12530
12604
|
// src/vite/api/schema-codegen.ts
|
|
12531
12605
|
var unescapeJsonPointer = (uri) => decodeURIComponent(uri.replace(/~1/g, "/").replace(/~0/g, "~"));
|
|
12532
|
-
var getSegmentsFromPath = (
|
|
12606
|
+
var getSegmentsFromPath = (path98) => path98.split("/").slice(1).map(unescapeJsonPointer);
|
|
12533
12607
|
var createLocalRefMap = (obj) => {
|
|
12534
12608
|
const refMap = /* @__PURE__ */ new Map();
|
|
12535
12609
|
const siblingsMap = /* @__PURE__ */ new Map();
|
|
@@ -12560,16 +12634,16 @@ var replaceMarkers = (code, mergedRefs) => code.replace(/"__refMap:(.*?)"/g, '__
|
|
|
12560
12634
|
/"__refMap\+Siblings:(.*?)"/g,
|
|
12561
12635
|
(_, key) => mergedRefs.get(key) ?? `__refMap["${key}"]`
|
|
12562
12636
|
);
|
|
12563
|
-
var lookup = (schema2,
|
|
12564
|
-
const parts = getSegmentsFromPath(
|
|
12637
|
+
var lookup = (schema2, path98, filePath) => {
|
|
12638
|
+
const parts = getSegmentsFromPath(path98);
|
|
12565
12639
|
let val = schema2;
|
|
12566
12640
|
for (const part of parts) {
|
|
12567
12641
|
while (val.$ref?.startsWith("#/")) {
|
|
12568
|
-
val = val.$ref ===
|
|
12642
|
+
val = val.$ref === path98 ? val : lookup(schema2, val.$ref, filePath);
|
|
12569
12643
|
}
|
|
12570
12644
|
if (val[part] === void 0) {
|
|
12571
12645
|
throw new Error(
|
|
12572
|
-
`Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${
|
|
12646
|
+
`Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path98}`
|
|
12573
12647
|
);
|
|
12574
12648
|
}
|
|
12575
12649
|
val = val[part];
|
|
@@ -12816,8 +12890,8 @@ var SchemaManager = class {
|
|
|
12816
12890
|
}
|
|
12817
12891
|
}
|
|
12818
12892
|
};
|
|
12819
|
-
getLatestSchema = (
|
|
12820
|
-
getSchemasForPath = (
|
|
12893
|
+
getLatestSchema = (path98) => this.processedSchemas[path98]?.at(0);
|
|
12894
|
+
getSchemasForPath = (path98) => this.processedSchemas[path98];
|
|
12821
12895
|
getSchemaImports = () => Object.values(this.processedSchemas).flat().filter((s) => s.importKey);
|
|
12822
12896
|
getUrlToFilePathMap = () => {
|
|
12823
12897
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -15309,14 +15383,14 @@ async function generateSitemap({
|
|
|
15309
15383
|
|
|
15310
15384
|
// src/vite/prerender/utils.ts
|
|
15311
15385
|
init_joinUrl();
|
|
15312
|
-
var resolveRoutePath = (
|
|
15313
|
-
const segments =
|
|
15386
|
+
var resolveRoutePath = (path98) => {
|
|
15387
|
+
const segments = path98.split("/");
|
|
15314
15388
|
if (segments.some((s) => s.startsWith(":") && !s.endsWith("?"))) {
|
|
15315
15389
|
return void 0;
|
|
15316
15390
|
}
|
|
15317
15391
|
return segments.filter((s) => !s.startsWith(":")).join("/") || void 0;
|
|
15318
15392
|
};
|
|
15319
|
-
var isSkipped = (
|
|
15393
|
+
var isSkipped = (path98) => path98.includes("*") || /^\d+$/.test(path98);
|
|
15320
15394
|
var resolveRoutes = (routes, parentPath = "") => routes.flatMap((route) => {
|
|
15321
15395
|
if (route.path && isSkipped(route.path)) return [];
|
|
15322
15396
|
const routePath = route.path ? resolveRoutePath(route.path) : void 0;
|
|
@@ -15393,9 +15467,9 @@ var prerender = async ({
|
|
|
15393
15467
|
let lastLogTime = start;
|
|
15394
15468
|
const quietDeployJson = process.env.APITOGO_JSON_ONLY === "1";
|
|
15395
15469
|
const writeProgress = throttle(
|
|
15396
|
-
(
|
|
15470
|
+
(count2, total, urlPath) => {
|
|
15397
15471
|
if (quietDeployJson) return;
|
|
15398
|
-
writeLine(`prerendering (${
|
|
15472
|
+
writeLine(`prerendering (${count2}/${total}) ${colors11.dim(urlPath)}`);
|
|
15399
15473
|
}
|
|
15400
15474
|
);
|
|
15401
15475
|
if (!isTTY() && !quietDeployJson) {
|
|
@@ -15759,11 +15833,12 @@ async function preparePortalWorkspace(dir, mode) {
|
|
|
15759
15833
|
return { resolved, prepared, root };
|
|
15760
15834
|
}
|
|
15761
15835
|
async function portalBuildHash(resolved, prepared) {
|
|
15836
|
+
const { generatedAt: _generatedAt, ...manifest } = prepared.publishedManifest ?? {};
|
|
15762
15837
|
return portalArtifactHash(
|
|
15763
15838
|
resolved,
|
|
15764
15839
|
void 0,
|
|
15765
15840
|
getZudokuPackageJson().version,
|
|
15766
|
-
prepared.wrapper + JSON.stringify(prepared.siteConfig) + JSON.stringify(prepared.publishedManifest
|
|
15841
|
+
prepared.wrapper + JSON.stringify(prepared.siteConfig) + JSON.stringify(prepared.publishedManifest ? manifest : null) + (prepared.referenceSpec ?? "")
|
|
15767
15842
|
);
|
|
15768
15843
|
}
|
|
15769
15844
|
function portalBuildStep(context, options = {}, build2 = runBuild) {
|
|
@@ -15824,15 +15899,15 @@ async function buildV2(options) {
|
|
|
15824
15899
|
// src/cli/check/gateway-online.ts
|
|
15825
15900
|
import { readFile as readFile16 } from "node:fs/promises";
|
|
15826
15901
|
var SPEC_SEND_LIMIT = 5 * 1024 * 1024 + 64 * 1024;
|
|
15827
|
-
var issue2 = (code,
|
|
15902
|
+
var issue2 = (code, path98, message, hint) => ({ code, path: path98, message, hint });
|
|
15828
15903
|
function capabilityIssues(gateway, answer) {
|
|
15829
15904
|
const can = answer.capabilities;
|
|
15830
15905
|
const plan2 = `your ${answer.tier} plan`;
|
|
15831
15906
|
const found = [];
|
|
15832
|
-
const unsupported = (
|
|
15907
|
+
const unsupported = (path98, what, hint) => found.push(
|
|
15833
15908
|
issue2(
|
|
15834
15909
|
"GATEWAY_CAPABILITY_UNSUPPORTED",
|
|
15835
|
-
|
|
15910
|
+
path98,
|
|
15836
15911
|
`${what} is not available on ${plan2}.`,
|
|
15837
15912
|
hint
|
|
15838
15913
|
)
|
|
@@ -15886,8 +15961,8 @@ async function onlineGatewayRules(gateway, projectId, api, derivedCors = []) {
|
|
|
15886
15961
|
const specFile = gateway.specs[0];
|
|
15887
15962
|
if (specFile) {
|
|
15888
15963
|
try {
|
|
15889
|
-
const
|
|
15890
|
-
if (
|
|
15964
|
+
const text2 = await readFile16(specFile, "utf8");
|
|
15965
|
+
if (text2.length <= SPEC_SEND_LIMIT) spec = text2;
|
|
15891
15966
|
} catch {
|
|
15892
15967
|
}
|
|
15893
15968
|
}
|
|
@@ -15956,9 +16031,9 @@ var issuesOf = (error) => error.issues.map(
|
|
|
15956
16031
|
(issue4) => `${issue4.path.join(".") || "(file)"}: ${issue4.message}`
|
|
15957
16032
|
);
|
|
15958
16033
|
async function readPlansFile(file) {
|
|
15959
|
-
let
|
|
16034
|
+
let text2;
|
|
15960
16035
|
try {
|
|
15961
|
-
|
|
16036
|
+
text2 = await readFile17(file, "utf8");
|
|
15962
16037
|
} catch {
|
|
15963
16038
|
throw new PlansFileError(
|
|
15964
16039
|
"PLANS_FILE_UNREADABLE",
|
|
@@ -15968,7 +16043,7 @@ async function readPlansFile(file) {
|
|
|
15968
16043
|
}
|
|
15969
16044
|
let raw;
|
|
15970
16045
|
try {
|
|
15971
|
-
raw = JSON.parse(
|
|
16046
|
+
raw = JSON.parse(text2);
|
|
15972
16047
|
} catch (error) {
|
|
15973
16048
|
throw new PlansFileError(
|
|
15974
16049
|
"PLANS_FILE_INVALID",
|
|
@@ -16036,9 +16111,9 @@ function toPlatformPlans(plans, options = {}) {
|
|
|
16036
16111
|
}
|
|
16037
16112
|
|
|
16038
16113
|
// src/cli/check/services-online.ts
|
|
16039
|
-
var issue3 = (code,
|
|
16114
|
+
var issue3 = (code, path98, message, hint) => ({
|
|
16040
16115
|
code,
|
|
16041
|
-
path:
|
|
16116
|
+
path: path98,
|
|
16042
16117
|
message,
|
|
16043
16118
|
hint
|
|
16044
16119
|
});
|
|
@@ -16396,7 +16471,7 @@ function platformDependencies(args) {
|
|
|
16396
16471
|
async function checkV2(dir, args, deps = platformDependencies(args)) {
|
|
16397
16472
|
const output4 = await runCheckV2(dir, args, deps);
|
|
16398
16473
|
if (args.json === false) {
|
|
16399
|
-
for (const
|
|
16474
|
+
for (const text2 of formatCheckV2(output4)) console.log(text2);
|
|
16400
16475
|
} else {
|
|
16401
16476
|
console.log(JSON.stringify(output4, null, 2));
|
|
16402
16477
|
}
|
|
@@ -16514,9 +16589,23 @@ async function initV2(argv) {
|
|
|
16514
16589
|
}
|
|
16515
16590
|
|
|
16516
16591
|
// src/cli/services/packages.ts
|
|
16517
|
-
import { spawn } from "node:child_process";
|
|
16518
16592
|
import { existsSync as existsSync6 } from "node:fs";
|
|
16519
16593
|
import path52 from "node:path";
|
|
16594
|
+
|
|
16595
|
+
// src/cli/common/spawn-command.ts
|
|
16596
|
+
import {
|
|
16597
|
+
spawn
|
|
16598
|
+
} from "node:child_process";
|
|
16599
|
+
function quoteForWindowsShell(arg) {
|
|
16600
|
+
return /[\s"^&|<>()%!]/.test(arg) ? `"${arg.replace(/"/g, '""')}"` : arg;
|
|
16601
|
+
}
|
|
16602
|
+
function spawnCommand(command2, args, options = {}) {
|
|
16603
|
+
if (process.platform !== "win32") return spawn(command2, [...args], options);
|
|
16604
|
+
const line2 = [command2, ...args.map(quoteForWindowsShell)].join(" ");
|
|
16605
|
+
return spawn(line2, { ...options, shell: true });
|
|
16606
|
+
}
|
|
16607
|
+
|
|
16608
|
+
// src/cli/services/packages.ts
|
|
16520
16609
|
var USER_PANEL_PACKAGE = "@lukoweb/apitogo-module-user-panel";
|
|
16521
16610
|
var BILLING_PLUGIN_PACKAGE = "@lukoweb/apitogo-plugin-dev-portal-billing";
|
|
16522
16611
|
var LANDING_PACKAGE = "@lukoweb/apitogo-module-landing";
|
|
@@ -16563,10 +16652,9 @@ function installSpecsCommand(manager, specs) {
|
|
|
16563
16652
|
}
|
|
16564
16653
|
var specName = (spec) => spec.slice(0, spec.lastIndexOf("@"));
|
|
16565
16654
|
var runInstaller = (dir, { command: command2, args }) => new Promise((resolve, reject) => {
|
|
16566
|
-
const child =
|
|
16655
|
+
const child = spawnCommand(command2, args, {
|
|
16567
16656
|
cwd: dir,
|
|
16568
|
-
stdio: "inherit"
|
|
16569
|
-
shell: process.platform === "win32"
|
|
16657
|
+
stdio: "inherit"
|
|
16570
16658
|
});
|
|
16571
16659
|
child.on("error", reject);
|
|
16572
16660
|
child.on(
|
|
@@ -18319,7 +18407,6 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
|
|
|
18319
18407
|
}
|
|
18320
18408
|
|
|
18321
18409
|
// src/cli/platform/helpers/npm-build.ts
|
|
18322
|
-
import { spawn as spawn2 } from "node:child_process";
|
|
18323
18410
|
import { access as access7, readFile as readFile22 } from "node:fs/promises";
|
|
18324
18411
|
import path59 from "node:path";
|
|
18325
18412
|
var BUILD_LOG_TAIL_BYTES = 8192;
|
|
@@ -18370,10 +18457,9 @@ async function pathExists2(filePath) {
|
|
|
18370
18457
|
}
|
|
18371
18458
|
function runCommand(command2, args, cwd, env) {
|
|
18372
18459
|
return new Promise((resolve, reject) => {
|
|
18373
|
-
const child =
|
|
18460
|
+
const child = spawnCommand(command2, args, {
|
|
18374
18461
|
cwd,
|
|
18375
|
-
env: env ? { ...process.env, ...env } : process.env
|
|
18376
|
-
shell: process.platform === "win32"
|
|
18462
|
+
env: env ? { ...process.env, ...env } : process.env
|
|
18377
18463
|
});
|
|
18378
18464
|
let output4 = "";
|
|
18379
18465
|
child.stdout.on("data", (chunk) => {
|
|
@@ -18929,7 +19015,7 @@ async function check(argv) {
|
|
|
18929
19015
|
|
|
18930
19016
|
// src/cli/cmds/check.ts
|
|
18931
19017
|
var check_default = {
|
|
18932
|
-
desc: "Check the
|
|
19018
|
+
desc: "Check the project before a deploy: apitogo.config.json, its files and, when you are logged in, the platform's rules",
|
|
18933
19019
|
command: "check",
|
|
18934
19020
|
builder: (yargs2) => yargs2.option("dir", {
|
|
18935
19021
|
type: "string",
|
|
@@ -18942,12 +19028,12 @@ var check_default = {
|
|
|
18942
19028
|
default: false
|
|
18943
19029
|
}).option("offline", {
|
|
18944
19030
|
type: "boolean",
|
|
18945
|
-
describe: "
|
|
19031
|
+
describe: "Do not ask the platform anything (secret names and the gateway's online rules are then not checked)",
|
|
18946
19032
|
default: false
|
|
18947
19033
|
}).option("json", {
|
|
18948
19034
|
type: "boolean",
|
|
18949
|
-
describe: "Print
|
|
18950
|
-
default:
|
|
19035
|
+
describe: "Print JSON instead of text",
|
|
19036
|
+
default: false
|
|
18951
19037
|
}),
|
|
18952
19038
|
handler: async (argv) => {
|
|
18953
19039
|
await captureEvent({ argv, event: "apitogo check" });
|
|
@@ -19119,13 +19205,17 @@ function normalizeDocsSlug(value) {
|
|
|
19119
19205
|
(part) => part.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "")
|
|
19120
19206
|
).filter(Boolean).join("/");
|
|
19121
19207
|
}
|
|
19122
|
-
function
|
|
19123
|
-
|
|
19208
|
+
function withoutLeadingH1(content) {
|
|
19209
|
+
return content.replace(/^\s*#\s+[^\n]*(\r?\n)*/, "").trim();
|
|
19210
|
+
}
|
|
19211
|
+
function buildDocsPage(title, content, order) {
|
|
19212
|
+
const given = content?.trim() ? withoutLeadingH1(content) : "";
|
|
19213
|
+
const body = given || "{/* Write this page in Markdown. Every .md or .mdx file in the pages folder becomes a page of your portal. */}\n\nComing soon.";
|
|
19214
|
+
const orderLine = order === void 0 ? "" : `order: ${order}
|
|
19215
|
+
`;
|
|
19124
19216
|
return `---
|
|
19125
19217
|
title: ${JSON.stringify(title)}
|
|
19126
|
-
---
|
|
19127
|
-
|
|
19128
|
-
# ${title}
|
|
19218
|
+
${orderLine}---
|
|
19129
19219
|
|
|
19130
19220
|
${body}
|
|
19131
19221
|
`;
|
|
@@ -19134,20 +19224,26 @@ function pageComponentName(slug) {
|
|
|
19134
19224
|
const name = slug.split(/[^A-Za-z0-9]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
19135
19225
|
return `${/^[0-9]/.test(name) ? "Page" : ""}${name || "Docs"}Page`;
|
|
19136
19226
|
}
|
|
19137
|
-
function buildTsxDocsPage(slug, title, file, content) {
|
|
19138
|
-
const
|
|
19227
|
+
function buildTsxDocsPage(slug, title, file, content, order) {
|
|
19228
|
+
const given = content?.trim() ? withoutLeadingH1(content) : "";
|
|
19229
|
+
const orderExport = order === void 0 ? "" : `
|
|
19230
|
+
/** Where the page sits in the sidebar: lower numbers come first. */
|
|
19231
|
+
export const order = ${order};
|
|
19232
|
+
`;
|
|
19233
|
+
const text2 = given ? `{${JSON.stringify(given)}}` : "Coming soon.";
|
|
19139
19234
|
return `import { Callout, Heading, Typography } from "@lukoweb/apitogo/components";
|
|
19140
19235
|
|
|
19141
19236
|
/** The page's label in the sidebar. */
|
|
19142
19237
|
export const title = ${JSON.stringify(title)};
|
|
19143
|
-
|
|
19238
|
+
${orderExport}
|
|
19239
|
+
// This page is a React component: change it like any other one (add state, fetch data, use the portal's components).
|
|
19144
19240
|
export default function ${pageComponentName(slug)}() {
|
|
19145
19241
|
return (
|
|
19146
19242
|
<section className="mx-auto max-w-screen-lg px-4 py-12 pt-(--padding-content-top)">
|
|
19147
19243
|
<Typography>
|
|
19148
19244
|
<Heading level={1}>{title}</Heading>
|
|
19149
|
-
<p>${
|
|
19150
|
-
{/* A note for you while you run the portal locally (\`apitogo
|
|
19245
|
+
<p>${text2}</p>
|
|
19246
|
+
{/* A note for you while you run the portal locally (\`apitogo run\`); the deployed portal does not show it. */}
|
|
19151
19247
|
{import.meta.env.DEV && (
|
|
19152
19248
|
<Callout type="info" title="Where this page lives">
|
|
19153
19249
|
Edit <code>${file}</code>. Files whose name starts with <code>_</code> are not pages, so you can keep
|
|
@@ -19177,6 +19273,12 @@ async function writeDocsPage(project, input5) {
|
|
|
19177
19273
|
}
|
|
19178
19274
|
const slug = normalizeDocsSlug(input5.slug);
|
|
19179
19275
|
if (!slug) throw new ConfigEditError("The page path must not be empty.");
|
|
19276
|
+
if (input5.order !== void 0 && !Number.isInteger(input5.order)) {
|
|
19277
|
+
throw new ConfigEditError(
|
|
19278
|
+
`--page-order must be a whole number, not ${input5.order}.`,
|
|
19279
|
+
"For example --page-order 1 puts the page first in the sidebar."
|
|
19280
|
+
);
|
|
19281
|
+
}
|
|
19180
19282
|
const base = path62.join(portal.dir, "pages", ...slug.split("/"));
|
|
19181
19283
|
const existing = (await Promise.all(
|
|
19182
19284
|
[`${base}.tsx`, `${base}.mdx`, `${base}.md`].map(
|
|
@@ -19184,9 +19286,9 @@ async function writeDocsPage(project, input5) {
|
|
|
19184
19286
|
)
|
|
19185
19287
|
)).find((file2) => file2 !== null);
|
|
19186
19288
|
const relative = (file2) => toPosix2(path62.relative(project.dir, file2));
|
|
19187
|
-
const write = (file2, title) => writeFile18(
|
|
19289
|
+
const write = (file2, title, order = input5.order) => writeFile18(
|
|
19188
19290
|
file2,
|
|
19189
|
-
file2.endsWith(".tsx") ? buildTsxDocsPage(slug, title, relative(file2), input5.content) : buildDocsPage(title, input5.content),
|
|
19291
|
+
file2.endsWith(".tsx") ? buildTsxDocsPage(slug, title, relative(file2), input5.content, order) : buildDocsPage(title, input5.content, order),
|
|
19190
19292
|
"utf8"
|
|
19191
19293
|
);
|
|
19192
19294
|
let file;
|
|
@@ -19202,7 +19304,8 @@ async function writeDocsPage(project, input5) {
|
|
|
19202
19304
|
const title = input5.title?.trim() || (existing.endsWith(".tsx") ? tsxPageLabel(source, existing) : titleOf(source));
|
|
19203
19305
|
file = existing;
|
|
19204
19306
|
action = "updated";
|
|
19205
|
-
|
|
19307
|
+
const keptOrder = input5.order ?? (existing.endsWith(".tsx") ? tsxPageOrder(source) : orderValue(/^order:\s*(.+?)\s*$/m.exec(source)?.[1]));
|
|
19308
|
+
await write(file, title ?? slug, keptOrder);
|
|
19206
19309
|
} else {
|
|
19207
19310
|
if (existing) {
|
|
19208
19311
|
throw new ConfigEditError(
|
|
@@ -19640,7 +19743,8 @@ async function makeConfig(argv) {
|
|
|
19640
19743
|
title: argv.pageTitle,
|
|
19641
19744
|
content: argv.pageContent,
|
|
19642
19745
|
update: argv.pageUpdate === true,
|
|
19643
|
-
format: argv.pageFormat
|
|
19746
|
+
format: argv.pageFormat,
|
|
19747
|
+
order: argv.pageOrder
|
|
19644
19748
|
});
|
|
19645
19749
|
changes.push(page.action === "added" ? "page_add" : "page_update");
|
|
19646
19750
|
}
|
|
@@ -19652,7 +19756,10 @@ async function makeConfig(argv) {
|
|
|
19652
19756
|
}
|
|
19653
19757
|
}
|
|
19654
19758
|
}
|
|
19655
|
-
const message = changes.length === 0 ? "Nothing to change." :
|
|
19759
|
+
const message = changes.length === 0 ? "Nothing to change." : (
|
|
19760
|
+
// The change codes (page_add, plan_update, ...) are for scripts: they stay in the JSON output (API-126).
|
|
19761
|
+
"Done."
|
|
19762
|
+
);
|
|
19656
19763
|
if (json) {
|
|
19657
19764
|
console.log(
|
|
19658
19765
|
JSON.stringify(
|
|
@@ -19738,6 +19845,9 @@ function addConfigOptions(yargs2) {
|
|
|
19738
19845
|
type: "string",
|
|
19739
19846
|
choices: ["tsx", "mdx"],
|
|
19740
19847
|
describe: "Format of a new page: tsx (a React component, the default) or mdx (Markdown)"
|
|
19848
|
+
}).option("page-order", {
|
|
19849
|
+
type: "number",
|
|
19850
|
+
describe: "Place of --page-slug in the sidebar: lower numbers come first (pages without one follow, by name)"
|
|
19741
19851
|
}).option("page-update", {
|
|
19742
19852
|
type: "boolean",
|
|
19743
19853
|
default: false,
|
|
@@ -19747,11 +19857,11 @@ function addConfigOptions(yargs2) {
|
|
|
19747
19857
|
describe: "JSON plan added to the plans file (plans.file, default apitogo/plans.json), or replacing the one with the same sku"
|
|
19748
19858
|
}).option("patch", {
|
|
19749
19859
|
type: "string",
|
|
19750
|
-
describe: "JSON object deep-merged into apitogo.config.json; the result must be a valid
|
|
19860
|
+
describe: "JSON object deep-merged into apitogo.config.json; the result must still be a valid config"
|
|
19751
19861
|
});
|
|
19752
19862
|
}
|
|
19753
19863
|
var config_default = {
|
|
19754
|
-
desc: "Change
|
|
19864
|
+
desc: "Change the project: portal name, API code, OpenAPI files, docs pages and plans (asks in a terminal)",
|
|
19755
19865
|
command: "config",
|
|
19756
19866
|
builder: (yargs2) => addConfigOptions(yargs2),
|
|
19757
19867
|
handler: async (argv) => {
|
|
@@ -19764,14 +19874,62 @@ var config_default = {
|
|
|
19764
19874
|
init_apitogo_config_core();
|
|
19765
19875
|
import { execFile } from "node:child_process";
|
|
19766
19876
|
import { readFile as readFile24 } from "node:fs/promises";
|
|
19767
|
-
import
|
|
19877
|
+
import path65 from "node:path";
|
|
19768
19878
|
import { promisify } from "node:util";
|
|
19879
|
+
|
|
19880
|
+
// src/cli/create/dry-run.ts
|
|
19881
|
+
import { mkdir as mkdir16, mkdtemp, readdir as readdir4, rm as rm9 } from "node:fs/promises";
|
|
19882
|
+
import { tmpdir } from "node:os";
|
|
19883
|
+
import path64 from "node:path";
|
|
19884
|
+
async function listFiles(root, dir = root) {
|
|
19885
|
+
const entries = await readdir4(dir, { withFileTypes: true });
|
|
19886
|
+
const nested = await Promise.all(
|
|
19887
|
+
entries.map(async (entry) => {
|
|
19888
|
+
const full = path64.join(dir, entry.name);
|
|
19889
|
+
if (entry.isDirectory()) return listFiles(root, full);
|
|
19890
|
+
return [path64.relative(root, full).split(path64.sep).join("/")];
|
|
19891
|
+
})
|
|
19892
|
+
);
|
|
19893
|
+
return nested.flat();
|
|
19894
|
+
}
|
|
19895
|
+
async function previewCreate(input5) {
|
|
19896
|
+
const scratch = await mkdtemp(path64.join(tmpdir(), "apitogo-create-"));
|
|
19897
|
+
const dir = path64.join(scratch, "project");
|
|
19898
|
+
try {
|
|
19899
|
+
await mkdir16(dir);
|
|
19900
|
+
await applyInitPlan(await planInit({ dir, name: input5.name }));
|
|
19901
|
+
const packages = /* @__PURE__ */ new Set();
|
|
19902
|
+
for (const service of input5.services) {
|
|
19903
|
+
const edit = await planAddService(service, {
|
|
19904
|
+
...addOptionsFromArguments(service, {
|
|
19905
|
+
service,
|
|
19906
|
+
dir,
|
|
19907
|
+
template: input5.template,
|
|
19908
|
+
yes: true
|
|
19909
|
+
})
|
|
19910
|
+
});
|
|
19911
|
+
for (const pkg of Object.values(
|
|
19912
|
+
packagesToInstall(dir, edit.config)
|
|
19913
|
+
).flat())
|
|
19914
|
+
packages.add(pkg);
|
|
19915
|
+
await applyServiceEdit(edit);
|
|
19916
|
+
}
|
|
19917
|
+
return {
|
|
19918
|
+
files: (await listFiles(dir)).sort(),
|
|
19919
|
+
packages: [...packages].sort()
|
|
19920
|
+
};
|
|
19921
|
+
} finally {
|
|
19922
|
+
await rm9(scratch, { recursive: true, force: true });
|
|
19923
|
+
}
|
|
19924
|
+
}
|
|
19925
|
+
|
|
19926
|
+
// src/cli/create/handler.ts
|
|
19769
19927
|
var execFileAsync = promisify(execFile);
|
|
19770
19928
|
function nextStepHint(dir) {
|
|
19771
19929
|
const linked = loadConfigV2(dir).resolved.project.id;
|
|
19772
|
-
const cd =
|
|
19930
|
+
const cd = path65.resolve(dir) === path65.resolve(process.cwd());
|
|
19773
19931
|
const steps = linked ? "apitogo deploy" : "apitogo project create, then apitogo deploy";
|
|
19774
|
-
return cd ? `Next: ${steps}` : `Next: cd ${JSON.stringify(
|
|
19932
|
+
return cd ? `Next: ${steps}` : `Next: cd ${JSON.stringify(path65.relative(process.cwd(), dir))}, then ${steps}`;
|
|
19775
19933
|
}
|
|
19776
19934
|
function projectFolderName(name) {
|
|
19777
19935
|
return name.trim().replace(/[<>:"/\\|?*\s]+/g, "-").replace(/^[-.]+|[-.]+$/g, "") || "apitogo-project";
|
|
@@ -19797,13 +19955,13 @@ async function gitHasUncommittedChanges(dir) {
|
|
|
19797
19955
|
async function defaultName(dir) {
|
|
19798
19956
|
try {
|
|
19799
19957
|
const parsed = JSON.parse(
|
|
19800
|
-
await readFile24(
|
|
19958
|
+
await readFile24(path65.join(dir, "package.json"), "utf8")
|
|
19801
19959
|
);
|
|
19802
19960
|
if (typeof parsed.name === "string" && parsed.name.trim())
|
|
19803
19961
|
return parsed.name.replace(/^@[^/]+\//, "");
|
|
19804
19962
|
} catch {
|
|
19805
19963
|
}
|
|
19806
|
-
return
|
|
19964
|
+
return path65.basename(dir);
|
|
19807
19965
|
}
|
|
19808
19966
|
function parseServicesFlag(value) {
|
|
19809
19967
|
const names = (value ?? "").split(",").map((name) => name.trim()).filter(Boolean);
|
|
@@ -19829,7 +19987,7 @@ async function createProject(argv, deps = {}) {
|
|
|
19829
19987
|
if (!json) printDiagnosticsToConsole(line2);
|
|
19830
19988
|
};
|
|
19831
19989
|
try {
|
|
19832
|
-
const base =
|
|
19990
|
+
const base = path65.resolve(process.cwd(), argv.dir ?? ".");
|
|
19833
19991
|
let dir = base;
|
|
19834
19992
|
let requested = parseServicesFlag(argv.services);
|
|
19835
19993
|
let template = argv.template;
|
|
@@ -19852,8 +20010,8 @@ async function createProject(argv, deps = {}) {
|
|
|
19852
20010
|
default: await defaultName(base)
|
|
19853
20011
|
}) : await defaultName(base));
|
|
19854
20012
|
const folder = projectFolderName(name);
|
|
19855
|
-
if (argv.dir === void 0 && folder !==
|
|
19856
|
-
dir =
|
|
20013
|
+
if (argv.dir === void 0 && folder !== path65.basename(base))
|
|
20014
|
+
dir = path65.join(base, folder);
|
|
19857
20015
|
}
|
|
19858
20016
|
if (await (deps.hasUncommittedChanges ?? gitHasUncommittedChanges)(dir))
|
|
19859
20017
|
say(
|
|
@@ -19861,26 +20019,45 @@ async function createProject(argv, deps = {}) {
|
|
|
19861
20019
|
);
|
|
19862
20020
|
if (name !== void 0 && !await isConfigV2(dir)) {
|
|
19863
20021
|
const plan2 = await planInit({ dir, name });
|
|
19864
|
-
for (const line2 of formatInitPlan(plan2)) say(line2);
|
|
20022
|
+
if (!argv.dryRun) for (const line2 of formatInitPlan(plan2)) say(line2);
|
|
19865
20023
|
commands.push(`apitogo init --name ${JSON.stringify(name)}`);
|
|
19866
20024
|
if (argv.dryRun) {
|
|
20025
|
+
const services = requested.length > 0 ? requested : templateServices ? STARTER_SERVICES : [];
|
|
20026
|
+
const preview2 = services.length > 0 ? await previewCreate({ name, template, services }) : void 0;
|
|
20027
|
+
const folder = path65.relative(process.cwd(), dir) || ".";
|
|
19867
20028
|
if (json)
|
|
19868
20029
|
console.log(
|
|
19869
20030
|
JSON.stringify({
|
|
19870
20031
|
status: "dry-run",
|
|
19871
|
-
|
|
20032
|
+
dir: folder,
|
|
20033
|
+
services,
|
|
20034
|
+
files: preview2?.files ?? [],
|
|
20035
|
+
packages: preview2?.packages ?? [],
|
|
19872
20036
|
commands: [
|
|
19873
20037
|
...commands,
|
|
19874
|
-
...
|
|
20038
|
+
...services.map((service) => `apitogo add ${service}`)
|
|
19875
20039
|
]
|
|
19876
20040
|
})
|
|
19877
20041
|
);
|
|
19878
|
-
else
|
|
20042
|
+
else {
|
|
20043
|
+
say(`Folder: ${folder}${dir === base ? "" : " (new)"}`);
|
|
20044
|
+
if (preview2) {
|
|
20045
|
+
say(`Files (${preview2.files.length}):`);
|
|
20046
|
+
for (const file of preview2.files) say(` ${file}`);
|
|
20047
|
+
if (preview2.packages.length > 0 && argv.install !== false)
|
|
20048
|
+
say(`Packages to install: ${preview2.packages.join(", ")}`);
|
|
20049
|
+
} else {
|
|
20050
|
+
say(
|
|
20051
|
+
"The services are chosen one by one in a real run; pass --template full or --services to see their files."
|
|
20052
|
+
);
|
|
20053
|
+
}
|
|
20054
|
+
printResultToConsole("Dry run: nothing was written.");
|
|
20055
|
+
}
|
|
19879
20056
|
return;
|
|
19880
20057
|
}
|
|
19881
20058
|
await applyInitPlan(plan2);
|
|
19882
20059
|
say(
|
|
19883
|
-
dir === base ? `Created ${APITOGO_CONFIG_FILENAME}.` : `Created ${
|
|
20060
|
+
dir === base ? `Created ${APITOGO_CONFIG_FILENAME}.` : `Created ${path65.relative(base, dir)}${path65.sep}${APITOGO_CONFIG_FILENAME}.`
|
|
19884
20061
|
);
|
|
19885
20062
|
} else {
|
|
19886
20063
|
say(`${APITOGO_CONFIG_FILENAME} exists: continuing from it.`);
|
|
@@ -19981,9 +20158,8 @@ var create_default = {
|
|
|
19981
20158
|
command: "create",
|
|
19982
20159
|
builder: (yargs2) => yargs2.option("dir", {
|
|
19983
20160
|
type: "string",
|
|
19984
|
-
describe: "Project
|
|
19985
|
-
normalize: true
|
|
19986
|
-
hidden: true
|
|
20161
|
+
describe: "Project folder (default: a new folder named after the project, inside the current one)",
|
|
20162
|
+
normalize: true
|
|
19987
20163
|
}).option("name", {
|
|
19988
20164
|
type: "string",
|
|
19989
20165
|
describe: "Project name (default: folder name or package.json name)"
|
|
@@ -20005,7 +20181,7 @@ var create_default = {
|
|
|
20005
20181
|
}).option("dry-run", {
|
|
20006
20182
|
type: "boolean",
|
|
20007
20183
|
default: false,
|
|
20008
|
-
describe: "
|
|
20184
|
+
describe: "Show the folder, every file and the packages a real run makes, and write nothing"
|
|
20009
20185
|
}).option("yes", {
|
|
20010
20186
|
alias: "y",
|
|
20011
20187
|
type: "boolean",
|
|
@@ -20023,10 +20199,10 @@ var create_default = {
|
|
|
20023
20199
|
};
|
|
20024
20200
|
|
|
20025
20201
|
// src/cli/cmds/deploy.ts
|
|
20026
|
-
import
|
|
20202
|
+
import path83 from "node:path";
|
|
20027
20203
|
|
|
20028
20204
|
// src/cli/apply/handler.ts
|
|
20029
|
-
import
|
|
20205
|
+
import path77 from "node:path";
|
|
20030
20206
|
|
|
20031
20207
|
// src/cli/platform/helpers/gateway-plan-validation.ts
|
|
20032
20208
|
init_gateway_limits();
|
|
@@ -20147,14 +20323,22 @@ var MODULE_DISPLAY_NAMES = {
|
|
|
20147
20323
|
"dev-portal": "Developer website",
|
|
20148
20324
|
apihub: "API hosting"
|
|
20149
20325
|
};
|
|
20150
|
-
function friendlyModuleNames(
|
|
20151
|
-
return
|
|
20326
|
+
function friendlyModuleNames(text2) {
|
|
20327
|
+
return text2.replace(
|
|
20152
20328
|
/(?:Module|module) (dev-portal|apihub)(?![\w-])/g,
|
|
20153
20329
|
(_match, id) => MODULE_DISPLAY_NAMES[id] ?? id
|
|
20154
20330
|
);
|
|
20155
20331
|
}
|
|
20156
|
-
|
|
20157
|
-
|
|
20332
|
+
var INFRASTRUCTURE_MESSAGE = /front ?door|\bapim\b|api management|fabric|container app|origin group|\borigin\b|binding|\bdns\b|static web app|\bswa\b|\bacr\b|resource group|revision|warm pool|capacity pool|pooled/i;
|
|
20333
|
+
function isInfrastructureMessage(message) {
|
|
20334
|
+
return INFRASTRUCTURE_MESSAGE.test(message);
|
|
20335
|
+
}
|
|
20336
|
+
function createConsoleProgressReporter(stream = process.stderr, options = {}) {
|
|
20337
|
+
const shared = {
|
|
20338
|
+
spinner: void 0,
|
|
20339
|
+
verbose: options.verbose === true,
|
|
20340
|
+
printed: /* @__PURE__ */ new Set()
|
|
20341
|
+
};
|
|
20158
20342
|
return {
|
|
20159
20343
|
...createScopedConsoleProgressReporter(stream, void 0, shared),
|
|
20160
20344
|
stop() {
|
|
@@ -20192,11 +20376,13 @@ function createScopedConsoleProgressReporter(stream, stepLabel, shared) {
|
|
|
20192
20376
|
},
|
|
20193
20377
|
async onNewMessages(messages) {
|
|
20194
20378
|
for (const entry of messages) {
|
|
20195
|
-
|
|
20196
|
-
|
|
20197
|
-
|
|
20198
|
-
)
|
|
20379
|
+
if (!shared.verbose && isInfrastructureMessage(entry.message)) continue;
|
|
20380
|
+
const line2 = friendlyModuleNames(
|
|
20381
|
+
stepLabel ? `[${stepLabel}] ${entry.message}` : entry.message
|
|
20199
20382
|
);
|
|
20383
|
+
if (shared.printed.has(line2)) continue;
|
|
20384
|
+
shared.printed.add(line2);
|
|
20385
|
+
writeLine2(line2);
|
|
20200
20386
|
}
|
|
20201
20387
|
},
|
|
20202
20388
|
isCancelled: () => false,
|
|
@@ -20235,11 +20421,11 @@ init_gateway_limits();
|
|
|
20235
20421
|
// src/cli/platform/helpers/deploy-artifact-hash.ts
|
|
20236
20422
|
import { createHash as createHash3 } from "node:crypto";
|
|
20237
20423
|
import { createReadStream, promises as fs6 } from "node:fs";
|
|
20238
|
-
import
|
|
20424
|
+
import path67 from "node:path";
|
|
20239
20425
|
|
|
20240
20426
|
// src/cli/platform/helpers/package-files.ts
|
|
20241
20427
|
import { promises as fs5 } from "node:fs";
|
|
20242
|
-
import
|
|
20428
|
+
import path66 from "node:path";
|
|
20243
20429
|
import ignore from "ignore";
|
|
20244
20430
|
var DEFAULT_EXCLUDES = /* @__PURE__ */ new Set([
|
|
20245
20431
|
"node_modules",
|
|
@@ -20253,7 +20439,7 @@ async function loadGitignore(rootDir, extraExcludes = []) {
|
|
|
20253
20439
|
const ig = ignore();
|
|
20254
20440
|
ig.add(["node_modules/", ".git/", "dist/", "bin/", "obj/"]);
|
|
20255
20441
|
if (extraExcludes.length > 0) ig.add([...extraExcludes]);
|
|
20256
|
-
const gitignorePath =
|
|
20442
|
+
const gitignorePath = path66.join(rootDir, ".gitignore");
|
|
20257
20443
|
try {
|
|
20258
20444
|
const content = await fs5.readFile(gitignorePath, "utf8");
|
|
20259
20445
|
ig.add(content);
|
|
@@ -20262,11 +20448,11 @@ async function loadGitignore(rootDir, extraExcludes = []) {
|
|
|
20262
20448
|
return ig;
|
|
20263
20449
|
}
|
|
20264
20450
|
async function collectFiles(rootDir, relativeDir, ig, files) {
|
|
20265
|
-
const absDir =
|
|
20451
|
+
const absDir = path66.join(rootDir, relativeDir);
|
|
20266
20452
|
const entries = await fs5.readdir(absDir, { withFileTypes: true });
|
|
20267
20453
|
for (const entry of entries) {
|
|
20268
|
-
const rel2 = relativeDir ?
|
|
20269
|
-
const relPosix = rel2.split(
|
|
20454
|
+
const rel2 = relativeDir ? path66.join(relativeDir, entry.name) : entry.name;
|
|
20455
|
+
const relPosix = rel2.split(path66.sep).join("/");
|
|
20270
20456
|
if (DEFAULT_EXCLUDES.has(entry.name) && !relativeDir) {
|
|
20271
20457
|
continue;
|
|
20272
20458
|
}
|
|
@@ -20281,7 +20467,7 @@ async function collectFiles(rootDir, relativeDir, ig, files) {
|
|
|
20281
20467
|
}
|
|
20282
20468
|
}
|
|
20283
20469
|
async function collectPackageableFiles(sourceDirectory, extraExcludes = []) {
|
|
20284
|
-
const resolved =
|
|
20470
|
+
const resolved = path66.resolve(sourceDirectory);
|
|
20285
20471
|
const stat7 = await fs5.stat(resolved).catch(() => null);
|
|
20286
20472
|
if (!stat7?.isDirectory()) {
|
|
20287
20473
|
throw new Error(`sourceDirectory is not a directory: ${resolved}`);
|
|
@@ -20307,7 +20493,7 @@ async function sha256File(filePath) {
|
|
|
20307
20493
|
return hash2.digest("hex");
|
|
20308
20494
|
}
|
|
20309
20495
|
async function hashDirectoryContents(rootDirectory, extraExcludes = []) {
|
|
20310
|
-
const resolved =
|
|
20496
|
+
const resolved = path67.resolve(rootDirectory);
|
|
20311
20497
|
const files = (await collectPackageableFiles(resolved, extraExcludes)).sort(
|
|
20312
20498
|
(a, b) => a.localeCompare(b)
|
|
20313
20499
|
);
|
|
@@ -20315,13 +20501,13 @@ async function hashDirectoryContents(rootDirectory, extraExcludes = []) {
|
|
|
20315
20501
|
for (const rel2 of files) {
|
|
20316
20502
|
hash2.update(rel2);
|
|
20317
20503
|
hash2.update("\0");
|
|
20318
|
-
hash2.update(await fs6.readFile(
|
|
20504
|
+
hash2.update(await fs6.readFile(path67.join(resolved, rel2)));
|
|
20319
20505
|
hash2.update("\0");
|
|
20320
20506
|
}
|
|
20321
20507
|
return hash2.digest("hex");
|
|
20322
20508
|
}
|
|
20323
20509
|
async function hashDevPortalSiteSources(siteDirectory, options) {
|
|
20324
|
-
const resolved =
|
|
20510
|
+
const resolved = path67.resolve(siteDirectory);
|
|
20325
20511
|
const hash2 = createHash3("sha256");
|
|
20326
20512
|
const candidates = [
|
|
20327
20513
|
"apitogo.config.json",
|
|
@@ -20331,7 +20517,7 @@ async function hashDevPortalSiteSources(siteDirectory, options) {
|
|
|
20331
20517
|
"zudoku.config.tsx"
|
|
20332
20518
|
];
|
|
20333
20519
|
for (const name of candidates) {
|
|
20334
|
-
const full =
|
|
20520
|
+
const full = path67.join(resolved, name);
|
|
20335
20521
|
try {
|
|
20336
20522
|
hash2.update(name);
|
|
20337
20523
|
hash2.update("\0");
|
|
@@ -20341,7 +20527,7 @@ async function hashDevPortalSiteSources(siteDirectory, options) {
|
|
|
20341
20527
|
}
|
|
20342
20528
|
}
|
|
20343
20529
|
for (const dir of ["pages", "landing", "src"]) {
|
|
20344
|
-
const full =
|
|
20530
|
+
const full = path67.join(resolved, dir);
|
|
20345
20531
|
try {
|
|
20346
20532
|
const st = await fs6.stat(full);
|
|
20347
20533
|
if (!st.isDirectory()) continue;
|
|
@@ -20570,8 +20756,8 @@ function normalizeActionKey(actionKey2) {
|
|
|
20570
20756
|
const trimmed = actionKey2.trim();
|
|
20571
20757
|
if (trimmed.includes(":")) {
|
|
20572
20758
|
const [method2, ...pathParts] = trimmed.split(":");
|
|
20573
|
-
const
|
|
20574
|
-
return `${method2?.toLowerCase()}:${
|
|
20759
|
+
const path99 = pathParts.join(":").trim();
|
|
20760
|
+
return `${method2?.toLowerCase()}:${path99.startsWith("/") ? path99 : `/${path99}`}`;
|
|
20575
20761
|
}
|
|
20576
20762
|
const spaceIndex = trimmed.indexOf(" ");
|
|
20577
20763
|
if (spaceIndex <= 0) {
|
|
@@ -20580,8 +20766,8 @@ function normalizeActionKey(actionKey2) {
|
|
|
20580
20766
|
);
|
|
20581
20767
|
}
|
|
20582
20768
|
const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
|
|
20583
|
-
const
|
|
20584
|
-
return `${method}:${
|
|
20769
|
+
const path98 = trimmed.slice(spaceIndex + 1).trim();
|
|
20770
|
+
return `${method}:${path98.startsWith("/") ? path98 : `/${path98}`}`;
|
|
20585
20771
|
}
|
|
20586
20772
|
async function applyGatewayPublicRoutes(client, projectId, routes, options) {
|
|
20587
20773
|
const applied = [];
|
|
@@ -21059,8 +21245,8 @@ async function upsertGatewayPlansFromManifest(client, config2, projectId, plans,
|
|
|
21059
21245
|
}
|
|
21060
21246
|
|
|
21061
21247
|
// src/cli/platform/helpers/openapi-gateway-servers.ts
|
|
21062
|
-
import { mkdir as
|
|
21063
|
-
import
|
|
21248
|
+
import { mkdir as mkdir17, readFile as readFile25, writeFile as writeFile19 } from "node:fs/promises";
|
|
21249
|
+
import path68 from "node:path";
|
|
21064
21250
|
import YAML from "yaml";
|
|
21065
21251
|
var GATEWAY_URL_ENV_KEY = "APITOGO_GATEWAY_URL";
|
|
21066
21252
|
var PUBLISH_OPENAPI_RELATIVE = ".apitogo/openapi-publish.json";
|
|
@@ -21092,7 +21278,7 @@ async function resolveProjectGatewayUrl(client, projectId) {
|
|
|
21092
21278
|
}
|
|
21093
21279
|
async function readOpenApiDocument(filePath) {
|
|
21094
21280
|
const content = await readFile25(filePath, "utf8");
|
|
21095
|
-
const ext =
|
|
21281
|
+
const ext = path68.extname(filePath).toLowerCase();
|
|
21096
21282
|
const parsed = ext === ".json" ? JSON.parse(content) : YAML.parse(content);
|
|
21097
21283
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
21098
21284
|
throw new Error(`OpenAPI document must be an object: ${filePath}`);
|
|
@@ -21100,13 +21286,13 @@ async function readOpenApiDocument(filePath) {
|
|
|
21100
21286
|
return parsed;
|
|
21101
21287
|
}
|
|
21102
21288
|
async function materializePublishOpenApiWithGateway(siteDirectory, sourceOpenApiPath, gatewayUrl) {
|
|
21103
|
-
const site =
|
|
21104
|
-
const source =
|
|
21289
|
+
const site = path68.resolve(siteDirectory);
|
|
21290
|
+
const source = path68.resolve(sourceOpenApiPath);
|
|
21105
21291
|
const relativeInput = PUBLISH_OPENAPI_RELATIVE;
|
|
21106
|
-
const outputPath =
|
|
21292
|
+
const outputPath = path68.join(site, ...relativeInput.split("/"));
|
|
21107
21293
|
const doc = await readOpenApiDocument(source);
|
|
21108
21294
|
const rewritten = withGatewayServers(doc, gatewayUrl);
|
|
21109
|
-
await
|
|
21295
|
+
await mkdir17(path68.dirname(outputPath), { recursive: true });
|
|
21110
21296
|
await writeFile19(
|
|
21111
21297
|
outputPath,
|
|
21112
21298
|
`${JSON.stringify(rewritten, null, 2)}
|
|
@@ -21116,8 +21302,8 @@ async function materializePublishOpenApiWithGateway(siteDirectory, sourceOpenApi
|
|
|
21116
21302
|
return { outputPath, relativeInput };
|
|
21117
21303
|
}
|
|
21118
21304
|
async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
|
|
21119
|
-
const configPath =
|
|
21120
|
-
|
|
21305
|
+
const configPath = path68.join(
|
|
21306
|
+
path68.resolve(siteDirectory),
|
|
21121
21307
|
APITOGO_CONFIG_FILENAME2
|
|
21122
21308
|
);
|
|
21123
21309
|
const raw = await readFile25(configPath, "utf8");
|
|
@@ -21159,7 +21345,7 @@ async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
|
|
|
21159
21345
|
};
|
|
21160
21346
|
}
|
|
21161
21347
|
async function prepareOpenApiServersForGatewayBuild(options) {
|
|
21162
|
-
const siteDirectory =
|
|
21348
|
+
const siteDirectory = path68.resolve(options.siteDirectory);
|
|
21163
21349
|
let openApiPath = resolveBackendOpenApiPath(
|
|
21164
21350
|
options.manifest?.backend?.openApiPath,
|
|
21165
21351
|
{
|
|
@@ -21173,7 +21359,7 @@ async function prepareOpenApiServersForGatewayBuild(options) {
|
|
|
21173
21359
|
if (!openApiPath) {
|
|
21174
21360
|
try {
|
|
21175
21361
|
const raw = await readFile25(
|
|
21176
|
-
|
|
21362
|
+
path68.join(siteDirectory, APITOGO_CONFIG_FILENAME2),
|
|
21177
21363
|
"utf8"
|
|
21178
21364
|
);
|
|
21179
21365
|
const config2 = JSON.parse(raw);
|
|
@@ -21202,8 +21388,8 @@ function normalizeActionKeyFormat(actionKey2) {
|
|
|
21202
21388
|
const trimmed = actionKey2.trim();
|
|
21203
21389
|
if (trimmed.includes(":")) {
|
|
21204
21390
|
const [method2, ...pathParts] = trimmed.split(":");
|
|
21205
|
-
const
|
|
21206
|
-
return `${method2.toLowerCase()}:${
|
|
21391
|
+
const path99 = pathParts.join(":").trim();
|
|
21392
|
+
return `${method2.toLowerCase()}:${path99.startsWith("/") ? path99 : `/${path99}`}`;
|
|
21207
21393
|
}
|
|
21208
21394
|
const spaceIndex = trimmed.indexOf(" ");
|
|
21209
21395
|
if (spaceIndex <= 0) {
|
|
@@ -21212,8 +21398,8 @@ function normalizeActionKeyFormat(actionKey2) {
|
|
|
21212
21398
|
);
|
|
21213
21399
|
}
|
|
21214
21400
|
const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
|
|
21215
|
-
const
|
|
21216
|
-
return `${method}:${
|
|
21401
|
+
const path98 = trimmed.slice(spaceIndex + 1).trim();
|
|
21402
|
+
return `${method}:${path98.startsWith("/") ? path98 : `/${path98}`}`;
|
|
21217
21403
|
}
|
|
21218
21404
|
function normalizePublicRoute(route) {
|
|
21219
21405
|
const trimmed = route.trim();
|
|
@@ -21246,11 +21432,11 @@ function collectManifestPublicActionKeys(gateway) {
|
|
|
21246
21432
|
}
|
|
21247
21433
|
|
|
21248
21434
|
// src/cli/platform/helpers/publish-ledger.ts
|
|
21249
|
-
import { mkdir as
|
|
21250
|
-
import
|
|
21435
|
+
import { mkdir as mkdir18, readFile as readFile26, writeFile as writeFile20 } from "node:fs/promises";
|
|
21436
|
+
import path69 from "node:path";
|
|
21251
21437
|
var PUBLISH_LEDGER_RELATIVE_PATH = ".apitogo/publish-state.json";
|
|
21252
21438
|
function publishLedgerPath(siteDirectory) {
|
|
21253
|
-
return
|
|
21439
|
+
return path69.join(path69.resolve(siteDirectory), PUBLISH_LEDGER_RELATIVE_PATH);
|
|
21254
21440
|
}
|
|
21255
21441
|
async function readPublishLedger(siteDirectory) {
|
|
21256
21442
|
const filePath = publishLedgerPath(siteDirectory);
|
|
@@ -21267,7 +21453,7 @@ async function readPublishLedger(siteDirectory) {
|
|
|
21267
21453
|
}
|
|
21268
21454
|
async function writePublishLedger(siteDirectory, ledger) {
|
|
21269
21455
|
const filePath = publishLedgerPath(siteDirectory);
|
|
21270
|
-
await
|
|
21456
|
+
await mkdir18(path69.dirname(filePath), { recursive: true });
|
|
21271
21457
|
const next = {
|
|
21272
21458
|
...ledger,
|
|
21273
21459
|
version: 1,
|
|
@@ -21786,20 +21972,19 @@ async function createProjectWithWarmPoolRetry(client, body, options) {
|
|
|
21786
21972
|
}
|
|
21787
21973
|
|
|
21788
21974
|
// src/cli/platform/helpers/backend-packaging.ts
|
|
21789
|
-
import {
|
|
21790
|
-
import {
|
|
21791
|
-
import
|
|
21792
|
-
import path69 from "node:path";
|
|
21975
|
+
import { mkdtemp as mkdtemp2, readdir as readdir5, rm as rm10 } from "node:fs/promises";
|
|
21976
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
21977
|
+
import path70 from "node:path";
|
|
21793
21978
|
async function directoryHasRuntimeConfig(dir) {
|
|
21794
21979
|
if (!await pathExists(dir)) {
|
|
21795
21980
|
return false;
|
|
21796
21981
|
}
|
|
21797
|
-
const entries = await
|
|
21982
|
+
const entries = await readdir5(dir);
|
|
21798
21983
|
return entries.some((name) => name.endsWith(".runtimeconfig.json"));
|
|
21799
21984
|
}
|
|
21800
21985
|
function runDotnetPublish(projectDir, outputDir) {
|
|
21801
21986
|
return new Promise((resolve, reject) => {
|
|
21802
|
-
const child =
|
|
21987
|
+
const child = spawnCommand(
|
|
21803
21988
|
"dotnet",
|
|
21804
21989
|
[
|
|
21805
21990
|
"publish",
|
|
@@ -21814,8 +21999,7 @@ function runDotnetPublish(projectDir, outputDir) {
|
|
|
21814
21999
|
],
|
|
21815
22000
|
{
|
|
21816
22001
|
cwd: projectDir,
|
|
21817
|
-
env: process.env
|
|
21818
|
-
shell: process.platform === "win32"
|
|
22002
|
+
env: process.env
|
|
21819
22003
|
}
|
|
21820
22004
|
);
|
|
21821
22005
|
let output4 = "";
|
|
@@ -21830,22 +22014,22 @@ function runDotnetPublish(projectDir, outputDir) {
|
|
|
21830
22014
|
});
|
|
21831
22015
|
}
|
|
21832
22016
|
async function findCsproj(projectDir) {
|
|
21833
|
-
const entries = await
|
|
22017
|
+
const entries = await readdir5(projectDir);
|
|
21834
22018
|
const csproj = entries.find((name) => name.endsWith(".csproj"));
|
|
21835
|
-
return csproj ?
|
|
22019
|
+
return csproj ? path70.join(projectDir, csproj) : null;
|
|
21836
22020
|
}
|
|
21837
22021
|
async function prepareBackendPackagingDirectory(args) {
|
|
21838
|
-
const sourceDirectory =
|
|
22022
|
+
const sourceDirectory = path70.resolve(args.sourceDirectory);
|
|
21839
22023
|
if (args.publishDirectory?.trim()) {
|
|
21840
22024
|
return {
|
|
21841
|
-
directory:
|
|
22025
|
+
directory: path70.resolve(args.publishDirectory),
|
|
21842
22026
|
packagingMode: "published"
|
|
21843
22027
|
};
|
|
21844
22028
|
}
|
|
21845
22029
|
if (await directoryHasRuntimeConfig(sourceDirectory)) {
|
|
21846
22030
|
return { directory: sourceDirectory, packagingMode: "published" };
|
|
21847
22031
|
}
|
|
21848
|
-
const publishSubdir =
|
|
22032
|
+
const publishSubdir = path70.join(sourceDirectory, "publish");
|
|
21849
22033
|
if (await directoryHasRuntimeConfig(publishSubdir)) {
|
|
21850
22034
|
return { directory: publishSubdir, packagingMode: "published" };
|
|
21851
22035
|
}
|
|
@@ -21856,19 +22040,19 @@ async function prepareBackendPackagingDirectory(args) {
|
|
|
21856
22040
|
if (!csproj) {
|
|
21857
22041
|
return { directory: sourceDirectory, packagingMode: "source" };
|
|
21858
22042
|
}
|
|
21859
|
-
const tempRoot = await
|
|
21860
|
-
|
|
22043
|
+
const tempRoot = await mkdtemp2(
|
|
22044
|
+
path70.join(tmpdir2(), "apitogo-dotnet-publish-")
|
|
21861
22045
|
);
|
|
21862
|
-
const outputDir =
|
|
22046
|
+
const outputDir = path70.join(tempRoot, "publish");
|
|
21863
22047
|
const result = await runDotnetPublish(sourceDirectory, outputDir);
|
|
21864
22048
|
if (result.exitCode !== 0) {
|
|
21865
|
-
await
|
|
22049
|
+
await rm10(tempRoot, { recursive: true, force: true });
|
|
21866
22050
|
throw new Error(
|
|
21867
22051
|
`dotnet publish failed (exit ${result.exitCode ?? "unknown"}): ${result.output.slice(-2e3)}`
|
|
21868
22052
|
);
|
|
21869
22053
|
}
|
|
21870
22054
|
if (!await directoryHasRuntimeConfig(outputDir)) {
|
|
21871
|
-
await
|
|
22055
|
+
await rm10(tempRoot, { recursive: true, force: true });
|
|
21872
22056
|
throw new Error(
|
|
21873
22057
|
"dotnet publish completed but no *.runtimeconfig.json was found in the output directory."
|
|
21874
22058
|
);
|
|
@@ -21877,7 +22061,7 @@ async function prepareBackendPackagingDirectory(args) {
|
|
|
21877
22061
|
directory: outputDir,
|
|
21878
22062
|
packagingMode: "published",
|
|
21879
22063
|
cleanup: async () => {
|
|
21880
|
-
await
|
|
22064
|
+
await rm10(tempRoot, { recursive: true, force: true });
|
|
21881
22065
|
}
|
|
21882
22066
|
};
|
|
21883
22067
|
}
|
|
@@ -21904,13 +22088,13 @@ function formatJobStatusResponse(options) {
|
|
|
21904
22088
|
|
|
21905
22089
|
// src/cli/platform/helpers/openapi.ts
|
|
21906
22090
|
import { promises as fs7 } from "node:fs";
|
|
21907
|
-
import
|
|
22091
|
+
import path71 from "node:path";
|
|
21908
22092
|
import SwaggerParser from "@apidevtools/swagger-parser";
|
|
21909
22093
|
import YAML2 from "yaml";
|
|
21910
22094
|
async function validateOpenApiFile(filePath) {
|
|
21911
|
-
const resolved =
|
|
22095
|
+
const resolved = path71.resolve(filePath);
|
|
21912
22096
|
const content = await fs7.readFile(resolved, "utf8");
|
|
21913
|
-
const ext =
|
|
22097
|
+
const ext = path71.extname(resolved).toLowerCase();
|
|
21914
22098
|
let parsed;
|
|
21915
22099
|
try {
|
|
21916
22100
|
parsed = ext === ".json" ? JSON.parse(content) : YAML2.parse(content);
|
|
@@ -21953,14 +22137,14 @@ async function validateOpenApiFile(filePath) {
|
|
|
21953
22137
|
|
|
21954
22138
|
// src/cli/platform/helpers/zip.ts
|
|
21955
22139
|
import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, promises as fs8 } from "node:fs";
|
|
21956
|
-
import { tmpdir as
|
|
21957
|
-
import
|
|
22140
|
+
import { tmpdir as tmpdir3 } from "node:os";
|
|
22141
|
+
import path72 from "node:path";
|
|
21958
22142
|
import { ZipArchive } from "archiver";
|
|
21959
22143
|
async function packageBackendDirectory(sourceDirectory, extraExcludes = []) {
|
|
21960
|
-
const resolved =
|
|
22144
|
+
const resolved = path72.resolve(sourceDirectory);
|
|
21961
22145
|
const files = await collectPackageableFiles(resolved, extraExcludes);
|
|
21962
|
-
const zipPath =
|
|
21963
|
-
|
|
22146
|
+
const zipPath = path72.join(
|
|
22147
|
+
tmpdir3(),
|
|
21964
22148
|
`apitogo-backend-${Date.now()}-${Math.random().toString(36).slice(2)}.zip`
|
|
21965
22149
|
);
|
|
21966
22150
|
await new Promise((resolve, reject) => {
|
|
@@ -21971,8 +22155,8 @@ async function packageBackendDirectory(sourceDirectory, extraExcludes = []) {
|
|
|
21971
22155
|
output4.on("error", reject);
|
|
21972
22156
|
archive.pipe(output4);
|
|
21973
22157
|
for (const rel2 of files) {
|
|
21974
|
-
archive.append(createReadStream2(
|
|
21975
|
-
name: rel2.split(
|
|
22158
|
+
archive.append(createReadStream2(path72.join(resolved, rel2)), {
|
|
22159
|
+
name: rel2.split(path72.sep).join("/")
|
|
21976
22160
|
});
|
|
21977
22161
|
}
|
|
21978
22162
|
void archive.finalize();
|
|
@@ -23523,11 +23707,11 @@ async function resolveProjectIdForPublish(client, config2, args, wait, progress,
|
|
|
23523
23707
|
}
|
|
23524
23708
|
|
|
23525
23709
|
// src/cli/platform/tools/dev-portal-site-build.ts
|
|
23526
|
-
import
|
|
23710
|
+
import path76 from "node:path";
|
|
23527
23711
|
|
|
23528
23712
|
// src/cli/platform/helpers/dev-portal-site-api-url.ts
|
|
23529
|
-
import { readdir as
|
|
23530
|
-
import
|
|
23713
|
+
import { readdir as readdir6, readFile as readFile27, writeFile as writeFile21 } from "node:fs/promises";
|
|
23714
|
+
import path73 from "node:path";
|
|
23531
23715
|
var SITE_API_BASE_URL_ENV_KEY = "VITE_APITOGO_AUTHENTICATION_API_BASE_URL";
|
|
23532
23716
|
var PLACEHOLDER_HOST_MARKERS = [
|
|
23533
23717
|
"dp-example.azurecontainerapps.io",
|
|
@@ -23548,10 +23732,10 @@ function isPlaceholderDevPortalApiUrl(apiBaseUrl) {
|
|
|
23548
23732
|
return PLACEHOLDER_HOST_MARKERS.some((marker) => normalized.includes(marker));
|
|
23549
23733
|
}
|
|
23550
23734
|
async function readSiteApiBaseUrl(sourceDirectory) {
|
|
23551
|
-
const resolved =
|
|
23735
|
+
const resolved = path73.resolve(sourceDirectory);
|
|
23552
23736
|
for (const envFile of [".env", ".env.production"]) {
|
|
23553
23737
|
try {
|
|
23554
|
-
const content = await readFile27(
|
|
23738
|
+
const content = await readFile27(path73.join(resolved, envFile), "utf8");
|
|
23555
23739
|
const lines = [...content.matchAll(ENV_LINE_GLOBAL_RE)];
|
|
23556
23740
|
if (lines.length === 0) {
|
|
23557
23741
|
continue;
|
|
@@ -23576,11 +23760,11 @@ async function readSiteApiBaseUrl(sourceDirectory) {
|
|
|
23576
23760
|
return null;
|
|
23577
23761
|
}
|
|
23578
23762
|
async function patchSiteApiBaseUrl(sourceDirectory, apiBaseUrl) {
|
|
23579
|
-
const resolved =
|
|
23763
|
+
const resolved = path73.resolve(sourceDirectory);
|
|
23580
23764
|
const line2 = `${SITE_API_BASE_URL_ENV_KEY}=${apiBaseUrl}`;
|
|
23581
23765
|
let patchedExisting = false;
|
|
23582
23766
|
for (const envFile of [".env.production", ".env"]) {
|
|
23583
|
-
const envPath =
|
|
23767
|
+
const envPath = path73.join(resolved, envFile);
|
|
23584
23768
|
try {
|
|
23585
23769
|
const content = await readFile27(envPath, "utf8");
|
|
23586
23770
|
const withoutAssignments = content.replace(ENV_LINE_GLOBAL_RE, "").replace(/\n{3,}/g, "\n\n").trimEnd();
|
|
@@ -23594,7 +23778,7 @@ ${line2}
|
|
|
23594
23778
|
}
|
|
23595
23779
|
}
|
|
23596
23780
|
if (!patchedExisting) {
|
|
23597
|
-
await writeFile21(
|
|
23781
|
+
await writeFile21(path73.join(resolved, ".env"), `${line2}
|
|
23598
23782
|
`);
|
|
23599
23783
|
}
|
|
23600
23784
|
}
|
|
@@ -23602,7 +23786,7 @@ function tryProjectId(explicit, manifestProjectId, config2) {
|
|
|
23602
23786
|
return explicit?.trim() || manifestProjectId?.trim() || config2.defaultProjectId?.trim() || void 0;
|
|
23603
23787
|
}
|
|
23604
23788
|
async function ensureLiveSiteApiBaseUrlForBuild(_client, config2, args, resolveFromProject) {
|
|
23605
|
-
const sourceDirectory =
|
|
23789
|
+
const sourceDirectory = path73.resolve(args.sourceDirectory);
|
|
23606
23790
|
const explicit = args.apiBaseUrl?.trim();
|
|
23607
23791
|
if (explicit && !isPlaceholderDevPortalApiUrl(explicit)) {
|
|
23608
23792
|
await patchSiteApiBaseUrl(sourceDirectory, explicit);
|
|
@@ -23633,12 +23817,12 @@ async function ensureLiveSiteApiBaseUrlForBuild(_client, config2, args, resolveF
|
|
|
23633
23817
|
async function* walkFiles(root) {
|
|
23634
23818
|
let entries;
|
|
23635
23819
|
try {
|
|
23636
|
-
entries = await
|
|
23820
|
+
entries = await readdir6(root, { withFileTypes: true });
|
|
23637
23821
|
} catch {
|
|
23638
23822
|
return;
|
|
23639
23823
|
}
|
|
23640
23824
|
for (const entry of entries) {
|
|
23641
|
-
const full =
|
|
23825
|
+
const full = path73.join(root, entry.name);
|
|
23642
23826
|
if (entry.isDirectory()) {
|
|
23643
23827
|
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
23644
23828
|
continue;
|
|
@@ -23650,8 +23834,8 @@ async function* walkFiles(root) {
|
|
|
23650
23834
|
}
|
|
23651
23835
|
}
|
|
23652
23836
|
async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiBaseUrl) {
|
|
23653
|
-
const dist =
|
|
23654
|
-
const siteRoot =
|
|
23837
|
+
const dist = path73.resolve(distDirectory);
|
|
23838
|
+
const siteRoot = path73.dirname(dist);
|
|
23655
23839
|
const fromEnv = expectedApiBaseUrl?.trim() || await readSiteApiBaseUrl(siteRoot) || await readSiteApiBaseUrl(dist);
|
|
23656
23840
|
if (!fromEnv || isPlaceholderDevPortalApiUrl(fromEnv)) {
|
|
23657
23841
|
throw new Error(
|
|
@@ -23687,7 +23871,7 @@ async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiB
|
|
|
23687
23871
|
|
|
23688
23872
|
// src/cli/platform/tools/dev-portal.ts
|
|
23689
23873
|
import { promises as fs10 } from "node:fs";
|
|
23690
|
-
import
|
|
23874
|
+
import path75 from "node:path";
|
|
23691
23875
|
|
|
23692
23876
|
// src/cli/platform/helpers/dev-portal-backend-job.ts
|
|
23693
23877
|
var DEV_PORTAL_BACKEND_UPDATE_RESOURCE_TYPE = "DevPortalBackendUpdate";
|
|
@@ -23796,8 +23980,8 @@ async function snapshotBackendUpdateJobIds(client, projectId) {
|
|
|
23796
23980
|
|
|
23797
23981
|
// src/cli/platform/helpers/tarball.ts
|
|
23798
23982
|
import { createReadStream as createReadStream3, createWriteStream as createWriteStream3, promises as fs9 } from "node:fs";
|
|
23799
|
-
import { tmpdir as
|
|
23800
|
-
import
|
|
23983
|
+
import { tmpdir as tmpdir4 } from "node:os";
|
|
23984
|
+
import path74 from "node:path";
|
|
23801
23985
|
import { TarArchive } from "archiver";
|
|
23802
23986
|
var DEV_PORTAL_DEPLOY_ARCHIVE_ROOT = "dist";
|
|
23803
23987
|
function normalizeArchiveRoot(archiveRoot) {
|
|
@@ -23808,11 +23992,11 @@ function normalizeArchiveRoot(archiveRoot) {
|
|
|
23808
23992
|
return `${trimmed}/`;
|
|
23809
23993
|
}
|
|
23810
23994
|
async function packageDirectoryAsTarGz(sourceDirectory, options) {
|
|
23811
|
-
const resolved =
|
|
23995
|
+
const resolved = path74.resolve(sourceDirectory);
|
|
23812
23996
|
const files = await collectPackageableFiles(resolved);
|
|
23813
23997
|
const entryPrefix = options?.archiveRoot ? normalizeArchiveRoot(options.archiveRoot) : "";
|
|
23814
|
-
const archivePath =
|
|
23815
|
-
|
|
23998
|
+
const archivePath = path74.join(
|
|
23999
|
+
tmpdir4(),
|
|
23816
24000
|
`apitogo-docs-${Date.now()}-${Math.random().toString(36).slice(2)}.tgz`
|
|
23817
24001
|
);
|
|
23818
24002
|
await new Promise((resolve, reject) => {
|
|
@@ -23823,8 +24007,8 @@ async function packageDirectoryAsTarGz(sourceDirectory, options) {
|
|
|
23823
24007
|
output4.on("error", reject);
|
|
23824
24008
|
archive.pipe(output4);
|
|
23825
24009
|
for (const rel2 of files) {
|
|
23826
|
-
const entryName = entryPrefix + rel2.split(
|
|
23827
|
-
archive.append(createReadStream3(
|
|
24010
|
+
const entryName = entryPrefix + rel2.split(path74.sep).join("/");
|
|
24011
|
+
archive.append(createReadStream3(path74.join(resolved, rel2)), {
|
|
23828
24012
|
name: entryName
|
|
23829
24013
|
});
|
|
23830
24014
|
}
|
|
@@ -24066,7 +24250,7 @@ function validateDeployArchiveInput(args) {
|
|
|
24066
24250
|
async function resolveDevPortalArchive(args) {
|
|
24067
24251
|
validateDeployArchiveInput(args);
|
|
24068
24252
|
if (args.archivePath?.trim()) {
|
|
24069
|
-
const archivePath =
|
|
24253
|
+
const archivePath = path75.resolve(args.archivePath.trim());
|
|
24070
24254
|
const stat7 = await fs10.stat(archivePath).catch(() => null);
|
|
24071
24255
|
if (!stat7?.isFile()) {
|
|
24072
24256
|
throw new Error(`archivePath is not a file: ${archivePath}`);
|
|
@@ -24131,7 +24315,7 @@ async function handleDeployDevPortal(client, config2, args, progress) {
|
|
|
24131
24315
|
// src/cli/platform/tools/dev-portal-site-build.ts
|
|
24132
24316
|
async function handleBuildDevPortalSite(client, config2, args, progress) {
|
|
24133
24317
|
const buildProgress = progress?.child("Build dev portal site");
|
|
24134
|
-
const sourceDirectory =
|
|
24318
|
+
const sourceDirectory = path76.resolve(args.sourceDirectory);
|
|
24135
24319
|
await buildProgress?.onStep("Ensuring live portal API URL");
|
|
24136
24320
|
const apiBaseUrl = await ensureLiveSiteApiBaseUrlForBuild(
|
|
24137
24321
|
client,
|
|
@@ -25637,7 +25821,7 @@ function resultLooksFailed(payload) {
|
|
|
25637
25821
|
return parsed.status === "failed" || parsed.status === "blocked";
|
|
25638
25822
|
}
|
|
25639
25823
|
async function apply(argv) {
|
|
25640
|
-
const sourceDirectory =
|
|
25824
|
+
const sourceDirectory = path77.resolve(process.cwd(), argv.dir);
|
|
25641
25825
|
let config2;
|
|
25642
25826
|
try {
|
|
25643
25827
|
config2 = loadConfig();
|
|
@@ -25707,7 +25891,7 @@ async function apply(argv) {
|
|
|
25707
25891
|
if (canPromptInteractively && parsed?.status === "blocked" && parsed.reason === "project_not_found") {
|
|
25708
25892
|
const resolution = await resolveProjectNotFoundInteractively(
|
|
25709
25893
|
parsed,
|
|
25710
|
-
|
|
25894
|
+
path77.basename(sourceDirectory)
|
|
25711
25895
|
);
|
|
25712
25896
|
if (resolution) {
|
|
25713
25897
|
effectiveProjectId = void 0;
|
|
@@ -25727,7 +25911,7 @@ async function apply(argv) {
|
|
|
25727
25911
|
while (canPromptInteractively && parsed?.status === "blocked" && parsed.reason === "project_name_exists") {
|
|
25728
25912
|
const resolution = await resolveProjectNameExistsInteractively(
|
|
25729
25913
|
parsed,
|
|
25730
|
-
effectiveProjectName ??
|
|
25914
|
+
effectiveProjectName ?? path77.basename(sourceDirectory)
|
|
25731
25915
|
);
|
|
25732
25916
|
if (!resolution) {
|
|
25733
25917
|
break;
|
|
@@ -25798,11 +25982,11 @@ async function apply(argv) {
|
|
|
25798
25982
|
}
|
|
25799
25983
|
|
|
25800
25984
|
// src/cli/deploy/command.ts
|
|
25801
|
-
import
|
|
25985
|
+
import path82 from "node:path";
|
|
25802
25986
|
init_invariant();
|
|
25803
25987
|
|
|
25804
25988
|
// src/cli/project/create-handler.ts
|
|
25805
|
-
import
|
|
25989
|
+
import path78 from "node:path";
|
|
25806
25990
|
import open2 from "open";
|
|
25807
25991
|
init_invariant();
|
|
25808
25992
|
|
|
@@ -25825,13 +26009,13 @@ function modulesForConfig(config2) {
|
|
|
25825
26009
|
}
|
|
25826
26010
|
function assertConfigChecksOut(output4) {
|
|
25827
26011
|
if (output4.status === "ok") return;
|
|
25828
|
-
const
|
|
26012
|
+
const count2 = output4.errors.length;
|
|
25829
26013
|
throw new ProjectCreateError(
|
|
25830
26014
|
"CONFIG_INVALID",
|
|
25831
|
-
`The config has ${
|
|
26015
|
+
`The config has ${count2} error${count2 === 1 ? "" : "s"}, so no project is created.`,
|
|
25832
26016
|
[
|
|
25833
26017
|
...output4.errors.slice(0, 5).map((issue4) => `- ${formatConfigIssue(issue4)}`),
|
|
25834
|
-
...
|
|
26018
|
+
...count2 > 5 ? [`- and ${count2 - 5} more`] : [],
|
|
25835
26019
|
"Fix them (`apitogo check` lists everything), then run `apitogo project create` again."
|
|
25836
26020
|
].join("\n")
|
|
25837
26021
|
);
|
|
@@ -26028,7 +26212,13 @@ async function createLinkedProject(argv, dir, options = {}) {
|
|
|
26028
26212
|
}
|
|
26029
26213
|
const config2 = loadConfig();
|
|
26030
26214
|
const client = new PlatformApiClient(config2);
|
|
26031
|
-
const progress = createConsoleProgressReporter(
|
|
26215
|
+
const progress = createConsoleProgressReporter(process.stderr, {
|
|
26216
|
+
verbose: argv.verbose === true
|
|
26217
|
+
});
|
|
26218
|
+
if (!json)
|
|
26219
|
+
printDiagnosticsToConsole(
|
|
26220
|
+
`Creating your project: reserving hosting, setting up its addresses, then getting the website ready. This usually takes 1 to 3 minutes.${plan2 && plan2 !== "free" ? " Paying for the plan on the dashboard works too: this command goes on once the payment is in." : ""} Add --verbose to see every step.`
|
|
26221
|
+
);
|
|
26032
26222
|
const result = await createProjectV2(
|
|
26033
26223
|
{
|
|
26034
26224
|
dir,
|
|
@@ -26106,7 +26296,7 @@ async function createLinkedProject(argv, dir, options = {}) {
|
|
|
26106
26296
|
}
|
|
26107
26297
|
}
|
|
26108
26298
|
async function createProject2(argv) {
|
|
26109
|
-
const dir =
|
|
26299
|
+
const dir = path78.resolve(process.cwd(), argv.dir ?? ".");
|
|
26110
26300
|
if (await isConfigV2(dir)) {
|
|
26111
26301
|
await createLinkedProject(argv, dir);
|
|
26112
26302
|
return;
|
|
@@ -26217,7 +26407,7 @@ async function confirm(question) {
|
|
|
26217
26407
|
}
|
|
26218
26408
|
|
|
26219
26409
|
// src/cli/deploy/stripe-key.ts
|
|
26220
|
-
import
|
|
26410
|
+
import path79 from "node:path";
|
|
26221
26411
|
init_invariant();
|
|
26222
26412
|
var StripeKeyError = class extends ApitogoError {
|
|
26223
26413
|
constructor(message, developerHint) {
|
|
@@ -26235,7 +26425,7 @@ async function ensureStripeKey(argv, deps) {
|
|
|
26235
26425
|
if (!wantsPlans(argv.only)) return { status: "not-needed" };
|
|
26236
26426
|
let resolved;
|
|
26237
26427
|
try {
|
|
26238
|
-
resolved = loadConfigV2(
|
|
26428
|
+
resolved = loadConfigV2(path79.resolve(process.cwd(), argv.dir)).resolved;
|
|
26239
26429
|
} catch {
|
|
26240
26430
|
return { status: "not-needed" };
|
|
26241
26431
|
}
|
|
@@ -26278,12 +26468,12 @@ async function ensureStripeKey(argv, deps) {
|
|
|
26278
26468
|
}
|
|
26279
26469
|
|
|
26280
26470
|
// src/cli/deploy/v2.ts
|
|
26281
|
-
import { rm as
|
|
26471
|
+
import { rm as rm11 } from "node:fs/promises";
|
|
26282
26472
|
init_invariant();
|
|
26283
26473
|
|
|
26284
26474
|
// src/cli/portal/report.ts
|
|
26285
26475
|
import { access as access9 } from "node:fs/promises";
|
|
26286
|
-
import
|
|
26476
|
+
import path80 from "node:path";
|
|
26287
26477
|
|
|
26288
26478
|
// src/cli/deploy/gateway.ts
|
|
26289
26479
|
import { createHash as createHash4 } from "node:crypto";
|
|
@@ -26302,7 +26492,7 @@ function isHostingNotActivated(error) {
|
|
|
26302
26492
|
`${error.message} ${error.problem?.detail ?? ""}`
|
|
26303
26493
|
);
|
|
26304
26494
|
}
|
|
26305
|
-
var sha256 = (
|
|
26495
|
+
var sha256 = (text2) => createHash4("sha256").update(text2).digest("hex");
|
|
26306
26496
|
function gatewayNotDeployableReason(gateway) {
|
|
26307
26497
|
if (gateway.specs.length > 1)
|
|
26308
26498
|
return "the platform takes one OpenAPI file per gateway, but the config lists several";
|
|
@@ -27751,7 +27941,7 @@ async function planPortalService(resolved, ledger) {
|
|
|
27751
27941
|
const hash2 = await portalBuildHash(resolved, prepared);
|
|
27752
27942
|
const previous = stepOf(ledger, "portal", "build");
|
|
27753
27943
|
const built = await exists5(
|
|
27754
|
-
|
|
27944
|
+
path80.join(resolved.state.buildDir, "index.html")
|
|
27755
27945
|
);
|
|
27756
27946
|
if (previous?.status === "succeeded" && previous.hash === hash2 && built) {
|
|
27757
27947
|
return {
|
|
@@ -27772,6 +27962,18 @@ async function planPortalService(resolved, ledger) {
|
|
|
27772
27962
|
};
|
|
27773
27963
|
} catch (error) {
|
|
27774
27964
|
if (!(error instanceof ConfigError)) throw error;
|
|
27965
|
+
const waitingFor = error.issues.every(
|
|
27966
|
+
(item) => item.code === "PORTAL_MANIFEST_MISSING"
|
|
27967
|
+
) ? error.issues.map((item) => item.path.replace(/^services\./, "")) : [];
|
|
27968
|
+
if (waitingFor.length > 0) {
|
|
27969
|
+
return {
|
|
27970
|
+
...base,
|
|
27971
|
+
action: "build",
|
|
27972
|
+
reason: `will build after ${joinNames(waitingFor)} ${waitingFor.length === 1 ? "is" : "are"} deployed (deploy does this in order)`,
|
|
27973
|
+
details: [],
|
|
27974
|
+
issues: []
|
|
27975
|
+
};
|
|
27976
|
+
}
|
|
27775
27977
|
return {
|
|
27776
27978
|
...base,
|
|
27777
27979
|
action: "blocked",
|
|
@@ -27781,15 +27983,30 @@ async function planPortalService(resolved, ledger) {
|
|
|
27781
27983
|
};
|
|
27782
27984
|
}
|
|
27783
27985
|
}
|
|
27986
|
+
function joinNames(names) {
|
|
27987
|
+
if (names.length <= 1) return names[0] ?? "";
|
|
27988
|
+
return `${names.slice(0, -1).join(", ")} and ${names.at(-1)}`;
|
|
27989
|
+
}
|
|
27990
|
+
function callersNeed(gateway) {
|
|
27991
|
+
const access11 = gateway.policies.access;
|
|
27992
|
+
const token = access11?.jwt ?? gateway.auth !== void 0;
|
|
27993
|
+
const key = access11?.apiKey ?? true;
|
|
27994
|
+
if (token && key) return "a sign-in token and an API key";
|
|
27995
|
+
if (token) return "a sign-in token";
|
|
27996
|
+
if (key) return "an API key";
|
|
27997
|
+
return "nothing (the API is public)";
|
|
27998
|
+
}
|
|
27999
|
+
var count = (value) => value.toLocaleString("en-US");
|
|
28000
|
+
function perPeriod(calls, seconds) {
|
|
28001
|
+
const period = seconds === 60 ? "minute" : seconds === 3600 ? "hour" : seconds === 86400 ? "day" : `${count(seconds)} seconds`;
|
|
28002
|
+
return `${count(calls)} calls per ${period}`;
|
|
28003
|
+
}
|
|
27784
28004
|
function describePolicies(gateway) {
|
|
27785
28005
|
const policies = gateway.policies;
|
|
27786
28006
|
return [
|
|
27787
|
-
|
|
27788
|
-
|
|
27789
|
-
|
|
27790
|
-
].filter(Boolean).join(", ")}` : void 0,
|
|
27791
|
-
policies.rateLimit ? `rate limit: ${policies.rateLimit.calls} per ${policies.rateLimit.periodSeconds} s` : void 0,
|
|
27792
|
-
policies.quota ? `quota: ${policies.quota.calls} per ${policies.quota.periodDays} day(s)` : void 0,
|
|
28007
|
+
`callers need: ${callersNeed(gateway)}`,
|
|
28008
|
+
policies.rateLimit ? `rate limit: ${perPeriod(policies.rateLimit.calls, policies.rateLimit.periodSeconds)}` : void 0,
|
|
28009
|
+
policies.quota ? `quota: ${count(policies.quota.calls)} calls per ${policies.quota.periodDays === 1 ? "day" : `${policies.quota.periodDays} days`}` : void 0,
|
|
27793
28010
|
policies.cors ? `cors: ${policies.cors.length} origin(s)` : void 0,
|
|
27794
28011
|
policies.operations?.public ? `public operations: ${policies.operations.public.length}` : void 0
|
|
27795
28012
|
].filter((line2) => line2 !== void 0);
|
|
@@ -28110,7 +28327,7 @@ async function statusV2(dir, only, options = {}) {
|
|
|
28110
28327
|
if (service === "portal") {
|
|
28111
28328
|
const build2 = stepOf(ledger, "portal", "build");
|
|
28112
28329
|
const built = await exists5(
|
|
28113
|
-
|
|
28330
|
+
path80.join(resolved.state.buildDir, "index.html")
|
|
28114
28331
|
);
|
|
28115
28332
|
const state = build2?.status === "failed" ? "build-failed" : build2?.status === "succeeded" && built ? "built" : "not-built";
|
|
28116
28333
|
services.push({
|
|
@@ -28121,7 +28338,7 @@ async function statusV2(dir, only, options = {}) {
|
|
|
28121
28338
|
...build2?.finishedAt ? [`last build: ${build2.finishedAt}`] : [],
|
|
28122
28339
|
...build2?.status === "failed" ? [`error: ${build2.error ?? "unknown"}`] : [],
|
|
28123
28340
|
...state === "built" ? [
|
|
28124
|
-
`output: ${
|
|
28341
|
+
`output: ${path80.relative(resolved.configDir, resolved.state.buildDir)}`
|
|
28125
28342
|
] : [],
|
|
28126
28343
|
...url2 ? [`url: ${url2}`] : ["url: not known (portal is not deployed yet)"],
|
|
28127
28344
|
...await hostingLine(resolved, manifest, options.hostingRemote)
|
|
@@ -28167,10 +28384,10 @@ async function statusV2(dir, only, options = {}) {
|
|
|
28167
28384
|
services
|
|
28168
28385
|
};
|
|
28169
28386
|
}
|
|
28170
|
-
function formatPlan(output4) {
|
|
28387
|
+
function formatPlan(output4, options = {}) {
|
|
28171
28388
|
return output4.services.flatMap((svc) => [
|
|
28172
28389
|
`${svc.service}: ${svc.reason}`,
|
|
28173
|
-
...svc.details.map((line2) => ` ${line2}`),
|
|
28390
|
+
...svc.details.filter((line2) => options.verbose === true || !line2.startsWith("step ")).map((line2) => ` ${line2}`),
|
|
28174
28391
|
...svc.issues.map(
|
|
28175
28392
|
(issue4) => ` problem: ${issue4.message}${issue4.hint ? ` ${issue4.hint}` : ""} [${issue4.code}]`
|
|
28176
28393
|
)
|
|
@@ -28188,7 +28405,7 @@ function formatStatus(output4) {
|
|
|
28188
28405
|
|
|
28189
28406
|
// src/cli/deploy/static-web-config.ts
|
|
28190
28407
|
import { access as access10, writeFile as writeFile22 } from "node:fs/promises";
|
|
28191
|
-
import
|
|
28408
|
+
import path81 from "node:path";
|
|
28192
28409
|
var STATIC_WEB_CONFIG_FILE = "staticwebapp.config.json";
|
|
28193
28410
|
var STATIC_WEB_CONFIG_VERSION = 3;
|
|
28194
28411
|
var CLIENT_ONLY_ROUTES = [
|
|
@@ -28206,7 +28423,7 @@ var DEFAULT_STATIC_WEB_CONFIG = {
|
|
|
28206
28423
|
}
|
|
28207
28424
|
};
|
|
28208
28425
|
async function ensureStaticWebConfig(buildDir) {
|
|
28209
|
-
const file =
|
|
28426
|
+
const file = path81.join(buildDir, STATIC_WEB_CONFIG_FILE);
|
|
28210
28427
|
try {
|
|
28211
28428
|
await access10(file);
|
|
28212
28429
|
return false;
|
|
@@ -28276,7 +28493,7 @@ function publishStep(deps, options) {
|
|
|
28276
28493
|
);
|
|
28277
28494
|
throw error;
|
|
28278
28495
|
} finally {
|
|
28279
|
-
await
|
|
28496
|
+
await rm11(archive.archivePath, { force: true });
|
|
28280
28497
|
}
|
|
28281
28498
|
}
|
|
28282
28499
|
};
|
|
@@ -28455,11 +28672,14 @@ async function deployPlansService(options, deps, projectId, named) {
|
|
|
28455
28672
|
{ ...deps.plans, client },
|
|
28456
28673
|
{ force: options.force }
|
|
28457
28674
|
);
|
|
28675
|
+
const planCount = resolved.plans?.file ? (await readPlansFile(resolved.plans.file).catch(() => [])).length : 0;
|
|
28676
|
+
const billing = resolved.plans?.billing.provider;
|
|
28458
28677
|
return {
|
|
28459
28678
|
service: "plans",
|
|
28460
28679
|
status: result.status,
|
|
28461
28680
|
steps: result.steps,
|
|
28462
28681
|
url: result.apiBaseUrl,
|
|
28682
|
+
summary: `${planCount} plan${planCount === 1 ? "" : "s"}${billing && billing !== "none" ? `, billing: ${billing}` : ""}`,
|
|
28463
28683
|
...result.notes ? { notes: result.notes } : {}
|
|
28464
28684
|
};
|
|
28465
28685
|
}
|
|
@@ -28541,7 +28761,7 @@ async function deployPortal(options, deps, projectId) {
|
|
|
28541
28761
|
}
|
|
28542
28762
|
function formatDeploy(output4) {
|
|
28543
28763
|
return output4.services.flatMap((result) => {
|
|
28544
|
-
const url2 = result.url ? ` (${result.url})` : "";
|
|
28764
|
+
const url2 = result.summary ? `, ${result.summary}` : result.url ? ` (${result.url})` : "";
|
|
28545
28765
|
const ops = result.operationCount !== void 0 ? `, ${result.operationCount} operation(s)` : "";
|
|
28546
28766
|
const head = result.status === "deployed" ? `${result.service}: deployed${result.environment ? ` to ${result.environment}` : ""}${url2}${ops}` : result.status === "unchanged" ? `${result.service}: unchanged, nothing to publish${url2}` : `${result.service}: skipped, ${result.reason}`;
|
|
28547
28767
|
return [
|
|
@@ -28557,7 +28777,7 @@ function formatDeploy(output4) {
|
|
|
28557
28777
|
// src/cli/deploy/command.ts
|
|
28558
28778
|
async function ensureLinkedProject(argv, deps) {
|
|
28559
28779
|
if (argv.projectId?.trim() || deps.envProjectId?.trim()) return true;
|
|
28560
|
-
const dir =
|
|
28780
|
+
const dir = path82.resolve(process.cwd(), argv.dir);
|
|
28561
28781
|
let linked;
|
|
28562
28782
|
try {
|
|
28563
28783
|
linked = Boolean(loadConfigV2(dir).resolved.project.id);
|
|
@@ -28609,7 +28829,7 @@ async function deployProject(argv) {
|
|
|
28609
28829
|
const config2 = loadConfig();
|
|
28610
28830
|
const output4 = await deployV2(
|
|
28611
28831
|
{
|
|
28612
|
-
dir:
|
|
28832
|
+
dir: path82.resolve(process.cwd(), argv.dir),
|
|
28613
28833
|
only: Array.isArray(argv.only) ? argv.only.join(",") : argv.only,
|
|
28614
28834
|
projectId: argv.projectId,
|
|
28615
28835
|
env: argv.env,
|
|
@@ -28653,7 +28873,7 @@ async function reportFailure(error, json) {
|
|
|
28653
28873
|
|
|
28654
28874
|
// src/cli/cmds/deploy.ts
|
|
28655
28875
|
var deploy_default = {
|
|
28656
|
-
desc: "Deploy to
|
|
28876
|
+
desc: "Deploy the project to API ToGo: the services in apitogo.config.json (identity, gateway, plans, portal), each only when it changed",
|
|
28657
28877
|
command: "deploy",
|
|
28658
28878
|
builder: (yargs2) => yargs2.option("dir", {
|
|
28659
28879
|
type: "string",
|
|
@@ -28665,17 +28885,19 @@ var deploy_default = {
|
|
|
28665
28885
|
describe: "Override project GUID"
|
|
28666
28886
|
}).option("project-name", {
|
|
28667
28887
|
type: "string",
|
|
28668
|
-
describe: "
|
|
28888
|
+
describe: "Older projects only. The project's name is project.name in apitogo.config.json",
|
|
28889
|
+
hidden: true
|
|
28669
28890
|
}).option("platform-plan", {
|
|
28670
28891
|
type: "string",
|
|
28671
|
-
describe: "
|
|
28892
|
+
describe: "Older projects only. Choose the project's plan with `apitogo project create --plan`, or change it on the dashboard",
|
|
28893
|
+
hidden: true,
|
|
28672
28894
|
choices: ["free", "starter", "professional"]
|
|
28673
28895
|
}).option("only", {
|
|
28674
28896
|
type: "string",
|
|
28675
|
-
describe: "
|
|
28897
|
+
describe: "Deploy only these services, comma separated: portal, gateway, identity, plans"
|
|
28676
28898
|
}).option("env", {
|
|
28677
28899
|
type: "string",
|
|
28678
|
-
describe: "
|
|
28900
|
+
describe: "Portal environment to publish to (default: production)"
|
|
28679
28901
|
}).option("force", {
|
|
28680
28902
|
type: "boolean",
|
|
28681
28903
|
describe: "Force redeploy of selected resources even when healthy",
|
|
@@ -28683,7 +28905,7 @@ var deploy_default = {
|
|
|
28683
28905
|
}).option("yes", {
|
|
28684
28906
|
alias: "y",
|
|
28685
28907
|
type: "boolean",
|
|
28686
|
-
describe: "
|
|
28908
|
+
describe: "Confirm a change that cannot be undone, such as switching the identity provider",
|
|
28687
28909
|
default: false
|
|
28688
28910
|
}).option("resume-from", {
|
|
28689
28911
|
type: "string",
|
|
@@ -28694,7 +28916,7 @@ var deploy_default = {
|
|
|
28694
28916
|
default: true
|
|
28695
28917
|
}).option("verbose", {
|
|
28696
28918
|
type: "boolean",
|
|
28697
|
-
describe: "
|
|
28919
|
+
describe: "Show the full build log (by default only the result of each service is printed)",
|
|
28698
28920
|
default: false
|
|
28699
28921
|
}).option("json", {
|
|
28700
28922
|
type: "boolean",
|
|
@@ -28703,7 +28925,7 @@ var deploy_default = {
|
|
|
28703
28925
|
}),
|
|
28704
28926
|
handler: async (argv) => {
|
|
28705
28927
|
await captureEvent({ argv, event: "apitogo deploy" });
|
|
28706
|
-
if (await isConfigV2(
|
|
28928
|
+
if (await isConfigV2(path83.resolve(process.cwd(), argv.dir))) {
|
|
28707
28929
|
await deployProject(argv);
|
|
28708
28930
|
return;
|
|
28709
28931
|
}
|
|
@@ -28712,8 +28934,8 @@ var deploy_default = {
|
|
|
28712
28934
|
};
|
|
28713
28935
|
|
|
28714
28936
|
// src/cli/export/handler.ts
|
|
28715
|
-
import { mkdir as
|
|
28716
|
-
import
|
|
28937
|
+
import { mkdir as mkdir19, writeFile as writeFile23 } from "node:fs/promises";
|
|
28938
|
+
import path84 from "node:path";
|
|
28717
28939
|
init_invariant();
|
|
28718
28940
|
var ExportError = class extends ApitogoError {
|
|
28719
28941
|
constructor(message, developerHint) {
|
|
@@ -28727,7 +28949,7 @@ async function exportOpenApi(args, deps) {
|
|
|
28727
28949
|
`Cannot export "${args.target}".`,
|
|
28728
28950
|
"Only `apitogo export openapi` exists."
|
|
28729
28951
|
);
|
|
28730
|
-
const dir =
|
|
28952
|
+
const dir = path84.resolve(process.cwd(), args.dir ?? ".");
|
|
28731
28953
|
if (!await isConfigV2(dir))
|
|
28732
28954
|
throw new ExportError(
|
|
28733
28955
|
"This command needs a config version 2 project.",
|
|
@@ -28740,9 +28962,9 @@ async function exportOpenApi(args, deps) {
|
|
|
28740
28962
|
"This folder is not linked to a project.",
|
|
28741
28963
|
"Run `apitogo project create`, or pass --project-id."
|
|
28742
28964
|
);
|
|
28743
|
-
let
|
|
28965
|
+
let text2;
|
|
28744
28966
|
try {
|
|
28745
|
-
|
|
28967
|
+
text2 = await deps.client.getGatewayOpenApi(projectId);
|
|
28746
28968
|
} catch (error) {
|
|
28747
28969
|
if (error instanceof PlatformApiError && error.status === 404)
|
|
28748
28970
|
throw new ExportError(
|
|
@@ -28751,11 +28973,11 @@ async function exportOpenApi(args, deps) {
|
|
|
28751
28973
|
);
|
|
28752
28974
|
throw error;
|
|
28753
28975
|
}
|
|
28754
|
-
if (!args.out) return { text };
|
|
28755
|
-
const file =
|
|
28756
|
-
await
|
|
28757
|
-
await writeFile23(file,
|
|
28758
|
-
return { text, file };
|
|
28976
|
+
if (!args.out) return { text: text2 };
|
|
28977
|
+
const file = path84.resolve(process.cwd(), args.out);
|
|
28978
|
+
await mkdir19(path84.dirname(file), { recursive: true });
|
|
28979
|
+
await writeFile23(file, text2);
|
|
28980
|
+
return { text: text2, file };
|
|
28759
28981
|
}
|
|
28760
28982
|
async function exportCommand(args) {
|
|
28761
28983
|
try {
|
|
@@ -28777,7 +28999,7 @@ async function exportCommand(args) {
|
|
|
28777
28999
|
|
|
28778
29000
|
// src/cli/cmds/export.ts
|
|
28779
29001
|
var export_default = {
|
|
28780
|
-
desc: "Print or save the OpenAPI file the platform publishes for your gateway
|
|
29002
|
+
desc: "Print or save the OpenAPI file the platform publishes for your gateway",
|
|
28781
29003
|
command: "export <target>",
|
|
28782
29004
|
builder: (yargs2) => yargs2.positional("target", {
|
|
28783
29005
|
type: "string",
|
|
@@ -28846,8 +29068,8 @@ import open3 from "open";
|
|
|
28846
29068
|
import colors14 from "picocolors";
|
|
28847
29069
|
|
|
28848
29070
|
// src/cli/platform/device-auth.ts
|
|
28849
|
-
function url(apiUrl,
|
|
28850
|
-
return `${apiUrl}${
|
|
29071
|
+
function url(apiUrl, path98) {
|
|
29072
|
+
return `${apiUrl}${path98.startsWith("/") ? path98 : `/${path98}`}`;
|
|
28851
29073
|
}
|
|
28852
29074
|
async function requestDeviceCode(apiUrl) {
|
|
28853
29075
|
const response = await fetchWithRetry(
|
|
@@ -29029,7 +29251,7 @@ var logout_default = {
|
|
|
29029
29251
|
};
|
|
29030
29252
|
|
|
29031
29253
|
// src/cli/portal/commands.ts
|
|
29032
|
-
import
|
|
29254
|
+
import path85 from "node:path";
|
|
29033
29255
|
init_invariant();
|
|
29034
29256
|
function parseOnly(value) {
|
|
29035
29257
|
if (value === void 0) return void 0;
|
|
@@ -29046,7 +29268,7 @@ function parseOnly(value) {
|
|
|
29046
29268
|
async function run2(command2, argv, compute, format) {
|
|
29047
29269
|
const json = argv.json === true;
|
|
29048
29270
|
try {
|
|
29049
|
-
const dir =
|
|
29271
|
+
const dir = path85.resolve(process.cwd(), argv.dir ?? ".");
|
|
29050
29272
|
if (!await isConfigV2(dir)) {
|
|
29051
29273
|
throw new ServiceEditError(
|
|
29052
29274
|
`${command2} works with a config version 2 project, and there is none in ${dir}.`,
|
|
@@ -29082,7 +29304,7 @@ var plan = (argv) => run2(
|
|
|
29082
29304
|
gatewayDryRun: gatewayDryRun(),
|
|
29083
29305
|
plansRemote: plansRemote()
|
|
29084
29306
|
}),
|
|
29085
|
-
formatPlan
|
|
29307
|
+
(output4) => formatPlan(output4, { verbose: argv.verbose === true })
|
|
29086
29308
|
);
|
|
29087
29309
|
function gatewayRemote() {
|
|
29088
29310
|
try {
|
|
@@ -29152,7 +29374,7 @@ var statusOfProject = (argv) => run2(
|
|
|
29152
29374
|
|
|
29153
29375
|
// src/cli/cmds/plan.ts
|
|
29154
29376
|
var plan_default = {
|
|
29155
|
-
desc: "Show what deploy would do for each service
|
|
29377
|
+
desc: "Show what deploy would do for each service (changes nothing)",
|
|
29156
29378
|
command: "plan",
|
|
29157
29379
|
builder: (yargs2) => yargs2.option("dir", {
|
|
29158
29380
|
type: "string",
|
|
@@ -29163,6 +29385,10 @@ var plan_default = {
|
|
|
29163
29385
|
}).option("only", {
|
|
29164
29386
|
type: "string",
|
|
29165
29387
|
describe: "Only these services, comma separated (portal, gateway, identity, plans)"
|
|
29388
|
+
}).option("verbose", {
|
|
29389
|
+
type: "boolean",
|
|
29390
|
+
default: false,
|
|
29391
|
+
describe: "Also show each service's steps and their state"
|
|
29166
29392
|
}).option("json", {
|
|
29167
29393
|
type: "boolean",
|
|
29168
29394
|
default: false,
|
|
@@ -29176,11 +29402,11 @@ var plan_default = {
|
|
|
29176
29402
|
|
|
29177
29403
|
// src/cli/cmds/project-create.ts
|
|
29178
29404
|
var project_create_default = {
|
|
29179
|
-
desc: "Create
|
|
29405
|
+
desc: "Create the API ToGo project for this folder: hosting for its services on the plan you choose, and project.id written into apitogo.config.json",
|
|
29180
29406
|
command: "project create",
|
|
29181
29407
|
builder: (yargs2) => yargs2.option("name", {
|
|
29182
29408
|
type: "string",
|
|
29183
|
-
describe: "Project display name (
|
|
29409
|
+
describe: "Project display name (default: project.name in apitogo.config.json)"
|
|
29184
29410
|
}).option("dir", {
|
|
29185
29411
|
type: "string",
|
|
29186
29412
|
describe: "Project directory",
|
|
@@ -29192,12 +29418,13 @@ var project_create_default = {
|
|
|
29192
29418
|
describe: "Optional project description"
|
|
29193
29419
|
}).option("modules", {
|
|
29194
29420
|
type: "string",
|
|
29195
|
-
describe: "
|
|
29421
|
+
describe: "Older projects only: comma-separated modules to activate. The services in apitogo.config.json decide them",
|
|
29422
|
+
hidden: true,
|
|
29196
29423
|
default: "apihub"
|
|
29197
29424
|
}).option("plan", {
|
|
29198
29425
|
type: "string",
|
|
29199
29426
|
choices: ["free", "starter", "professional"],
|
|
29200
|
-
describe: "
|
|
29427
|
+
describe: "The plan of the new project: free (default), starter or professional. Starter and Professional are paid through the platform's checkout, and a project needs one of them to sell paid plans"
|
|
29201
29428
|
}).option("open", {
|
|
29202
29429
|
type: "boolean",
|
|
29203
29430
|
describe: "Open the checkout page in the browser for a paid plan (use --no-open to only print the link)",
|
|
@@ -29209,8 +29436,12 @@ var project_create_default = {
|
|
|
29209
29436
|
hidden: true
|
|
29210
29437
|
}).option("wait", {
|
|
29211
29438
|
type: "boolean",
|
|
29212
|
-
describe: "Wait until the hosting
|
|
29439
|
+
describe: "Wait until the hosting is ready before returning. Use --no-wait to return sooner",
|
|
29213
29440
|
default: true
|
|
29441
|
+
}).option("verbose", {
|
|
29442
|
+
type: "boolean",
|
|
29443
|
+
default: false,
|
|
29444
|
+
describe: "Show every platform step, including hosting details"
|
|
29214
29445
|
}).option("json", {
|
|
29215
29446
|
type: "boolean",
|
|
29216
29447
|
describe: "Print raw JSON only",
|
|
@@ -29224,7 +29455,7 @@ var project_create_default = {
|
|
|
29224
29455
|
|
|
29225
29456
|
// src/cli/cmds/remove.ts
|
|
29226
29457
|
var remove_default = {
|
|
29227
|
-
desc: "Remove a service
|
|
29458
|
+
desc: "Remove a service from the project (its files are kept unless --delete-files)",
|
|
29228
29459
|
command: "remove <service>",
|
|
29229
29460
|
builder: (yargs2) => yargs2.positional("service", {
|
|
29230
29461
|
type: "string",
|
|
@@ -29262,14 +29493,14 @@ var remove_default = {
|
|
|
29262
29493
|
|
|
29263
29494
|
// src/cli/dev/handler.ts
|
|
29264
29495
|
init_joinUrl();
|
|
29265
|
-
import
|
|
29496
|
+
import path88 from "node:path";
|
|
29266
29497
|
|
|
29267
29498
|
// src/vite/dev-server.ts
|
|
29268
29499
|
init_logger();
|
|
29269
29500
|
import fs11 from "node:fs/promises";
|
|
29270
29501
|
import http from "node:http";
|
|
29271
29502
|
import https from "node:https";
|
|
29272
|
-
import
|
|
29503
|
+
import path87 from "node:path";
|
|
29273
29504
|
import { createHttpTerminator } from "http-terminator";
|
|
29274
29505
|
import {
|
|
29275
29506
|
createServer as createViteServer,
|
|
@@ -29302,7 +29533,7 @@ init_loader();
|
|
|
29302
29533
|
// src/vite/pagefind-dev-index.ts
|
|
29303
29534
|
init_invariant();
|
|
29304
29535
|
init_joinUrl();
|
|
29305
|
-
import
|
|
29536
|
+
import path86 from "node:path";
|
|
29306
29537
|
import { createIndex as createIndex2 } from "pagefind";
|
|
29307
29538
|
import { isRunnableDevEnvironment } from "vite";
|
|
29308
29539
|
async function* buildPagefindDevIndex(vite, config2) {
|
|
@@ -29355,7 +29586,7 @@ async function* buildPagefindDevIndex(vite, config2) {
|
|
|
29355
29586
|
path: urlPath
|
|
29356
29587
|
};
|
|
29357
29588
|
}
|
|
29358
|
-
const outputPath =
|
|
29589
|
+
const outputPath = path86.join(vite.config.publicDir, "pagefind");
|
|
29359
29590
|
await pagefindIndex.writeFiles({ outputPath });
|
|
29360
29591
|
yield { type: "complete", success: true, indexed };
|
|
29361
29592
|
}
|
|
@@ -29374,9 +29605,9 @@ var DevServer = class {
|
|
|
29374
29605
|
this.protocol = "https";
|
|
29375
29606
|
const { dir } = this.options;
|
|
29376
29607
|
const [key, cert, ca] = await Promise.all([
|
|
29377
|
-
fs11.readFile(
|
|
29378
|
-
fs11.readFile(
|
|
29379
|
-
config2.https.ca ? fs11.readFile(
|
|
29608
|
+
fs11.readFile(path87.resolve(dir, config2.https.key)),
|
|
29609
|
+
fs11.readFile(path87.resolve(dir, config2.https.cert)),
|
|
29610
|
+
config2.https.ca ? fs11.readFile(path87.resolve(dir, config2.https.ca)) : void 0
|
|
29380
29611
|
]);
|
|
29381
29612
|
return https.createServer({ key, cert, ca });
|
|
29382
29613
|
}
|
|
@@ -29393,7 +29624,7 @@ var DevServer = class {
|
|
|
29393
29624
|
);
|
|
29394
29625
|
const server = await this.createNodeServer(config2);
|
|
29395
29626
|
if (config2.search?.type === "pagefind" && viteConfig.publicDir !== false) {
|
|
29396
|
-
const publicRoot =
|
|
29627
|
+
const publicRoot = path87.resolve(
|
|
29397
29628
|
this.options.dir,
|
|
29398
29629
|
typeof viteConfig.publicDir === "string" ? viteConfig.publicDir : "public"
|
|
29399
29630
|
);
|
|
@@ -29410,7 +29641,7 @@ var DevServer = class {
|
|
|
29410
29641
|
// built-in transform middleware which would treat the path as a static asset.
|
|
29411
29642
|
name: "apitogo:entry-client",
|
|
29412
29643
|
configureServer(server2) {
|
|
29413
|
-
const entryPath =
|
|
29644
|
+
const entryPath = path87.posix.join(
|
|
29414
29645
|
server2.config.base,
|
|
29415
29646
|
"/__z/entry.client.tsx"
|
|
29416
29647
|
);
|
|
@@ -29575,7 +29806,7 @@ init_package_json();
|
|
|
29575
29806
|
async function dev(argv) {
|
|
29576
29807
|
const packageJson3 = getZudokuPackageJson();
|
|
29577
29808
|
process.env.NODE_ENV = "development";
|
|
29578
|
-
let dir =
|
|
29809
|
+
let dir = path88.resolve(process.cwd(), argv.dir);
|
|
29579
29810
|
if (await isConfigV2(dir)) {
|
|
29580
29811
|
const { root, prepared } = await preparePortalWorkspace(dir, "development");
|
|
29581
29812
|
dir = root;
|
|
@@ -29674,7 +29905,7 @@ var run_default = {
|
|
|
29674
29905
|
};
|
|
29675
29906
|
|
|
29676
29907
|
// src/cli/secrets/handler.ts
|
|
29677
|
-
import
|
|
29908
|
+
import path89 from "node:path";
|
|
29678
29909
|
init_invariant();
|
|
29679
29910
|
var SECRET_NAME = /^[A-Za-z_][A-Za-z0-9_]{0,127}$/;
|
|
29680
29911
|
var SecretsError = class extends ApitogoError {
|
|
@@ -29686,7 +29917,7 @@ var SecretsError = class extends ApitogoError {
|
|
|
29686
29917
|
async function resolveProjectId2(argv, deps) {
|
|
29687
29918
|
const explicit = argv.projectId?.trim();
|
|
29688
29919
|
if (explicit) return explicit;
|
|
29689
|
-
const dir =
|
|
29920
|
+
const dir = path89.resolve(process.cwd(), argv.dir ?? ".");
|
|
29690
29921
|
if (await isConfigV2(dir)) {
|
|
29691
29922
|
const id = loadConfigV2(dir).resolved.project.id;
|
|
29692
29923
|
if (id) return id;
|
|
@@ -29846,12 +30077,12 @@ var secrets_default = {
|
|
|
29846
30077
|
};
|
|
29847
30078
|
|
|
29848
30079
|
// src/cli/cmds/status.ts
|
|
29849
|
-
import
|
|
30080
|
+
import path91 from "node:path";
|
|
29850
30081
|
|
|
29851
30082
|
// src/cli/status/handler.ts
|
|
29852
|
-
import
|
|
30083
|
+
import path90 from "node:path";
|
|
29853
30084
|
async function status(argv) {
|
|
29854
|
-
const sourceDirectory =
|
|
30085
|
+
const sourceDirectory = path90.resolve(process.cwd(), argv.dir);
|
|
29855
30086
|
let config2;
|
|
29856
30087
|
try {
|
|
29857
30088
|
config2 = loadConfig();
|
|
@@ -29920,12 +30151,40 @@ async function status(argv) {
|
|
|
29920
30151
|
liveError,
|
|
29921
30152
|
sourceDirectory
|
|
29922
30153
|
};
|
|
29923
|
-
|
|
30154
|
+
if (argv.json) {
|
|
30155
|
+
console.log(JSON.stringify(payload));
|
|
30156
|
+
return;
|
|
30157
|
+
}
|
|
30158
|
+
for (const line2 of formatAccountStatus(payload)) console.log(line2);
|
|
30159
|
+
}
|
|
30160
|
+
var text = (value) => typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
30161
|
+
function formatAccountStatus(payload) {
|
|
30162
|
+
const tenant = payload.account.tenant ?? {};
|
|
30163
|
+
const who = text(tenant.email) ?? text(tenant.displayName) ?? "unknown";
|
|
30164
|
+
const lines = [`Signed in as ${who}.`];
|
|
30165
|
+
if (!payload.projectId) {
|
|
30166
|
+
lines.push(
|
|
30167
|
+
"No project here. Run `apitogo create` to start one, or run this in a project folder."
|
|
30168
|
+
);
|
|
30169
|
+
return lines;
|
|
30170
|
+
}
|
|
30171
|
+
const project = payload.project ?? {};
|
|
30172
|
+
const name = text(project.name) ?? payload.projectId;
|
|
30173
|
+
const state = text(project.status);
|
|
30174
|
+
lines.push(`Project: ${name}${state ? ` (${state})` : ""}`);
|
|
30175
|
+
if (payload.liveError) lines.push(`Live check: ${payload.liveError}`);
|
|
30176
|
+
else if (payload.live) {
|
|
30177
|
+
const ok = payload.live.ok ?? payload.live.healthy ?? payload.live.status;
|
|
30178
|
+
lines.push(
|
|
30179
|
+
`Live check: ${typeof ok === "boolean" ? ok ? "online" : "not reachable" : String(ok ?? "done")}`
|
|
30180
|
+
);
|
|
30181
|
+
}
|
|
30182
|
+
return lines;
|
|
29924
30183
|
}
|
|
29925
30184
|
|
|
29926
30185
|
// src/cli/cmds/status.ts
|
|
29927
30186
|
var status_default = {
|
|
29928
|
-
desc: "Show the state of each service
|
|
30187
|
+
desc: "Show the state of each service of the project, or of your account outside a project",
|
|
29929
30188
|
command: "status",
|
|
29930
30189
|
builder: (yargs2) => yargs2.option("dir", {
|
|
29931
30190
|
type: "string",
|
|
@@ -29941,15 +30200,15 @@ var status_default = {
|
|
|
29941
30200
|
default: false
|
|
29942
30201
|
}).option("only", {
|
|
29943
30202
|
type: "string",
|
|
29944
|
-
describe: "
|
|
30203
|
+
describe: "Only these services, comma separated (portal, gateway, identity, plans)"
|
|
29945
30204
|
}).option("json", {
|
|
29946
30205
|
type: "boolean",
|
|
29947
|
-
describe: "Print
|
|
30206
|
+
describe: "Print JSON instead of text",
|
|
29948
30207
|
default: false
|
|
29949
30208
|
}),
|
|
29950
30209
|
handler: async (argv) => {
|
|
29951
30210
|
await captureEvent({ argv, event: "apitogo status" });
|
|
29952
|
-
if (await isConfigV2(
|
|
30211
|
+
if (await isConfigV2(path91.resolve(process.cwd(), argv.dir))) {
|
|
29953
30212
|
await statusOfProject(argv);
|
|
29954
30213
|
return;
|
|
29955
30214
|
}
|
|
@@ -29958,11 +30217,11 @@ var status_default = {
|
|
|
29958
30217
|
};
|
|
29959
30218
|
|
|
29960
30219
|
// src/cli/cmds/teardown.ts
|
|
29961
|
-
import
|
|
30220
|
+
import path94 from "node:path";
|
|
29962
30221
|
|
|
29963
30222
|
// src/cli/teardown/command.ts
|
|
29964
30223
|
init_invariant();
|
|
29965
|
-
import
|
|
30224
|
+
import path92 from "node:path";
|
|
29966
30225
|
import { createInterface as createInterface7 } from "node:readline/promises";
|
|
29967
30226
|
|
|
29968
30227
|
// src/cli/teardown/v2.ts
|
|
@@ -30323,7 +30582,7 @@ async function teardownProject(argv) {
|
|
|
30323
30582
|
const progress = createConsoleProgressReporter();
|
|
30324
30583
|
const result = await teardownV2(
|
|
30325
30584
|
{
|
|
30326
|
-
dir:
|
|
30585
|
+
dir: path92.resolve(process.cwd(), argv.dir),
|
|
30327
30586
|
projectId: argv.projectId,
|
|
30328
30587
|
only: Array.isArray(argv.only) ? argv.only.join(",") : argv.only,
|
|
30329
30588
|
yes: argv.yes === true,
|
|
@@ -30382,7 +30641,7 @@ async function teardownProject(argv) {
|
|
|
30382
30641
|
}
|
|
30383
30642
|
|
|
30384
30643
|
// src/cli/teardown/handler.ts
|
|
30385
|
-
import
|
|
30644
|
+
import path93 from "node:path";
|
|
30386
30645
|
function resultLooksFailed3(payload) {
|
|
30387
30646
|
try {
|
|
30388
30647
|
const parsed = JSON.parse(payload);
|
|
@@ -30398,7 +30657,7 @@ async function teardown(argv) {
|
|
|
30398
30657
|
);
|
|
30399
30658
|
return;
|
|
30400
30659
|
}
|
|
30401
|
-
const sourceDirectory =
|
|
30660
|
+
const sourceDirectory = path93.resolve(process.cwd(), argv.dir);
|
|
30402
30661
|
let config2;
|
|
30403
30662
|
try {
|
|
30404
30663
|
config2 = loadConfig();
|
|
@@ -30447,7 +30706,7 @@ async function teardown(argv) {
|
|
|
30447
30706
|
|
|
30448
30707
|
// src/cli/cmds/teardown.ts
|
|
30449
30708
|
var teardown_default = {
|
|
30450
|
-
desc: "Delete the linked API ToGo project.
|
|
30709
|
+
desc: "Delete the linked API ToGo project. You type the project name to confirm; local files are kept",
|
|
30451
30710
|
command: "teardown",
|
|
30452
30711
|
builder: (yargs2) => yargs2.option("dir", {
|
|
30453
30712
|
type: "string",
|
|
@@ -30459,11 +30718,11 @@ var teardown_default = {
|
|
|
30459
30718
|
describe: "Override project GUID"
|
|
30460
30719
|
}).option("only", {
|
|
30461
30720
|
type: "string",
|
|
30462
|
-
describe: "
|
|
30721
|
+
describe: "`gateway`, `identity` or `plans` removes just that service and keeps the project (`identity` deletes every user in it); other hosting is released only by deleting the whole project"
|
|
30463
30722
|
}).option("yes", {
|
|
30464
30723
|
alias: "y",
|
|
30465
30724
|
type: "boolean",
|
|
30466
|
-
describe: "Confirm without asking
|
|
30725
|
+
describe: "Confirm without asking",
|
|
30467
30726
|
default: false
|
|
30468
30727
|
}).option("wait", {
|
|
30469
30728
|
type: "boolean",
|
|
@@ -30476,7 +30735,7 @@ var teardown_default = {
|
|
|
30476
30735
|
}),
|
|
30477
30736
|
handler: async (argv) => {
|
|
30478
30737
|
await captureEvent({ argv, event: "apitogo teardown" });
|
|
30479
|
-
if (await isConfigV2(
|
|
30738
|
+
if (await isConfigV2(path94.resolve(process.cwd(), argv.dir))) {
|
|
30480
30739
|
await teardownProject(argv);
|
|
30481
30740
|
return;
|
|
30482
30741
|
}
|
|
@@ -30486,7 +30745,7 @@ var teardown_default = {
|
|
|
30486
30745
|
|
|
30487
30746
|
// src/cli/teardown/reset-command.ts
|
|
30488
30747
|
init_invariant();
|
|
30489
|
-
import
|
|
30748
|
+
import path95 from "node:path";
|
|
30490
30749
|
|
|
30491
30750
|
// src/cli/teardown/reset.ts
|
|
30492
30751
|
init_invariant();
|
|
@@ -30609,7 +30868,7 @@ async function resetProject(argv) {
|
|
|
30609
30868
|
const config2 = loadConfig();
|
|
30610
30869
|
const result = await resetProjectV2(
|
|
30611
30870
|
{
|
|
30612
|
-
dir:
|
|
30871
|
+
dir: path95.resolve(process.cwd(), argv.dir),
|
|
30613
30872
|
projectId: argv.projectId,
|
|
30614
30873
|
yes: argv.yes === true
|
|
30615
30874
|
},
|
|
@@ -30673,7 +30932,7 @@ var test_reset_default = {
|
|
|
30673
30932
|
};
|
|
30674
30933
|
|
|
30675
30934
|
// src/cli/test-sign-in/handler.ts
|
|
30676
|
-
import
|
|
30935
|
+
import path96 from "node:path";
|
|
30677
30936
|
init_invariant();
|
|
30678
30937
|
var TestSignInError = class extends ApitogoError {
|
|
30679
30938
|
constructor(message, developerHint) {
|
|
@@ -30684,7 +30943,7 @@ var TestSignInError = class extends ApitogoError {
|
|
|
30684
30943
|
async function resolveProjectId3(argv) {
|
|
30685
30944
|
const explicit = argv.projectId?.trim();
|
|
30686
30945
|
if (explicit) return explicit;
|
|
30687
|
-
const dir =
|
|
30946
|
+
const dir = path96.resolve(process.cwd(), argv.dir ?? ".");
|
|
30688
30947
|
if (await isConfigV2(dir)) {
|
|
30689
30948
|
const id = loadConfigV2(dir).resolved.project.id;
|
|
30690
30949
|
if (id) return id;
|
|
@@ -30822,38 +31081,38 @@ function createApitogoCli(argv) {
|
|
|
30822
31081
|
}
|
|
30823
31082
|
|
|
30824
31083
|
// src/cli/local-handoff.ts
|
|
30825
|
-
import { spawn as
|
|
31084
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
30826
31085
|
import { existsSync as existsSync8, realpathSync as realpathSync2 } from "node:fs";
|
|
30827
|
-
import
|
|
31086
|
+
import path97 from "node:path";
|
|
30828
31087
|
var LOCAL_HANDOFF_ENV = "APITOGO_LOCAL_CLI";
|
|
30829
31088
|
var PACKAGE_NAME = "@lukoweb/apitogo";
|
|
30830
31089
|
var resolveProjectDir = (argv, cwd) => {
|
|
30831
31090
|
for (let i = 0; i < argv.length; i++) {
|
|
30832
31091
|
const arg = argv[i];
|
|
30833
31092
|
const next = argv[i + 1];
|
|
30834
|
-
if (arg === "--dir" && next) return
|
|
31093
|
+
if (arg === "--dir" && next) return path97.resolve(cwd, next);
|
|
30835
31094
|
if (arg?.startsWith("--dir=")) {
|
|
30836
|
-
return
|
|
31095
|
+
return path97.resolve(cwd, arg.slice("--dir=".length));
|
|
30837
31096
|
}
|
|
30838
31097
|
}
|
|
30839
31098
|
return cwd;
|
|
30840
31099
|
};
|
|
30841
31100
|
var findLocalCli = (projectDir, runningRoot) => {
|
|
30842
|
-
let dir =
|
|
31101
|
+
let dir = path97.resolve(projectDir);
|
|
30843
31102
|
let localPackageRoot;
|
|
30844
31103
|
while (!localPackageRoot) {
|
|
30845
|
-
const candidate =
|
|
30846
|
-
if (existsSync8(
|
|
31104
|
+
const candidate = path97.join(dir, "node_modules", PACKAGE_NAME);
|
|
31105
|
+
if (existsSync8(path97.join(candidate, "package.json"))) {
|
|
30847
31106
|
localPackageRoot = candidate;
|
|
30848
|
-
} else if (dir ===
|
|
31107
|
+
} else if (dir === path97.dirname(dir)) {
|
|
30849
31108
|
return void 0;
|
|
30850
31109
|
} else {
|
|
30851
|
-
dir =
|
|
31110
|
+
dir = path97.dirname(dir);
|
|
30852
31111
|
}
|
|
30853
31112
|
}
|
|
30854
31113
|
const localRoot = realpathSync2(localPackageRoot);
|
|
30855
31114
|
if (localRoot === realpathSync2(runningRoot)) return void 0;
|
|
30856
|
-
return
|
|
31115
|
+
return path97.join(localRoot, "cli.js");
|
|
30857
31116
|
};
|
|
30858
31117
|
var handoffToLocalCli = async (argv, runningRoot) => {
|
|
30859
31118
|
if (process.env[LOCAL_HANDOFF_ENV] || process.env.ZUDOKU_ENV === "internal") {
|
|
@@ -30865,9 +31124,9 @@ var handoffToLocalCli = async (argv, runningRoot) => {
|
|
|
30865
31124
|
);
|
|
30866
31125
|
if (!localCli) return void 0;
|
|
30867
31126
|
printDiagnosticsToConsole(
|
|
30868
|
-
`Using the project's local ${PACKAGE_NAME} (${
|
|
31127
|
+
`Using the project's local ${PACKAGE_NAME} (${path97.dirname(localCli)})`
|
|
30869
31128
|
);
|
|
30870
|
-
const child =
|
|
31129
|
+
const child = spawn2(process.execPath, [localCli, ...argv], {
|
|
30871
31130
|
stdio: "inherit",
|
|
30872
31131
|
env: { ...process.env, [LOCAL_HANDOFF_ENV]: "1" }
|
|
30873
31132
|
});
|