@lukoweb/apitogo 0.1.89 → 0.1.91
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
CHANGED
|
@@ -96,19 +96,19 @@ var init_plugins = __esm({
|
|
|
96
96
|
|
|
97
97
|
// src/lib/core/transform-config.ts
|
|
98
98
|
import { isValidElement } from "react";
|
|
99
|
-
var
|
|
99
|
+
var isPlainObject2, mergeConfig, runPluginTransformConfig;
|
|
100
100
|
var init_transform_config = __esm({
|
|
101
101
|
"src/lib/core/transform-config.ts"() {
|
|
102
102
|
init_plugins();
|
|
103
|
-
|
|
103
|
+
isPlainObject2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
|
|
104
104
|
mergeConfig = (target, source) => {
|
|
105
105
|
const result = { ...target };
|
|
106
106
|
for (const key of Object.keys(source)) {
|
|
107
107
|
const sourceValue = source[key];
|
|
108
108
|
const targetValue = target[key];
|
|
109
|
-
if (isValidElement(sourceValue) || Array.isArray(sourceValue) || !
|
|
109
|
+
if (isValidElement(sourceValue) || Array.isArray(sourceValue) || !isPlainObject2(sourceValue)) {
|
|
110
110
|
result[key] = sourceValue;
|
|
111
|
-
} else if (
|
|
111
|
+
} else if (isPlainObject2(targetValue)) {
|
|
112
112
|
result[key] = mergeConfig(
|
|
113
113
|
targetValue,
|
|
114
114
|
sourceValue
|
|
@@ -5964,6 +5964,39 @@ import { existsSync } from "node:fs";
|
|
|
5964
5964
|
import { access, mkdir, readFile as readFile2, writeFile } from "node:fs/promises";
|
|
5965
5965
|
import path2 from "node:path";
|
|
5966
5966
|
|
|
5967
|
+
// src/cli/make-config/header-pricing-nav.ts
|
|
5968
|
+
var HEADER_PRICING_PATH = "/pricing";
|
|
5969
|
+
var HEADER_PRICING_LABEL = "Pricing";
|
|
5970
|
+
function isPlainObject(value) {
|
|
5971
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
5972
|
+
}
|
|
5973
|
+
function isPricingItem(item) {
|
|
5974
|
+
return isPlainObject(item) && item.to === HEADER_PRICING_PATH;
|
|
5975
|
+
}
|
|
5976
|
+
function docsInsertIndex(navigation) {
|
|
5977
|
+
return navigation.findIndex(
|
|
5978
|
+
(item) => item.to === "/introduction" || item.label === "Docs"
|
|
5979
|
+
);
|
|
5980
|
+
}
|
|
5981
|
+
function ensureHeaderPricingNavigation(config2) {
|
|
5982
|
+
const header = isPlainObject(config2.header) ? { ...config2.header } : {};
|
|
5983
|
+
const navigation = Array.isArray(header.navigation) ? [...header.navigation] : [];
|
|
5984
|
+
if (navigation.some(isPricingItem)) {
|
|
5985
|
+
return { ...config2, header: { ...header, navigation } };
|
|
5986
|
+
}
|
|
5987
|
+
const pricingItem = {
|
|
5988
|
+
label: HEADER_PRICING_LABEL,
|
|
5989
|
+
to: HEADER_PRICING_PATH
|
|
5990
|
+
};
|
|
5991
|
+
const insertAt = docsInsertIndex(navigation);
|
|
5992
|
+
if (insertAt >= 0) {
|
|
5993
|
+
navigation.splice(insertAt, 0, pricingItem);
|
|
5994
|
+
} else {
|
|
5995
|
+
navigation.push(pricingItem);
|
|
5996
|
+
}
|
|
5997
|
+
return { ...config2, header: { ...header, navigation } };
|
|
5998
|
+
}
|
|
5999
|
+
|
|
5967
6000
|
// src/cli/platform/helpers/dev-portal-landing.ts
|
|
5968
6001
|
function readLandingFromConfig(config2) {
|
|
5969
6002
|
const modules = config2.modules;
|
|
@@ -6038,6 +6071,10 @@ function applyPlansToUserPanel(config2, plans, pricingEnabled) {
|
|
|
6038
6071
|
modules.userPanel = userPanel;
|
|
6039
6072
|
config2.modules = modules;
|
|
6040
6073
|
delete config2.plans;
|
|
6074
|
+
if (plans.length > 0) {
|
|
6075
|
+
const withPricingNav = ensureHeaderPricingNavigation(config2);
|
|
6076
|
+
config2.header = withPricingNav.header;
|
|
6077
|
+
}
|
|
6041
6078
|
}
|
|
6042
6079
|
function applyPricingToUserPanel(config2, pricing) {
|
|
6043
6080
|
if (pricing?.enabled === void 0) {
|
|
@@ -8095,11 +8132,18 @@ function buildPostPublishChecklist(args) {
|
|
|
8095
8132
|
},
|
|
8096
8133
|
{
|
|
8097
8134
|
id: "test_pricing",
|
|
8098
|
-
label: "Verify /pricing loads
|
|
8135
|
+
label: "Verify /pricing loads the public catalog (does not redirect to /account/plans)",
|
|
8099
8136
|
required: true,
|
|
8100
8137
|
completed: false,
|
|
8101
8138
|
url: args.swaUrl ? `${args.swaUrl}/pricing` : void 0
|
|
8102
8139
|
},
|
|
8140
|
+
{
|
|
8141
|
+
id: "test_account_plans",
|
|
8142
|
+
label: "Verify /account/plans requires sign-in and manages subscriptions",
|
|
8143
|
+
required: true,
|
|
8144
|
+
completed: false,
|
|
8145
|
+
url: args.swaUrl ? `${args.swaUrl}/account/plans` : void 0
|
|
8146
|
+
},
|
|
8103
8147
|
{
|
|
8104
8148
|
id: "test_credentials",
|
|
8105
8149
|
label: "Verify /credentials returns a subscription key after plan selection",
|
|
@@ -12493,7 +12537,7 @@ import {
|
|
|
12493
12537
|
// package.json
|
|
12494
12538
|
var package_default = {
|
|
12495
12539
|
name: "@lukoweb/apitogo",
|
|
12496
|
-
version: "0.1.
|
|
12540
|
+
version: "0.1.91",
|
|
12497
12541
|
type: "module",
|
|
12498
12542
|
sideEffects: [
|
|
12499
12543
|
"**/*.css",
|
|
@@ -18944,14 +18988,14 @@ var APITOGO_JSON_FILENAME = "apitogo.config.json";
|
|
|
18944
18988
|
var DOCUMENTATION_NAV_LABEL2 = "Documentation";
|
|
18945
18989
|
var API_REFERENCE_PATH = "/api";
|
|
18946
18990
|
var API_REFERENCE_LABEL = "API Reference";
|
|
18947
|
-
function
|
|
18991
|
+
function isPlainObject3(value) {
|
|
18948
18992
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
18949
18993
|
}
|
|
18950
18994
|
function deepMerge(target, source) {
|
|
18951
18995
|
const result = { ...target };
|
|
18952
18996
|
for (const [key, value] of Object.entries(source)) {
|
|
18953
18997
|
const existing = result[key];
|
|
18954
|
-
if (
|
|
18998
|
+
if (isPlainObject3(existing) && isPlainObject3(value)) {
|
|
18955
18999
|
result[key] = deepMerge(existing, value);
|
|
18956
19000
|
} else {
|
|
18957
19001
|
result[key] = value;
|
|
@@ -18969,7 +19013,7 @@ function parseJsonObjectFlag(raw, flagName) {
|
|
|
18969
19013
|
} catch {
|
|
18970
19014
|
throw new Error(`--${flagName} must be a JSON object.`);
|
|
18971
19015
|
}
|
|
18972
|
-
if (!
|
|
19016
|
+
if (!isPlainObject3(parsed)) {
|
|
18973
19017
|
throw new Error(`--${flagName} must be a JSON object.`);
|
|
18974
19018
|
}
|
|
18975
19019
|
return parsed;
|
|
@@ -19138,24 +19182,24 @@ function applyConfigPatches(config2, patches) {
|
|
|
19138
19182
|
let next = { ...config2 };
|
|
19139
19183
|
if (patches.site) {
|
|
19140
19184
|
next.site = deepMerge(
|
|
19141
|
-
|
|
19185
|
+
isPlainObject3(next.site) ? next.site : {},
|
|
19142
19186
|
patches.site
|
|
19143
19187
|
);
|
|
19144
19188
|
}
|
|
19145
19189
|
if (patches.theme) {
|
|
19146
19190
|
next.theme = deepMerge(
|
|
19147
|
-
|
|
19191
|
+
isPlainObject3(next.theme) ? next.theme : {},
|
|
19148
19192
|
patches.theme
|
|
19149
19193
|
);
|
|
19150
19194
|
}
|
|
19151
19195
|
if (patches.authentication) {
|
|
19152
19196
|
next.authentication = deepMerge(
|
|
19153
|
-
|
|
19197
|
+
isPlainObject3(next.authentication) ? next.authentication : {},
|
|
19154
19198
|
patches.authentication
|
|
19155
19199
|
);
|
|
19156
19200
|
}
|
|
19157
19201
|
if (patches.title?.trim()) {
|
|
19158
|
-
const site =
|
|
19202
|
+
const site = isPlainObject3(next.site) ? next.site : {};
|
|
19159
19203
|
next.site = { ...site, title: patches.title.trim() };
|
|
19160
19204
|
}
|
|
19161
19205
|
return next;
|
|
@@ -19334,9 +19378,9 @@ function applyPlansToJsonConfig(config2, planItems) {
|
|
|
19334
19378
|
if (planItems.length === 0) {
|
|
19335
19379
|
return config2;
|
|
19336
19380
|
}
|
|
19337
|
-
const modules =
|
|
19338
|
-
const userPanel =
|
|
19339
|
-
const plans =
|
|
19381
|
+
const modules = isPlainObject3(config2.modules) ? { ...config2.modules } : {};
|
|
19382
|
+
const userPanel = isPlainObject3(modules.userPanel) ? { ...modules.userPanel } : {};
|
|
19383
|
+
const plans = isPlainObject3(userPanel.plans) ? { ...userPanel.plans } : {};
|
|
19340
19384
|
const existing = Array.isArray(plans.items) ? [...plans.items] : [];
|
|
19341
19385
|
for (const item of planItems) {
|
|
19342
19386
|
const sku = item.sku;
|
|
@@ -19353,7 +19397,7 @@ function applyPlansToJsonConfig(config2, planItems) {
|
|
|
19353
19397
|
items: existing
|
|
19354
19398
|
};
|
|
19355
19399
|
modules.userPanel = userPanel;
|
|
19356
|
-
return { ...config2, modules };
|
|
19400
|
+
return ensureHeaderPricingNavigation({ ...config2, modules });
|
|
19357
19401
|
}
|
|
19358
19402
|
var BACKEND_RUNTIMES = ["dotnet", "nodejs", "python"];
|
|
19359
19403
|
var RUNTIME_VERSIONS_BY_RUNTIME = {
|
|
@@ -19383,7 +19427,7 @@ function parseRuntimeVersion(runtime, raw) {
|
|
|
19383
19427
|
return allowed.includes(value) ? value : null;
|
|
19384
19428
|
}
|
|
19385
19429
|
function applyBackendToJsonConfig(config2, backend) {
|
|
19386
|
-
const existing =
|
|
19430
|
+
const existing = isPlainObject3(config2.backend) ? config2.backend : {};
|
|
19387
19431
|
return {
|
|
19388
19432
|
...config2,
|
|
19389
19433
|
backend: {
|
|
@@ -19973,7 +20017,7 @@ var fileExists3 = async (filePath) => {
|
|
|
19973
20017
|
var readJsonConfig = async (filePath) => {
|
|
19974
20018
|
const raw = await readFile16(filePath, "utf8");
|
|
19975
20019
|
const parsed = JSON.parse(raw);
|
|
19976
|
-
if (!
|
|
20020
|
+
if (!isPlainObject3(parsed)) {
|
|
19977
20021
|
throw new Error(`${APITOGO_JSON_FILENAME} must be a JSON object.`);
|
|
19978
20022
|
}
|
|
19979
20023
|
return parsed;
|
|
@@ -20036,11 +20080,11 @@ function mergeBackendFlag(config2, backend) {
|
|
|
20036
20080
|
const { modules: modulesPatch, ...backendFields } = backend;
|
|
20037
20081
|
let next = { ...config2 };
|
|
20038
20082
|
if (Object.keys(backendFields).length > 0) {
|
|
20039
|
-
const existing =
|
|
20083
|
+
const existing = isPlainObject3(next.backend) ? next.backend : {};
|
|
20040
20084
|
next = { ...next, backend: deepMerge(existing, backendFields) };
|
|
20041
20085
|
}
|
|
20042
|
-
if (
|
|
20043
|
-
const existingModules =
|
|
20086
|
+
if (isPlainObject3(modulesPatch)) {
|
|
20087
|
+
const existingModules = isPlainObject3(next.modules) ? next.modules : {};
|
|
20044
20088
|
next = { ...next, modules: deepMerge(existingModules, modulesPatch) };
|
|
20045
20089
|
}
|
|
20046
20090
|
return next;
|
|
@@ -6,7 +6,11 @@ description:
|
|
|
6
6
|
behavior.
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
**Gateway plans** (also called API plans) are what your **end users** subscribe to
|
|
9
|
+
**Gateway plans** (also called API plans) are what your **end users** subscribe to.
|
|
10
|
+
|
|
11
|
+
- **`/pricing`** — public catalog. Visitors choose a plan before signup. Signed-in users still see this page; it must not redirect to `/account/plans`.
|
|
12
|
+
- **`/account/plans`** — authenticated billing. Sign-in required. Manage and change subscriptions.
|
|
13
|
+
|
|
10
14
|
They are separate from **platform hosting** (Free / Starter / Professional on APItoGo), which you
|
|
11
15
|
select with `apitogo apply --platform-plan`.
|
|
12
16
|
|
package/package.json
CHANGED
|
@@ -27,10 +27,9 @@ export function withoutPricingHeaderNavigation(
|
|
|
27
27
|
);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
/** Strip auth CTAs (Login/Signup) that have dedicated header buttons. Keep Pricing. */
|
|
30
31
|
export function withoutMarketingCtaHeaderNavigation(
|
|
31
32
|
navigation: HeaderNavigation,
|
|
32
33
|
): HeaderNavigation {
|
|
33
|
-
return
|
|
34
|
-
withoutAuthHeaderNavigation(navigation),
|
|
35
|
-
);
|
|
34
|
+
return withoutAuthHeaderNavigation(navigation);
|
|
36
35
|
}
|