@lukoweb/apitogo 0.1.51 → 0.1.54

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 (37) hide show
  1. package/dist/cli/cli.js +467 -197
  2. package/dist/declarations/config/apitogo-config-core.d.ts +35 -0
  3. package/dist/declarations/config/apitogo-config-loader.d.ts +2 -7
  4. package/dist/declarations/config/apitogo-config-loader.node.d.ts +4 -0
  5. package/dist/declarations/config/build-apitogo-config.d.ts +5 -4
  6. package/dist/declarations/config/loader.d.ts +2 -0
  7. package/dist/declarations/config/local-manifest.d.ts +22 -8
  8. package/dist/declarations/config/validators/ModulesSchema.d.ts +38 -0
  9. package/dist/declarations/config/validators/ZudokuConfig.d.ts +43 -2
  10. package/dist/declarations/index.d.ts +1 -1
  11. package/dist/declarations/lib/authentication/providers/dev-portal-auth-pages.d.ts +15 -0
  12. package/dist/declarations/lib/authentication/providers/dev-portal-constants.d.ts +19 -1
  13. package/dist/declarations/lib/authentication/providers/dev-portal-utils.d.ts +5 -1
  14. package/dist/declarations/lib/authentication/providers/dev-portal.d.ts +5 -0
  15. package/dist/declarations/lib/core/plugins.d.ts +1 -0
  16. package/dist/flat-config.d.ts +53 -24
  17. package/docs/configuration/authentication.md +11 -9
  18. package/docs/configuration/manifest.md +75 -74
  19. package/package.json +1 -1
  20. package/src/config/apitogo-config-core.ts +601 -0
  21. package/src/config/apitogo-config-loader.node.ts +88 -0
  22. package/src/config/apitogo-config-loader.ts +6 -224
  23. package/src/config/build-apitogo-config.ts +26 -17
  24. package/src/config/loader.ts +23 -2
  25. package/src/config/local-manifest.ts +58 -59
  26. package/src/config/resolve-modules.ts +16 -13
  27. package/src/config/validators/ModulesSchema.ts +17 -0
  28. package/src/config/validators/ZudokuConfig.ts +25 -1
  29. package/src/index.ts +3 -2
  30. package/src/lib/authentication/providers/dev-portal-auth-pages.tsx +439 -0
  31. package/src/lib/authentication/providers/dev-portal-constants.ts +15 -1
  32. package/src/lib/authentication/providers/dev-portal-utils.ts +124 -4
  33. package/src/lib/authentication/providers/dev-portal.tsx +41 -6
  34. package/src/lib/core/plugins.ts +1 -0
  35. package/src/vite/dev-portal-env.ts +12 -4
  36. package/src/vite/plugin-config.ts +20 -3
  37. package/src/vite/plugin-local-manifest.ts +15 -0
@@ -17,12 +17,20 @@ import type {
17
17
  EndUserMeResponse,
18
18
  } from "./dev-portal-constants.js";
19
19
  import {
20
- buildDevPortalLoginUrl,
20
+ DevPortalForgotPasswordPage,
21
+ DevPortalLoginPage,
22
+ DevPortalRegisterPage,
23
+ DevPortalResetPasswordPage,
24
+ DevPortalVerifyEmailPage,
25
+ } from "./dev-portal-auth-pages.js";
26
+ import {
21
27
  buildDevPortalLogoutUrl,
28
+ isNativeAuthEnabled,
22
29
  isPlaceholderDevPortalApiUrl,
23
30
  mapEndUserMeToProfile,
24
31
  probeDevPortalBackend,
25
32
  resolveDevPortalApiBaseUrl,
33
+ toAbsoluteReturnUrl,
26
34
  } from "./dev-portal-utils.js";
27
35
 
28
36
  export type DevPortalProviderData = {
@@ -49,6 +57,8 @@ export class DevPortalAuthenticationProvider
49
57
  private refreshGeneration = 0;
50
58
  private refreshInFlight: Promise<boolean> | null = null;
51
59
 
60
+ private authConfigNativeEnabled: boolean | null = null;
61
+
52
62
  constructor({
53
63
  apiBaseUrl,
54
64
  redirectToAfterSignIn,
@@ -62,6 +72,18 @@ export class DevPortalAuthenticationProvider
62
72
  this.redirectToAfterSignOut = redirectToAfterSignOut;
63
73
  }
64
74
 
75
+ getRoutes() {
76
+ const pageProps = { apiBaseUrl: this.apiBaseUrl };
77
+ return [
78
+ ...super.getRoutes(),
79
+ { path: "/login", element: <DevPortalLoginPage {...pageProps} /> },
80
+ { path: "/register", element: <DevPortalRegisterPage {...pageProps} /> },
81
+ { path: "/verify-email", element: <DevPortalVerifyEmailPage {...pageProps} /> },
82
+ { path: "/forgot-password", element: <DevPortalForgotPasswordPage {...pageProps} /> },
83
+ { path: "/reset-password", element: <DevPortalResetPasswordPage {...pageProps} /> },
84
+ ];
85
+ }
86
+
65
87
  async initialize(_context: ZudokuContext): Promise<void> {
66
88
  // Node SSR cannot reach local HTTPS backends with self-signed certs.
67
89
  if (typeof window === "undefined") {
@@ -70,6 +92,15 @@ export class DevPortalAuthenticationProvider
70
92
 
71
93
  await waitForAuthStateHydration();
72
94
  await this.syncBackendAvailability();
95
+ if (this.backendAvailable && this.apiBaseUrl) {
96
+ try {
97
+ const { fetchDevPortalAuthConfig } = await import("./dev-portal-utils.js");
98
+ const config = await fetchDevPortalAuthConfig(this.apiBaseUrl);
99
+ this.authConfigNativeEnabled = isNativeAuthEnabled(config);
100
+ } catch {
101
+ this.authConfigNativeEnabled = null;
102
+ }
103
+ }
73
104
  if (!this.backendAvailable) {
74
105
  this.setPreviewState();
75
106
  return;
@@ -235,20 +266,24 @@ export class DevPortalAuthenticationProvider
235
266
  _: AuthActionContext,
236
267
  { redirectTo }: AuthActionOptions = {},
237
268
  ): Promise<void> {
238
- const apiBaseUrl = this.ensureConfiguredBackend();
269
+ this.ensureConfiguredBackend();
239
270
  const target =
240
271
  redirectTo ?? this.redirectToAfterSignIn ?? window.location.href;
241
- window.location.assign(buildDevPortalLoginUrl(apiBaseUrl, target));
272
+ const url = new URL("/login", window.location.origin);
273
+ url.searchParams.set("redirect", toAbsoluteReturnUrl(target));
274
+ window.location.assign(url.toString());
242
275
  }
243
276
 
244
277
  async signUp(
245
278
  _: AuthActionContext,
246
279
  { redirectTo }: AuthActionOptions = {},
247
280
  ): Promise<void> {
248
- const apiBaseUrl = this.ensureConfiguredBackend();
281
+ this.ensureConfiguredBackend();
249
282
  const target =
250
283
  redirectTo ?? this.redirectToAfterSignUp ?? window.location.href;
251
- window.location.assign(buildDevPortalLoginUrl(apiBaseUrl, target));
284
+ const url = new URL("/register", window.location.origin);
285
+ url.searchParams.set("redirect", toAbsoluteReturnUrl(target));
286
+ window.location.assign(url.toString());
252
287
  }
253
288
 
254
289
  async signOut(_: AuthActionContext): Promise<void> {
@@ -259,7 +294,7 @@ export class DevPortalAuthenticationProvider
259
294
  }
260
295
 
261
296
  hasDistinctSignUpFlow(): boolean {
262
- return false;
297
+ return this.authConfigNativeEnabled !== false;
263
298
  }
264
299
 
265
300
  async signRequest(request: Request): Promise<Request> {
@@ -11,6 +11,7 @@ import type {
11
11
  ApitogoEvents,
12
12
  ZudokuContext,
13
13
  } from "./ZudokuContext.js";
14
+ export { createPlugin } from "../../config/create-plugin.js";
14
15
  export { runPluginTransformConfig } from "./transform-config.js";
15
16
 
16
17
  export type ApitogoPlugin =
@@ -1,8 +1,14 @@
1
-
2
1
  import { loadEnv } from "vite";
3
2
 
3
+ export const AUTHENTICATION_API_BASE_URL_ENV =
4
+ "VITE_APITOGO_AUTHENTICATION_API_BASE_URL";
5
+
6
+ /** @deprecated Use {@link AUTHENTICATION_API_BASE_URL_ENV}. */
7
+ export const LEGACY_DEV_PORTAL_API_URL_ENV = "VITE_APITOGO_DEV_PORTAL_API_URL";
8
+
4
9
  export const DEV_PORTAL_VITE_ENV_KEYS = [
5
- "VITE_APITOGO_DEV_PORTAL_API_URL",
10
+ AUTHENTICATION_API_BASE_URL_ENV,
11
+ LEGACY_DEV_PORTAL_API_URL_ENV,
6
12
  ] as const;
7
13
 
8
14
  export async function loadDevPortalViteDefines(
@@ -12,9 +18,11 @@ export async function loadDevPortalViteDefines(
12
18
  const env = loadEnv(mode, rootDir, "VITE_");
13
19
  const defines: Record<string, string> = {};
14
20
 
15
- const apiUrl = env.VITE_APITOGO_DEV_PORTAL_API_URL?.trim();
21
+ const apiUrl =
22
+ env[AUTHENTICATION_API_BASE_URL_ENV]?.trim() ||
23
+ env[LEGACY_DEV_PORTAL_API_URL_ENV]?.trim();
16
24
  if (apiUrl) {
17
- defines.VITE_APITOGO_DEV_PORTAL_API_URL = JSON.stringify(apiUrl);
25
+ defines[AUTHENTICATION_API_BASE_URL_ENV] = JSON.stringify(apiUrl);
18
26
  }
19
27
 
20
28
  return defines;
@@ -1,5 +1,5 @@
1
1
  import { normalizePath, type Plugin, type ResolvedConfig } from "vite";
2
- import { getCurrentConfig } from "../config/loader.js";
2
+ import { getCurrentConfig, loadZudokuConfig } from "../config/loader.js";
3
3
 
4
4
  const virtualModuleId = "virtual:zudoku-config";
5
5
  const resolvedVirtualModuleId = `\0${virtualModuleId}`;
@@ -17,7 +17,7 @@ const viteConfigPlugin = (): Plugin => {
17
17
  configResolved(resolvedConfig) {
18
18
  viteConfig = resolvedConfig;
19
19
  },
20
- load(id) {
20
+ async load(id) {
21
21
  if (id !== resolvedVirtualModuleId) return;
22
22
 
23
23
  const configPath = getCurrentConfig().__meta.configPath;
@@ -25,11 +25,28 @@ const viteConfigPlugin = (): Plugin => {
25
25
  return `export default {};`;
26
26
  }
27
27
 
28
+ const { config: loadedConfig } = await loadZudokuConfig(
29
+ {
30
+ mode: viteConfig.mode,
31
+ command: viteConfig.command,
32
+ },
33
+ viteConfig.root,
34
+ );
35
+ const clientMeta = {
36
+ rootDir: loadedConfig.__meta.rootDir,
37
+ pricingEnabled: loadedConfig.__meta.pricingEnabled,
38
+ authenticationEnabled: loadedConfig.__meta.authenticationEnabled,
39
+ previewPlans: loadedConfig.__meta.previewPlans,
40
+ };
41
+
28
42
  return `
29
43
  import rawConfig from "${normalizePath(configPath)}";
30
44
  import { runPluginTransformConfig } from "@lukoweb/apitogo/plugins";
31
45
 
32
- const config = await runPluginTransformConfig(rawConfig);
46
+ const config = await runPluginTransformConfig({
47
+ ...rawConfig,
48
+ __meta: ${JSON.stringify(clientMeta)},
49
+ });
33
50
  export default config;
34
51
  `;
35
52
  },
@@ -1,10 +1,16 @@
1
1
  import path from "node:path";
2
2
  import type { Plugin, ResolvedConfig } from "vite";
3
+ import {
4
+ loadApitogoConfig,
5
+ readPlanCatalogItems,
6
+ } from "../config/apitogo-config-loader.js";
3
7
  import {
4
8
  manifestPathsForEnv,
5
9
  manifestToPreviewCatalog,
10
+ plansToPreviewCatalog,
6
11
  readEffectiveManifest,
7
12
  resolveManifestEnv,
13
+ type ManifestPlanInput,
8
14
  } from "../config/local-manifest.js";
9
15
 
10
16
  export const APITOGO_LOCAL_MANIFEST_VIRTUAL_ID =
@@ -24,6 +30,15 @@ const viteLocalManifestPlugin = (): Plugin => {
24
30
  try {
25
31
  const manifest = await readEffectiveManifest(rootDir, env);
26
32
  catalog = manifestToPreviewCatalog(manifest);
33
+ if (!catalog.plans.length) {
34
+ const config = loadApitogoConfig(rootDir);
35
+ catalog = {
36
+ ...catalog,
37
+ ...plansToPreviewCatalog(
38
+ readPlanCatalogItems(config) as ManifestPlanInput[],
39
+ ),
40
+ };
41
+ }
27
42
  } catch {
28
43
  // Missing or invalid manifest — empty catalog for preview.
29
44
  }