@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 isPlainObject, mergeConfig, runPluginTransformConfig;
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
- isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
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) || !isPlainObject(sourceValue)) {
109
+ if (isValidElement(sourceValue) || Array.isArray(sourceValue) || !isPlainObject2(sourceValue)) {
110
110
  result[key] = sourceValue;
111
- } else if (isPlainObject(targetValue)) {
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 live plans",
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.89",
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 isPlainObject2(value) {
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 (isPlainObject2(existing) && isPlainObject2(value)) {
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 (!isPlainObject2(parsed)) {
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
- isPlainObject2(next.site) ? next.site : {},
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
- isPlainObject2(next.theme) ? next.theme : {},
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
- isPlainObject2(next.authentication) ? next.authentication : {},
19197
+ isPlainObject3(next.authentication) ? next.authentication : {},
19154
19198
  patches.authentication
19155
19199
  );
19156
19200
  }
19157
19201
  if (patches.title?.trim()) {
19158
- const site = isPlainObject2(next.site) ? next.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 = isPlainObject2(config2.modules) ? { ...config2.modules } : {};
19338
- const userPanel = isPlainObject2(modules.userPanel) ? { ...modules.userPanel } : {};
19339
- const plans = isPlainObject2(userPanel.plans) ? { ...userPanel.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 = isPlainObject2(config2.backend) ? config2.backend : {};
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 (!isPlainObject2(parsed)) {
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 = isPlainObject2(next.backend) ? next.backend : {};
20083
+ const existing = isPlainObject3(next.backend) ? next.backend : {};
20040
20084
  next = { ...next, backend: deepMerge(existing, backendFields) };
20041
20085
  }
20042
- if (isPlainObject2(modulesPatch)) {
20043
- const existingModules = isPlainObject2(next.modules) ? next.modules : {};
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;
@@ -0,0 +1,3 @@
1
+ export declare const HEADER_PRICING_PATH = "/pricing";
2
+ export declare const HEADER_PRICING_LABEL = "Pricing";
3
+ export declare function ensureHeaderPricingNavigation(config: Record<string, unknown>): Record<string, unknown>;
@@ -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 on `/pricing`.
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lukoweb/apitogo",
3
- "version": "0.1.89",
3
+ "version": "0.1.91",
4
4
  "type": "module",
5
5
  "sideEffects": [
6
6
  "**/*.css",
@@ -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 withoutPricingHeaderNavigation(
34
- withoutAuthHeaderNavigation(navigation),
35
- );
34
+ return withoutAuthHeaderNavigation(navigation);
36
35
  }