@lukoweb/apitogo 0.2.31 → 0.2.34

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.
Files changed (41) hide show
  1. package/dist/cli/cli.js +436 -153
  2. package/dist/declarations/app/entry.server.d.ts +2 -2
  3. package/dist/declarations/app/main.d.ts +3 -1
  4. package/dist/declarations/cli/platform/client/platform-api.d.ts +0 -4
  5. package/dist/declarations/cli/platform/helpers/deploy-artifact-hash.d.ts +1 -1
  6. package/dist/declarations/cli/platform/helpers/package-files.d.ts +1 -1
  7. package/dist/declarations/cli/platform/helpers/zip.d.ts +1 -1
  8. package/dist/declarations/cli/platform/tools/infrastructure.d.ts +0 -4
  9. package/dist/declarations/config/effective-redirects.d.ts +6 -0
  10. package/dist/declarations/config/header-navigation-guard.d.ts +2 -0
  11. package/dist/declarations/config/resolve-modules.d.ts +1 -4
  12. package/dist/declarations/config/validators/HeaderNavigationSchema.d.ts +1 -2
  13. package/docs/cli/commands.md +19 -0
  14. package/docs/configuration/gateway.md +52 -0
  15. package/docs/guides/customer-account.md +11 -1
  16. package/docs/mcp/tools.md +101 -102
  17. package/package.json +2 -1
  18. package/src/app/demo.tsx +78 -77
  19. package/src/app/entry.client.tsx +115 -107
  20. package/src/app/entry.server.tsx +164 -160
  21. package/src/app/main.tsx +175 -167
  22. package/src/app/standalone.tsx +61 -60
  23. package/src/config/effective-redirects.ts +31 -0
  24. package/src/config/header-navigation-guard.ts +13 -0
  25. package/src/config/resolve-modules.ts +331 -354
  26. package/src/config/v2/home-redirect.ts +104 -98
  27. package/src/config/v2/index.ts +127 -126
  28. package/src/config/v2/ledger.ts +242 -235
  29. package/src/config/v2/resolve.ts +12 -4
  30. package/src/config/v2/rules.ts +716 -714
  31. package/src/config/v2/services.ts +799 -663
  32. package/src/config/v2/workspace.ts +17 -1
  33. package/src/config/validators/HeaderNavigationSchema.ts +42 -44
  34. package/src/lib/assets/powered-by-icon.png +0 -0
  35. package/src/lib/authentication/providers/dev-portal-auth-pages.tsx +667 -602
  36. package/src/lib/authentication/providers/dev-portal.tsx +476 -448
  37. package/src/lib/components/HeaderNavigation.tsx +176 -176
  38. package/src/lib/components/MobileTopNavigation.tsx +283 -283
  39. package/src/lib/components/navigation/PoweredByZudoku.tsx +42 -39
  40. package/src/vite/plugin-offroot-resolve.ts +68 -67
  41. package/src/vite/prerender/prerender.ts +242 -242
@@ -1,98 +1,104 @@
1
- import path from "node:path";
2
- import { glob } from "glob";
3
- import globParent from "glob-parent";
4
- import { readFrontmatter } from "../../lib/util/readFrontmatter.js";
5
-
6
- export type HomeRedirect = { from: string; to: string };
7
-
8
- const IGNORED = ["**/node_modules/**", "**/dist/**", "**/.git/**"];
9
-
10
- /**
11
- * The routes the docs plugin gives the pages these globs match: the path inside the glob's folder, without the
12
- * extension. Missing folders and negated globs are fine, they just match nothing.
13
- */
14
- export async function docRoutes(
15
- patterns: string[],
16
- options: { includeDrafts?: boolean } = {},
17
- ): Promise<string[]> {
18
- const excluded = patterns
19
- .filter((pattern) => pattern.startsWith("!"))
20
- .map((pattern) => pattern.slice(1));
21
- const included = patterns.filter((pattern) => !pattern.startsWith("!"));
22
-
23
- const routes = await Promise.all(
24
- included.map(async (pattern) => {
25
- const files = await glob(pattern, {
26
- absolute: true,
27
- posix: true,
28
- ignore: [...IGNORED, ...excluded],
29
- });
30
- const parent = globParent(pattern);
31
- // The docs plugin leaves draft pages out of a production build, so the routes must too.
32
- const published = options.includeDrafts
33
- ? files
34
- : (
35
- await Promise.all(
36
- files.map(async (file) => ({
37
- file,
38
- draft: (await readFrontmatter(file)).data.draft === true,
39
- })),
40
- )
41
- )
42
- .filter(({ draft }) => !draft)
43
- .map(({ file }) => file);
44
- return published.map(
45
- (file) =>
46
- `/${path.posix.relative(parent, file).replace(/\.mdx?$/, "")}`,
47
- );
48
- }),
49
- );
50
- return [...new Set(routes.flat())].sort();
51
- }
52
-
53
- /** The page a visitor lands on when the site has no home page: the top-most page, then the first by name. */
54
- export function pickLandingRoute(routes: string[]): string | undefined {
55
- const depth = (route: string) => route.split("/").length;
56
- return [...routes].sort(
57
- (a, b) => depth(a) - depth(b) || a.localeCompare(b),
58
- )[0];
59
- }
60
-
61
- export type HomeRedirectInput = {
62
- /** APItoGo builds the docs pages. */
63
- hostsDocs: boolean;
64
- /** Routes of those pages (see `docRoutes`). */
65
- docRoutes: string[];
66
- /** Where the docs live when someone else hosts them. */
67
- externalDocsUrl?: string;
68
- /** The portal has an API reference page, at this path. */
69
- apiReferencePath?: string;
70
- /** The portal has console pages (sign-in, keys, plans). */
71
- userPanel: boolean;
72
- };
73
-
74
- /**
75
- * Where `/` should go when the portal has no page of its own there. Without this a visitor of the home page sees
76
- * "Page not found".
77
- *
78
- * - Hosted docs without an index page: the first page, so the team's own docs never need an extra file.
79
- * - Hosted docs without any page: the API reference, when there is one.
80
- * - External docs and no console: the external docs site, as the portal has nothing else to show.
81
- */
82
- export function homeRedirect(
83
- input: HomeRedirectInput,
84
- ): HomeRedirect | undefined {
85
- if (input.hostsDocs) {
86
- if (input.docRoutes.some((route) => route === "/" || route === "/index"))
87
- return undefined;
88
- const landing = pickLandingRoute(input.docRoutes);
89
- if (landing) return { from: "/", to: landing };
90
- return input.apiReferencePath
91
- ? { from: "/", to: input.apiReferencePath }
92
- : undefined;
93
- }
94
- if (input.externalDocsUrl && !input.userPanel) {
95
- return { from: "/", to: input.externalDocsUrl };
96
- }
97
- return undefined;
98
- }
1
+ import path from "node:path";
2
+ import { glob } from "glob";
3
+ import globParent from "glob-parent";
4
+ import { readFrontmatter } from "../../lib/util/readFrontmatter.js";
5
+ import { toGlobPath } from "./resolve.js";
6
+
7
+ export type HomeRedirect = { from: string; to: string };
8
+
9
+ const IGNORED = ["**/node_modules/**", "**/dist/**", "**/.git/**"];
10
+
11
+ /**
12
+ * The routes the docs plugin gives the pages these globs match: the path inside the glob's folder, without the
13
+ * extension. Missing folders and negated globs are fine, they just match nothing.
14
+ */
15
+ export async function docRoutes(
16
+ patterns: string[],
17
+ options: { includeDrafts?: boolean } = {},
18
+ ): Promise<string[]> {
19
+ // Windows paths use backslashes, which the glob library reads as escapes.
20
+ const globs = patterns.map(toGlobPath);
21
+ const excluded = globs
22
+ .filter((pattern) => pattern.startsWith("!"))
23
+ .map((pattern) => pattern.slice(1));
24
+ const included = globs.filter((pattern) => !pattern.startsWith("!"));
25
+
26
+ const routes = await Promise.all(
27
+ included.map(async (pattern) => {
28
+ const files = await glob(pattern, {
29
+ absolute: true,
30
+ posix: true,
31
+ ignore: [...IGNORED, ...excluded],
32
+ });
33
+ const parent = globParent(pattern);
34
+ // The docs plugin leaves draft pages out of a production build, so the routes must too.
35
+ const published = options.includeDrafts
36
+ ? files
37
+ : (
38
+ await Promise.all(
39
+ files.map(async (file) => ({
40
+ file,
41
+ draft: (await readFrontmatter(file)).data.draft === true,
42
+ })),
43
+ )
44
+ )
45
+ .filter(({ draft }) => !draft)
46
+ .map(({ file }) => file);
47
+ // On Windows the glob library answers with the extended form `//?/C:/...`, which would not relate to `parent`.
48
+ return published.map(
49
+ (file) =>
50
+ `/${path.posix
51
+ .relative(parent, file.replace(/^\/\/\?\//, ""))
52
+ .replace(/\.mdx?$/, "")}`,
53
+ );
54
+ }),
55
+ );
56
+ return [...new Set(routes.flat())].sort();
57
+ }
58
+
59
+ /** The page a visitor lands on when the site has no home page: the top-most page, then the first by name. */
60
+ export function pickLandingRoute(routes: string[]): string | undefined {
61
+ const depth = (route: string) => route.split("/").length;
62
+ return [...routes].sort(
63
+ (a, b) => depth(a) - depth(b) || a.localeCompare(b),
64
+ )[0];
65
+ }
66
+
67
+ export type HomeRedirectInput = {
68
+ /** APItoGo builds the docs pages. */
69
+ hostsDocs: boolean;
70
+ /** Routes of those pages (see `docRoutes`). */
71
+ docRoutes: string[];
72
+ /** Where the docs live when someone else hosts them. */
73
+ externalDocsUrl?: string;
74
+ /** The portal has an API reference page, at this path. */
75
+ apiReferencePath?: string;
76
+ /** The portal has console pages (sign-in, keys, plans). */
77
+ userPanel: boolean;
78
+ };
79
+
80
+ /**
81
+ * Where `/` should go when the portal has no page of its own there. Without this a visitor of the home page sees
82
+ * "Page not found".
83
+ *
84
+ * - Hosted docs without an index page: the first page, so the team's own docs never need an extra file.
85
+ * - Hosted docs without any page: the API reference, when there is one.
86
+ * - External docs and no console: the external docs site, as the portal has nothing else to show.
87
+ */
88
+ export function homeRedirect(
89
+ input: HomeRedirectInput,
90
+ ): HomeRedirect | undefined {
91
+ if (input.hostsDocs) {
92
+ if (input.docRoutes.some((route) => route === "/" || route === "/index"))
93
+ return undefined;
94
+ const landing = pickLandingRoute(input.docRoutes);
95
+ if (landing) return { from: "/", to: landing };
96
+ return input.apiReferencePath
97
+ ? { from: "/", to: input.apiReferencePath }
98
+ : undefined;
99
+ }
100
+ if (input.externalDocsUrl && !input.userPanel) {
101
+ return { from: "/", to: input.externalDocsUrl };
102
+ }
103
+ return undefined;
104
+ }
@@ -1,126 +1,127 @@
1
- export { ConfigError, type ConfigIssue, formatConfigIssue } from "./errors.js";
2
- export {
3
- applyInitPlan,
4
- formatInitPlan,
5
- InitError,
6
- type InitOptions,
7
- type InitPlan,
8
- type InitResult,
9
- type PlannedEntry,
10
- planInit,
11
- } from "./init.js";
12
- export {
13
- type DocsCandidate,
14
- detectExistingDocs,
15
- detectLayout,
16
- ensureStateDir,
17
- type LayoutDetection,
18
- } from "./layout.js";
19
- export { type LoadedConfigV2, loadConfigV2 } from "./load.js";
20
- export {
21
- BUILD_DIR,
22
- GENERATED_DIR,
23
- layoutRoot,
24
- STATE_FILE,
25
- type StatePaths,
26
- stateDirFor,
27
- statePathsFor,
28
- } from "./paths.js";
29
- export { parseConfigV2 } from "./parse.js";
30
- export {
31
- type CheckContext,
32
- type CheckReport,
33
- checkConfigV2,
34
- collectSecretRefs,
35
- } from "./rules.js";
36
- export {
37
- type ResolvedConfigV2,
38
- type ResolvedGateway,
39
- type ResolvedIdentity,
40
- type ResolvedPlans,
41
- type ResolvedPortal,
42
- resolveConfigV2,
43
- } from "./resolve.js";
44
- export {
45
- CONFIG_VERSION,
46
- type ConfigV2,
47
- ConfigV2Schema,
48
- type Layout,
49
- } from "./schema.js";
50
- export { type PortalProfile, portalProfile } from "./portal-profile.js";
51
- export {
52
- hasCapability,
53
- type ManifestServiceName,
54
- missingManifestServices,
55
- parseManifest,
56
- readManifest,
57
- removeServicesFromManifest,
58
- requiredServices,
59
- SUPPORTED_MANIFEST_SCHEMA,
60
- type ServiceManifest,
61
- serviceReady,
62
- stubManifest,
63
- withGatewayEntry,
64
- withIdentityEntry,
65
- withPlansEntry,
66
- withPortalEntry,
67
- writeManifest,
68
- } from "./manifest.js";
69
- export { MANIFEST_FILE, manifestPathFor } from "./paths.js";
70
- export {
71
- buildReferenceSpec,
72
- DEFAULT_KEY_HEADER,
73
- type ReferenceOptions,
74
- ReferenceSpecError,
75
- referenceOptions,
76
- renderReferenceSpec,
77
- } from "./gateway-reference.js";
78
- export {
79
- type DerivedCorsSite,
80
- derivedCorsSites,
81
- type GatewayConfigBody,
82
- gatewayConfigBody,
83
- stableJson,
84
- } from "./gateway-request.js";
85
- export {
86
- consoleLinks,
87
- planPortal,
88
- publishedManifest,
89
- type PortalPlan,
90
- type PreparedPortal,
91
- type PrepareMode,
92
- preparePortal,
93
- renderWrapper,
94
- requiredPackages,
95
- WRAPPER_FILE,
96
- } from "./wrapper.js";
97
- export { materializeWorkspace, portalArtifactHash } from "./workspace.js";
98
- export {
99
- type AddOptions,
100
- applyServiceEdit,
101
- formatServiceEdit,
102
- isServiceName,
103
- planAddService,
104
- planRemoveService,
105
- SERVICES,
106
- clearProjectId,
107
- ServiceEditError,
108
- setProjectId,
109
- type ServiceEdit,
110
- type ServiceName,
111
- } from "./services.js";
112
- export { checkDependencies } from "./rules.js";
113
- export {
114
- clearServices,
115
- emptyLedger,
116
- type Ledger,
117
- LEDGER_VERSION,
118
- LedgerError,
119
- type PipelineStep,
120
- readLedger,
121
- runPipeline,
122
- type StepOutcome,
123
- type StepRecord,
124
- stepOf,
125
- writeLedger,
126
- } from "./ledger.js";
1
+ export { ConfigError, type ConfigIssue, formatConfigIssue } from "./errors.js";
2
+ export {
3
+ applyInitPlan,
4
+ formatInitPlan,
5
+ InitError,
6
+ type InitOptions,
7
+ type InitPlan,
8
+ type InitResult,
9
+ type PlannedEntry,
10
+ planInit,
11
+ } from "./init.js";
12
+ export {
13
+ type DocsCandidate,
14
+ detectExistingDocs,
15
+ detectLayout,
16
+ ensureStateDir,
17
+ type LayoutDetection,
18
+ } from "./layout.js";
19
+ export { type LoadedConfigV2, loadConfigV2 } from "./load.js";
20
+ export {
21
+ BUILD_DIR,
22
+ GENERATED_DIR,
23
+ layoutRoot,
24
+ STATE_FILE,
25
+ type StatePaths,
26
+ stateDirFor,
27
+ statePathsFor,
28
+ } from "./paths.js";
29
+ export { parseConfigV2 } from "./parse.js";
30
+ export {
31
+ type CheckContext,
32
+ type CheckReport,
33
+ checkConfigV2,
34
+ collectSecretRefs,
35
+ } from "./rules.js";
36
+ export {
37
+ type ResolvedConfigV2,
38
+ type ResolvedGateway,
39
+ type ResolvedIdentity,
40
+ type ResolvedPlans,
41
+ type ResolvedPortal,
42
+ resolveConfigV2,
43
+ } from "./resolve.js";
44
+ export {
45
+ CONFIG_VERSION,
46
+ type ConfigV2,
47
+ ConfigV2Schema,
48
+ type Layout,
49
+ } from "./schema.js";
50
+ export { type PortalProfile, portalProfile } from "./portal-profile.js";
51
+ export {
52
+ hasCapability,
53
+ type ManifestServiceName,
54
+ missingManifestServices,
55
+ parseManifest,
56
+ readManifest,
57
+ removeServicesFromManifest,
58
+ requiredServices,
59
+ SUPPORTED_MANIFEST_SCHEMA,
60
+ type ServiceManifest,
61
+ serviceReady,
62
+ stubManifest,
63
+ withGatewayEntry,
64
+ withIdentityEntry,
65
+ withPlansEntry,
66
+ withPortalEntry,
67
+ writeManifest,
68
+ } from "./manifest.js";
69
+ export { MANIFEST_FILE, manifestPathFor } from "./paths.js";
70
+ export {
71
+ buildReferenceSpec,
72
+ DEFAULT_KEY_HEADER,
73
+ type ReferenceOptions,
74
+ ReferenceSpecError,
75
+ referenceOptions,
76
+ renderReferenceSpec,
77
+ } from "./gateway-reference.js";
78
+ export {
79
+ type DerivedCorsSite,
80
+ derivedCorsSites,
81
+ type GatewayConfigBody,
82
+ gatewayConfigBody,
83
+ stableJson,
84
+ } from "./gateway-request.js";
85
+ export {
86
+ consoleLinks,
87
+ planPortal,
88
+ publishedManifest,
89
+ type PortalPlan,
90
+ type PreparedPortal,
91
+ type PrepareMode,
92
+ preparePortal,
93
+ renderWrapper,
94
+ requiredPackages,
95
+ WRAPPER_FILE,
96
+ } from "./wrapper.js";
97
+ export { materializeWorkspace, portalArtifactHash } from "./workspace.js";
98
+ export {
99
+ type AddOptions,
100
+ type Asker,
101
+ applyServiceEdit,
102
+ formatServiceEdit,
103
+ isServiceName,
104
+ planAddService,
105
+ planRemoveService,
106
+ SERVICES,
107
+ clearProjectId,
108
+ ServiceEditError,
109
+ setProjectId,
110
+ type ServiceEdit,
111
+ type ServiceName,
112
+ } from "./services.js";
113
+ export { checkDependencies } from "./rules.js";
114
+ export {
115
+ clearServices,
116
+ emptyLedger,
117
+ type Ledger,
118
+ LEDGER_VERSION,
119
+ LedgerError,
120
+ type PipelineStep,
121
+ readLedger,
122
+ runPipeline,
123
+ type StepOutcome,
124
+ type StepRecord,
125
+ stepOf,
126
+ writeLedger,
127
+ } from "./ledger.js";