@lukoweb/apitogo 0.2.43 → 0.2.45

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.
@@ -1,188 +1,190 @@
1
- import path from "node:path";
2
- import type { Plugin } from "vite";
3
- import { normalizePath } from "vite";
4
- import { getCurrentConfig } from "../config/loader.js";
5
- import { writePluginDebugCode } from "./debug.js";
6
-
7
- const getLandingModuleImport = (moduleDir: string, mode: string) =>
8
- mode === "internal"
9
- ? normalizePath(path.join(moduleDir, "../module-landing/src/index.tsx"))
10
- : "@lukoweb/apitogo-module-landing";
11
-
12
- const getUserPanelModuleImport = (moduleDir: string, mode: string) =>
13
- mode === "internal"
14
- ? normalizePath(path.join(moduleDir, "../module-user-panel/src/index.tsx"))
15
- : "@lukoweb/apitogo-module-user-panel";
16
-
17
- const getBillingPluginImport = (moduleDir: string, mode: string) =>
18
- mode === "internal"
19
- ? normalizePath(
20
- path.join(moduleDir, "../plugin-dev-portal-billing/src/index.ts"),
21
- )
22
- : "@lukoweb/apitogo-plugin-dev-portal-billing";
23
-
24
- const resolveProjectPageImport = (rootDir: string, pagePath: string) =>
25
- normalizePath(path.resolve(rootDir, pagePath));
26
-
27
- const viteModulesPlugin = (): Plugin => {
28
- const virtualModuleId = "virtual:zudoku-modules-plugin";
29
- const resolvedVirtualModuleId = `\0${virtualModuleId}`;
30
-
31
- return {
32
- name: "zudoku-modules-plugin",
33
- resolveId(id) {
34
- if (id === virtualModuleId) {
35
- return resolvedVirtualModuleId;
36
- }
37
- },
38
- async load(id) {
39
- if (id !== resolvedVirtualModuleId) return;
40
-
41
- const config = getCurrentConfig();
42
- const { landing, userPanel } = config.__resolvedModules;
43
-
44
- if (config.__meta.mode === "standalone") {
45
- return [
46
- `export const configuredModulesPlugins = [];`,
47
- `export const configuredModulesSlots = {};`,
48
- ].join("\n");
49
- }
50
-
51
- const landingImport = getLandingModuleImport(
52
- config.__meta.moduleDir,
53
- config.__meta.mode,
54
- );
55
- const userPanelImport = getUserPanelModuleImport(
56
- config.__meta.moduleDir,
57
- config.__meta.mode,
58
- );
59
-
60
- const landingConfig = {
61
- enabled: landing.enabled,
62
- path: landing.path,
63
- layout: landing.layout,
64
- content: landing.content,
65
- };
66
-
67
- const userPanelConfig = {
68
- enabled: userPanel.enabled,
69
- basePath: userPanel.basePath,
70
- dashboard: {
71
- enabled: userPanel.dashboard.enabled,
72
- path: userPanel.dashboard.path,
73
- content: userPanel.dashboard.content,
74
- },
75
- userManagement: {
76
- enabled: userPanel.userManagement.enabled,
77
- routes: userPanel.userManagement.routes,
78
- content: userPanel.userManagement.content,
79
- },
80
- apiKeys: userPanel.apiKeys,
81
- plans: {
82
- enabled: userPanel.plans.enabled,
83
- path: userPanel.plans.path,
84
- content: userPanel.plans.content,
85
- },
86
- };
87
-
88
- const landingPagePath = config.modules?.landing?.page;
89
- const dashboardPagePath = config.modules?.userPanel?.dashboard?.page;
90
- const profilePagePath = config.modules?.userPanel?.userManagement?.page;
91
- const plansPagePath = config.modules?.userPanel?.plans?.page;
92
-
93
- const code: string[] = [`import config from "virtual:zudoku-config";`];
94
-
95
- if (landingPagePath) {
96
- code.push(
97
- `import LandingPage from "${resolveProjectPageImport(config.__meta.rootDir, landingPagePath)}";`,
98
- );
99
- }
100
-
101
- const useBillingDashboard = !dashboardPagePath && userPanel.plans.enabled;
102
-
103
- if (dashboardPagePath) {
104
- code.push(
105
- `import UserPanelDashboardPage from "${resolveProjectPageImport(config.__meta.rootDir, dashboardPagePath)}";`,
106
- );
107
- } else if (useBillingDashboard) {
108
- code.push(
109
- `import { OverviewDashboardPage as UserPanelDashboardPage } from "${getBillingPluginImport(config.__meta.moduleDir, config.__meta.mode)}";`,
110
- );
111
- }
112
-
113
- if (profilePagePath) {
114
- code.push(
115
- `import UserPanelProfilePage from "${resolveProjectPageImport(config.__meta.rootDir, profilePagePath)}";`,
116
- );
117
- }
118
-
119
- if (plansPagePath) {
120
- code.push(
121
- `import UserPanelPlansPage from "${resolveProjectPageImport(config.__meta.rootDir, plansPagePath)}";`,
122
- );
123
- }
124
-
125
- const configuredPlugins: string[] = [];
126
- let hasLandingFooterSlot = false;
127
-
128
- if (landing.enabled) {
129
- code.push(`import { landingModule } from "${landingImport}";`);
130
- code.push(
131
- `const landing = landingModule({`,
132
- ` ...${JSON.stringify(landingConfig)},`,
133
- ` component: config.modules?.landing?.component${landingPagePath ? " ?? LandingPage" : ""},`,
134
- `});`,
135
- );
136
- configuredPlugins.push("...(landing ? [landing] : [])");
137
-
138
- // Render the configured landing footer on every page via the
139
- // layout "footer" slot (home, docs, API reference, pricing, auth).
140
- if (landing.content.footer) {
141
- code.push(
142
- `import { createLandingFooterSlot } from "${landingImport}";`,
143
- `const landingFooterSlot = createLandingFooterSlot(${JSON.stringify(landing.content.footer)});`,
144
- );
145
- hasLandingFooterSlot = true;
146
- }
147
- }
148
-
149
- code.push(
150
- hasLandingFooterSlot
151
- ? `export const configuredModulesSlots = landingFooterSlot ? { footer: landingFooterSlot } : {};`
152
- : `export const configuredModulesSlots = {};`,
153
- );
154
-
155
- if (userPanel.enabled) {
156
- code.push(`import { userPanelModule } from "${userPanelImport}";`);
157
- code.push(
158
- `const userPanel = userPanelModule({`,
159
- ` ...${JSON.stringify(userPanelConfig)},`,
160
- ` dashboard: {`,
161
- ` ...${JSON.stringify(userPanelConfig.dashboard)},`,
162
- ` component: config.modules?.userPanel?.dashboard?.component${dashboardPagePath || useBillingDashboard ? " ?? UserPanelDashboardPage" : ""},`,
163
- ` },`,
164
- ` userManagement: {`,
165
- ` ...${JSON.stringify(userPanelConfig.userManagement)},`,
166
- ` component: config.modules?.userPanel?.userManagement?.component${profilePagePath ? " ?? UserPanelProfilePage" : ""},`,
167
- ` },`,
168
- ` plans: {`,
169
- ` ...${JSON.stringify(userPanelConfig.plans)},`,
170
- ` component: config.modules?.userPanel?.plans?.component${plansPagePath ? " ?? UserPanelPlansPage" : ""},`,
171
- ` },`,
172
- `});`,
173
- );
174
- configuredPlugins.push("...(userPanel ? [userPanel] : [])");
175
- }
176
-
177
- code.push(
178
- `export const configuredModulesPlugins = [${configuredPlugins.join(", ")}];`,
179
- );
180
-
181
- await writePluginDebugCode(config.__meta.rootDir, "modules-plugin", code);
182
-
183
- return code.join("\n");
184
- },
185
- };
186
- };
187
-
188
- export default viteModulesPlugin;
1
+ import path from "node:path";
2
+ import type { Plugin } from "vite";
3
+ import { normalizePath } from "vite";
4
+ import { getCurrentConfig } from "../config/loader.js";
5
+ import { writePluginDebugCode } from "./debug.js";
6
+
7
+ const getLandingModuleImport = (moduleDir: string, mode: string) =>
8
+ mode === "internal"
9
+ ? normalizePath(path.join(moduleDir, "../module-landing/src/index.tsx"))
10
+ : "@lukoweb/apitogo-module-landing";
11
+
12
+ const getUserPanelModuleImport = (moduleDir: string, mode: string) =>
13
+ mode === "internal"
14
+ ? normalizePath(path.join(moduleDir, "../module-user-panel/src/index.tsx"))
15
+ : "@lukoweb/apitogo-module-user-panel";
16
+
17
+ const getBillingPluginImport = (moduleDir: string, mode: string) =>
18
+ mode === "internal"
19
+ ? normalizePath(
20
+ path.join(moduleDir, "../plugin-dev-portal-billing/src/index.ts"),
21
+ )
22
+ : "@lukoweb/apitogo-plugin-dev-portal-billing";
23
+
24
+ const resolveProjectPageImport = (rootDir: string, pagePath: string) =>
25
+ normalizePath(path.resolve(rootDir, pagePath));
26
+
27
+ const viteModulesPlugin = (): Plugin => {
28
+ const virtualModuleId = "virtual:zudoku-modules-plugin";
29
+ const resolvedVirtualModuleId = `\0${virtualModuleId}`;
30
+
31
+ return {
32
+ name: "zudoku-modules-plugin",
33
+ resolveId(id) {
34
+ if (id === virtualModuleId) {
35
+ return resolvedVirtualModuleId;
36
+ }
37
+ },
38
+ async load(id) {
39
+ if (id !== resolvedVirtualModuleId) return;
40
+
41
+ const config = getCurrentConfig();
42
+ const { landing, userPanel } = config.__resolvedModules;
43
+
44
+ if (config.__meta.mode === "standalone") {
45
+ return [
46
+ `export const configuredModulesPlugins = [];`,
47
+ `export const configuredModulesSlots = {};`,
48
+ ].join("\n");
49
+ }
50
+
51
+ const landingImport = getLandingModuleImport(
52
+ config.__meta.moduleDir,
53
+ config.__meta.mode,
54
+ );
55
+ const userPanelImport = getUserPanelModuleImport(
56
+ config.__meta.moduleDir,
57
+ config.__meta.mode,
58
+ );
59
+
60
+ const landingConfig = {
61
+ enabled: landing.enabled,
62
+ path: landing.path,
63
+ layout: landing.layout,
64
+ content: landing.content,
65
+ };
66
+
67
+ const userPanelConfig = {
68
+ enabled: userPanel.enabled,
69
+ basePath: userPanel.basePath,
70
+ dashboard: {
71
+ enabled: userPanel.dashboard.enabled,
72
+ path: userPanel.dashboard.path,
73
+ content: userPanel.dashboard.content,
74
+ },
75
+ userManagement: {
76
+ enabled: userPanel.userManagement.enabled,
77
+ routes: userPanel.userManagement.routes,
78
+ content: userPanel.userManagement.content,
79
+ },
80
+ apiKeys: userPanel.apiKeys,
81
+ plans: {
82
+ enabled: userPanel.plans.enabled,
83
+ path: userPanel.plans.path,
84
+ content: userPanel.plans.content,
85
+ },
86
+ };
87
+
88
+ const landingPagePath = config.modules?.landing?.page;
89
+ const dashboardPagePath = config.modules?.userPanel?.dashboard?.page;
90
+ const profilePagePath = config.modules?.userPanel?.userManagement?.page;
91
+ const plansPagePath = config.modules?.userPanel?.plans?.page;
92
+
93
+ const code: string[] = [`import config from "virtual:zudoku-config";`];
94
+
95
+ if (landingPagePath) {
96
+ code.push(
97
+ `import LandingPage from "${resolveProjectPageImport(config.__meta.rootDir, landingPagePath)}";`,
98
+ );
99
+ }
100
+
101
+ const useBillingDashboard = !dashboardPagePath && userPanel.plans.enabled;
102
+
103
+ if (dashboardPagePath) {
104
+ code.push(
105
+ `import UserPanelDashboardPage from "${resolveProjectPageImport(config.__meta.rootDir, dashboardPagePath)}";`,
106
+ );
107
+ } else if (useBillingDashboard) {
108
+ code.push(
109
+ `import { OverviewDashboardPage as UserPanelDashboardPage } from "${getBillingPluginImport(config.__meta.moduleDir, config.__meta.mode)}";`,
110
+ );
111
+ }
112
+
113
+ if (profilePagePath) {
114
+ code.push(
115
+ `import UserPanelProfilePage from "${resolveProjectPageImport(config.__meta.rootDir, profilePagePath)}";`,
116
+ );
117
+ }
118
+
119
+ if (plansPagePath) {
120
+ code.push(
121
+ `import UserPanelPlansPage from "${resolveProjectPageImport(config.__meta.rootDir, plansPagePath)}";`,
122
+ );
123
+ }
124
+
125
+ const configuredPlugins: string[] = [];
126
+ let hasLandingFooterSlot = false;
127
+
128
+ if (landing.enabled) {
129
+ code.push(`import { landingModule } from "${landingImport}";`);
130
+ code.push(
131
+ `const landing = landingModule({`,
132
+ ` ...${JSON.stringify(landingConfig)},`,
133
+ ` component: config.modules?.landing?.component${landingPagePath ? " ?? LandingPage" : ""},`,
134
+ `});`,
135
+ );
136
+ configuredPlugins.push("...(landing ? [landing] : [])");
137
+
138
+ // Render the configured landing footer on every page via the
139
+ // layout "footer" slot (home, docs, API reference, pricing, auth).
140
+ if (landing.content.footer) {
141
+ code.push(
142
+ `import { createLandingFooterSlot } from "${landingImport}";`,
143
+ `const landingFooterSlot = createLandingFooterSlot(${JSON.stringify(landing.content.footer)});`,
144
+ );
145
+ hasLandingFooterSlot = true;
146
+ }
147
+ }
148
+
149
+ code.push(
150
+ hasLandingFooterSlot
151
+ ? `export const configuredModulesSlots = landingFooterSlot ? { footer: landingFooterSlot } : {};`
152
+ : `export const configuredModulesSlots = {};`,
153
+ );
154
+
155
+ if (userPanel.enabled) {
156
+ code.push(`import { userPanelModule } from "${userPanelImport}";`);
157
+ code.push(
158
+ `const userPanel = userPanelModule({`,
159
+ ` ...${JSON.stringify(userPanelConfig)},`,
160
+ // With billing on, the billing plugin owns the plans page and the account side menu.
161
+ ` billingNav: ${config.__meta.pricingEnabled === true},`,
162
+ ` dashboard: {`,
163
+ ` ...${JSON.stringify(userPanelConfig.dashboard)},`,
164
+ ` component: config.modules?.userPanel?.dashboard?.component${dashboardPagePath || useBillingDashboard ? " ?? UserPanelDashboardPage" : ""},`,
165
+ ` },`,
166
+ ` userManagement: {`,
167
+ ` ...${JSON.stringify(userPanelConfig.userManagement)},`,
168
+ ` component: config.modules?.userPanel?.userManagement?.component${profilePagePath ? " ?? UserPanelProfilePage" : ""},`,
169
+ ` },`,
170
+ ` plans: {`,
171
+ ` ...${JSON.stringify(userPanelConfig.plans)},`,
172
+ ` component: config.modules?.userPanel?.plans?.component${plansPagePath ? " ?? UserPanelPlansPage" : ""},`,
173
+ ` },`,
174
+ `});`,
175
+ );
176
+ configuredPlugins.push("...(userPanel ? [userPanel] : [])");
177
+ }
178
+
179
+ code.push(
180
+ `export const configuredModulesPlugins = [${configuredPlugins.join(", ")}];`,
181
+ );
182
+
183
+ await writePluginDebugCode(config.__meta.rootDir, "modules-plugin", code);
184
+
185
+ return code.join("\n");
186
+ },
187
+ };
188
+ };
189
+
190
+ export default viteModulesPlugin;