@lukoweb/apitogo 0.2.31 → 0.2.35
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 +440 -153
- package/dist/declarations/app/entry.server.d.ts +2 -2
- package/dist/declarations/app/main.d.ts +3 -1
- package/dist/declarations/cli/platform/client/platform-api.d.ts +0 -4
- package/dist/declarations/cli/platform/helpers/deploy-artifact-hash.d.ts +1 -1
- package/dist/declarations/cli/platform/helpers/package-files.d.ts +1 -1
- package/dist/declarations/cli/platform/helpers/zip.d.ts +1 -1
- package/dist/declarations/cli/platform/tools/infrastructure.d.ts +0 -4
- package/dist/declarations/config/effective-redirects.d.ts +6 -0
- package/dist/declarations/config/header-navigation-guard.d.ts +2 -0
- package/dist/declarations/config/resolve-modules.d.ts +1 -4
- package/dist/declarations/config/validators/HeaderNavigationSchema.d.ts +1 -2
- package/docs/cli/commands.md +19 -0
- package/docs/configuration/gateway.md +52 -0
- package/docs/guides/customer-account.md +11 -1
- package/docs/mcp/tools.md +101 -102
- package/package.json +2 -1
- package/src/app/demo.tsx +78 -77
- package/src/app/entry.client.tsx +115 -107
- package/src/app/entry.server.tsx +164 -160
- package/src/app/main.tsx +175 -167
- package/src/app/standalone.tsx +61 -60
- package/src/config/effective-redirects.ts +31 -0
- package/src/config/header-navigation-guard.ts +13 -0
- package/src/config/resolve-modules.ts +331 -354
- package/src/config/v2/home-redirect.ts +104 -98
- package/src/config/v2/index.ts +127 -126
- package/src/config/v2/ledger.ts +242 -235
- package/src/config/v2/resolve.ts +12 -4
- package/src/config/v2/rules.ts +716 -714
- package/src/config/v2/services.ts +799 -663
- package/src/config/v2/workspace.ts +17 -1
- package/src/config/validators/HeaderNavigationSchema.ts +42 -44
- package/src/lib/assets/powered-by-icon.png +0 -0
- package/src/lib/authentication/providers/dev-portal-auth-pages.tsx +667 -602
- package/src/lib/authentication/providers/dev-portal.tsx +476 -448
- package/src/lib/components/HeaderNavigation.tsx +176 -176
- package/src/lib/components/MobileTopNavigation.tsx +283 -283
- package/src/lib/components/navigation/PoweredByZudoku.tsx +42 -39
- package/src/vite/plugin-offroot-resolve.ts +68 -67
- package/src/vite/prerender/prerender.ts +242 -242
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type RouteObject } from "react-router";
|
|
2
2
|
import "vite/modulepreload-polyfill";
|
|
3
|
-
import {
|
|
4
|
-
export
|
|
3
|
+
import type { ApitogoConfig } from "../config/config.js";
|
|
4
|
+
export declare const getRoutesByConfig: (config: ApitogoConfig) => RouteObject[];
|
|
5
5
|
export declare const handleRequest: ({ template, request, routes, basePath, bypassProtection, }: {
|
|
6
6
|
template: string;
|
|
7
7
|
request: Request;
|
|
@@ -2,6 +2,7 @@ import type { RouteObject } from "react-router";
|
|
|
2
2
|
import type { HighlighterCore } from "shiki";
|
|
3
3
|
import "virtual:zudoku-theme.css";
|
|
4
4
|
import type { ApitogoConfig } from "../config/config.js";
|
|
5
|
+
import type { ResolvedModulesConfig } from "../config/validators/ModulesSchema.js";
|
|
5
6
|
import "./main.css";
|
|
6
7
|
import "./polyfills.js";
|
|
7
8
|
import type { ZudokuContextOptions } from "../lib/core/ZudokuContext.js";
|
|
@@ -99,4 +100,5 @@ export declare const getRoutesByOptions: (options: ZudokuContextOptions, enableS
|
|
|
99
100
|
ErrorBoundary?: (() => Promise<import("react").ComponentType<{}> | null | undefined>) | undefined;
|
|
100
101
|
}) | import("react-router").LazyRouteFunction<RouteObject>;
|
|
101
102
|
})[];
|
|
102
|
-
export
|
|
103
|
+
export type ModulesResolver = (config: ApitogoConfig) => ResolvedModulesConfig;
|
|
104
|
+
export declare const getRoutesByConfig: (config: ApitogoConfig, resolveModules: ModulesResolver) => RouteObject[];
|
|
@@ -206,9 +206,6 @@ export interface CheckoutSessionResponse {
|
|
|
206
206
|
url: string | null;
|
|
207
207
|
granted?: boolean;
|
|
208
208
|
}
|
|
209
|
-
export interface DeploymentTokenResponse {
|
|
210
|
-
token: string;
|
|
211
|
-
}
|
|
212
209
|
export interface ProvisioningJobListItemDto {
|
|
213
210
|
id: string;
|
|
214
211
|
resourceType: string;
|
|
@@ -538,7 +535,6 @@ export declare class PlatformApiClient {
|
|
|
538
535
|
retryAzureInfrastructure(projectId: string): Promise<StartDeployResponse>;
|
|
539
536
|
getAzureInfrastructureDeployStatus(projectId: string, jobId: string): Promise<DeployStatusResponse>;
|
|
540
537
|
listProvisioningJobs(projectId: string): Promise<ProvisioningJobListResponse>;
|
|
541
|
-
getDeploymentToken(projectId: string, regenerate?: boolean): Promise<DeploymentTokenResponse>;
|
|
542
538
|
uploadStaticWebDeployment(projectId: string, archivePath: string, env?: string): Promise<StaticWebSiteDeploymentDto>;
|
|
543
539
|
listSecrets(projectId: string): Promise<ProjectSecretListResponse>;
|
|
544
540
|
setSecret(projectId: string, name: string, value: string): Promise<SetProjectSecretResponse>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare function sha256File(filePath: string): Promise<string>;
|
|
2
2
|
export declare function sha256Buffer(data: Buffer | string): Promise<string>;
|
|
3
|
-
export declare function hashDirectoryContents(rootDirectory: string): Promise<string>;
|
|
3
|
+
export declare function hashDirectoryContents(rootDirectory: string, extraExcludes?: readonly string[]): Promise<string>;
|
|
4
4
|
export declare function hashDevPortalSiteSources(siteDirectory: string, options?: {
|
|
5
5
|
gatewayUrl?: string | null;
|
|
6
6
|
}): Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function collectPackageableFiles(sourceDirectory: string): Promise<string[]>;
|
|
1
|
+
export declare function collectPackageableFiles(sourceDirectory: string, extraExcludes?: readonly string[]): Promise<string[]>;
|
|
@@ -2,5 +2,5 @@ export interface PackageBackendResult {
|
|
|
2
2
|
zipPath: string;
|
|
3
3
|
byteSize: number;
|
|
4
4
|
}
|
|
5
|
-
export declare function packageBackendDirectory(sourceDirectory: string): Promise<PackageBackendResult>;
|
|
5
|
+
export declare function packageBackendDirectory(sourceDirectory: string, extraExcludes?: readonly string[]): Promise<PackageBackendResult>;
|
|
6
6
|
export declare function cleanupZip(zipPath: string): Promise<void>;
|
|
@@ -21,10 +21,6 @@ export declare function handleRetryAzureInfrastructure(client: PlatformApiClient
|
|
|
21
21
|
export declare function handleListProvisioningJobs(client: PlatformApiClient, config: ApitogoConfig, args: {
|
|
22
22
|
projectId?: string;
|
|
23
23
|
}): Promise<string>;
|
|
24
|
-
export declare function handleGetDeploymentToken(client: PlatformApiClient, config: ApitogoConfig, args: {
|
|
25
|
-
projectId?: string;
|
|
26
|
-
regenerate?: boolean;
|
|
27
|
-
}): Promise<string>;
|
|
28
24
|
export declare function handleGetCustomDomain(client: PlatformApiClient, config: ApitogoConfig, args: {
|
|
29
25
|
projectId?: string;
|
|
30
26
|
}): Promise<string>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ResolvedModulesConfig } from "./validators/ModulesSchema.js";
|
|
2
|
+
import type { ZudokuConfig } from "./validators/ZudokuConfig.js";
|
|
3
|
+
export declare const getEffectiveRedirects: (config: ZudokuConfig, resolved: ResolvedModulesConfig) => {
|
|
4
|
+
from: string;
|
|
5
|
+
to: string;
|
|
6
|
+
}[];
|
|
@@ -8,10 +8,7 @@ export declare const resolveDashboardContent: (content?: DashboardContentConfig)
|
|
|
8
8
|
export declare const resolveProfileContent: (content?: ProfileContentConfig) => ResolvedProfileContent;
|
|
9
9
|
export declare const resolvePlansContent: (content?: PlansContentConfig) => ResolvedPlansContent;
|
|
10
10
|
export declare const resolveModulesConfig: (config: ZudokuConfig) => ResolvedModulesConfig;
|
|
11
|
-
export
|
|
12
|
-
from: string;
|
|
13
|
-
to: string;
|
|
14
|
-
}[];
|
|
11
|
+
export { getEffectiveRedirects } from "./effective-redirects.js";
|
|
15
12
|
export declare const getEffectiveDocsConfig: (_config: ZudokuConfig, resolved: ResolvedModulesConfig) => {
|
|
16
13
|
files: string | string[];
|
|
17
14
|
publishMarkdown: boolean;
|
|
@@ -15800,9 +15800,8 @@ export declare const HeaderNavigationSchema: z.ZodArray<z.ZodUnion<readonly [z.Z
|
|
|
15800
15800
|
}, z.core.$strip>>;
|
|
15801
15801
|
}, z.core.$strip>]>>;
|
|
15802
15802
|
}, z.core.$strip>]>>;
|
|
15803
|
-
export
|
|
15803
|
+
export { isHeaderNavGroup } from "../header-navigation-guard.js";
|
|
15804
15804
|
export type HeaderNavLinkItem = z.infer<typeof HeaderNavLinkItemSchema>;
|
|
15805
15805
|
export type HeaderNavGroup = z.infer<typeof HeaderNavGroupSchema>;
|
|
15806
15806
|
export type HeaderNavItem = z.infer<typeof HeaderNavItemSchema>;
|
|
15807
15807
|
export type HeaderNavigation = z.infer<typeof HeaderNavigationSchema>;
|
|
15808
|
-
export {};
|
package/docs/cli/commands.md
CHANGED
|
@@ -58,6 +58,25 @@ See [Make config (CLI)](../configuration/make-config.mdx) for all `config` flags
|
|
|
58
58
|
|
|
59
59
|
Env: `APITOGO_API_KEY_ID`, `APITOGO_API_SECRET`. Optional: `APITOGO_API_URL`.
|
|
60
60
|
|
|
61
|
+
## Config version 2: add a service
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npx apitogo add gateway
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`add` puts one service (`portal`, `gateway`, `identity` or `plans`) into `apitogo.config.json`. In a
|
|
68
|
+
terminal it **asks** for what you did not pass as a flag: for the gateway how it reaches your API
|
|
69
|
+
(an address you host, or code the platform runs, with the folder, runtime and version) and which
|
|
70
|
+
OpenAPI file to use. For an OIDC identity it asks for the issuer, and for external docs the address
|
|
71
|
+
of the docs site. It shows the change and asks before it writes.
|
|
72
|
+
|
|
73
|
+
Some services need another one. `plans` needs the gateway and an identity source, and a portal that
|
|
74
|
+
requires login needs an identity source. `add` then offers to add the missing service first, asks
|
|
75
|
+
for its values, and goes on with the one you named.
|
|
76
|
+
|
|
77
|
+
With `--yes`, `--json` or without a terminal it never asks: a missing value is an error that names
|
|
78
|
+
the flag to pass, and `--dry-run` shows the change without writing it.
|
|
79
|
+
|
|
61
80
|
## Config version 2: create the project, then deploy
|
|
62
81
|
|
|
63
82
|
```bash
|
|
@@ -194,6 +194,53 @@ npx apitogo secrets set GATEWAY_SECRET
|
|
|
194
194
|
The value is a reference, never the secret itself. The secret is stored encrypted and never shown
|
|
195
195
|
again. Then make your API refuse any call without that header.
|
|
196
196
|
|
|
197
|
+
## Run your API on the platform (`managed` origin)
|
|
198
|
+
|
|
199
|
+
If you have no place to host your API, the platform can run your code. Set the origin mode to
|
|
200
|
+
`managed` and point `source` at the folder with your code:
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
"gateway": {
|
|
204
|
+
"origin": {
|
|
205
|
+
"mode": "managed",
|
|
206
|
+
"source": "backend",
|
|
207
|
+
"runtime": "nodejs",
|
|
208
|
+
"runtimeVersion": "NODE_22_LTS",
|
|
209
|
+
"healthPath": "/health",
|
|
210
|
+
"exclude": ["tests/"]
|
|
211
|
+
},
|
|
212
|
+
"specs": ["openapi.json"]
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
| Field | Meaning |
|
|
217
|
+
| ---------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
218
|
+
| `source` | Folder with your code, relative to the config. Files in its `.gitignore` and in `exclude` are not uploaded. |
|
|
219
|
+
| `runtime` | `nodejs`, `python` or `dotnet`. |
|
|
220
|
+
| `runtimeVersion` | For example `NODE_22_LTS`. The platform lists the allowed values. |
|
|
221
|
+
| `healthPath` | Path the platform probes to check that your API is up. |
|
|
222
|
+
| `exclude` | More paths to leave out, in `.gitignore` syntax. |
|
|
223
|
+
|
|
224
|
+
`npx apitogo project create` prepares the hosting for your code. `npx apitogo deploy` then uploads
|
|
225
|
+
the OpenAPI file and the config, uploads your code and waits until it runs, and the gateway starts
|
|
226
|
+
sending calls to it. A deploy with the same code uploads nothing. A .NET project is published for
|
|
227
|
+
you (this needs the .NET SDK on your machine), or you can point `source` at a folder that is already
|
|
228
|
+
published.
|
|
229
|
+
|
|
230
|
+
Your code can also be reached by its own address, so check that a call came through the gateway. The
|
|
231
|
+
platform gives your code two settings for this: `APITOGO_ORIGIN_SECRET_HEADER` (the header name) and
|
|
232
|
+
`APITOGO_ORIGIN_SECRET` (the value). The gateway sends that header with every call. Refuse any
|
|
233
|
+
request without it, as in
|
|
234
|
+
[Keep your API from being called directly](#keep-your-api-from-being-called-directly):
|
|
235
|
+
|
|
236
|
+
```js
|
|
237
|
+
const header = process.env.APITOGO_ORIGIN_SECRET_HEADER.toLowerCase();
|
|
238
|
+
if (req.headers[header] !== process.env.APITOGO_ORIGIN_SECRET) {
|
|
239
|
+
res.writeHead(403).end();
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
197
244
|
## 4. Try it and check it
|
|
198
245
|
|
|
199
246
|
Run these before you deploy:
|
|
@@ -219,3 +266,8 @@ curl -i https://YOUR-GATEWAY-ADDRESS/orders
|
|
|
219
266
|
| `404` | The path is not in your OpenAPI file. |
|
|
220
267
|
| `429` | The rate limit was reached. |
|
|
221
268
|
| `502` or `504` | Your API did not answer. Check `origin.url` and `healthPath`. |
|
|
269
|
+
|
|
270
|
+
A change is live a few seconds after `deploy` reports it ready: the gateway keeps answering with the
|
|
271
|
+
previous rules for up to about ten seconds. If a test right after a deploy shows the old behavior,
|
|
272
|
+
wait a moment and try again. The same delay applies when you remove a gateway: its keys stop working
|
|
273
|
+
within seconds, not at the same instant.
|
|
@@ -47,8 +47,18 @@ If a payment fails, Stripe retries it. The subscription shows as past due. When
|
|
|
47
47
|
cancels it, the plan ends and its keys stop working with `401`. The customer is not moved to a free
|
|
48
48
|
plan on their own. They can subscribe to one on the **Plans** page.
|
|
49
49
|
|
|
50
|
+
## Cancelling and refunds
|
|
51
|
+
|
|
52
|
+
- **The customer cancels** on the **Plans** page. The subscription ends in Stripe at once, the plan
|
|
53
|
+
ends and the customer's keys stop working with `401`.
|
|
54
|
+
- **You cancel** a subscription in your Stripe dashboard. Stripe tells the portal, and the plan ends
|
|
55
|
+
the same way.
|
|
56
|
+
- **A refund** is made in your Stripe dashboard. A refund alone does not end the plan: the customer
|
|
57
|
+
keeps the key until the subscription is cancelled. Cancel it as well if the customer should lose
|
|
58
|
+
access. The portal has no refund screen.
|
|
59
|
+
|
|
50
60
|
What you see is in your own Stripe account: payments, customers and refunds. APItoGo does not take a
|
|
51
|
-
share and does not issue refunds. Tax
|
|
61
|
+
share and does not issue refunds. Tax and trials are not handled by the portal.
|
|
52
62
|
|
|
53
63
|
## API keys
|
|
54
64
|
|
package/docs/mcp/tools.md
CHANGED
|
@@ -1,102 +1,101 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: MCP tools
|
|
3
|
-
description: APItoGo MCP tool catalog by category and hand-edit exceptions.
|
|
4
|
-
sidebar_icon: wrench
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Tools are exposed by the APItoGo MCP server. Prefer **`apply_product_intent`** for create / shape /
|
|
8
|
-
go-live. Use granular tools for advanced edits, debugging, or CI.
|
|
9
|
-
|
|
10
|
-
## Lifecycle (prefer these)
|
|
11
|
-
|
|
12
|
-
| Tool | Role |
|
|
13
|
-
| ------------------------------------ | ---------------------------------------------- |
|
|
14
|
-
| `apply_product_intent` | Shape or goLive from a product intent |
|
|
15
|
-
| `create_dev_portal` | Scaffold site (+ optional project bootstrap) |
|
|
16
|
-
| `check_dev_portal_publish_readiness` | Pre-publish checklist |
|
|
17
|
-
| `publish_dev_portal` | Publish portal + plans (+ optional backend) |
|
|
18
|
-
| `verify_dev_portal_live` | Post-publish verification |
|
|
19
|
-
| `bootstrap_dev_portal` | CI one-shot provision + deploy |
|
|
20
|
-
| `bootstrap_project` | Create platform project only (plan unselected) |
|
|
21
|
-
| `teardown_project` | Tear down a project |
|
|
22
|
-
|
|
23
|
-
## Site shaping
|
|
24
|
-
|
|
25
|
-
| Tool | Role |
|
|
26
|
-
| ---------------------------------- | ------------------------------------------------------------------------- |
|
|
27
|
-
| `update_dev_portal_manifest` | Plans, branding, backend, projectId |
|
|
28
|
-
| `set_dev_portal_openapi` | OpenAPI / API reference |
|
|
29
|
-
| `set_dev_portal_theme` | Colors and fonts |
|
|
30
|
-
| `add_dev_portal_page` | Add a TSX docs page (site components; `template`: docs\|guide\|marketing) |
|
|
31
|
-
| `update_dev_portal_page` | Edit a docs page |
|
|
32
|
-
| `scaffold_dev_portal_landing_page` | Scaffold missing landing file |
|
|
33
|
-
| `get_dev_portal_landing_guide` | Landing component catalog |
|
|
34
|
-
| `preview_dev_portal_site` | Start / restart local preview |
|
|
35
|
-
| `build_dev_portal_site` | Production build |
|
|
36
|
-
|
|
37
|
-
Hosted page CRUD also exists (`list/create/delete/rename/reorder_dev_portal_pages`) for the platform
|
|
38
|
-
API surface.
|
|
39
|
-
|
|
40
|
-
## Projects and platform billing
|
|
41
|
-
|
|
42
|
-
| Tool | Role |
|
|
43
|
-
| ------------------------------------------- | ------------------------------------- |
|
|
44
|
-
| `whoami`, `list_projects`, `get_project`, … | Tenant / project CRUD |
|
|
45
|
-
| `list_platform_plans` | Free / Starter / Professional + quota |
|
|
46
|
-
| `ensure_platform_plan` | Select or checkout platform plan |
|
|
47
|
-
| `wait_for_platform_plan` | Poll until active |
|
|
48
|
-
| `get_subscription` | Current subscription |
|
|
49
|
-
| `select_free_plan` | Free hosting |
|
|
50
|
-
| `create_checkout_session` | Stripe checkout for paid hosting |
|
|
51
|
-
|
|
52
|
-
## Backend and OpenAPI
|
|
53
|
-
|
|
54
|
-
| Tool | Role |
|
|
55
|
-
| ----------------------- | ------------------------ |
|
|
56
|
-
| `validate_openapi` | Validate OpenAPI |
|
|
57
|
-
| `update_openapi` | Update stored OpenAPI |
|
|
58
|
-
| `package_backend` | Package backend artifact |
|
|
59
|
-
| `deploy_backend` | Deploy API hub |
|
|
60
|
-
| `get_backend_summary` | Backend status |
|
|
61
|
-
| `get_deployment_status` | Deployment job status |
|
|
62
|
-
| `get_gateway_readiness` | Gateway readiness |
|
|
63
|
-
|
|
64
|
-
## Gateway
|
|
65
|
-
|
|
66
|
-
| Tool | Role |
|
|
67
|
-
| ------------------------------------------------------------------ | ------------------------ |
|
|
68
|
-
| `list/get/create/update/patch_gateway_plan` | Plan CRUD |
|
|
69
|
-
| `add_actions_to_gateway_plan` / `remove_actions_from_gateway_plan` | Attach ops |
|
|
70
|
-
| `set_action_public` | Public routes |
|
|
71
|
-
| `upsert_entitlement` | Entitlements |
|
|
72
|
-
| `configure_gateway_baseline` | Baseline policies |
|
|
73
|
-
| `get/update_gateway_settings` | Settings |
|
|
74
|
-
| `get/update_gateway_auth` | Gateway auth |
|
|
75
|
-
| `sync_gateway_plans_from_manifest` | Post-publish action sync |
|
|
76
|
-
| `reorder_gateway_plans_from_manifest` | Plan order |
|
|
77
|
-
|
|
78
|
-
## Infrastructure and deploy
|
|
79
|
-
|
|
80
|
-
| Tool | Role |
|
|
81
|
-
| ------------------------------------------------------ | ---------------- |
|
|
82
|
-
| `activate_module` | Activate modules |
|
|
83
|
-
| `get_infrastructure_status` / Azure variants | Infra status |
|
|
84
|
-
| `list_provisioning_jobs`, `wait_for_job` | Jobs |
|
|
85
|
-
| `
|
|
86
|
-
| `
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
|
92
|
-
|
|
|
93
|
-
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
- [
|
|
101
|
-
- [
|
|
102
|
-
- [Go live](./go-live.md)
|
|
1
|
+
---
|
|
2
|
+
title: MCP tools
|
|
3
|
+
description: APItoGo MCP tool catalog by category and hand-edit exceptions.
|
|
4
|
+
sidebar_icon: wrench
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Tools are exposed by the APItoGo MCP server. Prefer **`apply_product_intent`** for create / shape /
|
|
8
|
+
go-live. Use granular tools for advanced edits, debugging, or CI.
|
|
9
|
+
|
|
10
|
+
## Lifecycle (prefer these)
|
|
11
|
+
|
|
12
|
+
| Tool | Role |
|
|
13
|
+
| ------------------------------------ | ---------------------------------------------- |
|
|
14
|
+
| `apply_product_intent` | Shape or goLive from a product intent |
|
|
15
|
+
| `create_dev_portal` | Scaffold site (+ optional project bootstrap) |
|
|
16
|
+
| `check_dev_portal_publish_readiness` | Pre-publish checklist |
|
|
17
|
+
| `publish_dev_portal` | Publish portal + plans (+ optional backend) |
|
|
18
|
+
| `verify_dev_portal_live` | Post-publish verification |
|
|
19
|
+
| `bootstrap_dev_portal` | CI one-shot provision + deploy |
|
|
20
|
+
| `bootstrap_project` | Create platform project only (plan unselected) |
|
|
21
|
+
| `teardown_project` | Tear down a project |
|
|
22
|
+
|
|
23
|
+
## Site shaping
|
|
24
|
+
|
|
25
|
+
| Tool | Role |
|
|
26
|
+
| ---------------------------------- | ------------------------------------------------------------------------- |
|
|
27
|
+
| `update_dev_portal_manifest` | Plans, branding, backend, projectId |
|
|
28
|
+
| `set_dev_portal_openapi` | OpenAPI / API reference |
|
|
29
|
+
| `set_dev_portal_theme` | Colors and fonts |
|
|
30
|
+
| `add_dev_portal_page` | Add a TSX docs page (site components; `template`: docs\|guide\|marketing) |
|
|
31
|
+
| `update_dev_portal_page` | Edit a docs page |
|
|
32
|
+
| `scaffold_dev_portal_landing_page` | Scaffold missing landing file |
|
|
33
|
+
| `get_dev_portal_landing_guide` | Landing component catalog |
|
|
34
|
+
| `preview_dev_portal_site` | Start / restart local preview |
|
|
35
|
+
| `build_dev_portal_site` | Production build |
|
|
36
|
+
|
|
37
|
+
Hosted page CRUD also exists (`list/create/delete/rename/reorder_dev_portal_pages`) for the platform
|
|
38
|
+
API surface.
|
|
39
|
+
|
|
40
|
+
## Projects and platform billing
|
|
41
|
+
|
|
42
|
+
| Tool | Role |
|
|
43
|
+
| ------------------------------------------- | ------------------------------------- |
|
|
44
|
+
| `whoami`, `list_projects`, `get_project`, … | Tenant / project CRUD |
|
|
45
|
+
| `list_platform_plans` | Free / Starter / Professional + quota |
|
|
46
|
+
| `ensure_platform_plan` | Select or checkout platform plan |
|
|
47
|
+
| `wait_for_platform_plan` | Poll until active |
|
|
48
|
+
| `get_subscription` | Current subscription |
|
|
49
|
+
| `select_free_plan` | Free hosting |
|
|
50
|
+
| `create_checkout_session` | Stripe checkout for paid hosting |
|
|
51
|
+
|
|
52
|
+
## Backend and OpenAPI
|
|
53
|
+
|
|
54
|
+
| Tool | Role |
|
|
55
|
+
| ----------------------- | ------------------------ |
|
|
56
|
+
| `validate_openapi` | Validate OpenAPI |
|
|
57
|
+
| `update_openapi` | Update stored OpenAPI |
|
|
58
|
+
| `package_backend` | Package backend artifact |
|
|
59
|
+
| `deploy_backend` | Deploy API hub |
|
|
60
|
+
| `get_backend_summary` | Backend status |
|
|
61
|
+
| `get_deployment_status` | Deployment job status |
|
|
62
|
+
| `get_gateway_readiness` | Gateway readiness |
|
|
63
|
+
|
|
64
|
+
## Gateway
|
|
65
|
+
|
|
66
|
+
| Tool | Role |
|
|
67
|
+
| ------------------------------------------------------------------ | ------------------------ |
|
|
68
|
+
| `list/get/create/update/patch_gateway_plan` | Plan CRUD |
|
|
69
|
+
| `add_actions_to_gateway_plan` / `remove_actions_from_gateway_plan` | Attach ops |
|
|
70
|
+
| `set_action_public` | Public routes |
|
|
71
|
+
| `upsert_entitlement` | Entitlements |
|
|
72
|
+
| `configure_gateway_baseline` | Baseline policies |
|
|
73
|
+
| `get/update_gateway_settings` | Settings |
|
|
74
|
+
| `get/update_gateway_auth` | Gateway auth |
|
|
75
|
+
| `sync_gateway_plans_from_manifest` | Post-publish action sync |
|
|
76
|
+
| `reorder_gateway_plans_from_manifest` | Plan order |
|
|
77
|
+
|
|
78
|
+
## Infrastructure and deploy
|
|
79
|
+
|
|
80
|
+
| Tool | Role |
|
|
81
|
+
| ------------------------------------------------------ | ---------------- |
|
|
82
|
+
| `activate_module` | Activate modules |
|
|
83
|
+
| `get_infrastructure_status` / Azure variants | Infra status |
|
|
84
|
+
| `list_provisioning_jobs`, `wait_for_job` | Jobs |
|
|
85
|
+
| `get/set/delete_custom_domain` | Custom domain |
|
|
86
|
+
| `get_dev_portal_deploy_config`, `deploy_dev_portal`, … | SWA deploy |
|
|
87
|
+
|
|
88
|
+
## Hand-edit exceptions
|
|
89
|
+
|
|
90
|
+
| Change | Where |
|
|
91
|
+
| ----------------- | -------------------------------------------------------- |
|
|
92
|
+
| Home page content | `landing/LandingPage.tsx` |
|
|
93
|
+
| Site footer | `apitogo.config.json` → `modules.landing.content.footer` |
|
|
94
|
+
|
|
95
|
+
There is **no** `update_dev_portal_landing` tool for arbitrary home content.
|
|
96
|
+
|
|
97
|
+
## Related
|
|
98
|
+
|
|
99
|
+
- [Overview](./overview.md)
|
|
100
|
+
- [Shape](./shape.md)
|
|
101
|
+
- [Go live](./go-live.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lukoweb/apitogo",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.35",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": [
|
|
6
6
|
"**/*.css",
|
|
@@ -171,6 +171,7 @@
|
|
|
171
171
|
"build": "esbuild src/cli/cli.ts src/vite/prerender/worker.ts --outdir=dist/cli --entry-names=[name] --bundle --format=esm --packages=external --target=node20 --platform=node --log-level=error",
|
|
172
172
|
"postbuild": "tsx scripts/check-external-deps.ts",
|
|
173
173
|
"typecheck": "tsc --project tsconfig.app.json --noEmit",
|
|
174
|
+
"test:e2e": "vitest run --config vitest.e2e.config.ts",
|
|
174
175
|
"generate:types": "tsx scripts/generate-types.js && tsx scripts/generate-flat-config.js",
|
|
175
176
|
"build:standalone": "vite build --mode standalone --config vite.standalone.config.ts --log-level=error",
|
|
176
177
|
"prepack": "npm run build && tsx scripts/generate-publish-exports.ts",
|
package/src/app/demo.tsx
CHANGED
|
@@ -1,77 +1,78 @@
|
|
|
1
|
-
import logger from "loglevel";
|
|
2
|
-
import { createRoot } from "react-dom/client";
|
|
3
|
-
import { createBrowserRouter } from "react-router";
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import "../lib/util/logInit.js";
|
|
8
|
-
import "./main.css";
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
// This
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
1
|
+
import logger from "loglevel";
|
|
2
|
+
import { createRoot } from "react-dom/client";
|
|
3
|
+
import { createBrowserRouter } from "react-router";
|
|
4
|
+
import { resolveModulesConfig } from "../config/resolve-modules.js";
|
|
5
|
+
import type { ZudokuConfig } from "../config/validators/ZudokuConfig.js";
|
|
6
|
+
import { Bootstrap } from "../lib/components/Bootstrap.js";
|
|
7
|
+
import "../lib/util/logInit.js";
|
|
8
|
+
import "./main.css";
|
|
9
|
+
import DemoAnnouncement from "../lib/demo/DemoAnnouncement.js";
|
|
10
|
+
import { openApiPlugin } from "../lib/plugins/openapi/index.js";
|
|
11
|
+
import { getRoutesByConfig } from "./main.js";
|
|
12
|
+
|
|
13
|
+
const apiUrl = new URL(window.location.href).searchParams.get("api-url");
|
|
14
|
+
const logoUrl = new URL(window.location.href).searchParams.get("logo-url");
|
|
15
|
+
const logoWidth = new URL(window.location.href).searchParams.get("logo-width");
|
|
16
|
+
const title =
|
|
17
|
+
new URL(window.location.href).searchParams.get("title") ?? "Zudoku Demo";
|
|
18
|
+
|
|
19
|
+
if (!apiUrl) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
"No API URL in query parameters. Please provide an API URL using the `api-url` query parameter.",
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
logger.info(`API URL: ${apiUrl}`);
|
|
26
|
+
|
|
27
|
+
const root =
|
|
28
|
+
document.getElementById("zudoku") ?? document.getElementById("root");
|
|
29
|
+
|
|
30
|
+
if (!root) {
|
|
31
|
+
throw new Error("No div found with id root");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// IMPORTANT: This component must not contain tailwind classes
|
|
35
|
+
// This directory is not processed by the tailwind plugin
|
|
36
|
+
|
|
37
|
+
const config: ZudokuConfig = {
|
|
38
|
+
site: {
|
|
39
|
+
title,
|
|
40
|
+
banner: {
|
|
41
|
+
message: <DemoAnnouncement />,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
navigation: [
|
|
45
|
+
{
|
|
46
|
+
type: "link",
|
|
47
|
+
to: "/",
|
|
48
|
+
label: "API Reference",
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
plugins: [
|
|
52
|
+
// Using the plugin directly because there's no config file to load in the virtual plugins
|
|
53
|
+
openApiPlugin({
|
|
54
|
+
type: "url",
|
|
55
|
+
input: apiUrl,
|
|
56
|
+
path: "/",
|
|
57
|
+
}),
|
|
58
|
+
],
|
|
59
|
+
} satisfies ZudokuConfig;
|
|
60
|
+
|
|
61
|
+
if (logoUrl && logoWidth) {
|
|
62
|
+
config.site = {
|
|
63
|
+
...config.site,
|
|
64
|
+
logo: {
|
|
65
|
+
src: {
|
|
66
|
+
light: logoUrl,
|
|
67
|
+
dark: logoUrl,
|
|
68
|
+
},
|
|
69
|
+
width: logoWidth,
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const routes = getRoutesByConfig(config, resolveModulesConfig);
|
|
75
|
+
const router = createBrowserRouter(routes, {
|
|
76
|
+
basename: window.location.pathname,
|
|
77
|
+
});
|
|
78
|
+
createRoot(root).render(<Bootstrap router={router} />);
|