@lukoweb/apitogo 0.2.47 → 0.2.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/cli.js +421 -323
- package/docs/cli/shape.md +4 -3
- package/docs/cli/walkthrough.md +14 -25
- package/docs/configuration/make-config.mdx +3 -2
- package/package.json +1 -1
- package/src/config/v2/__fixtures__/scenario-a-docs-only.json +6 -6
- package/src/config/v2/__fixtures__/scenario-b-managed-origin.json +14 -14
- package/src/config/v2/__fixtures__/scenario-c-proxy-oidc.json +15 -15
- package/src/config/v2/__fixtures__/scenario-h-full-stack.json +28 -28
- package/src/config/v2/billing.ts +59 -0
- package/src/config/v2/docs-navigation.ts +72 -72
- package/src/config/v2/errors.ts +42 -42
- package/src/config/v2/gateway-reference.ts +220 -220
- package/src/config/v2/gateway-request.ts +123 -123
- package/src/config/v2/index.ts +7 -0
- package/src/config/v2/layout.ts +237 -237
- package/src/config/v2/load.ts +70 -70
- package/src/config/v2/parse.ts +214 -214
- package/src/config/v2/portal-profile.ts +88 -88
- package/src/config/v2/resolve.ts +6 -1
- package/src/config/v2/rules.ts +27 -15
- package/src/config/v2/services.ts +5 -20
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 = (path96) => stat4(path96).then(() => true).catch(() => false);
|
|
841
841
|
}
|
|
842
842
|
});
|
|
843
843
|
|
|
@@ -5836,6 +5836,36 @@ import yargs from "yargs/yargs";
|
|
|
5836
5836
|
// src/cli/services/handler.ts
|
|
5837
5837
|
import path52 from "node:path";
|
|
5838
5838
|
|
|
5839
|
+
// src/config/v2/billing.ts
|
|
5840
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
5841
|
+
var DEFAULT_STRIPE_KEY_SECRET = "STRIPE_API_KEY";
|
|
5842
|
+
function isPaidPlan(plan2) {
|
|
5843
|
+
return plan2.pricingModel !== "custom" && typeof plan2.priceAmount === "number" && plan2.priceAmount > 0;
|
|
5844
|
+
}
|
|
5845
|
+
async function paidPlanSkus(resolved) {
|
|
5846
|
+
const file = resolved.plans?.file;
|
|
5847
|
+
if (!file) return [];
|
|
5848
|
+
try {
|
|
5849
|
+
const raw = JSON.parse(await readFile2(file, "utf8"));
|
|
5850
|
+
if (!Array.isArray(raw.plans)) return [];
|
|
5851
|
+
return raw.plans.filter(
|
|
5852
|
+
(plan2) => typeof plan2 === "object" && plan2 !== null && isPaidPlan(plan2)
|
|
5853
|
+
).map((plan2) => String(plan2.sku ?? "?"));
|
|
5854
|
+
} catch {
|
|
5855
|
+
return [];
|
|
5856
|
+
}
|
|
5857
|
+
}
|
|
5858
|
+
async function billingNeeded(resolved) {
|
|
5859
|
+
const plans = resolved.plans;
|
|
5860
|
+
if (!plans?.enabled || plans.billing.provider !== "stripe") return false;
|
|
5861
|
+
return (await paidPlanSkus(resolved)).length > 0;
|
|
5862
|
+
}
|
|
5863
|
+
function stripeKeySecretName(resolved) {
|
|
5864
|
+
const ref = resolved.plans?.billing.apiKey;
|
|
5865
|
+
const match = ref ? /^secret:(.+)$/.exec(ref) : null;
|
|
5866
|
+
return match?.[1] ?? DEFAULT_STRIPE_KEY_SECRET;
|
|
5867
|
+
}
|
|
5868
|
+
|
|
5839
5869
|
// src/config/v2/errors.ts
|
|
5840
5870
|
init_invariant();
|
|
5841
5871
|
function formatConfigIssue(issue4) {
|
|
@@ -6043,8 +6073,8 @@ var ConfigV2Schema = z.strictObject({
|
|
|
6043
6073
|
var REMOVED_KEYS = {
|
|
6044
6074
|
"plans.provider": "plans.provider was removed. Only plans.billing.provider (stripe or none) is selectable."
|
|
6045
6075
|
};
|
|
6046
|
-
function pathToString(
|
|
6047
|
-
return
|
|
6076
|
+
function pathToString(path96) {
|
|
6077
|
+
return path96.reduce(
|
|
6048
6078
|
(acc, segment) => typeof segment === "number" ? `${acc}[${segment}]` : acc === "" ? String(segment) : `${acc}.${String(segment)}`,
|
|
6049
6079
|
""
|
|
6050
6080
|
);
|
|
@@ -6064,9 +6094,9 @@ function step(schema2, segment) {
|
|
|
6064
6094
|
}
|
|
6065
6095
|
return void 0;
|
|
6066
6096
|
}
|
|
6067
|
-
function knownKeysAt(
|
|
6097
|
+
function knownKeysAt(path96) {
|
|
6068
6098
|
let current = ConfigV2Schema;
|
|
6069
|
-
for (const segment of
|
|
6099
|
+
for (const segment of path96) {
|
|
6070
6100
|
if (!current) return [];
|
|
6071
6101
|
current = step(current, segment);
|
|
6072
6102
|
}
|
|
@@ -6102,7 +6132,7 @@ function unknownKeyHint(fullPath, key, known) {
|
|
|
6102
6132
|
return known.length > 0 ? `Allowed keys: ${known.join(", ")}.` : void 0;
|
|
6103
6133
|
}
|
|
6104
6134
|
function mapIssue(issue4) {
|
|
6105
|
-
const
|
|
6135
|
+
const path96 = pathToString(issue4.path);
|
|
6106
6136
|
switch (issue4.code) {
|
|
6107
6137
|
case "unrecognized_keys":
|
|
6108
6138
|
return issue4.keys.map((key) => {
|
|
@@ -6118,20 +6148,20 @@ function mapIssue(issue4) {
|
|
|
6118
6148
|
return [
|
|
6119
6149
|
{
|
|
6120
6150
|
code: "CONFIG_INVALID_VALUE",
|
|
6121
|
-
path:
|
|
6151
|
+
path: path96,
|
|
6122
6152
|
message: `must be one of: ${issue4.values.map((v) => JSON.stringify(v)).join(", ")}.`
|
|
6123
6153
|
}
|
|
6124
6154
|
];
|
|
6125
6155
|
case "custom": {
|
|
6126
6156
|
const code = typeof issue4.params?.code === "string" ? issue4.params.code : "CONFIG_INVALID_VALUE";
|
|
6127
|
-
return [{ code, path:
|
|
6157
|
+
return [{ code, path: path96, message: issue4.message ?? "is invalid." }];
|
|
6128
6158
|
}
|
|
6129
6159
|
case "invalid_type":
|
|
6130
6160
|
return [
|
|
6131
|
-
/received undefined/.test(issue4.message) ? { code: "CONFIG_MISSING_FIELD", path:
|
|
6161
|
+
/received undefined/.test(issue4.message) ? { code: "CONFIG_MISSING_FIELD", path: path96, message: "is required." } : { code: "CONFIG_INVALID_VALUE", path: path96, message: issue4.message }
|
|
6132
6162
|
];
|
|
6133
6163
|
default:
|
|
6134
|
-
return [{ code: "CONFIG_INVALID_VALUE", path:
|
|
6164
|
+
return [{ code: "CONFIG_INVALID_VALUE", path: path96, message: issue4.message }];
|
|
6135
6165
|
}
|
|
6136
6166
|
}
|
|
6137
6167
|
function isRecord(value) {
|
|
@@ -6495,7 +6525,8 @@ function resolveConfigV2(config2, configPath) {
|
|
|
6495
6525
|
file: plans.file ? path7.resolve(configDir, plans.file) : path7.join(root, "plans.json"),
|
|
6496
6526
|
billing: {
|
|
6497
6527
|
provider: plans.billing?.provider ?? "stripe",
|
|
6498
|
-
|
|
6528
|
+
// Stripe is the only provider. Its key lives in the STRIPE_API_KEY secret unless the config names another.
|
|
6529
|
+
apiKey: plans.billing?.apiKey ?? ((plans.billing?.provider ?? "stripe") === "stripe" ? "secret:STRIPE_API_KEY" : void 0),
|
|
6499
6530
|
webhookSecret: plans.billing?.webhookSecret,
|
|
6500
6531
|
successUrl: plans.billing?.successUrl,
|
|
6501
6532
|
cancelUrl: plans.billing?.cancelUrl
|
|
@@ -6575,7 +6606,7 @@ function loadConfigV2(pathOrDir) {
|
|
|
6575
6606
|
}
|
|
6576
6607
|
|
|
6577
6608
|
// src/config/v2/rules.ts
|
|
6578
|
-
import { readdir as readdir2, readFile as
|
|
6609
|
+
import { readdir as readdir2, readFile as readFile3, stat as stat2 } from "node:fs/promises";
|
|
6579
6610
|
import path9 from "node:path";
|
|
6580
6611
|
import { glob } from "glob";
|
|
6581
6612
|
import { parse as parseYaml } from "yaml";
|
|
@@ -6727,7 +6758,7 @@ async function portalRules(config2, resolved, out) {
|
|
|
6727
6758
|
}
|
|
6728
6759
|
if (await isFile(portal.theme)) {
|
|
6729
6760
|
try {
|
|
6730
|
-
JSON.parse(await
|
|
6761
|
+
JSON.parse(await readFile3(portal.theme, "utf8"));
|
|
6731
6762
|
} catch (error) {
|
|
6732
6763
|
out.error({
|
|
6733
6764
|
code: "PORTAL_THEME_INVALID",
|
|
@@ -6924,7 +6955,7 @@ async function specRule(spec, index, resolved, out) {
|
|
|
6924
6955
|
}
|
|
6925
6956
|
let document;
|
|
6926
6957
|
try {
|
|
6927
|
-
const text = await
|
|
6958
|
+
const text = await readFile3(spec, "utf8");
|
|
6928
6959
|
document = spec.toLowerCase().endsWith(".json") ? JSON.parse(text) : parseYaml(text);
|
|
6929
6960
|
} catch (error) {
|
|
6930
6961
|
out.error({
|
|
@@ -7066,7 +7097,7 @@ function identityRules(config2, resolved, out) {
|
|
|
7066
7097
|
}
|
|
7067
7098
|
}
|
|
7068
7099
|
}
|
|
7069
|
-
async function plansRules(
|
|
7100
|
+
async function plansRules(resolved, out, paid) {
|
|
7070
7101
|
const plans = resolved.plans;
|
|
7071
7102
|
if (!plans?.enabled) return;
|
|
7072
7103
|
if (!await isFile(plans.file)) {
|
|
@@ -7078,7 +7109,7 @@ async function plansRules(config2, resolved, out) {
|
|
|
7078
7109
|
});
|
|
7079
7110
|
} else {
|
|
7080
7111
|
try {
|
|
7081
|
-
JSON.parse(await
|
|
7112
|
+
JSON.parse(await readFile3(plans.file, "utf8"));
|
|
7082
7113
|
} catch (error) {
|
|
7083
7114
|
out.error({
|
|
7084
7115
|
code: "PLANS_FILE_INVALID",
|
|
@@ -7087,15 +7118,7 @@ async function plansRules(config2, resolved, out) {
|
|
|
7087
7118
|
});
|
|
7088
7119
|
}
|
|
7089
7120
|
}
|
|
7090
|
-
if (
|
|
7091
|
-
if (!config2.plans?.billing?.apiKey) {
|
|
7092
|
-
out.error({
|
|
7093
|
-
code: "PLANS_BILLING_INCOMPLETE",
|
|
7094
|
-
path: "plans.billing.apiKey",
|
|
7095
|
-
message: "plans.billing.apiKey is required when billing.provider is stripe.",
|
|
7096
|
-
hint: 'Set it to a secret reference, for example "secret:STRIPE_API_KEY".'
|
|
7097
|
-
});
|
|
7098
|
-
}
|
|
7121
|
+
if (paid) {
|
|
7099
7122
|
const headless = !(resolved.portal?.enabled === true);
|
|
7100
7123
|
for (const field of ["successUrl", "cancelUrl"]) {
|
|
7101
7124
|
if (headless && !plans.billing[field]) {
|
|
@@ -7109,8 +7132,12 @@ async function plansRules(config2, resolved, out) {
|
|
|
7109
7132
|
}
|
|
7110
7133
|
}
|
|
7111
7134
|
}
|
|
7112
|
-
function secretRules(config2, context, out, skipped) {
|
|
7113
|
-
const
|
|
7135
|
+
function secretRules(config2, resolved, context, out, skipped, paid) {
|
|
7136
|
+
const stripeKeyPath = "plans.billing.apiKey";
|
|
7137
|
+
const named = collectSecretRefs(config2).filter(
|
|
7138
|
+
(ref) => paid || !ref.path.startsWith("plans.billing")
|
|
7139
|
+
);
|
|
7140
|
+
const refs = paid && !named.some((ref) => ref.path === stripeKeyPath) ? [...named, { name: stripeKeySecretName(resolved), path: stripeKeyPath }] : named;
|
|
7114
7141
|
if (refs.length === 0) return;
|
|
7115
7142
|
if (!context.knownSecrets) {
|
|
7116
7143
|
skipped.push(
|
|
@@ -7119,7 +7146,14 @@ function secretRules(config2, context, out, skipped) {
|
|
|
7119
7146
|
return;
|
|
7120
7147
|
}
|
|
7121
7148
|
for (const ref of refs) {
|
|
7122
|
-
if (!context.knownSecrets.has(ref.name)) {
|
|
7149
|
+
if (ref.path === stripeKeyPath && !context.knownSecrets.has(ref.name)) {
|
|
7150
|
+
out.warn({
|
|
7151
|
+
code: "SECRET_NOT_SET",
|
|
7152
|
+
path: ref.path,
|
|
7153
|
+
message: `a plan has a price, and the Stripe key (secret ${ref.name}) is not set yet.`,
|
|
7154
|
+
hint: `apitogo deploy asks for it. Or run: apitogo secrets set ${ref.name}`
|
|
7155
|
+
});
|
|
7156
|
+
} else if (!context.knownSecrets.has(ref.name)) {
|
|
7123
7157
|
out.error({
|
|
7124
7158
|
code: "SECRET_NOT_SET",
|
|
7125
7159
|
path: ref.path,
|
|
@@ -7139,12 +7173,13 @@ async function checkConfigV2(config2, resolved, context = {}) {
|
|
|
7139
7173
|
error: (issue4) => errors.push(issue4),
|
|
7140
7174
|
warn: (issue4) => warnings.push(issue4)
|
|
7141
7175
|
};
|
|
7176
|
+
const paid = await billingNeeded(resolved);
|
|
7142
7177
|
dependencyRules(config2, resolved, out);
|
|
7143
|
-
secretRules(config2, context, out, skipped);
|
|
7178
|
+
secretRules(config2, resolved, context, out, skipped, paid);
|
|
7144
7179
|
await portalRules(config2, resolved, out);
|
|
7145
7180
|
await gatewayRules(resolved, out);
|
|
7146
7181
|
identityRules(config2, resolved, out);
|
|
7147
|
-
await plansRules(
|
|
7182
|
+
await plansRules(resolved, out, paid);
|
|
7148
7183
|
return { errors, warnings, skipped };
|
|
7149
7184
|
}
|
|
7150
7185
|
|
|
@@ -7190,7 +7225,7 @@ function portalProfile(resolved) {
|
|
|
7190
7225
|
}
|
|
7191
7226
|
|
|
7192
7227
|
// src/config/v2/manifest.ts
|
|
7193
|
-
import { mkdir as mkdir3, readFile as
|
|
7228
|
+
import { mkdir as mkdir3, readFile as readFile4, rename, rm, writeFile as writeFile4 } from "node:fs/promises";
|
|
7194
7229
|
import path10 from "node:path";
|
|
7195
7230
|
import { z as z3 } from "zod";
|
|
7196
7231
|
var SUPPORTED_MANIFEST_SCHEMA = 1;
|
|
@@ -7240,7 +7275,7 @@ var ServiceManifestSchema = z3.looseObject({
|
|
|
7240
7275
|
}).optional()
|
|
7241
7276
|
}).default({})
|
|
7242
7277
|
});
|
|
7243
|
-
var issue = (code,
|
|
7278
|
+
var issue = (code, path96, message, hint) => ({ code, path: path96, message, hint });
|
|
7244
7279
|
function parseManifest(raw, file = "services.json") {
|
|
7245
7280
|
const version = typeof raw === "object" && raw !== null && "schemaVersion" in raw ? raw.schemaVersion : void 0;
|
|
7246
7281
|
if (typeof version === "number" && version > SUPPORTED_MANIFEST_SCHEMA) {
|
|
@@ -7273,7 +7308,7 @@ async function readManifest(state) {
|
|
|
7273
7308
|
const file = manifestPathFor(state);
|
|
7274
7309
|
let text;
|
|
7275
7310
|
try {
|
|
7276
|
-
text = await
|
|
7311
|
+
text = await readFile4(file, "utf8");
|
|
7277
7312
|
} catch (error) {
|
|
7278
7313
|
if (error.code === "ENOENT") return void 0;
|
|
7279
7314
|
throw error;
|
|
@@ -7488,7 +7523,7 @@ async function removeServicesFromManifest(state, names) {
|
|
|
7488
7523
|
}
|
|
7489
7524
|
|
|
7490
7525
|
// src/config/v2/gateway-reference.ts
|
|
7491
|
-
import { readFile as
|
|
7526
|
+
import { readFile as readFile5 } from "node:fs/promises";
|
|
7492
7527
|
import { parse } from "yaml";
|
|
7493
7528
|
var DEFAULT_KEY_HEADER = "Ocp-Apim-Subscription-Key";
|
|
7494
7529
|
var METHODS = [
|
|
@@ -7502,8 +7537,8 @@ var METHODS = [
|
|
|
7502
7537
|
"trace"
|
|
7503
7538
|
];
|
|
7504
7539
|
var isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7505
|
-
function actionKey(method,
|
|
7506
|
-
const trimmed =
|
|
7540
|
+
function actionKey(method, path96) {
|
|
7541
|
+
const trimmed = path96.trim();
|
|
7507
7542
|
const withSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
7508
7543
|
const normalized = withSlash.length > 1 ? withSlash.replace(/\/+$/, "") || "/" : withSlash;
|
|
7509
7544
|
return `${method.trim().toLowerCase()}:${normalized}`;
|
|
@@ -7540,8 +7575,8 @@ var ReferenceSpecError = class extends Error {
|
|
|
7540
7575
|
};
|
|
7541
7576
|
function operationsOf(paths) {
|
|
7542
7577
|
return Object.entries(paths).flatMap(
|
|
7543
|
-
([
|
|
7544
|
-
(method) => [
|
|
7578
|
+
([path96, item]) => isObject(item) ? METHODS.filter((method) => isObject(item[method])).map(
|
|
7579
|
+
(method) => [path96, item, method]
|
|
7545
7580
|
) : []
|
|
7546
7581
|
);
|
|
7547
7582
|
}
|
|
@@ -7556,14 +7591,14 @@ function buildReferenceSpec(specText, options) {
|
|
|
7556
7591
|
throw new ReferenceSpecError("The OpenAPI file could not be read.");
|
|
7557
7592
|
const doc = structuredClone(root);
|
|
7558
7593
|
const paths = isObject(doc.paths) ? doc.paths : {};
|
|
7559
|
-
for (const [
|
|
7560
|
-
if (options.deniedOperations.has(actionKey(method,
|
|
7594
|
+
for (const [path96, item, method] of operationsOf(paths))
|
|
7595
|
+
if (options.deniedOperations.has(actionKey(method, path96)))
|
|
7561
7596
|
delete item[method];
|
|
7562
|
-
for (const [
|
|
7597
|
+
for (const [path96, item] of Object.entries(paths))
|
|
7563
7598
|
if (!isObject(item) || !METHODS.some((method) => method in item))
|
|
7564
|
-
delete paths[
|
|
7565
|
-
for (const [
|
|
7566
|
-
if (options.publicOperations.has(actionKey(method,
|
|
7599
|
+
delete paths[path96];
|
|
7600
|
+
for (const [path96, item, method] of operationsOf(paths))
|
|
7601
|
+
if (options.publicOperations.has(actionKey(method, path96)))
|
|
7567
7602
|
item[method].security = [];
|
|
7568
7603
|
doc.servers = [{ url: options.gatewayBaseUrl.replace(/\/+$/, "") }];
|
|
7569
7604
|
for (const item of Object.values(paths)) {
|
|
@@ -7626,7 +7661,7 @@ async function renderReferenceSpec(gateway, gatewayBaseUrl, keyHeaderName) {
|
|
|
7626
7661
|
throw new ReferenceSpecError("gateway.specs lists no OpenAPI file.");
|
|
7627
7662
|
let text;
|
|
7628
7663
|
try {
|
|
7629
|
-
text = await
|
|
7664
|
+
text = await readFile5(file, "utf8");
|
|
7630
7665
|
} catch {
|
|
7631
7666
|
throw new ReferenceSpecError(`Cannot read the OpenAPI file ${file}.`);
|
|
7632
7667
|
}
|
|
@@ -7697,7 +7732,7 @@ function stableJson(value) {
|
|
|
7697
7732
|
}
|
|
7698
7733
|
|
|
7699
7734
|
// src/config/v2/wrapper.ts
|
|
7700
|
-
import { mkdir as mkdir4, readFile as
|
|
7735
|
+
import { mkdir as mkdir4, readFile as readFile7, rename as rename2, rm as rm2, writeFile as writeFile5 } from "node:fs/promises";
|
|
7701
7736
|
import path12 from "node:path";
|
|
7702
7737
|
|
|
7703
7738
|
// src/config/v2/docs-navigation.ts
|
|
@@ -7759,7 +7794,7 @@ import { glob as glob2 } from "glob";
|
|
|
7759
7794
|
import globParent from "glob-parent";
|
|
7760
7795
|
|
|
7761
7796
|
// src/lib/util/readFrontmatter.ts
|
|
7762
|
-
import { readFile as
|
|
7797
|
+
import { readFile as readFile6 } from "node:fs/promises";
|
|
7763
7798
|
import matter from "gray-matter";
|
|
7764
7799
|
import { parse as parse2, stringify } from "yaml";
|
|
7765
7800
|
var yaml = {
|
|
@@ -7767,7 +7802,7 @@ var yaml = {
|
|
|
7767
7802
|
stringify: (obj) => stringify(obj)
|
|
7768
7803
|
};
|
|
7769
7804
|
var readFrontmatter = async (filePath) => {
|
|
7770
|
-
const content = await
|
|
7805
|
+
const content = await readFile6(filePath, "utf-8");
|
|
7771
7806
|
const normalizedContent = content.replace(/\r\n/g, "\n");
|
|
7772
7807
|
return matter(normalizedContent, { engines: { yaml } });
|
|
7773
7808
|
};
|
|
@@ -8103,7 +8138,7 @@ function renderWrapper(plan2) {
|
|
|
8103
8138
|
async function readDemoPlans(file) {
|
|
8104
8139
|
if (!file) return void 0;
|
|
8105
8140
|
try {
|
|
8106
|
-
const parsed = JSON.parse(await
|
|
8141
|
+
const parsed = JSON.parse(await readFile7(file, "utf8"));
|
|
8107
8142
|
return Array.isArray(parsed.plans) ? parsed.plans : void 0;
|
|
8108
8143
|
} catch {
|
|
8109
8144
|
return void 0;
|
|
@@ -8113,7 +8148,7 @@ async function readTheme(resolved) {
|
|
|
8113
8148
|
const file = resolved.portal?.theme;
|
|
8114
8149
|
if (!file) return void 0;
|
|
8115
8150
|
try {
|
|
8116
|
-
return JSON.parse(await
|
|
8151
|
+
return JSON.parse(await readFile7(file, "utf8"));
|
|
8117
8152
|
} catch {
|
|
8118
8153
|
return void 0;
|
|
8119
8154
|
}
|
|
@@ -8249,7 +8284,7 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
|
|
|
8249
8284
|
|
|
8250
8285
|
// src/config/v2/workspace.ts
|
|
8251
8286
|
import { createHash as createHash2 } from "node:crypto";
|
|
8252
|
-
import { access as access2, lstat, readFile as
|
|
8287
|
+
import { access as access2, lstat, readFile as readFile8, rm as rm3, writeFile as writeFile6 } from "node:fs/promises";
|
|
8253
8288
|
import path13 from "node:path";
|
|
8254
8289
|
import { glob as glob3 } from "glob";
|
|
8255
8290
|
|
|
@@ -8285,7 +8320,7 @@ async function relink(target, link) {
|
|
|
8285
8320
|
var GENERATED_PACKAGE_JSON = '{\n "private": true,\n "type": "module"\n}\n';
|
|
8286
8321
|
async function writeGeneratedPackageJson(root) {
|
|
8287
8322
|
const file = path13.join(root, "package.json");
|
|
8288
|
-
const current = await
|
|
8323
|
+
const current = await readFile8(file, "utf8").catch(() => void 0);
|
|
8289
8324
|
if (current !== GENERATED_PACKAGE_JSON)
|
|
8290
8325
|
await writeFile6(file, GENERATED_PACKAGE_JSON, "utf8");
|
|
8291
8326
|
}
|
|
@@ -8304,7 +8339,7 @@ async function materializeWorkspace(resolved, prepared) {
|
|
|
8304
8339
|
return root;
|
|
8305
8340
|
}
|
|
8306
8341
|
async function configFingerprint(configPath) {
|
|
8307
|
-
const text = await
|
|
8342
|
+
const text = await readFile8(configPath, "utf8");
|
|
8308
8343
|
try {
|
|
8309
8344
|
const raw = JSON.parse(text);
|
|
8310
8345
|
if (raw.project) {
|
|
@@ -8353,7 +8388,7 @@ async function portalArtifactHash(resolved, manifestText, cliVersion, wrapper =
|
|
|
8353
8388
|
for (const file of files) {
|
|
8354
8389
|
hash2.update(`file:${path13.relative(resolved.configDir, file)}
|
|
8355
8390
|
`);
|
|
8356
|
-
hash2.update(await
|
|
8391
|
+
hash2.update(await readFile8(file));
|
|
8357
8392
|
}
|
|
8358
8393
|
return hash2.digest("hex");
|
|
8359
8394
|
}
|
|
@@ -9163,13 +9198,6 @@ async function buildPlans(context) {
|
|
|
9163
9198
|
const { options, dir, resolved } = context;
|
|
9164
9199
|
const o = options.plans ?? {};
|
|
9165
9200
|
const template = o.template ?? (options.template === "blank" ? "none" : isFilled(options.template) ? "starter" : "free");
|
|
9166
|
-
const billing = o.billing ?? (template === "tiered" ? "stripe" : "none");
|
|
9167
|
-
if (template === "tiered" && billing === "none") {
|
|
9168
|
-
throw new ServiceEditError(
|
|
9169
|
-
"The tiered template has paid plans, which need a billing provider.",
|
|
9170
|
-
"Use --billing stripe, or --template free."
|
|
9171
|
-
);
|
|
9172
|
-
}
|
|
9173
9201
|
const file = o.file ? insideProject(dir, o.file, "Plans file") : void 0;
|
|
9174
9202
|
const target = file ? path14.join(dir, file) : resolved.plans?.file ?? path14.join(resolved.root, "plans.json");
|
|
9175
9203
|
await addFile(
|
|
@@ -9178,20 +9206,14 @@ async function buildPlans(context) {
|
|
|
9178
9206
|
`${JSON.stringify({ version: 1, plans: PLAN_TEMPLATES[template] }, null, 2)}
|
|
9179
9207
|
`
|
|
9180
9208
|
);
|
|
9181
|
-
if (
|
|
9209
|
+
if (PLAN_TEMPLATES[template].some((plan2) => isPaidPlan(plan2))) {
|
|
9182
9210
|
context.notes.push(
|
|
9183
|
-
"
|
|
9211
|
+
"A plan has a price, so payments go through Stripe: apitogo deploy asks for your Stripe secret key."
|
|
9184
9212
|
);
|
|
9185
9213
|
}
|
|
9186
9214
|
return {
|
|
9187
9215
|
...options.disabled ? { enabled: false } : {},
|
|
9188
|
-
...file ? { file } : {}
|
|
9189
|
-
...billing === "stripe" ? {
|
|
9190
|
-
billing: {
|
|
9191
|
-
provider: "stripe",
|
|
9192
|
-
apiKey: "secret:STRIPE_API_KEY"
|
|
9193
|
-
}
|
|
9194
|
-
} : { billing: { provider: "none" } }
|
|
9216
|
+
...file ? { file } : {}
|
|
9195
9217
|
};
|
|
9196
9218
|
}
|
|
9197
9219
|
function reparse(configPath, raw) {
|
|
@@ -9383,7 +9405,7 @@ async function clearProjectId(dir, projectId) {
|
|
|
9383
9405
|
|
|
9384
9406
|
// src/config/v2/ledger.ts
|
|
9385
9407
|
init_invariant();
|
|
9386
|
-
import { mkdir as mkdir6, readFile as
|
|
9408
|
+
import { mkdir as mkdir6, readFile as readFile9, rename as rename4, rm as rm5, writeFile as writeFile8 } from "node:fs/promises";
|
|
9387
9409
|
import path15 from "node:path";
|
|
9388
9410
|
var LEDGER_VERSION = 1;
|
|
9389
9411
|
var LedgerError = class extends ApitogoError {
|
|
@@ -9400,7 +9422,7 @@ var emptyLedger = () => ({
|
|
|
9400
9422
|
async function readLedger(state) {
|
|
9401
9423
|
let text;
|
|
9402
9424
|
try {
|
|
9403
|
-
text = await
|
|
9425
|
+
text = await readFile9(state.file, "utf8");
|
|
9404
9426
|
} catch (error) {
|
|
9405
9427
|
if (error.code === "ENOENT")
|
|
9406
9428
|
return emptyLedger();
|
|
@@ -9535,7 +9557,7 @@ init_invariant();
|
|
|
9535
9557
|
|
|
9536
9558
|
// src/cli/check/v2.ts
|
|
9537
9559
|
init_apitogo_config_core();
|
|
9538
|
-
import { readFile as
|
|
9560
|
+
import { readFile as readFile16 } from "node:fs/promises";
|
|
9539
9561
|
import path49 from "node:path";
|
|
9540
9562
|
|
|
9541
9563
|
// src/cli/platform/client/platform-api.ts
|
|
@@ -9649,8 +9671,8 @@ var PlatformApiClient = class {
|
|
|
9649
9671
|
constructor(config2) {
|
|
9650
9672
|
this.config = config2;
|
|
9651
9673
|
}
|
|
9652
|
-
url(
|
|
9653
|
-
return `${this.config.apiUrl}${
|
|
9674
|
+
url(path96) {
|
|
9675
|
+
return `${this.config.apiUrl}${path96.startsWith("/") ? path96 : `/${path96}`}`;
|
|
9654
9676
|
}
|
|
9655
9677
|
headers(extra) {
|
|
9656
9678
|
return {
|
|
@@ -9660,9 +9682,9 @@ var PlatformApiClient = class {
|
|
|
9660
9682
|
...extra
|
|
9661
9683
|
};
|
|
9662
9684
|
}
|
|
9663
|
-
async request(method,
|
|
9685
|
+
async request(method, path96, init3) {
|
|
9664
9686
|
const response = await fetchWithRetry(
|
|
9665
|
-
this.url(
|
|
9687
|
+
this.url(path96),
|
|
9666
9688
|
{
|
|
9667
9689
|
method,
|
|
9668
9690
|
...init3,
|
|
@@ -10108,15 +10130,15 @@ var PlatformApiClient = class {
|
|
|
10108
10130
|
}
|
|
10109
10131
|
);
|
|
10110
10132
|
}
|
|
10111
|
-
deleteDevPortalPage(projectId,
|
|
10112
|
-
const query = new URLSearchParams({ path:
|
|
10133
|
+
deleteDevPortalPage(projectId, path96) {
|
|
10134
|
+
const query = new URLSearchParams({ path: path96 });
|
|
10113
10135
|
return this.request(
|
|
10114
10136
|
"DELETE",
|
|
10115
10137
|
`/api/v1/projects/${projectId}/dev-portal/pages/files?${query.toString()}`
|
|
10116
10138
|
);
|
|
10117
10139
|
}
|
|
10118
|
-
renameDevPortalPage(projectId,
|
|
10119
|
-
const query = new URLSearchParams({ path:
|
|
10140
|
+
renameDevPortalPage(projectId, path96, newName) {
|
|
10141
|
+
const query = new URLSearchParams({ path: path96 });
|
|
10120
10142
|
return this.request(
|
|
10121
10143
|
"POST",
|
|
10122
10144
|
`/api/v1/projects/${projectId}/dev-portal/pages/files/rename?${query.toString()}`,
|
|
@@ -10232,8 +10254,8 @@ var PlatformApiClient = class {
|
|
|
10232
10254
|
* the project-less endpoint is used; `planTier` overrides the tier used for paid-plan checks.
|
|
10233
10255
|
*/
|
|
10234
10256
|
validateGatewayPlans(plans, options = {}) {
|
|
10235
|
-
const
|
|
10236
|
-
return this.request("POST",
|
|
10257
|
+
const path96 = options.projectId ? `/api/v1/projects/${options.projectId}/gateway/plans/validate` : "/api/v1/gateway/plans/validate";
|
|
10258
|
+
return this.request("POST", path96, {
|
|
10237
10259
|
headers: { "Content-Type": "application/json" },
|
|
10238
10260
|
body: JSON.stringify({ plans, planTier: options.planTier })
|
|
10239
10261
|
});
|
|
@@ -10358,8 +10380,8 @@ var PlatformApiClient = class {
|
|
|
10358
10380
|
}
|
|
10359
10381
|
};
|
|
10360
10382
|
async function readFileBytes(filePath) {
|
|
10361
|
-
const { readFile:
|
|
10362
|
-
const buffer = await
|
|
10383
|
+
const { readFile: readFile27 } = await import("node:fs/promises");
|
|
10384
|
+
const buffer = await readFile27(filePath);
|
|
10363
10385
|
const arrayBuffer = new ArrayBuffer(buffer.byteLength);
|
|
10364
10386
|
new Uint8Array(arrayBuffer).set(buffer);
|
|
10365
10387
|
return arrayBuffer;
|
|
@@ -10456,7 +10478,7 @@ function resolveProjectId(explicit, config2) {
|
|
|
10456
10478
|
import {
|
|
10457
10479
|
access as access4,
|
|
10458
10480
|
mkdir as mkdir12,
|
|
10459
|
-
readFile as
|
|
10481
|
+
readFile as readFile13,
|
|
10460
10482
|
rename as rename6,
|
|
10461
10483
|
rm as rm8,
|
|
10462
10484
|
writeFile as writeFile15
|
|
@@ -10464,7 +10486,7 @@ import {
|
|
|
10464
10486
|
import path48 from "node:path";
|
|
10465
10487
|
|
|
10466
10488
|
// src/vite/build.ts
|
|
10467
|
-
import { mkdir as mkdir11, readFile as
|
|
10489
|
+
import { mkdir as mkdir11, readFile as readFile11, rename as rename5, rm as rm7, writeFile as writeFile13 } from "node:fs/promises";
|
|
10468
10490
|
import path46 from "node:path";
|
|
10469
10491
|
import { build as esbuild } from "esbuild";
|
|
10470
10492
|
import { build as viteBuild, mergeConfig as mergeConfig3 } from "vite";
|
|
@@ -10612,7 +10634,7 @@ import {
|
|
|
10612
10634
|
// package.json
|
|
10613
10635
|
var package_default = {
|
|
10614
10636
|
name: "@lukoweb/apitogo",
|
|
10615
|
-
version: "0.2.
|
|
10637
|
+
version: "0.2.49",
|
|
10616
10638
|
type: "module",
|
|
10617
10639
|
sideEffects: [
|
|
10618
10640
|
"**/*.css",
|
|
@@ -11397,14 +11419,14 @@ var flattenAllOf = (schema2) => {
|
|
|
11397
11419
|
};
|
|
11398
11420
|
|
|
11399
11421
|
// src/lib/util/traverse.ts
|
|
11400
|
-
var traverse = (specification, transform,
|
|
11401
|
-
const transformed = transform(specification,
|
|
11422
|
+
var traverse = (specification, transform, path96 = []) => {
|
|
11423
|
+
const transformed = transform(specification, path96);
|
|
11402
11424
|
if (typeof transformed !== "object" || transformed === null) {
|
|
11403
11425
|
return transformed;
|
|
11404
11426
|
}
|
|
11405
11427
|
const result = Array.isArray(transformed) ? [] : {};
|
|
11406
11428
|
for (const [key, value] of Object.entries(transformed)) {
|
|
11407
|
-
const currentPath = [...
|
|
11429
|
+
const currentPath = [...path96, key];
|
|
11408
11430
|
if (Array.isArray(value)) {
|
|
11409
11431
|
result[key] = value.map(
|
|
11410
11432
|
(item, index) => typeof item === "object" && item != null ? traverse(item, transform, [...currentPath, index.toString()]) : item
|
|
@@ -11432,9 +11454,9 @@ var resolveLocalRef = (schema2, ref) => {
|
|
|
11432
11454
|
if (schemaCache?.has(ref)) {
|
|
11433
11455
|
return schemaCache.get(ref);
|
|
11434
11456
|
}
|
|
11435
|
-
const
|
|
11457
|
+
const path96 = ref.split("/").slice(1);
|
|
11436
11458
|
let current = schema2;
|
|
11437
|
-
for (const segment of
|
|
11459
|
+
for (const segment of path96) {
|
|
11438
11460
|
if (!current || typeof current !== "object") {
|
|
11439
11461
|
current = null;
|
|
11440
11462
|
}
|
|
@@ -11453,7 +11475,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
11453
11475
|
}
|
|
11454
11476
|
const cloned = structuredClone(schema2);
|
|
11455
11477
|
const visited = /* @__PURE__ */ new Set();
|
|
11456
|
-
const resolve = async (current,
|
|
11478
|
+
const resolve = async (current, path96) => {
|
|
11457
11479
|
if (isIndexableObject(current)) {
|
|
11458
11480
|
if (visited.has(current)) {
|
|
11459
11481
|
return CIRCULAR_REF;
|
|
@@ -11461,7 +11483,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
11461
11483
|
visited.add(current);
|
|
11462
11484
|
if (Array.isArray(current)) {
|
|
11463
11485
|
for (let index = 0; index < current.length; index++) {
|
|
11464
|
-
current[index] = await resolve(current[index], `${
|
|
11486
|
+
current[index] = await resolve(current[index], `${path96}/${index}`);
|
|
11465
11487
|
}
|
|
11466
11488
|
} else {
|
|
11467
11489
|
if ("$ref" in current && typeof current.$ref === "string") {
|
|
@@ -11472,13 +11494,13 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
11472
11494
|
for (const resolver of resolvers) {
|
|
11473
11495
|
const resolved = await resolver($ref);
|
|
11474
11496
|
if (resolved) {
|
|
11475
|
-
result2 = await resolve(resolved,
|
|
11497
|
+
result2 = await resolve(resolved, path96);
|
|
11476
11498
|
break;
|
|
11477
11499
|
}
|
|
11478
11500
|
}
|
|
11479
11501
|
if (result2 === void 0) {
|
|
11480
11502
|
const resolved = await resolveLocalRef(cloned, $ref);
|
|
11481
|
-
result2 = await resolve(resolved,
|
|
11503
|
+
result2 = await resolve(resolved, path96);
|
|
11482
11504
|
}
|
|
11483
11505
|
if (hasSiblings) {
|
|
11484
11506
|
if (result2 === CIRCULAR_REF) {
|
|
@@ -11491,7 +11513,7 @@ var dereference = async (schema2, resolvers = []) => {
|
|
|
11491
11513
|
return result2;
|
|
11492
11514
|
}
|
|
11493
11515
|
for (const key in current) {
|
|
11494
|
-
current[key] = await resolve(current[key], `${
|
|
11516
|
+
current[key] = await resolve(current[key], `${path96}/${key}`);
|
|
11495
11517
|
}
|
|
11496
11518
|
}
|
|
11497
11519
|
visited.delete(current);
|
|
@@ -11530,9 +11552,9 @@ var upgradeSchema = (schema2) => {
|
|
|
11530
11552
|
}
|
|
11531
11553
|
return sub;
|
|
11532
11554
|
});
|
|
11533
|
-
schema2 = traverse(schema2, (sub,
|
|
11555
|
+
schema2 = traverse(schema2, (sub, path96) => {
|
|
11534
11556
|
if (sub.example !== void 0) {
|
|
11535
|
-
if (isSchemaPath(
|
|
11557
|
+
if (isSchemaPath(path96 ?? [])) {
|
|
11536
11558
|
sub.examples = [sub.example];
|
|
11537
11559
|
} else {
|
|
11538
11560
|
sub.examples = {
|
|
@@ -11545,11 +11567,11 @@ var upgradeSchema = (schema2) => {
|
|
|
11545
11567
|
}
|
|
11546
11568
|
return sub;
|
|
11547
11569
|
});
|
|
11548
|
-
schema2 = traverse(schema2, (schema3,
|
|
11570
|
+
schema2 = traverse(schema2, (schema3, path96) => {
|
|
11549
11571
|
if (schema3.type === "object" && schema3.properties !== void 0) {
|
|
11550
|
-
const parentPath =
|
|
11572
|
+
const parentPath = path96?.slice(0, -1);
|
|
11551
11573
|
const isMultipart = parentPath?.some((segment, index) => {
|
|
11552
|
-
return segment === "content" &&
|
|
11574
|
+
return segment === "content" && path96?.[index + 1] === "multipart/form-data";
|
|
11553
11575
|
});
|
|
11554
11576
|
if (isMultipart) {
|
|
11555
11577
|
const entries = Object.entries(schema3.properties);
|
|
@@ -11563,8 +11585,8 @@ var upgradeSchema = (schema2) => {
|
|
|
11563
11585
|
}
|
|
11564
11586
|
return schema3;
|
|
11565
11587
|
});
|
|
11566
|
-
schema2 = traverse(schema2, (schema3,
|
|
11567
|
-
if (
|
|
11588
|
+
schema2 = traverse(schema2, (schema3, path96) => {
|
|
11589
|
+
if (path96?.includes("content") && path96.includes("application/octet-stream")) {
|
|
11568
11590
|
return {};
|
|
11569
11591
|
}
|
|
11570
11592
|
if (schema3.type === "string" && schema3.format === "binary") {
|
|
@@ -11590,11 +11612,11 @@ var upgradeSchema = (schema2) => {
|
|
|
11590
11612
|
}
|
|
11591
11613
|
return sub;
|
|
11592
11614
|
});
|
|
11593
|
-
schema2 = traverse(schema2, (schema3,
|
|
11615
|
+
schema2 = traverse(schema2, (schema3, path96) => {
|
|
11594
11616
|
if (schema3.type === "string" && schema3.format === "byte") {
|
|
11595
|
-
const parentPath =
|
|
11617
|
+
const parentPath = path96?.slice(0, -1);
|
|
11596
11618
|
const contentMediaType = parentPath?.find(
|
|
11597
|
-
(_, index) =>
|
|
11619
|
+
(_, index) => path96?.[index - 1] === "content"
|
|
11598
11620
|
);
|
|
11599
11621
|
return {
|
|
11600
11622
|
type: "string",
|
|
@@ -11606,7 +11628,7 @@ var upgradeSchema = (schema2) => {
|
|
|
11606
11628
|
});
|
|
11607
11629
|
return schema2;
|
|
11608
11630
|
};
|
|
11609
|
-
function isSchemaPath(
|
|
11631
|
+
function isSchemaPath(path96) {
|
|
11610
11632
|
const schemaLocations = [
|
|
11611
11633
|
["components", "schemas"],
|
|
11612
11634
|
"properties",
|
|
@@ -11619,10 +11641,10 @@ function isSchemaPath(path95) {
|
|
|
11619
11641
|
];
|
|
11620
11642
|
return schemaLocations.some((location) => {
|
|
11621
11643
|
if (Array.isArray(location)) {
|
|
11622
|
-
return location.every((segment, index) =>
|
|
11644
|
+
return location.every((segment, index) => path96[index] === segment);
|
|
11623
11645
|
}
|
|
11624
|
-
return
|
|
11625
|
-
}) ||
|
|
11646
|
+
return path96.includes(location);
|
|
11647
|
+
}) || path96.includes("schema") || path96.some((segment) => segment.endsWith("Schema"));
|
|
11626
11648
|
}
|
|
11627
11649
|
|
|
11628
11650
|
// src/lib/oas/parser/index.ts
|
|
@@ -11704,13 +11726,13 @@ var OPENAPI_PROPS = /* @__PURE__ */ new Set([
|
|
|
11704
11726
|
"anyOf",
|
|
11705
11727
|
"oneOf"
|
|
11706
11728
|
]);
|
|
11707
|
-
var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(),
|
|
11729
|
+
var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path96 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
|
|
11708
11730
|
if (obj === null || typeof obj !== "object") return obj;
|
|
11709
11731
|
const refPath = obj.__$ref;
|
|
11710
11732
|
const isCircular = currentPath.has(obj) || typeof refPath === "string" && currentRefPaths.has(refPath);
|
|
11711
11733
|
if (isCircular) {
|
|
11712
11734
|
if (typeof refPath === "string") return SCHEMA_REF_PREFIX + refPath;
|
|
11713
|
-
const circularProp =
|
|
11735
|
+
const circularProp = path96.find((p) => !OPENAPI_PROPS.has(p)) || path96[0];
|
|
11714
11736
|
return [CIRCULAR_REF, circularProp].filter(Boolean).join(":");
|
|
11715
11737
|
}
|
|
11716
11738
|
if (refs.has(obj)) return refs.get(obj);
|
|
@@ -11720,7 +11742,7 @@ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs
|
|
|
11720
11742
|
value,
|
|
11721
11743
|
currentPath,
|
|
11722
11744
|
refs,
|
|
11723
|
-
[...
|
|
11745
|
+
[...path96, key],
|
|
11724
11746
|
currentRefPaths
|
|
11725
11747
|
);
|
|
11726
11748
|
const result = Array.isArray(obj) ? obj.map((item, i) => recurse(item, i.toString())) : Object.fromEntries(
|
|
@@ -11755,7 +11777,7 @@ var resolveExtensions = (obj) => Object.fromEntries(
|
|
|
11755
11777
|
var getAllTags = (schema2) => {
|
|
11756
11778
|
const rootTags = schema2.tags ?? [];
|
|
11757
11779
|
const operations = Object.values(schema2.paths ?? {}).flatMap(
|
|
11758
|
-
(
|
|
11780
|
+
(path96) => HttpMethods.map((k) => path96?.[k]).filter((op) => op != null)
|
|
11759
11781
|
);
|
|
11760
11782
|
const operationTags = new Set(operations.flatMap((op) => op.tags ?? []));
|
|
11761
11783
|
const hasUntaggedOperations = operations.some(
|
|
@@ -11810,7 +11832,7 @@ var getAllSlugs = (ops, schemaTags = []) => {
|
|
|
11810
11832
|
var getOperationSlugKey = (op) => [op.path, op.method, op.operationId, op.summary].filter(Boolean).join("-");
|
|
11811
11833
|
var getAllOperations = (paths) => {
|
|
11812
11834
|
const operations = Object.entries(paths ?? {}).flatMap(
|
|
11813
|
-
([
|
|
11835
|
+
([path96, value]) => HttpMethods.flatMap((method) => {
|
|
11814
11836
|
if (!value?.[method]) return [];
|
|
11815
11837
|
const operation = value[method];
|
|
11816
11838
|
const pathParameters = value.parameters ?? [];
|
|
@@ -11830,7 +11852,7 @@ var getAllOperations = (paths) => {
|
|
|
11830
11852
|
return {
|
|
11831
11853
|
...operation,
|
|
11832
11854
|
method,
|
|
11833
|
-
path:
|
|
11855
|
+
path: path96,
|
|
11834
11856
|
parameters,
|
|
11835
11857
|
servers,
|
|
11836
11858
|
tags: operation.tags ?? []
|
|
@@ -12188,8 +12210,8 @@ var Schema = builder.objectRef("Schema").implement({
|
|
|
12188
12210
|
}),
|
|
12189
12211
|
paths: t.field({
|
|
12190
12212
|
type: [PathItem],
|
|
12191
|
-
resolve: (root) => Object.entries(root.paths ?? {}).map(([
|
|
12192
|
-
path:
|
|
12213
|
+
resolve: (root) => Object.entries(root.paths ?? {}).map(([path96, value]) => ({
|
|
12214
|
+
path: path96,
|
|
12193
12215
|
// biome-ignore lint/style/noNonNullAssertion: value is guaranteed to be defined
|
|
12194
12216
|
methods: Object.keys(value)
|
|
12195
12217
|
}))
|
|
@@ -12354,7 +12376,7 @@ init_joinUrl();
|
|
|
12354
12376
|
|
|
12355
12377
|
// src/vite/api/schema-codegen.ts
|
|
12356
12378
|
var unescapeJsonPointer = (uri) => decodeURIComponent(uri.replace(/~1/g, "/").replace(/~0/g, "~"));
|
|
12357
|
-
var getSegmentsFromPath = (
|
|
12379
|
+
var getSegmentsFromPath = (path96) => path96.split("/").slice(1).map(unescapeJsonPointer);
|
|
12358
12380
|
var createLocalRefMap = (obj) => {
|
|
12359
12381
|
const refMap = /* @__PURE__ */ new Map();
|
|
12360
12382
|
const siblingsMap = /* @__PURE__ */ new Map();
|
|
@@ -12385,16 +12407,16 @@ var replaceMarkers = (code, mergedRefs) => code.replace(/"__refMap:(.*?)"/g, '__
|
|
|
12385
12407
|
/"__refMap\+Siblings:(.*?)"/g,
|
|
12386
12408
|
(_, key) => mergedRefs.get(key) ?? `__refMap["${key}"]`
|
|
12387
12409
|
);
|
|
12388
|
-
var lookup = (schema2,
|
|
12389
|
-
const parts = getSegmentsFromPath(
|
|
12410
|
+
var lookup = (schema2, path96, filePath) => {
|
|
12411
|
+
const parts = getSegmentsFromPath(path96);
|
|
12390
12412
|
let val = schema2;
|
|
12391
12413
|
for (const part of parts) {
|
|
12392
12414
|
while (val.$ref?.startsWith("#/")) {
|
|
12393
|
-
val = val.$ref ===
|
|
12415
|
+
val = val.$ref === path96 ? val : lookup(schema2, val.$ref, filePath);
|
|
12394
12416
|
}
|
|
12395
12417
|
if (val[part] === void 0) {
|
|
12396
12418
|
throw new Error(
|
|
12397
|
-
`Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${
|
|
12419
|
+
`Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path96}`
|
|
12398
12420
|
);
|
|
12399
12421
|
}
|
|
12400
12422
|
val = val[part];
|
|
@@ -12639,8 +12661,8 @@ var SchemaManager = class {
|
|
|
12639
12661
|
}
|
|
12640
12662
|
}
|
|
12641
12663
|
};
|
|
12642
|
-
getLatestSchema = (
|
|
12643
|
-
getSchemasForPath = (
|
|
12664
|
+
getLatestSchema = (path96) => this.processedSchemas[path96]?.at(0);
|
|
12665
|
+
getSchemasForPath = (path96) => this.processedSchemas[path96];
|
|
12644
12666
|
getSchemaImports = () => Object.values(this.processedSchemas).flat().filter((s) => s.importKey);
|
|
12645
12667
|
getUrlToFilePathMap = () => {
|
|
12646
12668
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -15008,7 +15030,7 @@ async function writeOutput(dir, {
|
|
|
15008
15030
|
// src/vite/prerender/prerender.ts
|
|
15009
15031
|
init_logger();
|
|
15010
15032
|
init_file_exists();
|
|
15011
|
-
import { readFile as
|
|
15033
|
+
import { readFile as readFile10, rm as rm6 } from "node:fs/promises";
|
|
15012
15034
|
import os from "node:os";
|
|
15013
15035
|
import path45 from "node:path";
|
|
15014
15036
|
import { pathToFileURL } from "node:url";
|
|
@@ -15100,14 +15122,14 @@ async function generateSitemap({
|
|
|
15100
15122
|
|
|
15101
15123
|
// src/vite/prerender/utils.ts
|
|
15102
15124
|
init_joinUrl();
|
|
15103
|
-
var resolveRoutePath = (
|
|
15104
|
-
const segments =
|
|
15125
|
+
var resolveRoutePath = (path96) => {
|
|
15126
|
+
const segments = path96.split("/");
|
|
15105
15127
|
if (segments.some((s) => s.startsWith(":") && !s.endsWith("?"))) {
|
|
15106
15128
|
return void 0;
|
|
15107
15129
|
}
|
|
15108
15130
|
return segments.filter((s) => !s.startsWith(":")).join("/") || void 0;
|
|
15109
15131
|
};
|
|
15110
|
-
var isSkipped = (
|
|
15132
|
+
var isSkipped = (path96) => path96.includes("*") || /^\d+$/.test(path96);
|
|
15111
15133
|
var resolveRoutes = (routes, parentPath = "") => routes.flatMap((route) => {
|
|
15112
15134
|
if (route.path && isSkipped(route.path)) return [];
|
|
15113
15135
|
const routePath = route.path ? resolveRoutePath(route.path) : void 0;
|
|
@@ -15284,7 +15306,7 @@ var prerender = async ({
|
|
|
15284
15306
|
);
|
|
15285
15307
|
let markdownFileInfos = [];
|
|
15286
15308
|
if (await fileExists(markdownInfoPath)) {
|
|
15287
|
-
const markdownInfoContent = await
|
|
15309
|
+
const markdownInfoContent = await readFile10(markdownInfoPath, "utf-8");
|
|
15288
15310
|
markdownFileInfos = JSON.parse(markdownInfoContent);
|
|
15289
15311
|
}
|
|
15290
15312
|
if (llmsConfig.llmsTxt || llmsConfig.llmsTxtFull) {
|
|
@@ -15435,7 +15457,7 @@ var bundleSSREntry = async (options) => {
|
|
|
15435
15457
|
const { dir, adapter, serverOutDir, serverConfigFilename, html, basePath } = options;
|
|
15436
15458
|
const tempEntryPath = path46.join(dir, "__ssr-entry.ts");
|
|
15437
15459
|
const packageRoot = getZudokuRootDir();
|
|
15438
|
-
const templateContent = await
|
|
15460
|
+
const templateContent = await readFile11(
|
|
15439
15461
|
path46.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
|
|
15440
15462
|
"utf-8"
|
|
15441
15463
|
);
|
|
@@ -15466,7 +15488,7 @@ init_package_json();
|
|
|
15466
15488
|
|
|
15467
15489
|
// src/cli/init/v2-packages.ts
|
|
15468
15490
|
import { existsSync as existsSync5 } from "node:fs";
|
|
15469
|
-
import { readFile as
|
|
15491
|
+
import { readFile as readFile12, writeFile as writeFile14 } from "node:fs/promises";
|
|
15470
15492
|
import path47 from "node:path";
|
|
15471
15493
|
var CORE_PACKAGES = [
|
|
15472
15494
|
"@lukoweb/apitogo",
|
|
@@ -15613,17 +15635,17 @@ async function buildV2(options) {
|
|
|
15613
15635
|
}
|
|
15614
15636
|
|
|
15615
15637
|
// src/cli/check/gateway-online.ts
|
|
15616
|
-
import { readFile as
|
|
15638
|
+
import { readFile as readFile14 } from "node:fs/promises";
|
|
15617
15639
|
var SPEC_SEND_LIMIT = 5 * 1024 * 1024 + 64 * 1024;
|
|
15618
|
-
var issue2 = (code,
|
|
15640
|
+
var issue2 = (code, path96, message, hint) => ({ code, path: path96, message, hint });
|
|
15619
15641
|
function capabilityIssues(gateway, answer) {
|
|
15620
15642
|
const can = answer.capabilities;
|
|
15621
15643
|
const plan2 = `your ${answer.tier} plan`;
|
|
15622
15644
|
const found = [];
|
|
15623
|
-
const unsupported = (
|
|
15645
|
+
const unsupported = (path96, what, hint) => found.push(
|
|
15624
15646
|
issue2(
|
|
15625
15647
|
"GATEWAY_CAPABILITY_UNSUPPORTED",
|
|
15626
|
-
|
|
15648
|
+
path96,
|
|
15627
15649
|
`${what} is not available on ${plan2}.`,
|
|
15628
15650
|
hint
|
|
15629
15651
|
)
|
|
@@ -15677,7 +15699,7 @@ async function onlineGatewayRules(gateway, projectId, api, derivedCors = []) {
|
|
|
15677
15699
|
const specFile = gateway.specs[0];
|
|
15678
15700
|
if (specFile) {
|
|
15679
15701
|
try {
|
|
15680
|
-
const text = await
|
|
15702
|
+
const text = await readFile14(specFile, "utf8");
|
|
15681
15703
|
if (text.length <= SPEC_SEND_LIMIT) spec = text;
|
|
15682
15704
|
} catch {
|
|
15683
15705
|
}
|
|
@@ -15704,9 +15726,9 @@ async function onlineGatewayRules(gateway, projectId, api, derivedCors = []) {
|
|
|
15704
15726
|
}
|
|
15705
15727
|
|
|
15706
15728
|
// src/cli/deploy/plans-file.ts
|
|
15707
|
-
|
|
15708
|
-
import { readFile as readFile14 } from "node:fs/promises";
|
|
15729
|
+
import { readFile as readFile15 } from "node:fs/promises";
|
|
15709
15730
|
import { z as z14 } from "zod";
|
|
15731
|
+
init_invariant();
|
|
15710
15732
|
var PlansFileError = class extends ApitogoError {
|
|
15711
15733
|
constructor(code, message, developerHint) {
|
|
15712
15734
|
super(message, { developerHint, title: "Cannot read the plans file" });
|
|
@@ -15749,7 +15771,7 @@ var issuesOf = (error) => error.issues.map(
|
|
|
15749
15771
|
async function readPlansFile(file) {
|
|
15750
15772
|
let text;
|
|
15751
15773
|
try {
|
|
15752
|
-
text = await
|
|
15774
|
+
text = await readFile15(file, "utf8");
|
|
15753
15775
|
} catch {
|
|
15754
15776
|
throw new PlansFileError(
|
|
15755
15777
|
"PLANS_FILE_UNREADABLE",
|
|
@@ -15790,12 +15812,12 @@ async function readPlansFile(file) {
|
|
|
15790
15812
|
var BILLING_PERIOD = { month: "monthly", year: "annual" };
|
|
15791
15813
|
function toPlatformPlans(plans, options = {}) {
|
|
15792
15814
|
return plans.map((plan2, index) => {
|
|
15793
|
-
const paid =
|
|
15815
|
+
const paid = isPaidPlan(plan2);
|
|
15794
15816
|
if (paid && !options.billing)
|
|
15795
15817
|
throw new PlansFileError(
|
|
15796
15818
|
"PLANS_PAID_UNSUPPORTED",
|
|
15797
|
-
`The plan "${plan2.sku}" has a price,
|
|
15798
|
-
"
|
|
15819
|
+
`The plan "${plan2.sku}" has a price, but plans.billing.provider is "none", so nobody could pay for it.`,
|
|
15820
|
+
"Remove plans.billing.provider (Stripe is the provider; deploy asks for its key), or set priceAmount to 0 (or pricingModel to custom for a contact-us plan)."
|
|
15799
15821
|
);
|
|
15800
15822
|
const limits = plan2.limits ? {
|
|
15801
15823
|
...plan2.limits.rateLimit ? {
|
|
@@ -15827,9 +15849,9 @@ function toPlatformPlans(plans, options = {}) {
|
|
|
15827
15849
|
}
|
|
15828
15850
|
|
|
15829
15851
|
// src/cli/check/services-online.ts
|
|
15830
|
-
var issue3 = (code,
|
|
15852
|
+
var issue3 = (code, path96, message, hint) => ({
|
|
15831
15853
|
code,
|
|
15832
|
-
path:
|
|
15854
|
+
path: path96,
|
|
15833
15855
|
message,
|
|
15834
15856
|
hint
|
|
15835
15857
|
});
|
|
@@ -15940,7 +15962,7 @@ async function onlinePlansRules(resolved, projectId, api) {
|
|
|
15940
15962
|
async function isConfigV2(dir) {
|
|
15941
15963
|
try {
|
|
15942
15964
|
return /"version"\s*:\s*2\b/.test(
|
|
15943
|
-
await
|
|
15965
|
+
await readFile16(path49.join(dir, APITOGO_CONFIG_FILENAME), "utf8")
|
|
15944
15966
|
);
|
|
15945
15967
|
} catch {
|
|
15946
15968
|
return false;
|
|
@@ -16502,8 +16524,7 @@ function addOptionsFromArguments(service, argv) {
|
|
|
16502
16524
|
} : void 0,
|
|
16503
16525
|
plans: service === "plans" ? {
|
|
16504
16526
|
file: argv.file,
|
|
16505
|
-
template: argv.template === "free" || argv.template === "tiered" ? argv.template : void 0
|
|
16506
|
-
billing: argv.billing
|
|
16527
|
+
template: argv.template === "free" || argv.template === "tiered" ? argv.template : void 0
|
|
16507
16528
|
} : void 0
|
|
16508
16529
|
};
|
|
16509
16530
|
}
|
|
@@ -16810,10 +16831,6 @@ var add_default = {
|
|
|
16810
16831
|
"none"
|
|
16811
16832
|
],
|
|
16812
16833
|
describe: "Content to create: blank (empty shell), starter (filled example) or full (starter plus a Node.js backend in server/). Plans also accept free, tiered and none; none is blank"
|
|
16813
|
-
}).option("billing", {
|
|
16814
|
-
type: "string",
|
|
16815
|
-
choices: ["stripe", "none"],
|
|
16816
|
-
describe: "plans: billing provider"
|
|
16817
16834
|
}),
|
|
16818
16835
|
handler: async (argv) => {
|
|
16819
16836
|
await captureEvent({ argv, event: "apitogo add" });
|
|
@@ -17026,7 +17043,7 @@ function formatDevPortalBackendResponse(projectId, backend) {
|
|
|
17026
17043
|
// src/cli/platform/helpers/dev-portal-manifest.ts
|
|
17027
17044
|
init_gateway_limits();
|
|
17028
17045
|
import { existsSync as existsSync7 } from "node:fs";
|
|
17029
|
-
import { access as access5, mkdir as mkdir13, readFile as
|
|
17046
|
+
import { access as access5, mkdir as mkdir13, readFile as readFile17, writeFile as writeFile16 } from "node:fs/promises";
|
|
17030
17047
|
import path55 from "node:path";
|
|
17031
17048
|
|
|
17032
17049
|
// src/cli/make-config/header-pricing-nav.ts
|
|
@@ -17606,7 +17623,7 @@ function mergePublishPrerequisitesWithPlatformValidation(prerequisites, manifest
|
|
|
17606
17623
|
async function readManifest2(siteDirectory) {
|
|
17607
17624
|
const filePath = manifestFilePath(siteDirectory);
|
|
17608
17625
|
if (await pathExists(filePath)) {
|
|
17609
|
-
const raw = await
|
|
17626
|
+
const raw = await readFile17(filePath, "utf8");
|
|
17610
17627
|
const config2 = JSON.parse(raw);
|
|
17611
17628
|
return extractManifestFromConfig(config2);
|
|
17612
17629
|
}
|
|
@@ -17617,7 +17634,7 @@ async function writeManifest2(siteDirectory, manifest) {
|
|
|
17617
17634
|
await mkdir13(path55.dirname(filePath), { recursive: true });
|
|
17618
17635
|
let config2 = {};
|
|
17619
17636
|
if (await pathExists(filePath)) {
|
|
17620
|
-
const raw = await
|
|
17637
|
+
const raw = await readFile17(filePath, "utf8");
|
|
17621
17638
|
config2 = JSON.parse(raw);
|
|
17622
17639
|
}
|
|
17623
17640
|
const {
|
|
@@ -17636,7 +17653,7 @@ import {
|
|
|
17636
17653
|
access as access6,
|
|
17637
17654
|
appendFile,
|
|
17638
17655
|
mkdir as mkdir14,
|
|
17639
|
-
readFile as
|
|
17656
|
+
readFile as readFile18,
|
|
17640
17657
|
unlink,
|
|
17641
17658
|
writeFile as writeFile17
|
|
17642
17659
|
} from "node:fs/promises";
|
|
@@ -17742,7 +17759,7 @@ function applyEnvOverrides2(config2, env) {
|
|
|
17742
17759
|
}
|
|
17743
17760
|
async function readEnvFile(filePath) {
|
|
17744
17761
|
try {
|
|
17745
|
-
const raw = await
|
|
17762
|
+
const raw = await readFile18(filePath, "utf8");
|
|
17746
17763
|
const env = {};
|
|
17747
17764
|
for (const line2 of raw.split("\n")) {
|
|
17748
17765
|
const trimmed = line2.trim();
|
|
@@ -17875,7 +17892,7 @@ var SECRETS_COLLECTION_INSTRUCTION = "For go-live, plans must already be in apit
|
|
|
17875
17892
|
|
|
17876
17893
|
// src/cli/platform/helpers/dev-portal-site-validation.ts
|
|
17877
17894
|
init_gateway_limits();
|
|
17878
|
-
import { readFile as
|
|
17895
|
+
import { readFile as readFile19 } from "node:fs/promises";
|
|
17879
17896
|
import { createRequire as createRequire2 } from "node:module";
|
|
17880
17897
|
import path57 from "node:path";
|
|
17881
17898
|
var cachedFallbackTs;
|
|
@@ -18053,7 +18070,7 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
|
|
|
18053
18070
|
let parsed;
|
|
18054
18071
|
let parseFailed = false;
|
|
18055
18072
|
try {
|
|
18056
|
-
parsed = JSON.parse(await
|
|
18073
|
+
parsed = JSON.parse(await readFile19(jsonPath, "utf8"));
|
|
18057
18074
|
} catch (error) {
|
|
18058
18075
|
parseFailed = true;
|
|
18059
18076
|
issues.push({
|
|
@@ -18092,7 +18109,7 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
|
|
|
18092
18109
|
} else {
|
|
18093
18110
|
for (const relativeFile of existingTsxFiles) {
|
|
18094
18111
|
checkedFiles.push(relativeFile);
|
|
18095
|
-
const content = await
|
|
18112
|
+
const content = await readFile19(
|
|
18096
18113
|
path57.join(resolvedDir, relativeFile),
|
|
18097
18114
|
"utf8"
|
|
18098
18115
|
);
|
|
@@ -18115,7 +18132,7 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
|
|
|
18115
18132
|
|
|
18116
18133
|
// src/cli/platform/helpers/npm-build.ts
|
|
18117
18134
|
import { spawn as spawn2 } from "node:child_process";
|
|
18118
|
-
import { access as access7, readFile as
|
|
18135
|
+
import { access as access7, readFile as readFile20 } from "node:fs/promises";
|
|
18119
18136
|
import path58 from "node:path";
|
|
18120
18137
|
var BUILD_LOG_TAIL_BYTES = 8192;
|
|
18121
18138
|
var MIN_NODE_MAJOR = 20;
|
|
@@ -18761,7 +18778,7 @@ import { createInterface as createInterface3 } from "node:readline/promises";
|
|
|
18761
18778
|
|
|
18762
18779
|
// src/cli/make-config/v2-edits.ts
|
|
18763
18780
|
init_apitogo_config_core();
|
|
18764
|
-
import { access as access8, mkdir as mkdir15, readFile as
|
|
18781
|
+
import { access as access8, mkdir as mkdir15, readFile as readFile21, writeFile as writeFile18 } from "node:fs/promises";
|
|
18765
18782
|
import path61 from "node:path";
|
|
18766
18783
|
import { glob as glob7 } from "glob";
|
|
18767
18784
|
init_invariant();
|
|
@@ -18957,7 +18974,7 @@ async function writeDocsPage(project, input5) {
|
|
|
18957
18974
|
"Leave out --page-update to add it."
|
|
18958
18975
|
);
|
|
18959
18976
|
}
|
|
18960
|
-
const title = input5.title?.trim() || titleOf(await
|
|
18977
|
+
const title = input5.title?.trim() || titleOf(await readFile21(existing, "utf8"));
|
|
18961
18978
|
file = existing;
|
|
18962
18979
|
action = "updated";
|
|
18963
18980
|
await writeFile18(file, buildDocsPage(title ?? slug, input5.content), "utf8");
|
|
@@ -19046,7 +19063,7 @@ async function upsertPlan(project, plan2) {
|
|
|
19046
19063
|
if (await exists4(plans.file)) {
|
|
19047
19064
|
let raw;
|
|
19048
19065
|
try {
|
|
19049
|
-
raw = JSON.parse(await
|
|
19066
|
+
raw = JSON.parse(await readFile21(plans.file, "utf8"));
|
|
19050
19067
|
} catch (error) {
|
|
19051
19068
|
throw new ConfigEditError(
|
|
19052
19069
|
`${relativeToConfig(project, plans.file)} is not valid JSON (${error.message}).`
|
|
@@ -19073,7 +19090,7 @@ async function upsertPlan(project, plan2) {
|
|
|
19073
19090
|
`,
|
|
19074
19091
|
"utf8"
|
|
19075
19092
|
);
|
|
19076
|
-
const paid =
|
|
19093
|
+
const paid = isPaidPlan(plan2);
|
|
19077
19094
|
return {
|
|
19078
19095
|
action: index === -1 ? "added" : "updated",
|
|
19079
19096
|
sku: plan2.sku,
|
|
@@ -19117,7 +19134,12 @@ function printPlanResult(plan2) {
|
|
|
19117
19134
|
printSuccessToConsole(`Plan "${plan2.sku}" ${plan2.action} in ${plan2.file}.`);
|
|
19118
19135
|
if (plan2.needsBilling) {
|
|
19119
19136
|
printWarningToConsole(
|
|
19120
|
-
|
|
19137
|
+
'This plan has a price, but plans.billing.provider is "none", so deploy will refuse it. Remove plans.billing.provider (Stripe is the provider), or make the plan free or custom.'
|
|
19138
|
+
);
|
|
19139
|
+
}
|
|
19140
|
+
if (plan2.paid && !plan2.needsBilling) {
|
|
19141
|
+
printHintToConsole(
|
|
19142
|
+
"Payments go through Stripe: apitogo deploy asks for your Stripe secret key if the project has none yet."
|
|
19121
19143
|
);
|
|
19122
19144
|
}
|
|
19123
19145
|
if (plan2.paid) printPaidPlanPlatformWarning();
|
|
@@ -19512,7 +19534,7 @@ var config_default = {
|
|
|
19512
19534
|
// src/cli/create/handler.ts
|
|
19513
19535
|
init_apitogo_config_core();
|
|
19514
19536
|
import { execFile } from "node:child_process";
|
|
19515
|
-
import { readFile as
|
|
19537
|
+
import { readFile as readFile22 } from "node:fs/promises";
|
|
19516
19538
|
import path63 from "node:path";
|
|
19517
19539
|
import { promisify } from "node:util";
|
|
19518
19540
|
var execFileAsync = promisify(execFile);
|
|
@@ -19546,7 +19568,7 @@ async function gitHasUncommittedChanges(dir) {
|
|
|
19546
19568
|
async function defaultName(dir) {
|
|
19547
19569
|
try {
|
|
19548
19570
|
const parsed = JSON.parse(
|
|
19549
|
-
await
|
|
19571
|
+
await readFile22(path63.join(dir, "package.json"), "utf8")
|
|
19550
19572
|
);
|
|
19551
19573
|
if (typeof parsed.name === "string" && parsed.name.trim())
|
|
19552
19574
|
return parsed.name.replace(/^@[^/]+\//, "");
|
|
@@ -19772,7 +19794,7 @@ var create_default = {
|
|
|
19772
19794
|
};
|
|
19773
19795
|
|
|
19774
19796
|
// src/cli/cmds/deploy.ts
|
|
19775
|
-
import
|
|
19797
|
+
import path81 from "node:path";
|
|
19776
19798
|
|
|
19777
19799
|
// src/cli/apply/handler.ts
|
|
19778
19800
|
import path75 from "node:path";
|
|
@@ -20319,8 +20341,8 @@ function normalizeActionKey(actionKey2) {
|
|
|
20319
20341
|
const trimmed = actionKey2.trim();
|
|
20320
20342
|
if (trimmed.includes(":")) {
|
|
20321
20343
|
const [method2, ...pathParts] = trimmed.split(":");
|
|
20322
|
-
const
|
|
20323
|
-
return `${method2?.toLowerCase()}:${
|
|
20344
|
+
const path97 = pathParts.join(":").trim();
|
|
20345
|
+
return `${method2?.toLowerCase()}:${path97.startsWith("/") ? path97 : `/${path97}`}`;
|
|
20324
20346
|
}
|
|
20325
20347
|
const spaceIndex = trimmed.indexOf(" ");
|
|
20326
20348
|
if (spaceIndex <= 0) {
|
|
@@ -20329,8 +20351,8 @@ function normalizeActionKey(actionKey2) {
|
|
|
20329
20351
|
);
|
|
20330
20352
|
}
|
|
20331
20353
|
const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
|
|
20332
|
-
const
|
|
20333
|
-
return `${method}:${
|
|
20354
|
+
const path96 = trimmed.slice(spaceIndex + 1).trim();
|
|
20355
|
+
return `${method}:${path96.startsWith("/") ? path96 : `/${path96}`}`;
|
|
20334
20356
|
}
|
|
20335
20357
|
async function applyGatewayPublicRoutes(client, projectId, routes, options) {
|
|
20336
20358
|
const applied = [];
|
|
@@ -20808,7 +20830,7 @@ async function upsertGatewayPlansFromManifest(client, config2, projectId, plans,
|
|
|
20808
20830
|
}
|
|
20809
20831
|
|
|
20810
20832
|
// src/cli/platform/helpers/openapi-gateway-servers.ts
|
|
20811
|
-
import { mkdir as mkdir16, readFile as
|
|
20833
|
+
import { mkdir as mkdir16, readFile as readFile23, writeFile as writeFile19 } from "node:fs/promises";
|
|
20812
20834
|
import path66 from "node:path";
|
|
20813
20835
|
import YAML from "yaml";
|
|
20814
20836
|
var GATEWAY_URL_ENV_KEY = "APITOGO_GATEWAY_URL";
|
|
@@ -20840,7 +20862,7 @@ async function resolveProjectGatewayUrl(client, projectId) {
|
|
|
20840
20862
|
return null;
|
|
20841
20863
|
}
|
|
20842
20864
|
async function readOpenApiDocument(filePath) {
|
|
20843
|
-
const content = await
|
|
20865
|
+
const content = await readFile23(filePath, "utf8");
|
|
20844
20866
|
const ext = path66.extname(filePath).toLowerCase();
|
|
20845
20867
|
const parsed = ext === ".json" ? JSON.parse(content) : YAML.parse(content);
|
|
20846
20868
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
@@ -20869,7 +20891,7 @@ async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
|
|
|
20869
20891
|
path66.resolve(siteDirectory),
|
|
20870
20892
|
APITOGO_CONFIG_FILENAME2
|
|
20871
20893
|
);
|
|
20872
|
-
const raw = await
|
|
20894
|
+
const raw = await readFile23(configPath, "utf8");
|
|
20873
20895
|
const config2 = JSON.parse(raw);
|
|
20874
20896
|
const previousApis = config2.apis;
|
|
20875
20897
|
const previousBackend = config2.backend;
|
|
@@ -20886,7 +20908,7 @@ async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
|
|
|
20886
20908
|
`, "utf8");
|
|
20887
20909
|
return {
|
|
20888
20910
|
restore: async () => {
|
|
20889
|
-
const currentRaw = await
|
|
20911
|
+
const currentRaw = await readFile23(configPath, "utf8");
|
|
20890
20912
|
const current = JSON.parse(currentRaw);
|
|
20891
20913
|
if (previousApis === void 0) {
|
|
20892
20914
|
delete current.apis;
|
|
@@ -20921,7 +20943,7 @@ async function prepareOpenApiServersForGatewayBuild(options) {
|
|
|
20921
20943
|
);
|
|
20922
20944
|
if (!openApiPath) {
|
|
20923
20945
|
try {
|
|
20924
|
-
const raw = await
|
|
20946
|
+
const raw = await readFile23(
|
|
20925
20947
|
path66.join(siteDirectory, APITOGO_CONFIG_FILENAME2),
|
|
20926
20948
|
"utf8"
|
|
20927
20949
|
);
|
|
@@ -20951,8 +20973,8 @@ function normalizeActionKeyFormat(actionKey2) {
|
|
|
20951
20973
|
const trimmed = actionKey2.trim();
|
|
20952
20974
|
if (trimmed.includes(":")) {
|
|
20953
20975
|
const [method2, ...pathParts] = trimmed.split(":");
|
|
20954
|
-
const
|
|
20955
|
-
return `${method2.toLowerCase()}:${
|
|
20976
|
+
const path97 = pathParts.join(":").trim();
|
|
20977
|
+
return `${method2.toLowerCase()}:${path97.startsWith("/") ? path97 : `/${path97}`}`;
|
|
20956
20978
|
}
|
|
20957
20979
|
const spaceIndex = trimmed.indexOf(" ");
|
|
20958
20980
|
if (spaceIndex <= 0) {
|
|
@@ -20961,8 +20983,8 @@ function normalizeActionKeyFormat(actionKey2) {
|
|
|
20961
20983
|
);
|
|
20962
20984
|
}
|
|
20963
20985
|
const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
|
|
20964
|
-
const
|
|
20965
|
-
return `${method}:${
|
|
20986
|
+
const path96 = trimmed.slice(spaceIndex + 1).trim();
|
|
20987
|
+
return `${method}:${path96.startsWith("/") ? path96 : `/${path96}`}`;
|
|
20966
20988
|
}
|
|
20967
20989
|
function normalizePublicRoute(route) {
|
|
20968
20990
|
const trimmed = route.trim();
|
|
@@ -20995,7 +21017,7 @@ function collectManifestPublicActionKeys(gateway) {
|
|
|
20995
21017
|
}
|
|
20996
21018
|
|
|
20997
21019
|
// src/cli/platform/helpers/publish-ledger.ts
|
|
20998
|
-
import { mkdir as mkdir17, readFile as
|
|
21020
|
+
import { mkdir as mkdir17, readFile as readFile24, writeFile as writeFile20 } from "node:fs/promises";
|
|
20999
21021
|
import path67 from "node:path";
|
|
21000
21022
|
var PUBLISH_LEDGER_RELATIVE_PATH = ".apitogo/publish-state.json";
|
|
21001
21023
|
function publishLedgerPath(siteDirectory) {
|
|
@@ -21004,7 +21026,7 @@ function publishLedgerPath(siteDirectory) {
|
|
|
21004
21026
|
async function readPublishLedger(siteDirectory) {
|
|
21005
21027
|
const filePath = publishLedgerPath(siteDirectory);
|
|
21006
21028
|
try {
|
|
21007
|
-
const raw = await
|
|
21029
|
+
const raw = await readFile24(filePath, "utf8");
|
|
21008
21030
|
const parsed = JSON.parse(raw);
|
|
21009
21031
|
if (parsed?.version !== 1 || !Array.isArray(parsed.steps)) {
|
|
21010
21032
|
return null;
|
|
@@ -23275,7 +23297,7 @@ async function resolveProjectIdForPublish(client, config2, args, wait, progress,
|
|
|
23275
23297
|
import path74 from "node:path";
|
|
23276
23298
|
|
|
23277
23299
|
// src/cli/platform/helpers/dev-portal-site-api-url.ts
|
|
23278
|
-
import { readdir as readdir5, readFile as
|
|
23300
|
+
import { readdir as readdir5, readFile as readFile25, writeFile as writeFile21 } from "node:fs/promises";
|
|
23279
23301
|
import path71 from "node:path";
|
|
23280
23302
|
var SITE_API_BASE_URL_ENV_KEY = "VITE_APITOGO_AUTHENTICATION_API_BASE_URL";
|
|
23281
23303
|
var PLACEHOLDER_HOST_MARKERS = [
|
|
@@ -23300,7 +23322,7 @@ async function readSiteApiBaseUrl(sourceDirectory) {
|
|
|
23300
23322
|
const resolved = path71.resolve(sourceDirectory);
|
|
23301
23323
|
for (const envFile of [".env", ".env.production"]) {
|
|
23302
23324
|
try {
|
|
23303
|
-
const content = await
|
|
23325
|
+
const content = await readFile25(path71.join(resolved, envFile), "utf8");
|
|
23304
23326
|
const lines = [...content.matchAll(ENV_LINE_GLOBAL_RE)];
|
|
23305
23327
|
if (lines.length === 0) {
|
|
23306
23328
|
continue;
|
|
@@ -23331,7 +23353,7 @@ async function patchSiteApiBaseUrl(sourceDirectory, apiBaseUrl) {
|
|
|
23331
23353
|
for (const envFile of [".env.production", ".env"]) {
|
|
23332
23354
|
const envPath = path71.join(resolved, envFile);
|
|
23333
23355
|
try {
|
|
23334
|
-
const content = await
|
|
23356
|
+
const content = await readFile25(envPath, "utf8");
|
|
23335
23357
|
const withoutAssignments = content.replace(ENV_LINE_GLOBAL_RE, "").replace(/\n{3,}/g, "\n\n").trimEnd();
|
|
23336
23358
|
const patched = withoutAssignments ? `${withoutAssignments}
|
|
23337
23359
|
${line2}
|
|
@@ -23411,7 +23433,7 @@ async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiB
|
|
|
23411
23433
|
let found = false;
|
|
23412
23434
|
let foundPlaceholder = false;
|
|
23413
23435
|
for await (const file of walkFiles(dist)) {
|
|
23414
|
-
const content = await
|
|
23436
|
+
const content = await readFile25(file, "utf8");
|
|
23415
23437
|
if (content.includes(needle)) {
|
|
23416
23438
|
found = true;
|
|
23417
23439
|
}
|
|
@@ -25547,7 +25569,7 @@ async function apply(argv) {
|
|
|
25547
25569
|
}
|
|
25548
25570
|
|
|
25549
25571
|
// src/cli/deploy/command.ts
|
|
25550
|
-
import
|
|
25572
|
+
import path80 from "node:path";
|
|
25551
25573
|
init_invariant();
|
|
25552
25574
|
|
|
25553
25575
|
// src/cli/project/create-handler.ts
|
|
@@ -25914,17 +25936,129 @@ async function createProject2(argv) {
|
|
|
25914
25936
|
}
|
|
25915
25937
|
}
|
|
25916
25938
|
|
|
25939
|
+
// src/cli/secrets/input.ts
|
|
25940
|
+
import { createInterface as createInterface6 } from "node:readline/promises";
|
|
25941
|
+
var CTRL_C = "";
|
|
25942
|
+
var CTRL_D = "";
|
|
25943
|
+
function readHidden(prompt, input5 = process.stdin, output4 = process.stdout) {
|
|
25944
|
+
return new Promise((resolve, reject) => {
|
|
25945
|
+
if (!input5.isTTY || !input5.setRawMode) {
|
|
25946
|
+
reject(new Error("A hidden prompt needs an interactive terminal."));
|
|
25947
|
+
return;
|
|
25948
|
+
}
|
|
25949
|
+
let value = "";
|
|
25950
|
+
output4.write(prompt);
|
|
25951
|
+
input5.setRawMode(true);
|
|
25952
|
+
input5.resume();
|
|
25953
|
+
const finish = (action) => {
|
|
25954
|
+
input5.removeListener("data", onData);
|
|
25955
|
+
input5.setRawMode?.(false);
|
|
25956
|
+
input5.pause();
|
|
25957
|
+
output4.write("\n");
|
|
25958
|
+
action();
|
|
25959
|
+
};
|
|
25960
|
+
const onData = (chunk) => {
|
|
25961
|
+
for (const char of chunk.toString("utf8")) {
|
|
25962
|
+
if (char === CTRL_C)
|
|
25963
|
+
return finish(() => reject(new Error("Cancelled.")));
|
|
25964
|
+
if (char === "\r" || char === "\n" || char === CTRL_D)
|
|
25965
|
+
return finish(() => resolve(value));
|
|
25966
|
+
if (char === "\x7F" || char === "\b") value = value.slice(0, -1);
|
|
25967
|
+
else value += char;
|
|
25968
|
+
}
|
|
25969
|
+
};
|
|
25970
|
+
input5.on("data", onData);
|
|
25971
|
+
});
|
|
25972
|
+
}
|
|
25973
|
+
async function readStdin(input5 = process.stdin) {
|
|
25974
|
+
const chunks = [];
|
|
25975
|
+
for await (const chunk of input5) {
|
|
25976
|
+
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
25977
|
+
}
|
|
25978
|
+
return Buffer.concat(chunks).toString("utf8").replace(/\r?\n$/, "");
|
|
25979
|
+
}
|
|
25980
|
+
async function confirm(question) {
|
|
25981
|
+
const rl = createInterface6({ input: process.stdin, output: process.stdout });
|
|
25982
|
+
try {
|
|
25983
|
+
const answer = (await rl.question(question)).trim().toLowerCase();
|
|
25984
|
+
return answer === "y" || answer === "yes";
|
|
25985
|
+
} finally {
|
|
25986
|
+
rl.close();
|
|
25987
|
+
}
|
|
25988
|
+
}
|
|
25989
|
+
|
|
25990
|
+
// src/cli/deploy/stripe-key.ts
|
|
25991
|
+
import path77 from "node:path";
|
|
25992
|
+
init_invariant();
|
|
25993
|
+
var StripeKeyError = class extends ApitogoError {
|
|
25994
|
+
constructor(message, developerHint) {
|
|
25995
|
+
super(message, { developerHint, title: "Stripe key needed" });
|
|
25996
|
+
this.name = "StripeKeyError";
|
|
25997
|
+
}
|
|
25998
|
+
};
|
|
25999
|
+
var STRIPE_KEY = /^(sk|rk)_(test|live)_[A-Za-z0-9]+$/;
|
|
26000
|
+
var wantsPlans = (only) => {
|
|
26001
|
+
if (only === void 0) return true;
|
|
26002
|
+
const names = (Array.isArray(only) ? only : only.split(",")).map((name) => name.trim()).filter(Boolean);
|
|
26003
|
+
return names.length === 0 || names.includes("plans");
|
|
26004
|
+
};
|
|
26005
|
+
async function ensureStripeKey(argv, deps) {
|
|
26006
|
+
if (!wantsPlans(argv.only)) return { status: "not-needed" };
|
|
26007
|
+
let resolved;
|
|
26008
|
+
try {
|
|
26009
|
+
resolved = loadConfigV2(path77.resolve(process.cwd(), argv.dir)).resolved;
|
|
26010
|
+
} catch {
|
|
26011
|
+
return { status: "not-needed" };
|
|
26012
|
+
}
|
|
26013
|
+
if (!resolved.plans?.enabled || resolved.plans.billing.provider !== "stripe")
|
|
26014
|
+
return { status: "not-needed" };
|
|
26015
|
+
const paid = await paidPlanSkus(resolved);
|
|
26016
|
+
if (paid.length === 0) return { status: "not-needed" };
|
|
26017
|
+
const projectId = argv.projectId?.trim() || resolved.project.id || deps.envProjectId?.trim();
|
|
26018
|
+
if (!projectId) return { status: "not-needed" };
|
|
26019
|
+
const name = stripeKeySecretName(resolved);
|
|
26020
|
+
const client = deps.client();
|
|
26021
|
+
const { secrets: secrets2 } = await client.listSecrets(projectId);
|
|
26022
|
+
if (secrets2.some((secret) => secret.name === name))
|
|
26023
|
+
return { status: "present", name };
|
|
26024
|
+
const reason = `The plan${paid.length > 1 ? "s" : ""} ${paid.join(", ")} ${paid.length > 1 ? "have" : "has"} a price, so payments go through Stripe, and this project has no Stripe key yet.`;
|
|
26025
|
+
if (!deps.interactive) {
|
|
26026
|
+
throw new StripeKeyError(
|
|
26027
|
+
reason,
|
|
26028
|
+
`Store it with \`apitogo secrets set ${name}\`, then deploy again. Or make the plans free.`
|
|
26029
|
+
);
|
|
26030
|
+
}
|
|
26031
|
+
deps.print(reason);
|
|
26032
|
+
deps.print(
|
|
26033
|
+
"Paste your Stripe secret key (starts with sk_ or rk_; use an sk_test_ key to try it out). It is stored as a project secret, not in your files."
|
|
26034
|
+
);
|
|
26035
|
+
const key = (await deps.askHidden("Stripe secret key (hidden): ")).trim();
|
|
26036
|
+
if (!key)
|
|
26037
|
+
throw new StripeKeyError(
|
|
26038
|
+
"No key was entered. Nothing was deployed.",
|
|
26039
|
+
`Run \`apitogo secrets set ${name}\` when you have it, then deploy again.`
|
|
26040
|
+
);
|
|
26041
|
+
if (!STRIPE_KEY.test(key))
|
|
26042
|
+
throw new StripeKeyError(
|
|
26043
|
+
"That is not a Stripe secret key. Nothing was deployed.",
|
|
26044
|
+
"A Stripe secret key starts with sk_test_, sk_live_, rk_test_ or rk_live_. Find it in Stripe under Developers > API keys."
|
|
26045
|
+
);
|
|
26046
|
+
await client.setSecret(projectId, name, key);
|
|
26047
|
+
deps.print(`Stripe key saved as the project secret ${name}.`);
|
|
26048
|
+
return { status: "saved", name };
|
|
26049
|
+
}
|
|
26050
|
+
|
|
25917
26051
|
// src/cli/deploy/v2.ts
|
|
25918
26052
|
import { rm as rm10 } from "node:fs/promises";
|
|
25919
26053
|
init_invariant();
|
|
25920
26054
|
|
|
25921
26055
|
// src/cli/portal/report.ts
|
|
25922
26056
|
import { access as access9 } from "node:fs/promises";
|
|
25923
|
-
import
|
|
26057
|
+
import path78 from "node:path";
|
|
25924
26058
|
|
|
25925
26059
|
// src/cli/deploy/gateway.ts
|
|
25926
26060
|
import { createHash as createHash4 } from "node:crypto";
|
|
25927
|
-
import { readFile as
|
|
26061
|
+
import { readFile as readFile26 } from "node:fs/promises";
|
|
25928
26062
|
init_invariant();
|
|
25929
26063
|
var GatewayDeployError = class extends ApitogoError {
|
|
25930
26064
|
constructor(code, message, developerHint) {
|
|
@@ -25962,7 +26096,7 @@ async function readSpec(gateway) {
|
|
|
25962
26096
|
"Add one to gateway.specs in the config."
|
|
25963
26097
|
);
|
|
25964
26098
|
try {
|
|
25965
|
-
return await
|
|
26099
|
+
return await readFile26(file);
|
|
25966
26100
|
} catch {
|
|
25967
26101
|
throw new GatewayDeployError(
|
|
25968
26102
|
"GATEWAY_SPEC_UNREADABLE",
|
|
@@ -26722,12 +26856,13 @@ async function plansInputs(resolved, projectId) {
|
|
|
26722
26856
|
const plans = resolved.plans;
|
|
26723
26857
|
if (!plans) throw new Error("plans is not in the config.");
|
|
26724
26858
|
const billing = plans.billing;
|
|
26725
|
-
const
|
|
26859
|
+
const filePlans = await readPlansFile(plans.file);
|
|
26860
|
+
const wanted = toPlatformPlans(filePlans, {
|
|
26726
26861
|
billing: billing.provider === "stripe"
|
|
26727
26862
|
});
|
|
26728
26863
|
const manifest = await readManifest(resolved.state);
|
|
26729
26864
|
const ledger = await readLedger(resolved.state);
|
|
26730
|
-
const billingOn = billing.provider === "stripe";
|
|
26865
|
+
const billingOn = billing.provider === "stripe" && filePlans.some((plan2) => isPaidPlan(plan2));
|
|
26731
26866
|
const billingStep = billingOn || stepOf(ledger, "plans", "billing") !== void 0;
|
|
26732
26867
|
const identity = manifest?.services.identity;
|
|
26733
26868
|
const ownIdentity = Boolean(
|
|
@@ -26739,11 +26874,12 @@ async function plansInputs(resolved, projectId) {
|
|
|
26739
26874
|
ownIdentity,
|
|
26740
26875
|
catalogHash: stableJson({ projectId, plans: wanted }),
|
|
26741
26876
|
backendHash: stableJson({ projectId }),
|
|
26877
|
+
billingOn,
|
|
26742
26878
|
billingStep,
|
|
26743
26879
|
// Only the references to the project's secrets: a rotated value is applied with --force.
|
|
26744
26880
|
billingHash: stableJson({
|
|
26745
26881
|
projectId,
|
|
26746
|
-
provider:
|
|
26882
|
+
provider: billingOn ? "stripe" : "none",
|
|
26747
26883
|
apiKey: billingOn ? billing.apiKey : void 0,
|
|
26748
26884
|
webhookSecret: billingOn ? billing.webhookSecret : void 0,
|
|
26749
26885
|
successUrl: billingOn ? billing.successUrl : void 0,
|
|
@@ -26809,6 +26945,7 @@ async function deployPlans(resolved, projectId, deps, options = {}) {
|
|
|
26809
26945
|
wanted,
|
|
26810
26946
|
manifest,
|
|
26811
26947
|
ownIdentity,
|
|
26948
|
+
billingOn,
|
|
26812
26949
|
billingStep,
|
|
26813
26950
|
billingHash,
|
|
26814
26951
|
catalogHash,
|
|
@@ -26968,7 +27105,7 @@ async function deployPlans(resolved, projectId, deps, options = {}) {
|
|
|
26968
27105
|
name: "billing",
|
|
26969
27106
|
hash: () => billingHash,
|
|
26970
27107
|
run: async () => {
|
|
26971
|
-
const body =
|
|
27108
|
+
const body = billingOn ? {
|
|
26972
27109
|
provider: "stripe",
|
|
26973
27110
|
apiKey: plans.billing.apiKey,
|
|
26974
27111
|
webhookSecret: plans.billing.webhookSecret,
|
|
@@ -26985,8 +27122,7 @@ async function deployPlans(resolved, projectId, deps, options = {}) {
|
|
|
26985
27122
|
code: "PLANS_BILLING",
|
|
26986
27123
|
text: "the billing settings"
|
|
26987
27124
|
});
|
|
26988
|
-
if (
|
|
26989
|
-
billingNote = billingNotes(queued);
|
|
27125
|
+
if (billingOn) billingNote = billingNotes(queued);
|
|
26990
27126
|
return { ...done, mode: queued.mode };
|
|
26991
27127
|
}
|
|
26992
27128
|
};
|
|
@@ -27029,9 +27165,9 @@ async function deployPlans(resolved, projectId, deps, options = {}) {
|
|
|
27029
27165
|
projectId,
|
|
27030
27166
|
projectName: resolved.project.name,
|
|
27031
27167
|
apiBaseUrl,
|
|
27032
|
-
billing:
|
|
27168
|
+
billing: billingOn ? "stripe" : "none",
|
|
27033
27169
|
catalogRevision: catalog && !catalog.skipped ? previous + 1 : Math.max(previous, 1),
|
|
27034
|
-
capabilities:
|
|
27170
|
+
capabilities: billingOn ? { ...PLANS_CAPABILITIES, checkout: true } : PLANS_CAPABILITIES
|
|
27035
27171
|
})
|
|
27036
27172
|
);
|
|
27037
27173
|
}
|
|
@@ -27190,7 +27326,7 @@ async function planPlansService(resolved, ledger, plansRemote2) {
|
|
|
27190
27326
|
),
|
|
27191
27327
|
inputs.ownIdentity ? "sign-in: the project's identity will be applied to the plans backend" : "sign-in: no identity of the platform deployed, so nothing is applied to the plans backend",
|
|
27192
27328
|
...inputs.billingStep ? [
|
|
27193
|
-
|
|
27329
|
+
inputs.billingOn ? "billing: a plan has a price, so the Stripe key and webhook secret of the project's secrets will be applied to the plans backend" : "billing: no plan has a price, so the stored Stripe settings will be removed from the plans backend"
|
|
27194
27330
|
] : [],
|
|
27195
27331
|
...steps.map(
|
|
27196
27332
|
(name) => `step ${name}: ${stepState(stepOf(ledger, "plans", name), hashes[name])}`
|
|
@@ -27384,7 +27520,7 @@ async function planPortalService(resolved, ledger) {
|
|
|
27384
27520
|
const hash2 = await portalBuildHash(resolved, prepared);
|
|
27385
27521
|
const previous = stepOf(ledger, "portal", "build");
|
|
27386
27522
|
const built = await exists5(
|
|
27387
|
-
|
|
27523
|
+
path78.join(resolved.state.buildDir, "index.html")
|
|
27388
27524
|
);
|
|
27389
27525
|
if (previous?.status === "succeeded" && previous.hash === hash2 && built) {
|
|
27390
27526
|
return {
|
|
@@ -27743,7 +27879,7 @@ async function statusV2(dir, only, options = {}) {
|
|
|
27743
27879
|
if (service === "portal") {
|
|
27744
27880
|
const build2 = stepOf(ledger, "portal", "build");
|
|
27745
27881
|
const built = await exists5(
|
|
27746
|
-
|
|
27882
|
+
path78.join(resolved.state.buildDir, "index.html")
|
|
27747
27883
|
);
|
|
27748
27884
|
const state = build2?.status === "failed" ? "build-failed" : build2?.status === "succeeded" && built ? "built" : "not-built";
|
|
27749
27885
|
services.push({
|
|
@@ -27754,7 +27890,7 @@ async function statusV2(dir, only, options = {}) {
|
|
|
27754
27890
|
...build2?.finishedAt ? [`last build: ${build2.finishedAt}`] : [],
|
|
27755
27891
|
...build2?.status === "failed" ? [`error: ${build2.error ?? "unknown"}`] : [],
|
|
27756
27892
|
...state === "built" ? [
|
|
27757
|
-
`output: ${
|
|
27893
|
+
`output: ${path78.relative(resolved.configDir, resolved.state.buildDir)}`
|
|
27758
27894
|
] : [],
|
|
27759
27895
|
...url2 ? [`url: ${url2}`] : ["url: not known (portal is not deployed yet)"],
|
|
27760
27896
|
...await hostingLine(resolved, manifest, options.hostingRemote)
|
|
@@ -27821,7 +27957,7 @@ function formatStatus(output4) {
|
|
|
27821
27957
|
|
|
27822
27958
|
// src/cli/deploy/static-web-config.ts
|
|
27823
27959
|
import { access as access10, writeFile as writeFile22 } from "node:fs/promises";
|
|
27824
|
-
import
|
|
27960
|
+
import path79 from "node:path";
|
|
27825
27961
|
var STATIC_WEB_CONFIG_FILE = "staticwebapp.config.json";
|
|
27826
27962
|
var STATIC_WEB_CONFIG_VERSION = 3;
|
|
27827
27963
|
var CLIENT_ONLY_ROUTES = [
|
|
@@ -27839,7 +27975,7 @@ var DEFAULT_STATIC_WEB_CONFIG = {
|
|
|
27839
27975
|
}
|
|
27840
27976
|
};
|
|
27841
27977
|
async function ensureStaticWebConfig(buildDir) {
|
|
27842
|
-
const file =
|
|
27978
|
+
const file = path79.join(buildDir, STATIC_WEB_CONFIG_FILE);
|
|
27843
27979
|
try {
|
|
27844
27980
|
await access10(file);
|
|
27845
27981
|
return false;
|
|
@@ -28190,7 +28326,7 @@ function formatDeploy(output4) {
|
|
|
28190
28326
|
// src/cli/deploy/command.ts
|
|
28191
28327
|
async function ensureLinkedProject(argv, deps) {
|
|
28192
28328
|
if (argv.projectId?.trim() || deps.envProjectId?.trim()) return true;
|
|
28193
|
-
const dir =
|
|
28329
|
+
const dir = path80.resolve(process.cwd(), argv.dir);
|
|
28194
28330
|
let linked;
|
|
28195
28331
|
try {
|
|
28196
28332
|
linked = Boolean(loadConfigV2(dir).resolved.project.id);
|
|
@@ -28220,6 +28356,18 @@ async function deployProject(argv) {
|
|
|
28220
28356
|
createProject: (dir) => createLinkedProject({ dir }, dir, { continuingDeploy: true })
|
|
28221
28357
|
});
|
|
28222
28358
|
if (!ready) return;
|
|
28359
|
+
try {
|
|
28360
|
+
await ensureStripeKey(argv, {
|
|
28361
|
+
client: () => new PlatformApiClient(loadConfig()),
|
|
28362
|
+
envProjectId: process.env.APITOGO_DEFAULT_PROJECT_ID,
|
|
28363
|
+
interactive,
|
|
28364
|
+
askHidden: (prompt) => readHidden(prompt),
|
|
28365
|
+
print: printDiagnosticsToConsole
|
|
28366
|
+
});
|
|
28367
|
+
} catch (error) {
|
|
28368
|
+
await reportFailure(error, json);
|
|
28369
|
+
return;
|
|
28370
|
+
}
|
|
28223
28371
|
const quiet = json || argv.verbose !== true;
|
|
28224
28372
|
if (quiet) applyJsonOnlyDeployQuietMode();
|
|
28225
28373
|
if (!json && quiet)
|
|
@@ -28230,7 +28378,7 @@ async function deployProject(argv) {
|
|
|
28230
28378
|
const config2 = loadConfig();
|
|
28231
28379
|
const output4 = await deployV2(
|
|
28232
28380
|
{
|
|
28233
|
-
dir:
|
|
28381
|
+
dir: path80.resolve(process.cwd(), argv.dir),
|
|
28234
28382
|
only: Array.isArray(argv.only) ? argv.only.join(",") : argv.only,
|
|
28235
28383
|
projectId: argv.projectId,
|
|
28236
28384
|
env: argv.env,
|
|
@@ -28250,23 +28398,26 @@ async function deployProject(argv) {
|
|
|
28250
28398
|
for (const line2 of formatDeploy(output4)) printDiagnosticsToConsole(line2);
|
|
28251
28399
|
printResultToConsole("Deploy finished.");
|
|
28252
28400
|
} catch (error) {
|
|
28253
|
-
|
|
28254
|
-
|
|
28255
|
-
|
|
28256
|
-
|
|
28257
|
-
|
|
28258
|
-
|
|
28259
|
-
|
|
28260
|
-
|
|
28261
|
-
|
|
28262
|
-
|
|
28263
|
-
|
|
28264
|
-
|
|
28265
|
-
|
|
28266
|
-
await printCriticalFailureToConsoleAndExit(
|
|
28267
|
-
hint ? `${message} ${hint}` : message
|
|
28401
|
+
await reportFailure(error, json);
|
|
28402
|
+
}
|
|
28403
|
+
}
|
|
28404
|
+
async function reportFailure(error, json) {
|
|
28405
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
28406
|
+
const hint = error instanceof ApitogoError ? error.developerHint : void 0;
|
|
28407
|
+
if (json) {
|
|
28408
|
+
console.log(
|
|
28409
|
+
JSON.stringify({
|
|
28410
|
+
status: "failed",
|
|
28411
|
+
error: message,
|
|
28412
|
+
hint: hint ?? null
|
|
28413
|
+
})
|
|
28268
28414
|
);
|
|
28415
|
+
process.exitCode = 1;
|
|
28416
|
+
return;
|
|
28269
28417
|
}
|
|
28418
|
+
await printCriticalFailureToConsoleAndExit(
|
|
28419
|
+
hint ? `${message} ${hint}` : message
|
|
28420
|
+
);
|
|
28270
28421
|
}
|
|
28271
28422
|
|
|
28272
28423
|
// src/cli/cmds/deploy.ts
|
|
@@ -28321,7 +28472,7 @@ var deploy_default = {
|
|
|
28321
28472
|
}),
|
|
28322
28473
|
handler: async (argv) => {
|
|
28323
28474
|
await captureEvent({ argv, event: "apitogo deploy" });
|
|
28324
|
-
if (await isConfigV2(
|
|
28475
|
+
if (await isConfigV2(path81.resolve(process.cwd(), argv.dir))) {
|
|
28325
28476
|
await deployProject(argv);
|
|
28326
28477
|
return;
|
|
28327
28478
|
}
|
|
@@ -28331,7 +28482,7 @@ var deploy_default = {
|
|
|
28331
28482
|
|
|
28332
28483
|
// src/cli/export/handler.ts
|
|
28333
28484
|
import { mkdir as mkdir18, writeFile as writeFile23 } from "node:fs/promises";
|
|
28334
|
-
import
|
|
28485
|
+
import path82 from "node:path";
|
|
28335
28486
|
init_invariant();
|
|
28336
28487
|
var ExportError = class extends ApitogoError {
|
|
28337
28488
|
constructor(message, developerHint) {
|
|
@@ -28345,7 +28496,7 @@ async function exportOpenApi(args, deps) {
|
|
|
28345
28496
|
`Cannot export "${args.target}".`,
|
|
28346
28497
|
"Only `apitogo export openapi` exists."
|
|
28347
28498
|
);
|
|
28348
|
-
const dir =
|
|
28499
|
+
const dir = path82.resolve(process.cwd(), args.dir ?? ".");
|
|
28349
28500
|
if (!await isConfigV2(dir))
|
|
28350
28501
|
throw new ExportError(
|
|
28351
28502
|
"This command needs a config version 2 project.",
|
|
@@ -28370,8 +28521,8 @@ async function exportOpenApi(args, deps) {
|
|
|
28370
28521
|
throw error;
|
|
28371
28522
|
}
|
|
28372
28523
|
if (!args.out) return { text };
|
|
28373
|
-
const file =
|
|
28374
|
-
await mkdir18(
|
|
28524
|
+
const file = path82.resolve(process.cwd(), args.out);
|
|
28525
|
+
await mkdir18(path82.dirname(file), { recursive: true });
|
|
28375
28526
|
await writeFile23(file, text);
|
|
28376
28527
|
return { text, file };
|
|
28377
28528
|
}
|
|
@@ -28464,8 +28615,8 @@ import open3 from "open";
|
|
|
28464
28615
|
import colors14 from "picocolors";
|
|
28465
28616
|
|
|
28466
28617
|
// src/cli/platform/device-auth.ts
|
|
28467
|
-
function url(apiUrl,
|
|
28468
|
-
return `${apiUrl}${
|
|
28618
|
+
function url(apiUrl, path96) {
|
|
28619
|
+
return `${apiUrl}${path96.startsWith("/") ? path96 : `/${path96}`}`;
|
|
28469
28620
|
}
|
|
28470
28621
|
async function requestDeviceCode(apiUrl) {
|
|
28471
28622
|
const response = await fetchWithRetry(
|
|
@@ -28647,7 +28798,7 @@ var logout_default = {
|
|
|
28647
28798
|
};
|
|
28648
28799
|
|
|
28649
28800
|
// src/cli/portal/commands.ts
|
|
28650
|
-
import
|
|
28801
|
+
import path83 from "node:path";
|
|
28651
28802
|
init_invariant();
|
|
28652
28803
|
function parseOnly(value) {
|
|
28653
28804
|
if (value === void 0) return void 0;
|
|
@@ -28664,7 +28815,7 @@ function parseOnly(value) {
|
|
|
28664
28815
|
async function run2(command2, argv, compute, format) {
|
|
28665
28816
|
const json = argv.json === true;
|
|
28666
28817
|
try {
|
|
28667
|
-
const dir =
|
|
28818
|
+
const dir = path83.resolve(process.cwd(), argv.dir ?? ".");
|
|
28668
28819
|
if (!await isConfigV2(dir)) {
|
|
28669
28820
|
throw new ServiceEditError(
|
|
28670
28821
|
`${command2} works with a config version 2 project, and there is none in ${dir}.`,
|
|
@@ -28880,14 +29031,14 @@ var remove_default = {
|
|
|
28880
29031
|
|
|
28881
29032
|
// src/cli/dev/handler.ts
|
|
28882
29033
|
init_joinUrl();
|
|
28883
|
-
import
|
|
29034
|
+
import path86 from "node:path";
|
|
28884
29035
|
|
|
28885
29036
|
// src/vite/dev-server.ts
|
|
28886
29037
|
init_logger();
|
|
28887
29038
|
import fs11 from "node:fs/promises";
|
|
28888
29039
|
import http from "node:http";
|
|
28889
29040
|
import https from "node:https";
|
|
28890
|
-
import
|
|
29041
|
+
import path85 from "node:path";
|
|
28891
29042
|
import { createHttpTerminator } from "http-terminator";
|
|
28892
29043
|
import {
|
|
28893
29044
|
createServer as createViteServer,
|
|
@@ -28920,7 +29071,7 @@ init_loader();
|
|
|
28920
29071
|
// src/vite/pagefind-dev-index.ts
|
|
28921
29072
|
init_invariant();
|
|
28922
29073
|
init_joinUrl();
|
|
28923
|
-
import
|
|
29074
|
+
import path84 from "node:path";
|
|
28924
29075
|
import { createIndex as createIndex2 } from "pagefind";
|
|
28925
29076
|
import { isRunnableDevEnvironment } from "vite";
|
|
28926
29077
|
async function* buildPagefindDevIndex(vite, config2) {
|
|
@@ -28973,7 +29124,7 @@ async function* buildPagefindDevIndex(vite, config2) {
|
|
|
28973
29124
|
path: urlPath
|
|
28974
29125
|
};
|
|
28975
29126
|
}
|
|
28976
|
-
const outputPath =
|
|
29127
|
+
const outputPath = path84.join(vite.config.publicDir, "pagefind");
|
|
28977
29128
|
await pagefindIndex.writeFiles({ outputPath });
|
|
28978
29129
|
yield { type: "complete", success: true, indexed };
|
|
28979
29130
|
}
|
|
@@ -28992,9 +29143,9 @@ var DevServer = class {
|
|
|
28992
29143
|
this.protocol = "https";
|
|
28993
29144
|
const { dir } = this.options;
|
|
28994
29145
|
const [key, cert, ca] = await Promise.all([
|
|
28995
|
-
fs11.readFile(
|
|
28996
|
-
fs11.readFile(
|
|
28997
|
-
config2.https.ca ? fs11.readFile(
|
|
29146
|
+
fs11.readFile(path85.resolve(dir, config2.https.key)),
|
|
29147
|
+
fs11.readFile(path85.resolve(dir, config2.https.cert)),
|
|
29148
|
+
config2.https.ca ? fs11.readFile(path85.resolve(dir, config2.https.ca)) : void 0
|
|
28998
29149
|
]);
|
|
28999
29150
|
return https.createServer({ key, cert, ca });
|
|
29000
29151
|
}
|
|
@@ -29011,7 +29162,7 @@ var DevServer = class {
|
|
|
29011
29162
|
);
|
|
29012
29163
|
const server = await this.createNodeServer(config2);
|
|
29013
29164
|
if (config2.search?.type === "pagefind" && viteConfig.publicDir !== false) {
|
|
29014
|
-
const publicRoot =
|
|
29165
|
+
const publicRoot = path85.resolve(
|
|
29015
29166
|
this.options.dir,
|
|
29016
29167
|
typeof viteConfig.publicDir === "string" ? viteConfig.publicDir : "public"
|
|
29017
29168
|
);
|
|
@@ -29028,7 +29179,7 @@ var DevServer = class {
|
|
|
29028
29179
|
// built-in transform middleware which would treat the path as a static asset.
|
|
29029
29180
|
name: "apitogo:entry-client",
|
|
29030
29181
|
configureServer(server2) {
|
|
29031
|
-
const entryPath =
|
|
29182
|
+
const entryPath = path85.posix.join(
|
|
29032
29183
|
server2.config.base,
|
|
29033
29184
|
"/__z/entry.client.tsx"
|
|
29034
29185
|
);
|
|
@@ -29193,7 +29344,7 @@ init_package_json();
|
|
|
29193
29344
|
async function dev(argv) {
|
|
29194
29345
|
const packageJson3 = getZudokuPackageJson();
|
|
29195
29346
|
process.env.NODE_ENV = "development";
|
|
29196
|
-
let dir =
|
|
29347
|
+
let dir = path86.resolve(process.cwd(), argv.dir);
|
|
29197
29348
|
if (await isConfigV2(dir)) {
|
|
29198
29349
|
const { root, prepared } = await preparePortalWorkspace(dir, "development");
|
|
29199
29350
|
dir = root;
|
|
@@ -29292,61 +29443,8 @@ var run_default = {
|
|
|
29292
29443
|
};
|
|
29293
29444
|
|
|
29294
29445
|
// src/cli/secrets/handler.ts
|
|
29295
|
-
import
|
|
29446
|
+
import path87 from "node:path";
|
|
29296
29447
|
init_invariant();
|
|
29297
|
-
|
|
29298
|
-
// src/cli/secrets/input.ts
|
|
29299
|
-
import { createInterface as createInterface6 } from "node:readline/promises";
|
|
29300
|
-
var CTRL_C = "";
|
|
29301
|
-
var CTRL_D = "";
|
|
29302
|
-
function readHidden(prompt, input5 = process.stdin, output4 = process.stdout) {
|
|
29303
|
-
return new Promise((resolve, reject) => {
|
|
29304
|
-
if (!input5.isTTY || !input5.setRawMode) {
|
|
29305
|
-
reject(new Error("A hidden prompt needs an interactive terminal."));
|
|
29306
|
-
return;
|
|
29307
|
-
}
|
|
29308
|
-
let value = "";
|
|
29309
|
-
output4.write(prompt);
|
|
29310
|
-
input5.setRawMode(true);
|
|
29311
|
-
input5.resume();
|
|
29312
|
-
const finish = (action) => {
|
|
29313
|
-
input5.removeListener("data", onData);
|
|
29314
|
-
input5.setRawMode?.(false);
|
|
29315
|
-
input5.pause();
|
|
29316
|
-
output4.write("\n");
|
|
29317
|
-
action();
|
|
29318
|
-
};
|
|
29319
|
-
const onData = (chunk) => {
|
|
29320
|
-
for (const char of chunk.toString("utf8")) {
|
|
29321
|
-
if (char === CTRL_C)
|
|
29322
|
-
return finish(() => reject(new Error("Cancelled.")));
|
|
29323
|
-
if (char === "\r" || char === "\n" || char === CTRL_D)
|
|
29324
|
-
return finish(() => resolve(value));
|
|
29325
|
-
if (char === "\x7F" || char === "\b") value = value.slice(0, -1);
|
|
29326
|
-
else value += char;
|
|
29327
|
-
}
|
|
29328
|
-
};
|
|
29329
|
-
input5.on("data", onData);
|
|
29330
|
-
});
|
|
29331
|
-
}
|
|
29332
|
-
async function readStdin(input5 = process.stdin) {
|
|
29333
|
-
const chunks = [];
|
|
29334
|
-
for await (const chunk of input5) {
|
|
29335
|
-
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
29336
|
-
}
|
|
29337
|
-
return Buffer.concat(chunks).toString("utf8").replace(/\r?\n$/, "");
|
|
29338
|
-
}
|
|
29339
|
-
async function confirm(question) {
|
|
29340
|
-
const rl = createInterface6({ input: process.stdin, output: process.stdout });
|
|
29341
|
-
try {
|
|
29342
|
-
const answer = (await rl.question(question)).trim().toLowerCase();
|
|
29343
|
-
return answer === "y" || answer === "yes";
|
|
29344
|
-
} finally {
|
|
29345
|
-
rl.close();
|
|
29346
|
-
}
|
|
29347
|
-
}
|
|
29348
|
-
|
|
29349
|
-
// src/cli/secrets/handler.ts
|
|
29350
29448
|
var SECRET_NAME = /^[A-Za-z_][A-Za-z0-9_]{0,127}$/;
|
|
29351
29449
|
var SecretsError = class extends ApitogoError {
|
|
29352
29450
|
constructor(message, developerHint) {
|
|
@@ -29357,7 +29455,7 @@ var SecretsError = class extends ApitogoError {
|
|
|
29357
29455
|
async function resolveProjectId2(argv, deps) {
|
|
29358
29456
|
const explicit = argv.projectId?.trim();
|
|
29359
29457
|
if (explicit) return explicit;
|
|
29360
|
-
const dir =
|
|
29458
|
+
const dir = path87.resolve(process.cwd(), argv.dir ?? ".");
|
|
29361
29459
|
if (await isConfigV2(dir)) {
|
|
29362
29460
|
const id = loadConfigV2(dir).resolved.project.id;
|
|
29363
29461
|
if (id) return id;
|
|
@@ -29517,12 +29615,12 @@ var secrets_default = {
|
|
|
29517
29615
|
};
|
|
29518
29616
|
|
|
29519
29617
|
// src/cli/cmds/status.ts
|
|
29520
|
-
import
|
|
29618
|
+
import path89 from "node:path";
|
|
29521
29619
|
|
|
29522
29620
|
// src/cli/status/handler.ts
|
|
29523
|
-
import
|
|
29621
|
+
import path88 from "node:path";
|
|
29524
29622
|
async function status(argv) {
|
|
29525
|
-
const sourceDirectory =
|
|
29623
|
+
const sourceDirectory = path88.resolve(process.cwd(), argv.dir);
|
|
29526
29624
|
let config2;
|
|
29527
29625
|
try {
|
|
29528
29626
|
config2 = loadConfig();
|
|
@@ -29620,7 +29718,7 @@ var status_default = {
|
|
|
29620
29718
|
}),
|
|
29621
29719
|
handler: async (argv) => {
|
|
29622
29720
|
await captureEvent({ argv, event: "apitogo status" });
|
|
29623
|
-
if (await isConfigV2(
|
|
29721
|
+
if (await isConfigV2(path89.resolve(process.cwd(), argv.dir))) {
|
|
29624
29722
|
await statusOfProject(argv);
|
|
29625
29723
|
return;
|
|
29626
29724
|
}
|
|
@@ -29629,11 +29727,11 @@ var status_default = {
|
|
|
29629
29727
|
};
|
|
29630
29728
|
|
|
29631
29729
|
// src/cli/cmds/teardown.ts
|
|
29632
|
-
import
|
|
29730
|
+
import path92 from "node:path";
|
|
29633
29731
|
|
|
29634
29732
|
// src/cli/teardown/command.ts
|
|
29635
29733
|
init_invariant();
|
|
29636
|
-
import
|
|
29734
|
+
import path90 from "node:path";
|
|
29637
29735
|
import { createInterface as createInterface7 } from "node:readline/promises";
|
|
29638
29736
|
|
|
29639
29737
|
// src/cli/teardown/v2.ts
|
|
@@ -29994,7 +30092,7 @@ async function teardownProject(argv) {
|
|
|
29994
30092
|
const progress = createConsoleProgressReporter();
|
|
29995
30093
|
const result = await teardownV2(
|
|
29996
30094
|
{
|
|
29997
|
-
dir:
|
|
30095
|
+
dir: path90.resolve(process.cwd(), argv.dir),
|
|
29998
30096
|
projectId: argv.projectId,
|
|
29999
30097
|
only: Array.isArray(argv.only) ? argv.only.join(",") : argv.only,
|
|
30000
30098
|
yes: argv.yes === true,
|
|
@@ -30053,7 +30151,7 @@ async function teardownProject(argv) {
|
|
|
30053
30151
|
}
|
|
30054
30152
|
|
|
30055
30153
|
// src/cli/teardown/handler.ts
|
|
30056
|
-
import
|
|
30154
|
+
import path91 from "node:path";
|
|
30057
30155
|
function resultLooksFailed3(payload) {
|
|
30058
30156
|
try {
|
|
30059
30157
|
const parsed = JSON.parse(payload);
|
|
@@ -30069,7 +30167,7 @@ async function teardown(argv) {
|
|
|
30069
30167
|
);
|
|
30070
30168
|
return;
|
|
30071
30169
|
}
|
|
30072
|
-
const sourceDirectory =
|
|
30170
|
+
const sourceDirectory = path91.resolve(process.cwd(), argv.dir);
|
|
30073
30171
|
let config2;
|
|
30074
30172
|
try {
|
|
30075
30173
|
config2 = loadConfig();
|
|
@@ -30147,7 +30245,7 @@ var teardown_default = {
|
|
|
30147
30245
|
}),
|
|
30148
30246
|
handler: async (argv) => {
|
|
30149
30247
|
await captureEvent({ argv, event: "apitogo teardown" });
|
|
30150
|
-
if (await isConfigV2(
|
|
30248
|
+
if (await isConfigV2(path92.resolve(process.cwd(), argv.dir))) {
|
|
30151
30249
|
await teardownProject(argv);
|
|
30152
30250
|
return;
|
|
30153
30251
|
}
|
|
@@ -30157,7 +30255,7 @@ var teardown_default = {
|
|
|
30157
30255
|
|
|
30158
30256
|
// src/cli/teardown/reset-command.ts
|
|
30159
30257
|
init_invariant();
|
|
30160
|
-
import
|
|
30258
|
+
import path93 from "node:path";
|
|
30161
30259
|
|
|
30162
30260
|
// src/cli/teardown/reset.ts
|
|
30163
30261
|
init_invariant();
|
|
@@ -30280,7 +30378,7 @@ async function resetProject(argv) {
|
|
|
30280
30378
|
const config2 = loadConfig();
|
|
30281
30379
|
const result = await resetProjectV2(
|
|
30282
30380
|
{
|
|
30283
|
-
dir:
|
|
30381
|
+
dir: path93.resolve(process.cwd(), argv.dir),
|
|
30284
30382
|
projectId: argv.projectId,
|
|
30285
30383
|
yes: argv.yes === true
|
|
30286
30384
|
},
|
|
@@ -30344,7 +30442,7 @@ var test_reset_default = {
|
|
|
30344
30442
|
};
|
|
30345
30443
|
|
|
30346
30444
|
// src/cli/test-sign-in/handler.ts
|
|
30347
|
-
import
|
|
30445
|
+
import path94 from "node:path";
|
|
30348
30446
|
init_invariant();
|
|
30349
30447
|
var TestSignInError = class extends ApitogoError {
|
|
30350
30448
|
constructor(message, developerHint) {
|
|
@@ -30355,7 +30453,7 @@ var TestSignInError = class extends ApitogoError {
|
|
|
30355
30453
|
async function resolveProjectId3(argv) {
|
|
30356
30454
|
const explicit = argv.projectId?.trim();
|
|
30357
30455
|
if (explicit) return explicit;
|
|
30358
|
-
const dir =
|
|
30456
|
+
const dir = path94.resolve(process.cwd(), argv.dir ?? ".");
|
|
30359
30457
|
if (await isConfigV2(dir)) {
|
|
30360
30458
|
const id = loadConfigV2(dir).resolved.project.id;
|
|
30361
30459
|
if (id) return id;
|
|
@@ -30495,36 +30593,36 @@ function createApitogoCli(argv) {
|
|
|
30495
30593
|
// src/cli/local-handoff.ts
|
|
30496
30594
|
import { spawn as spawn4 } from "node:child_process";
|
|
30497
30595
|
import { existsSync as existsSync8, realpathSync as realpathSync2 } from "node:fs";
|
|
30498
|
-
import
|
|
30596
|
+
import path95 from "node:path";
|
|
30499
30597
|
var LOCAL_HANDOFF_ENV = "APITOGO_LOCAL_CLI";
|
|
30500
30598
|
var PACKAGE_NAME = "@lukoweb/apitogo";
|
|
30501
30599
|
var resolveProjectDir = (argv, cwd) => {
|
|
30502
30600
|
for (let i = 0; i < argv.length; i++) {
|
|
30503
30601
|
const arg = argv[i];
|
|
30504
30602
|
const next = argv[i + 1];
|
|
30505
|
-
if (arg === "--dir" && next) return
|
|
30603
|
+
if (arg === "--dir" && next) return path95.resolve(cwd, next);
|
|
30506
30604
|
if (arg?.startsWith("--dir=")) {
|
|
30507
|
-
return
|
|
30605
|
+
return path95.resolve(cwd, arg.slice("--dir=".length));
|
|
30508
30606
|
}
|
|
30509
30607
|
}
|
|
30510
30608
|
return cwd;
|
|
30511
30609
|
};
|
|
30512
30610
|
var findLocalCli = (projectDir, runningRoot) => {
|
|
30513
|
-
let dir =
|
|
30611
|
+
let dir = path95.resolve(projectDir);
|
|
30514
30612
|
let localPackageRoot;
|
|
30515
30613
|
while (!localPackageRoot) {
|
|
30516
|
-
const candidate =
|
|
30517
|
-
if (existsSync8(
|
|
30614
|
+
const candidate = path95.join(dir, "node_modules", PACKAGE_NAME);
|
|
30615
|
+
if (existsSync8(path95.join(candidate, "package.json"))) {
|
|
30518
30616
|
localPackageRoot = candidate;
|
|
30519
|
-
} else if (dir ===
|
|
30617
|
+
} else if (dir === path95.dirname(dir)) {
|
|
30520
30618
|
return void 0;
|
|
30521
30619
|
} else {
|
|
30522
|
-
dir =
|
|
30620
|
+
dir = path95.dirname(dir);
|
|
30523
30621
|
}
|
|
30524
30622
|
}
|
|
30525
30623
|
const localRoot = realpathSync2(localPackageRoot);
|
|
30526
30624
|
if (localRoot === realpathSync2(runningRoot)) return void 0;
|
|
30527
|
-
return
|
|
30625
|
+
return path95.join(localRoot, "cli.js");
|
|
30528
30626
|
};
|
|
30529
30627
|
var handoffToLocalCli = async (argv, runningRoot) => {
|
|
30530
30628
|
if (process.env[LOCAL_HANDOFF_ENV] || process.env.ZUDOKU_ENV === "internal") {
|
|
@@ -30536,7 +30634,7 @@ var handoffToLocalCli = async (argv, runningRoot) => {
|
|
|
30536
30634
|
);
|
|
30537
30635
|
if (!localCli) return void 0;
|
|
30538
30636
|
printDiagnosticsToConsole(
|
|
30539
|
-
`Using the project's local ${PACKAGE_NAME} (${
|
|
30637
|
+
`Using the project's local ${PACKAGE_NAME} (${path95.dirname(localCli)})`
|
|
30540
30638
|
);
|
|
30541
30639
|
const child = spawn4(process.execPath, [localCli, ...argv], {
|
|
30542
30640
|
stdio: "inherit",
|