@lukoweb/apitogo 0.1.46 → 0.1.48
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 +328 -217
- package/dist/declarations/config/local-manifest.d.ts +17 -1
- package/docs/configuration/authentication.md +7 -7
- package/docs/configuration/manifest.md +116 -0
- package/package.json +1 -1
- package/src/config/local-manifest.ts +141 -12
- package/src/vite/dev-portal-env.ts +1 -1
- package/src/vite/plugin-local-manifest.ts +21 -13
- package/src/vite/plugin-modules.ts +36 -25
- package/src/vite/plugin.ts +1 -1
package/dist/cli/cli.js
CHANGED
|
@@ -3985,7 +3985,7 @@ import yargs from "yargs/yargs";
|
|
|
3985
3985
|
import path29 from "node:path";
|
|
3986
3986
|
|
|
3987
3987
|
// src/vite/build.ts
|
|
3988
|
-
import { mkdir as mkdir5, readFile as
|
|
3988
|
+
import { mkdir as mkdir5, readFile as readFile4, rename, rm as rm2, writeFile as writeFile5 } from "node:fs/promises";
|
|
3989
3989
|
import path27 from "node:path";
|
|
3990
3990
|
import { build as esbuild } from "esbuild";
|
|
3991
3991
|
import { build as viteBuild, mergeConfig as mergeConfig3 } from "vite";
|
|
@@ -4133,7 +4133,7 @@ import {
|
|
|
4133
4133
|
// package.json
|
|
4134
4134
|
var package_default = {
|
|
4135
4135
|
name: "@lukoweb/apitogo",
|
|
4136
|
-
version: "0.1.
|
|
4136
|
+
version: "0.1.48",
|
|
4137
4137
|
type: "module",
|
|
4138
4138
|
sideEffects: [
|
|
4139
4139
|
"**/*.css",
|
|
@@ -7085,12 +7085,270 @@ var viteDocsPlugin = () => {
|
|
|
7085
7085
|
};
|
|
7086
7086
|
var plugin_docs_default = viteDocsPlugin;
|
|
7087
7087
|
|
|
7088
|
+
// src/vite/plugin-local-manifest.ts
|
|
7089
|
+
import path16 from "node:path";
|
|
7090
|
+
|
|
7091
|
+
// src/config/local-manifest.ts
|
|
7092
|
+
import { access, readFile as readFile2 } from "node:fs/promises";
|
|
7093
|
+
import path15 from "node:path";
|
|
7094
|
+
import { z as z10 } from "zod";
|
|
7095
|
+
var DEV_PORTAL_MANIFEST_FILENAME = "apitogo.local.json";
|
|
7096
|
+
var APITOGO_MANIFEST_BASE_FILENAME = "apitogo.json";
|
|
7097
|
+
var APITOGO_MANIFEST_ENV_FILES = {
|
|
7098
|
+
development: "apitogo.local.json",
|
|
7099
|
+
production: "apitogo.prod.json"
|
|
7100
|
+
};
|
|
7101
|
+
var BillingPeriodSchema = z10.enum(["month", "year", "monthly", "annual"]);
|
|
7102
|
+
var ManifestPlanInputSchema = z10.object({
|
|
7103
|
+
sku: z10.string().min(1),
|
|
7104
|
+
displayName: z10.string().min(1),
|
|
7105
|
+
isFree: z10.boolean(),
|
|
7106
|
+
priceAmount: z10.number().optional(),
|
|
7107
|
+
priceCurrency: z10.string().optional(),
|
|
7108
|
+
billingPeriod: BillingPeriodSchema.optional(),
|
|
7109
|
+
limitsJson: z10.string().optional(),
|
|
7110
|
+
includedActionKeys: z10.array(z10.string()).optional()
|
|
7111
|
+
});
|
|
7112
|
+
var DevPortalLocalManifestSchema = z10.object({
|
|
7113
|
+
siteName: z10.string().optional(),
|
|
7114
|
+
branding: z10.object({
|
|
7115
|
+
title: z10.string().optional(),
|
|
7116
|
+
logoUrl: z10.string().optional()
|
|
7117
|
+
}).optional(),
|
|
7118
|
+
plans: z10.array(ManifestPlanInputSchema).optional(),
|
|
7119
|
+
backend: z10.object({
|
|
7120
|
+
sourceDirectory: z10.string().optional(),
|
|
7121
|
+
publishDirectory: z10.string().optional(),
|
|
7122
|
+
openApiPath: z10.string().optional(),
|
|
7123
|
+
runtime: z10.string().optional(),
|
|
7124
|
+
runtimeVersion: z10.string().optional(),
|
|
7125
|
+
deployed: z10.boolean().optional()
|
|
7126
|
+
}).optional(),
|
|
7127
|
+
gateway: z10.object({
|
|
7128
|
+
authMode: z10.enum(["platformManagedEntra", "bringYourOwnOidc"]).optional(),
|
|
7129
|
+
oidcMetadataUrl: z10.string().optional(),
|
|
7130
|
+
oidcAllowedIssuers: z10.array(z10.string()).optional(),
|
|
7131
|
+
oidcAudiences: z10.array(z10.string()).optional(),
|
|
7132
|
+
limitsJson: z10.string().optional(),
|
|
7133
|
+
publicHealthActionKey: z10.string().optional()
|
|
7134
|
+
}).optional(),
|
|
7135
|
+
projectId: z10.string().optional(),
|
|
7136
|
+
projectName: z10.string().optional()
|
|
7137
|
+
});
|
|
7138
|
+
function normalizeBillingPeriod(period) {
|
|
7139
|
+
if (!period) {
|
|
7140
|
+
return "monthly";
|
|
7141
|
+
}
|
|
7142
|
+
const normalized = period.toLowerCase();
|
|
7143
|
+
if (normalized === "month") {
|
|
7144
|
+
return "monthly";
|
|
7145
|
+
}
|
|
7146
|
+
if (normalized === "year") {
|
|
7147
|
+
return "annual";
|
|
7148
|
+
}
|
|
7149
|
+
return normalized;
|
|
7150
|
+
}
|
|
7151
|
+
function plansToPreviewCatalog(plans) {
|
|
7152
|
+
if (!plans?.length) {
|
|
7153
|
+
return { plans: [] };
|
|
7154
|
+
}
|
|
7155
|
+
return {
|
|
7156
|
+
plans: plans.map((plan) => ({
|
|
7157
|
+
sku: plan.sku,
|
|
7158
|
+
displayName: plan.displayName,
|
|
7159
|
+
isFree: plan.isFree,
|
|
7160
|
+
priceAmount: plan.priceAmount ?? 0,
|
|
7161
|
+
priceCurrency: plan.priceCurrency ?? "usd",
|
|
7162
|
+
billingPeriod: normalizeBillingPeriod(plan.billingPeriod),
|
|
7163
|
+
limitsJson: plan.limitsJson ?? null,
|
|
7164
|
+
includedActionKeys: plan.includedActionKeys ?? []
|
|
7165
|
+
}))
|
|
7166
|
+
};
|
|
7167
|
+
}
|
|
7168
|
+
function resolveManifestEnv(viteMode) {
|
|
7169
|
+
return viteMode === "production" ? "production" : "development";
|
|
7170
|
+
}
|
|
7171
|
+
function mergePlansBySku(existing, patch) {
|
|
7172
|
+
const bySku = /* @__PURE__ */ new Map();
|
|
7173
|
+
for (const plan of existing ?? []) {
|
|
7174
|
+
bySku.set(plan.sku, plan);
|
|
7175
|
+
}
|
|
7176
|
+
for (const plan of patch) {
|
|
7177
|
+
const prior = bySku.get(plan.sku);
|
|
7178
|
+
bySku.set(plan.sku, prior ? { ...prior, ...plan } : plan);
|
|
7179
|
+
}
|
|
7180
|
+
return Array.from(bySku.values());
|
|
7181
|
+
}
|
|
7182
|
+
function mergeManifest(base, override) {
|
|
7183
|
+
const merged = { ...base, ...override };
|
|
7184
|
+
if (override.branding) {
|
|
7185
|
+
merged.branding = { ...base.branding, ...override.branding };
|
|
7186
|
+
}
|
|
7187
|
+
if (override.backend) {
|
|
7188
|
+
merged.backend = { ...base.backend, ...override.backend };
|
|
7189
|
+
}
|
|
7190
|
+
if (override.gateway) {
|
|
7191
|
+
merged.gateway = { ...base.gateway, ...override.gateway };
|
|
7192
|
+
}
|
|
7193
|
+
if (override.plans) {
|
|
7194
|
+
merged.plans = mergePlansBySku(base.plans, override.plans);
|
|
7195
|
+
}
|
|
7196
|
+
return merged;
|
|
7197
|
+
}
|
|
7198
|
+
function manifestFilePath(rootDir, filename) {
|
|
7199
|
+
return path15.join(
|
|
7200
|
+
path15.resolve(rootDir),
|
|
7201
|
+
filename ?? DEV_PORTAL_MANIFEST_FILENAME
|
|
7202
|
+
);
|
|
7203
|
+
}
|
|
7204
|
+
function manifestPathsForEnv(rootDir, env) {
|
|
7205
|
+
const resolvedRoot = path15.resolve(rootDir);
|
|
7206
|
+
const basePath = path15.join(resolvedRoot, APITOGO_MANIFEST_BASE_FILENAME);
|
|
7207
|
+
const overridePath = path15.join(
|
|
7208
|
+
resolvedRoot,
|
|
7209
|
+
APITOGO_MANIFEST_ENV_FILES[env]
|
|
7210
|
+
);
|
|
7211
|
+
return {
|
|
7212
|
+
basePath,
|
|
7213
|
+
overridePath,
|
|
7214
|
+
watchPaths: [basePath, overridePath]
|
|
7215
|
+
};
|
|
7216
|
+
}
|
|
7217
|
+
function parseLocalManifestJson(raw) {
|
|
7218
|
+
try {
|
|
7219
|
+
const parsed = JSON.parse(raw);
|
|
7220
|
+
const result = DevPortalLocalManifestSchema.safeParse(parsed);
|
|
7221
|
+
if (!result.success) {
|
|
7222
|
+
return null;
|
|
7223
|
+
}
|
|
7224
|
+
return result.data;
|
|
7225
|
+
} catch {
|
|
7226
|
+
return null;
|
|
7227
|
+
}
|
|
7228
|
+
}
|
|
7229
|
+
async function fileExists2(filePath) {
|
|
7230
|
+
try {
|
|
7231
|
+
await access(filePath);
|
|
7232
|
+
return true;
|
|
7233
|
+
} catch {
|
|
7234
|
+
return false;
|
|
7235
|
+
}
|
|
7236
|
+
}
|
|
7237
|
+
async function readManifestFile(rootDir, filename) {
|
|
7238
|
+
const filePath = manifestFilePath(rootDir, filename);
|
|
7239
|
+
try {
|
|
7240
|
+
const raw = await readFile2(filePath, "utf8");
|
|
7241
|
+
return parseLocalManifestJson(raw);
|
|
7242
|
+
} catch {
|
|
7243
|
+
return null;
|
|
7244
|
+
}
|
|
7245
|
+
}
|
|
7246
|
+
async function readEffectiveManifest(rootDir, env) {
|
|
7247
|
+
const { basePath, overridePath } = manifestPathsForEnv(rootDir, env);
|
|
7248
|
+
const hasBase = await fileExists2(basePath);
|
|
7249
|
+
const hasOverride = await fileExists2(overridePath);
|
|
7250
|
+
if (!hasBase) {
|
|
7251
|
+
const legacy = await readManifestFile(
|
|
7252
|
+
rootDir,
|
|
7253
|
+
APITOGO_MANIFEST_ENV_FILES.development
|
|
7254
|
+
);
|
|
7255
|
+
if (legacy) {
|
|
7256
|
+
return legacy;
|
|
7257
|
+
}
|
|
7258
|
+
if (hasOverride) {
|
|
7259
|
+
return readManifestFile(rootDir, APITOGO_MANIFEST_ENV_FILES[env]);
|
|
7260
|
+
}
|
|
7261
|
+
return null;
|
|
7262
|
+
}
|
|
7263
|
+
const base = await readManifestFile(rootDir, APITOGO_MANIFEST_BASE_FILENAME);
|
|
7264
|
+
if (!base) {
|
|
7265
|
+
return null;
|
|
7266
|
+
}
|
|
7267
|
+
if (!hasOverride) {
|
|
7268
|
+
return base;
|
|
7269
|
+
}
|
|
7270
|
+
const override = await readManifestFile(
|
|
7271
|
+
rootDir,
|
|
7272
|
+
APITOGO_MANIFEST_ENV_FILES[env]
|
|
7273
|
+
);
|
|
7274
|
+
if (!override) {
|
|
7275
|
+
return base;
|
|
7276
|
+
}
|
|
7277
|
+
return mergeManifest(base, override);
|
|
7278
|
+
}
|
|
7279
|
+
|
|
7280
|
+
// src/vite/plugin-local-manifest.ts
|
|
7281
|
+
var APITOGO_LOCAL_MANIFEST_VIRTUAL_ID = "virtual:apitogo-local-manifest";
|
|
7282
|
+
var resolvedVirtualModuleId4 = `\0${APITOGO_LOCAL_MANIFEST_VIRTUAL_ID}`;
|
|
7283
|
+
var viteLocalManifestPlugin = () => {
|
|
7284
|
+
let rootDir = "";
|
|
7285
|
+
let viteMode = "development";
|
|
7286
|
+
let watchPaths = [];
|
|
7287
|
+
const loadManifestModule = async () => {
|
|
7288
|
+
const env = resolveManifestEnv(viteMode);
|
|
7289
|
+
let catalog = {
|
|
7290
|
+
plans: []
|
|
7291
|
+
};
|
|
7292
|
+
try {
|
|
7293
|
+
const manifest = await readEffectiveManifest(rootDir, env);
|
|
7294
|
+
catalog = plansToPreviewCatalog(manifest?.plans);
|
|
7295
|
+
} catch {
|
|
7296
|
+
}
|
|
7297
|
+
return `export default ${JSON.stringify(catalog)};`;
|
|
7298
|
+
};
|
|
7299
|
+
return {
|
|
7300
|
+
name: "apitogo-local-manifest-plugin",
|
|
7301
|
+
configResolved(resolvedConfig) {
|
|
7302
|
+
rootDir = resolvedConfig.root;
|
|
7303
|
+
viteMode = resolvedConfig.mode;
|
|
7304
|
+
const env = resolveManifestEnv(viteMode);
|
|
7305
|
+
watchPaths = manifestPathsForEnv(rootDir, env).watchPaths;
|
|
7306
|
+
},
|
|
7307
|
+
resolveId(id) {
|
|
7308
|
+
if (id === APITOGO_LOCAL_MANIFEST_VIRTUAL_ID) {
|
|
7309
|
+
return resolvedVirtualModuleId4;
|
|
7310
|
+
}
|
|
7311
|
+
},
|
|
7312
|
+
async load(id) {
|
|
7313
|
+
if (id !== resolvedVirtualModuleId4) {
|
|
7314
|
+
return;
|
|
7315
|
+
}
|
|
7316
|
+
return loadManifestModule();
|
|
7317
|
+
},
|
|
7318
|
+
configureServer(server) {
|
|
7319
|
+
for (const watchPath of watchPaths) {
|
|
7320
|
+
server.watcher.add(watchPath);
|
|
7321
|
+
}
|
|
7322
|
+
server.watcher.on("change", async (changedPath) => {
|
|
7323
|
+
const resolvedChanged = path16.resolve(changedPath);
|
|
7324
|
+
if (!watchPaths.some((p) => path16.resolve(p) === resolvedChanged)) {
|
|
7325
|
+
return;
|
|
7326
|
+
}
|
|
7327
|
+
const module = server.moduleGraph.getModuleById(
|
|
7328
|
+
resolvedVirtualModuleId4
|
|
7329
|
+
);
|
|
7330
|
+
if (module) {
|
|
7331
|
+
server.moduleGraph.invalidateModule(module);
|
|
7332
|
+
}
|
|
7333
|
+
const mod = await server.moduleGraph.getModuleByUrl(
|
|
7334
|
+
APITOGO_LOCAL_MANIFEST_VIRTUAL_ID
|
|
7335
|
+
);
|
|
7336
|
+
if (mod) {
|
|
7337
|
+
server.reloadModule(mod);
|
|
7338
|
+
}
|
|
7339
|
+
server.ws.send({ type: "full-reload", path: "*" });
|
|
7340
|
+
});
|
|
7341
|
+
}
|
|
7342
|
+
};
|
|
7343
|
+
};
|
|
7344
|
+
var plugin_local_manifest_default = viteLocalManifestPlugin;
|
|
7345
|
+
|
|
7088
7346
|
// src/vite/plugin-markdown-export.ts
|
|
7089
7347
|
init_loader();
|
|
7090
7348
|
init_ProtectedRoutesSchema();
|
|
7091
7349
|
init_joinUrl();
|
|
7092
7350
|
import { mkdir as mkdir2, writeFile as writeFile2 } from "node:fs/promises";
|
|
7093
|
-
import
|
|
7351
|
+
import path17 from "node:path";
|
|
7094
7352
|
import { matchPath } from "react-router";
|
|
7095
7353
|
var processMarkdownFile = async (filePath) => {
|
|
7096
7354
|
const { content: markdownContent, data: frontmatter } = await readFrontmatter(filePath);
|
|
@@ -7178,7 +7436,7 @@ var viteMarkdownExportPlugin = () => {
|
|
|
7178
7436
|
if (process.env.NODE_ENV !== "production" || Object.keys(markdownFiles).length === 0 || !needsMdFiles) {
|
|
7179
7437
|
return;
|
|
7180
7438
|
}
|
|
7181
|
-
const distDir =
|
|
7439
|
+
const distDir = path17.join(
|
|
7182
7440
|
config2.__meta.rootDir,
|
|
7183
7441
|
"dist",
|
|
7184
7442
|
config2.basePath ?? ""
|
|
@@ -7199,15 +7457,15 @@ var viteMarkdownExportPlugin = () => {
|
|
|
7199
7457
|
content: finalMarkdown
|
|
7200
7458
|
});
|
|
7201
7459
|
const segments = routePath === "/" ? ["index"] : routePath.split("/").filter(Boolean);
|
|
7202
|
-
const outputPath = `${
|
|
7203
|
-
await mkdir2(
|
|
7460
|
+
const outputPath = `${path17.join(distDir, ...segments)}.md`;
|
|
7461
|
+
await mkdir2(path17.dirname(outputPath), { recursive: true });
|
|
7204
7462
|
await writeFile2(outputPath, finalMarkdown, "utf-8");
|
|
7205
7463
|
} catch (error) {
|
|
7206
7464
|
console.warn(`Failed to export markdown for ${routePath}:`, error);
|
|
7207
7465
|
}
|
|
7208
7466
|
}
|
|
7209
7467
|
if (config2.docs?.llms?.llmsTxt || config2.docs?.llms?.llmsTxtFull) {
|
|
7210
|
-
const markdownInfoPath =
|
|
7468
|
+
const markdownInfoPath = path17.join(
|
|
7211
7469
|
config2.__meta.rootDir,
|
|
7212
7470
|
"node_modules/.apitogo/markdown-info.json"
|
|
7213
7471
|
);
|
|
@@ -7359,9 +7617,9 @@ var remarkCodeTabs = () => (tree) => {
|
|
|
7359
7617
|
};
|
|
7360
7618
|
|
|
7361
7619
|
// src/vite/mdx/remark-inject-filepath.ts
|
|
7362
|
-
import
|
|
7620
|
+
import path18 from "node:path";
|
|
7363
7621
|
var remarkInjectFilepath = (rootDir) => (tree, vfile) => {
|
|
7364
|
-
const relativePath =
|
|
7622
|
+
const relativePath = path18.relative(rootDir, vfile.path).split(path18.sep).join(path18.posix.sep);
|
|
7365
7623
|
tree.children.unshift(exportMdxjsConst("__filepath", relativePath));
|
|
7366
7624
|
};
|
|
7367
7625
|
|
|
@@ -7448,18 +7706,18 @@ var remarkLastModified = () => {
|
|
|
7448
7706
|
};
|
|
7449
7707
|
|
|
7450
7708
|
// src/vite/mdx/remark-link-rewrite.ts
|
|
7451
|
-
import
|
|
7709
|
+
import path19 from "node:path";
|
|
7452
7710
|
import { visit as visit5 } from "unist-util-visit";
|
|
7453
7711
|
var remarkLinkRewrite = (basePath = "") => (tree) => {
|
|
7454
7712
|
visit5(tree, "link", (node) => {
|
|
7455
7713
|
if (!node.url) return;
|
|
7456
7714
|
if (node.url.startsWith("http") || node.url.startsWith("mailto:")) return;
|
|
7457
7715
|
node.url = node.url.replace(/\\/g, "/");
|
|
7458
|
-
const base =
|
|
7716
|
+
const base = path19.posix.join(basePath);
|
|
7459
7717
|
if (basePath && node.url.startsWith(base)) {
|
|
7460
7718
|
node.url = node.url.slice(base.length);
|
|
7461
7719
|
} else if (!node.url.startsWith("/") && !node.url.startsWith("#")) {
|
|
7462
|
-
node.url =
|
|
7720
|
+
node.url = path19.posix.join("..", node.url);
|
|
7463
7721
|
}
|
|
7464
7722
|
node.url = node.url.replace(/\.mdx?(#.*)?$/, "$1");
|
|
7465
7723
|
});
|
|
@@ -7679,11 +7937,11 @@ var plugin_mdx_default = viteMdxPlugin;
|
|
|
7679
7937
|
|
|
7680
7938
|
// src/vite/plugin-modules.ts
|
|
7681
7939
|
init_loader();
|
|
7682
|
-
import
|
|
7940
|
+
import path20 from "node:path";
|
|
7683
7941
|
import { normalizePath as normalizePath2 } from "vite";
|
|
7684
|
-
var getLandingModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(
|
|
7685
|
-
var getUserPanelModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(
|
|
7686
|
-
var resolveProjectPageImport = (rootDir, pagePath) => normalizePath2(
|
|
7942
|
+
var getLandingModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path20.join(moduleDir, "../module-landing/src/index.tsx")) : "@lukoweb/apitogo-module-landing";
|
|
7943
|
+
var getUserPanelModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path20.join(moduleDir, "../module-user-panel/src/index.tsx")) : "@lukoweb/apitogo-module-user-panel";
|
|
7944
|
+
var resolveProjectPageImport = (rootDir, pagePath) => normalizePath2(path20.resolve(rootDir, pagePath));
|
|
7687
7945
|
var viteModulesPlugin = () => {
|
|
7688
7946
|
const virtualModuleId4 = "virtual:zudoku-modules-plugin";
|
|
7689
7947
|
const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
|
|
@@ -7760,32 +8018,40 @@ var viteModulesPlugin = () => {
|
|
|
7760
8018
|
`import UserPanelPlansPage from "${resolveProjectPageImport(config2.__meta.rootDir, plansPagePath)}";`
|
|
7761
8019
|
);
|
|
7762
8020
|
}
|
|
8021
|
+
const configuredPlugins = [];
|
|
8022
|
+
if (landing.enabled) {
|
|
8023
|
+
code.push(`import { landingModule } from "${landingImport}";`);
|
|
8024
|
+
code.push(
|
|
8025
|
+
`const landing = landingModule({`,
|
|
8026
|
+
` ...${JSON.stringify(landingConfig)},`,
|
|
8027
|
+
` component: config.modules?.landing?.component${landingPagePath ? " ?? LandingPage" : ""},`,
|
|
8028
|
+
`});`
|
|
8029
|
+
);
|
|
8030
|
+
configuredPlugins.push("...(landing ? [landing] : [])");
|
|
8031
|
+
}
|
|
8032
|
+
if (userPanel.enabled) {
|
|
8033
|
+
code.push(`import { userPanelModule } from "${userPanelImport}";`);
|
|
8034
|
+
code.push(
|
|
8035
|
+
`const userPanel = userPanelModule({`,
|
|
8036
|
+
` ...${JSON.stringify(userPanelConfig)},`,
|
|
8037
|
+
` dashboard: {`,
|
|
8038
|
+
` ...${JSON.stringify(userPanelConfig.dashboard)},`,
|
|
8039
|
+
` component: config.modules?.userPanel?.dashboard?.component${dashboardPagePath ? " ?? UserPanelDashboardPage" : ""},`,
|
|
8040
|
+
` },`,
|
|
8041
|
+
` userManagement: {`,
|
|
8042
|
+
` ...${JSON.stringify(userPanelConfig.userManagement)},`,
|
|
8043
|
+
` component: config.modules?.userPanel?.userManagement?.component${profilePagePath ? " ?? UserPanelProfilePage" : ""},`,
|
|
8044
|
+
` },`,
|
|
8045
|
+
` plans: {`,
|
|
8046
|
+
` ...${JSON.stringify(userPanelConfig.plans)},`,
|
|
8047
|
+
` component: config.modules?.userPanel?.plans?.component${plansPagePath ? " ?? UserPanelPlansPage" : ""},`,
|
|
8048
|
+
` },`,
|
|
8049
|
+
`});`
|
|
8050
|
+
);
|
|
8051
|
+
configuredPlugins.push("...(userPanel ? [userPanel] : [])");
|
|
8052
|
+
}
|
|
7763
8053
|
code.push(
|
|
7764
|
-
`
|
|
7765
|
-
`import { userPanelModule } from "${userPanelImport}";`,
|
|
7766
|
-
`const landing = landingModule({`,
|
|
7767
|
-
` ...${JSON.stringify(landingConfig)},`,
|
|
7768
|
-
` component: config.modules?.landing?.component${landingPagePath ? " ?? LandingPage" : ""},`,
|
|
7769
|
-
`});`,
|
|
7770
|
-
`const userPanel = userPanelModule({`,
|
|
7771
|
-
` ...${JSON.stringify(userPanelConfig)},`,
|
|
7772
|
-
` dashboard: {`,
|
|
7773
|
-
` ...${JSON.stringify(userPanelConfig.dashboard)},`,
|
|
7774
|
-
` component: config.modules?.userPanel?.dashboard?.component${dashboardPagePath ? " ?? UserPanelDashboardPage" : ""},`,
|
|
7775
|
-
` },`,
|
|
7776
|
-
` userManagement: {`,
|
|
7777
|
-
` ...${JSON.stringify(userPanelConfig.userManagement)},`,
|
|
7778
|
-
` component: config.modules?.userPanel?.userManagement?.component${profilePagePath ? " ?? UserPanelProfilePage" : ""},`,
|
|
7779
|
-
` },`,
|
|
7780
|
-
` plans: {`,
|
|
7781
|
-
` ...${JSON.stringify(userPanelConfig.plans)},`,
|
|
7782
|
-
` component: config.modules?.userPanel?.plans?.component${plansPagePath ? " ?? UserPanelPlansPage" : ""},`,
|
|
7783
|
-
` },`,
|
|
7784
|
-
`});`,
|
|
7785
|
-
`export const configuredModulesPlugins = [`,
|
|
7786
|
-
` ...(landing ? [landing] : []),`,
|
|
7787
|
-
` ...(userPanel ? [userPanel] : []),`,
|
|
7788
|
-
`];`
|
|
8054
|
+
`export const configuredModulesPlugins = [${configuredPlugins.join(", ")}];`
|
|
7789
8055
|
);
|
|
7790
8056
|
await writePluginDebugCode(config2.__meta.rootDir, "modules-plugin", code);
|
|
7791
8057
|
return code.join("\n");
|
|
@@ -7796,7 +8062,7 @@ var plugin_modules_default = viteModulesPlugin;
|
|
|
7796
8062
|
|
|
7797
8063
|
// src/vite/plugin-search.ts
|
|
7798
8064
|
init_loader();
|
|
7799
|
-
import
|
|
8065
|
+
import path21 from "node:path";
|
|
7800
8066
|
var viteSearchPlugin = () => {
|
|
7801
8067
|
const virtualModuleId4 = "virtual:zudoku-search-plugin";
|
|
7802
8068
|
const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
|
|
@@ -7814,7 +8080,7 @@ var viteSearchPlugin = () => {
|
|
|
7814
8080
|
return resolvedVirtualModuleId5;
|
|
7815
8081
|
}
|
|
7816
8082
|
if (id === "/pagefind/pagefind.js" && resolvedViteConfig?.publicDir) {
|
|
7817
|
-
return
|
|
8083
|
+
return path21.join(resolvedViteConfig.publicDir, "pagefind/pagefind.js");
|
|
7818
8084
|
}
|
|
7819
8085
|
},
|
|
7820
8086
|
async load(id) {
|
|
@@ -7925,161 +8191,6 @@ var viteShikiRegisterPlugin = () => {
|
|
|
7925
8191
|
};
|
|
7926
8192
|
};
|
|
7927
8193
|
|
|
7928
|
-
// src/vite/plugin-local-manifest.ts
|
|
7929
|
-
import path21 from "node:path";
|
|
7930
|
-
|
|
7931
|
-
// src/config/local-manifest.ts
|
|
7932
|
-
import path20 from "node:path";
|
|
7933
|
-
import { z as z10 } from "zod";
|
|
7934
|
-
var DEV_PORTAL_MANIFEST_FILENAME = "apitogo.local.json";
|
|
7935
|
-
var BillingPeriodSchema = z10.enum([
|
|
7936
|
-
"month",
|
|
7937
|
-
"year",
|
|
7938
|
-
"monthly",
|
|
7939
|
-
"annual"
|
|
7940
|
-
]);
|
|
7941
|
-
var ManifestPlanInputSchema = z10.object({
|
|
7942
|
-
sku: z10.string().min(1),
|
|
7943
|
-
displayName: z10.string().min(1),
|
|
7944
|
-
isFree: z10.boolean(),
|
|
7945
|
-
priceAmount: z10.number().optional(),
|
|
7946
|
-
priceCurrency: z10.string().optional(),
|
|
7947
|
-
billingPeriod: BillingPeriodSchema.optional(),
|
|
7948
|
-
limitsJson: z10.string().optional(),
|
|
7949
|
-
includedActionKeys: z10.array(z10.string()).optional()
|
|
7950
|
-
});
|
|
7951
|
-
var DevPortalLocalManifestSchema = z10.object({
|
|
7952
|
-
siteName: z10.string().optional(),
|
|
7953
|
-
branding: z10.object({
|
|
7954
|
-
title: z10.string().optional(),
|
|
7955
|
-
logoUrl: z10.string().optional()
|
|
7956
|
-
}).optional(),
|
|
7957
|
-
plans: z10.array(ManifestPlanInputSchema).optional(),
|
|
7958
|
-
backend: z10.object({
|
|
7959
|
-
sourceDirectory: z10.string().optional(),
|
|
7960
|
-
publishDirectory: z10.string().optional(),
|
|
7961
|
-
openApiPath: z10.string().optional(),
|
|
7962
|
-
runtime: z10.string().optional(),
|
|
7963
|
-
runtimeVersion: z10.string().optional(),
|
|
7964
|
-
deployed: z10.boolean().optional()
|
|
7965
|
-
}).optional(),
|
|
7966
|
-
gateway: z10.object({
|
|
7967
|
-
authMode: z10.enum(["platformManagedEntra", "bringYourOwnOidc"]).optional(),
|
|
7968
|
-
oidcMetadataUrl: z10.string().optional(),
|
|
7969
|
-
oidcAllowedIssuers: z10.array(z10.string()).optional(),
|
|
7970
|
-
oidcAudiences: z10.array(z10.string()).optional(),
|
|
7971
|
-
limitsJson: z10.string().optional(),
|
|
7972
|
-
publicHealthActionKey: z10.string().optional()
|
|
7973
|
-
}).optional(),
|
|
7974
|
-
projectId: z10.string().optional(),
|
|
7975
|
-
projectName: z10.string().optional()
|
|
7976
|
-
});
|
|
7977
|
-
function normalizeBillingPeriod(period) {
|
|
7978
|
-
if (!period) {
|
|
7979
|
-
return "monthly";
|
|
7980
|
-
}
|
|
7981
|
-
const normalized = period.toLowerCase();
|
|
7982
|
-
if (normalized === "month") {
|
|
7983
|
-
return "monthly";
|
|
7984
|
-
}
|
|
7985
|
-
if (normalized === "year") {
|
|
7986
|
-
return "annual";
|
|
7987
|
-
}
|
|
7988
|
-
return normalized;
|
|
7989
|
-
}
|
|
7990
|
-
function plansToPreviewCatalog(plans) {
|
|
7991
|
-
if (!plans?.length) {
|
|
7992
|
-
return { plans: [] };
|
|
7993
|
-
}
|
|
7994
|
-
return {
|
|
7995
|
-
plans: plans.map((plan) => ({
|
|
7996
|
-
sku: plan.sku,
|
|
7997
|
-
displayName: plan.displayName,
|
|
7998
|
-
isFree: plan.isFree,
|
|
7999
|
-
priceAmount: plan.priceAmount ?? 0,
|
|
8000
|
-
priceCurrency: plan.priceCurrency ?? "usd",
|
|
8001
|
-
billingPeriod: normalizeBillingPeriod(plan.billingPeriod),
|
|
8002
|
-
limitsJson: plan.limitsJson ?? null,
|
|
8003
|
-
includedActionKeys: plan.includedActionKeys ?? []
|
|
8004
|
-
}))
|
|
8005
|
-
};
|
|
8006
|
-
}
|
|
8007
|
-
function manifestFilePath(rootDir) {
|
|
8008
|
-
return path20.join(path20.resolve(rootDir), DEV_PORTAL_MANIFEST_FILENAME);
|
|
8009
|
-
}
|
|
8010
|
-
function parseLocalManifestJson(raw) {
|
|
8011
|
-
try {
|
|
8012
|
-
const parsed = JSON.parse(raw);
|
|
8013
|
-
const result = DevPortalLocalManifestSchema.safeParse(parsed);
|
|
8014
|
-
if (!result.success) {
|
|
8015
|
-
return null;
|
|
8016
|
-
}
|
|
8017
|
-
return result.data;
|
|
8018
|
-
} catch {
|
|
8019
|
-
return null;
|
|
8020
|
-
}
|
|
8021
|
-
}
|
|
8022
|
-
|
|
8023
|
-
// src/vite/plugin-local-manifest.ts
|
|
8024
|
-
var APITOGO_LOCAL_MANIFEST_VIRTUAL_ID = "virtual:apitogo-local-manifest";
|
|
8025
|
-
var resolvedVirtualModuleId4 = `\0${APITOGO_LOCAL_MANIFEST_VIRTUAL_ID}`;
|
|
8026
|
-
var viteLocalManifestPlugin = () => {
|
|
8027
|
-
let rootDir = "";
|
|
8028
|
-
let manifestPath = "";
|
|
8029
|
-
const loadManifestModule = async () => {
|
|
8030
|
-
const { readFile: readFile8 } = await import("node:fs/promises");
|
|
8031
|
-
let catalog = { plans: [] };
|
|
8032
|
-
try {
|
|
8033
|
-
const raw = await readFile8(manifestPath, "utf8");
|
|
8034
|
-
const manifest = parseLocalManifestJson(raw);
|
|
8035
|
-
catalog = plansToPreviewCatalog(manifest?.plans);
|
|
8036
|
-
} catch {
|
|
8037
|
-
}
|
|
8038
|
-
return `export default ${JSON.stringify(catalog)};`;
|
|
8039
|
-
};
|
|
8040
|
-
return {
|
|
8041
|
-
name: "apitogo-local-manifest-plugin",
|
|
8042
|
-
configResolved(resolvedConfig) {
|
|
8043
|
-
rootDir = resolvedConfig.root;
|
|
8044
|
-
manifestPath = manifestFilePath(rootDir);
|
|
8045
|
-
},
|
|
8046
|
-
resolveId(id) {
|
|
8047
|
-
if (id === APITOGO_LOCAL_MANIFEST_VIRTUAL_ID) {
|
|
8048
|
-
return resolvedVirtualModuleId4;
|
|
8049
|
-
}
|
|
8050
|
-
},
|
|
8051
|
-
async load(id) {
|
|
8052
|
-
if (id !== resolvedVirtualModuleId4) {
|
|
8053
|
-
return;
|
|
8054
|
-
}
|
|
8055
|
-
return loadManifestModule();
|
|
8056
|
-
},
|
|
8057
|
-
configureServer(server) {
|
|
8058
|
-
const watchPath = path21.join(rootDir, DEV_PORTAL_MANIFEST_FILENAME);
|
|
8059
|
-
server.watcher.add(watchPath);
|
|
8060
|
-
server.watcher.on("change", async (changedPath) => {
|
|
8061
|
-
if (path21.resolve(changedPath) !== path21.resolve(manifestPath)) {
|
|
8062
|
-
return;
|
|
8063
|
-
}
|
|
8064
|
-
const module = server.moduleGraph.getModuleById(
|
|
8065
|
-
resolvedVirtualModuleId4
|
|
8066
|
-
);
|
|
8067
|
-
if (module) {
|
|
8068
|
-
server.moduleGraph.invalidateModule(module);
|
|
8069
|
-
}
|
|
8070
|
-
const mod = await server.moduleGraph.getModuleByUrl(
|
|
8071
|
-
APITOGO_LOCAL_MANIFEST_VIRTUAL_ID
|
|
8072
|
-
);
|
|
8073
|
-
if (mod) {
|
|
8074
|
-
server.reloadModule(mod);
|
|
8075
|
-
}
|
|
8076
|
-
server.ws.send({ type: "full-reload", path: "*" });
|
|
8077
|
-
});
|
|
8078
|
-
}
|
|
8079
|
-
};
|
|
8080
|
-
};
|
|
8081
|
-
var plugin_local_manifest_default = viteLocalManifestPlugin;
|
|
8082
|
-
|
|
8083
8194
|
// src/vite/plugin.ts
|
|
8084
8195
|
init_plugin_theme();
|
|
8085
8196
|
function vitePlugin() {
|
|
@@ -8411,7 +8522,7 @@ async function writeOutput(dir, {
|
|
|
8411
8522
|
// src/vite/prerender/prerender.ts
|
|
8412
8523
|
init_logger();
|
|
8413
8524
|
init_file_exists();
|
|
8414
|
-
import { readFile as
|
|
8525
|
+
import { readFile as readFile3, rm } from "node:fs/promises";
|
|
8415
8526
|
import os from "node:os";
|
|
8416
8527
|
import path26 from "node:path";
|
|
8417
8528
|
import { pathToFileURL } from "node:url";
|
|
@@ -8687,7 +8798,7 @@ var prerender = async ({
|
|
|
8687
8798
|
);
|
|
8688
8799
|
let markdownFileInfos = [];
|
|
8689
8800
|
if (await fileExists(markdownInfoPath)) {
|
|
8690
|
-
const markdownInfoContent = await
|
|
8801
|
+
const markdownInfoContent = await readFile3(markdownInfoPath, "utf-8");
|
|
8691
8802
|
markdownFileInfos = JSON.parse(markdownInfoContent);
|
|
8692
8803
|
}
|
|
8693
8804
|
if (llmsConfig.llmsTxt || llmsConfig.llmsTxtFull) {
|
|
@@ -8838,7 +8949,7 @@ var bundleSSREntry = async (options) => {
|
|
|
8838
8949
|
const { dir, adapter, serverOutDir, serverConfigFilename, html, basePath } = options;
|
|
8839
8950
|
const tempEntryPath = path27.join(dir, "__ssr-entry.ts");
|
|
8840
8951
|
const packageRoot = getZudokuRootDir();
|
|
8841
|
-
const templateContent = await
|
|
8952
|
+
const templateContent = await readFile4(
|
|
8842
8953
|
path27.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
|
|
8843
8954
|
"utf-8"
|
|
8844
8955
|
);
|
|
@@ -9115,7 +9226,7 @@ var build_default = {
|
|
|
9115
9226
|
|
|
9116
9227
|
// src/cli/configure-github-workflow/handler.ts
|
|
9117
9228
|
import { constants } from "node:fs";
|
|
9118
|
-
import { access, mkdir as mkdir6, writeFile as writeFile6 } from "node:fs/promises";
|
|
9229
|
+
import { access as access2, mkdir as mkdir6, writeFile as writeFile6 } from "node:fs/promises";
|
|
9119
9230
|
import path30 from "node:path";
|
|
9120
9231
|
var APITOGO_DEPLOY_WORKFLOW_YAML = `name: Build and Deploy
|
|
9121
9232
|
|
|
@@ -9232,7 +9343,7 @@ async function configureGithubWorkflow(argv) {
|
|
|
9232
9343
|
const workflowPath = path30.join(workflowDir, "apitogo-deploy.yml");
|
|
9233
9344
|
try {
|
|
9234
9345
|
try {
|
|
9235
|
-
await
|
|
9346
|
+
await access2(workflowPath, constants.F_OK);
|
|
9236
9347
|
if (!argv.force) {
|
|
9237
9348
|
await printCriticalFailureToConsoleAndExit(
|
|
9238
9349
|
`Workflow file already exists: ${workflowPath}. Pass --force to overwrite.`
|
|
@@ -9301,14 +9412,14 @@ function applyJsonOnlyDeployQuietMode() {
|
|
|
9301
9412
|
}
|
|
9302
9413
|
|
|
9303
9414
|
// src/cli/deploy/handler.ts
|
|
9304
|
-
import { access as
|
|
9415
|
+
import { access as access3, readFile as readFile5 } from "node:fs/promises";
|
|
9305
9416
|
import path31 from "node:path";
|
|
9306
9417
|
import { create as createTar } from "tar";
|
|
9307
9418
|
var DEPLOY_ENDPOINT = "https://deploy-server-dotnet2-b3fkcaaraydbckfe.canadacentral-01.azurewebsites.net/deploy";
|
|
9308
9419
|
var ARCHIVE_NAME = "dist.tgz";
|
|
9309
9420
|
var createDeploymentArchive = async (dir) => {
|
|
9310
9421
|
const distDir = path31.join(dir, "dist");
|
|
9311
|
-
await
|
|
9422
|
+
await access3(distDir);
|
|
9312
9423
|
const archivePath = path31.join(dir, ARCHIVE_NAME);
|
|
9313
9424
|
await createTar(
|
|
9314
9425
|
{
|
|
@@ -9339,7 +9450,7 @@ async function deploy(argv) {
|
|
|
9339
9450
|
`Uploading ${path31.basename(archivePath)} to ${env}...`
|
|
9340
9451
|
);
|
|
9341
9452
|
}
|
|
9342
|
-
const archiveBuffer = await
|
|
9453
|
+
const archiveBuffer = await readFile5(archivePath);
|
|
9343
9454
|
const formData = new FormData();
|
|
9344
9455
|
formData.append(
|
|
9345
9456
|
"file",
|
|
@@ -9826,14 +9937,14 @@ var dev_default = {
|
|
|
9826
9937
|
|
|
9827
9938
|
// src/cli/make-config/handler.ts
|
|
9828
9939
|
import { constants as constants3 } from "node:fs";
|
|
9829
|
-
import { access as
|
|
9940
|
+
import { access as access5, mkdir as mkdir7, readFile as readFile7, writeFile as writeFile8 } from "node:fs/promises";
|
|
9830
9941
|
import path36 from "node:path";
|
|
9831
9942
|
import { glob as glob5 } from "glob";
|
|
9832
9943
|
|
|
9833
9944
|
// src/cli/make-config/scaffold-project.ts
|
|
9834
9945
|
init_package_json();
|
|
9835
9946
|
import { constants as constants2 } from "node:fs";
|
|
9836
|
-
import { access as
|
|
9947
|
+
import { access as access4, readFile as readFile6, writeFile as writeFile7 } from "node:fs/promises";
|
|
9837
9948
|
import path35 from "node:path";
|
|
9838
9949
|
import { glob as glob4 } from "glob";
|
|
9839
9950
|
var OPENAPI_GLOBS = [
|
|
@@ -9908,7 +10019,7 @@ async function findOpenApiSpecPath(dir) {
|
|
|
9908
10019
|
for (const rel of OPENAPI_GLOBS) {
|
|
9909
10020
|
const full = path35.join(dir, rel);
|
|
9910
10021
|
try {
|
|
9911
|
-
await
|
|
10022
|
+
await access4(full, constants2.R_OK);
|
|
9912
10023
|
return toPosix(rel);
|
|
9913
10024
|
} catch {
|
|
9914
10025
|
}
|
|
@@ -9934,7 +10045,7 @@ async function ensurePackageJson(dir) {
|
|
|
9934
10045
|
preview: "apitogo preview"
|
|
9935
10046
|
};
|
|
9936
10047
|
try {
|
|
9937
|
-
await
|
|
10048
|
+
await access4(pkgPath, constants2.R_OK);
|
|
9938
10049
|
} catch (err) {
|
|
9939
10050
|
const code = err.code;
|
|
9940
10051
|
if (code !== "ENOENT") throw err;
|
|
@@ -9956,7 +10067,7 @@ async function ensurePackageJson(dir) {
|
|
|
9956
10067
|
`, "utf8");
|
|
9957
10068
|
return true;
|
|
9958
10069
|
}
|
|
9959
|
-
const raw = await
|
|
10070
|
+
const raw = await readFile6(pkgPath, "utf8");
|
|
9960
10071
|
let pkg;
|
|
9961
10072
|
try {
|
|
9962
10073
|
pkg = JSON.parse(raw);
|
|
@@ -9986,7 +10097,7 @@ async function ensurePackageJson(dir) {
|
|
|
9986
10097
|
async function ensureTsconfigJson(dir) {
|
|
9987
10098
|
const tsPath = path35.join(dir, "tsconfig.json");
|
|
9988
10099
|
try {
|
|
9989
|
-
await
|
|
10100
|
+
await access4(tsPath, constants2.R_OK);
|
|
9990
10101
|
return false;
|
|
9991
10102
|
} catch {
|
|
9992
10103
|
const tsconfig = {
|
|
@@ -10318,7 +10429,7 @@ var ensureApitogoDeployWorkflow = async (dir) => {
|
|
|
10318
10429
|
"apitogo-deploy.yml"
|
|
10319
10430
|
);
|
|
10320
10431
|
try {
|
|
10321
|
-
await
|
|
10432
|
+
await access5(workflowPath, constants3.F_OK);
|
|
10322
10433
|
return false;
|
|
10323
10434
|
} catch {
|
|
10324
10435
|
}
|
|
@@ -10330,7 +10441,7 @@ var findExistingConfigPath = async (dir) => {
|
|
|
10330
10441
|
for (const filename of CONFIG_FILENAMES) {
|
|
10331
10442
|
const fullPath = path36.join(dir, filename);
|
|
10332
10443
|
try {
|
|
10333
|
-
await
|
|
10444
|
+
await readFile7(fullPath, "utf8");
|
|
10334
10445
|
return fullPath;
|
|
10335
10446
|
} catch {
|
|
10336
10447
|
}
|
|
@@ -10377,7 +10488,7 @@ async function makeConfig(argv) {
|
|
|
10377
10488
|
if (routePaths.length === 0) {
|
|
10378
10489
|
throw new Error(`No .md or .mdx files found under '${pagesDir}'.`);
|
|
10379
10490
|
}
|
|
10380
|
-
let originalConfig = await
|
|
10491
|
+
let originalConfig = await readFile7(configPath, "utf8");
|
|
10381
10492
|
if (!createdNew && openApiSpecPath) {
|
|
10382
10493
|
originalConfig = insertApisIfMissing(
|
|
10383
10494
|
originalConfig,
|
|
@@ -10541,7 +10652,7 @@ var remove_default = {
|
|
|
10541
10652
|
|
|
10542
10653
|
// src/cli/common/outdated.ts
|
|
10543
10654
|
import { existsSync as existsSync2, mkdirSync } from "node:fs";
|
|
10544
|
-
import { readFile as
|
|
10655
|
+
import { readFile as readFile8, writeFile as writeFile9 } from "node:fs/promises";
|
|
10545
10656
|
import { join } from "node:path";
|
|
10546
10657
|
import colors10 from "picocolors";
|
|
10547
10658
|
import { gt } from "semver";
|
|
@@ -10671,7 +10782,7 @@ async function getVersionCheckInfo() {
|
|
|
10671
10782
|
let versionCheckInfo;
|
|
10672
10783
|
if (existsSync2(versionCheckPath)) {
|
|
10673
10784
|
try {
|
|
10674
|
-
versionCheckInfo = await
|
|
10785
|
+
versionCheckInfo = await readFile8(versionCheckPath, "utf-8").then(
|
|
10675
10786
|
JSON.parse
|
|
10676
10787
|
);
|
|
10677
10788
|
} catch {
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export declare const DEV_PORTAL_MANIFEST_FILENAME = "apitogo.local.json";
|
|
3
|
+
export declare const APITOGO_MANIFEST_BASE_FILENAME = "apitogo.json";
|
|
4
|
+
export declare const APITOGO_MANIFEST_ENV_FILES: {
|
|
5
|
+
readonly development: "apitogo.local.json";
|
|
6
|
+
readonly production: "apitogo.prod.json";
|
|
7
|
+
};
|
|
8
|
+
export type ApitogoManifestEnv = keyof typeof APITOGO_MANIFEST_ENV_FILES;
|
|
3
9
|
export declare const ManifestPlanInputSchema: z.ZodObject<{
|
|
4
10
|
sku: z.ZodString;
|
|
5
11
|
displayName: z.ZodString;
|
|
@@ -75,6 +81,16 @@ export type DevPortalPreviewPlanCatalog = {
|
|
|
75
81
|
};
|
|
76
82
|
export declare function normalizeBillingPeriod(period?: string): string;
|
|
77
83
|
export declare function plansToPreviewCatalog(plans: ManifestPlanInput[] | undefined): DevPortalPreviewPlanCatalog;
|
|
78
|
-
export declare function
|
|
84
|
+
export declare function resolveManifestEnv(viteMode: string): ApitogoManifestEnv;
|
|
85
|
+
export declare function mergePlansBySku(existing: ManifestPlanInput[] | undefined, patch: ManifestPlanInput[]): ManifestPlanInput[];
|
|
86
|
+
export declare function mergeManifest(base: DevPortalLocalManifest, override: DevPortalLocalManifest): DevPortalLocalManifest;
|
|
87
|
+
export declare function manifestFilePath(rootDir: string, filename?: string): string;
|
|
88
|
+
export declare function manifestPathsForEnv(rootDir: string, env: ApitogoManifestEnv): {
|
|
89
|
+
basePath: string;
|
|
90
|
+
overridePath: string;
|
|
91
|
+
watchPaths: string[];
|
|
92
|
+
};
|
|
79
93
|
export declare function parseLocalManifestJson(raw: string): DevPortalLocalManifest | null;
|
|
94
|
+
export declare function readManifestFile(rootDir: string, filename: string): Promise<DevPortalLocalManifest | null>;
|
|
95
|
+
export declare function readEffectiveManifest(rootDir: string, env: ApitogoManifestEnv): Promise<DevPortalLocalManifest | null>;
|
|
80
96
|
export declare function readLocalManifest(rootDir: string): Promise<DevPortalLocalManifest | null>;
|
|
@@ -46,16 +46,16 @@ VITE_APITOGO_DEV_PORTAL_API_URL=https://your-dev-portal-api.example.com
|
|
|
46
46
|
|
|
47
47
|
**Local preview:** When the backend URL is a placeholder or unreachable, the account area shows a
|
|
48
48
|
message that sign-in unlocks after publish. Docs and API reference remain public. Plans on
|
|
49
|
-
`/pricing` load from `apitogo.
|
|
50
|
-
hot-reload without restarting the dev server.
|
|
49
|
+
`/pricing` load from `apitogo.json` with optional `apitogo.local.json` overrides (including
|
|
50
|
+
`includedActionKeys` per plan). Plan edits hot-reload without restarting the dev server.
|
|
51
51
|
|
|
52
52
|
### Dev portal configuration files
|
|
53
53
|
|
|
54
|
-
| Concern
|
|
55
|
-
|
|
|
56
|
-
| Site nav, docs, plugins, auth wiring
|
|
57
|
-
| Plans, rate limits, `includedActionKeys`, project/deploy metadata | `apitogo.
|
|
58
|
-
| OIDC and Stripe for publish (MCP only)
|
|
54
|
+
| Concern | File |
|
|
55
|
+
| ----------------------------------------------------------------- | ---------------------------- |
|
|
56
|
+
| Site nav, docs, plugins, auth wiring | `apitogo.config.tsx` |
|
|
57
|
+
| Plans, rate limits, `includedActionKeys`, project/deploy metadata | `apitogo.json` (+ env overrides — see [Manifest](./manifest.md)) |
|
|
58
|
+
| OIDC and Stripe for publish (MCP only) | `apitogo.local.secrets.json` |
|
|
59
59
|
|
|
60
60
|
**Production:** Register one OIDC app with redirect URI `https://{backend}/signin-oidc` (see MCP
|
|
61
61
|
`manualSteps.oidcRedirectUri`). The frontend uses cookie sessions via `credentials: "include"` on
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Manifest (apitogo.json)
|
|
3
|
+
sidebar_icon: file-json
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Dev portal sites provisioned through APItoGo use JSON manifest files for plans, branding, backend
|
|
7
|
+
paths, and gateway settings. Shared defaults live in **`apitogo.json`**; optional per-environment
|
|
8
|
+
files override values without duplicating the full config.
|
|
9
|
+
|
|
10
|
+
## Files
|
|
11
|
+
|
|
12
|
+
| File | When used | Purpose |
|
|
13
|
+
| ---- | --------- | ------- |
|
|
14
|
+
| `apitogo.json` | Always (base) | Committed defaults: `siteName`, `branding`, `plans`, `backend`, `gateway` |
|
|
15
|
+
| `apitogo.local.json` | `npm run dev` | Local-only overrides (optional) |
|
|
16
|
+
| `apitogo.prod.json` | `npm run build` | Production build overrides (optional) |
|
|
17
|
+
| `apitogo.local.secrets.json` | MCP publish only | OIDC and Stripe credentials — never loaded by the dev server |
|
|
18
|
+
|
|
19
|
+
New scaffolds ship `apitogo.json` plus `apitogo.local.example.json` and `apitogo.prod.example.json`
|
|
20
|
+
to show how overrides work. Copy or rename the examples when you need environment-specific values.
|
|
21
|
+
|
|
22
|
+
## Resolution
|
|
23
|
+
|
|
24
|
+
At dev and build time the tooling merges the base file with the environment override:
|
|
25
|
+
|
|
26
|
+
```mermaid
|
|
27
|
+
flowchart LR
|
|
28
|
+
base["apitogo.json"]
|
|
29
|
+
local["apitogo.local.json"]
|
|
30
|
+
prod["apitogo.prod.json"]
|
|
31
|
+
devMerge["merge"]
|
|
32
|
+
buildMerge["merge"]
|
|
33
|
+
viteDev["npm run dev"]
|
|
34
|
+
viteBuild["npm run build"]
|
|
35
|
+
|
|
36
|
+
base --> devMerge
|
|
37
|
+
local --> devMerge
|
|
38
|
+
base --> buildMerge
|
|
39
|
+
prod --> buildMerge
|
|
40
|
+
viteDev --> devMerge
|
|
41
|
+
buildMerge --> viteBuild
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
- **Local preview** (`npm run dev`): `apitogo.json` + `apitogo.local.json`
|
|
45
|
+
- **Production build** (`npm run build`): `apitogo.json` + `apitogo.prod.json`
|
|
46
|
+
- **Deployed site**: plans are served from the live dev-portal API (`GET /api/v1/plans`), not from
|
|
47
|
+
JSON files in the browser bundle
|
|
48
|
+
|
|
49
|
+
If `apitogo.json` is missing but `apitogo.local.json` exists, the local file is used as the full
|
|
50
|
+
manifest (legacy single-file projects).
|
|
51
|
+
|
|
52
|
+
## Merge rules
|
|
53
|
+
|
|
54
|
+
Override files patch the base manifest:
|
|
55
|
+
|
|
56
|
+
- Top-level keys: override wins
|
|
57
|
+
- `branding`, `backend`, `gateway`: deep-merged (override fields patch nested objects)
|
|
58
|
+
- `plans`: merged by `sku` — an override plan with the same SKU updates only the fields you specify
|
|
59
|
+
|
|
60
|
+
Example base (`apitogo.json`):
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"siteName": "My API",
|
|
65
|
+
"branding": { "title": "My API" },
|
|
66
|
+
"plans": [
|
|
67
|
+
{
|
|
68
|
+
"sku": "pro",
|
|
69
|
+
"displayName": "Pro",
|
|
70
|
+
"isFree": false,
|
|
71
|
+
"priceAmount": 9.99,
|
|
72
|
+
"billingPeriod": "month"
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Example local override (`apitogo.local.json`):
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"projectId": "your-local-project-id",
|
|
83
|
+
"backend": { "sourceDirectory": "../my-api" }
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Example production override (`apitogo.prod.json`):
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"plans": [{ "sku": "pro", "priceAmount": 19.99 }],
|
|
92
|
+
"backend": { "deployed": true }
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## What to put where
|
|
97
|
+
|
|
98
|
+
| Concern | Recommended file |
|
|
99
|
+
| ------- | ---------------- |
|
|
100
|
+
| Plans, rate limits, `includedActionKeys` | `apitogo.json` (shared) |
|
|
101
|
+
| Branding, site name | `apitogo.json` |
|
|
102
|
+
| Backend paths, OpenAPI location | `apitogo.json`; machine-specific paths in `apitogo.local.json` |
|
|
103
|
+
| `projectId` after bootstrap | `apitogo.local.json` until MCP writes to the correct file |
|
|
104
|
+
| Production-only plan pricing or deploy flags | `apitogo.prod.json` |
|
|
105
|
+
| OIDC / Stripe | `apitogo.local.secrets.json` (see [Authentication](./authentication.md)) |
|
|
106
|
+
|
|
107
|
+
## Hot reload
|
|
108
|
+
|
|
109
|
+
During `npm run dev`, changes to `apitogo.json` or `apitogo.local.json` hot-reload on `/pricing`
|
|
110
|
+
without restarting the server. Restart the dev server after changing `VITE_APITOGO_DEV_PORTAL_API_URL`
|
|
111
|
+
in `.env`.
|
|
112
|
+
|
|
113
|
+
## Related configuration
|
|
114
|
+
|
|
115
|
+
- Site navigation, docs, and plugins: [`apitogo.config.tsx`](./overview.md)
|
|
116
|
+
- Authentication for dev-portal sites: [Authentication](./authentication.md)
|
package/package.json
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
1
|
+
import { access, readFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
|
|
5
|
+
/** @deprecated Use {@link APITOGO_MANIFEST_ENV_FILES.development} — kept for external consumers. */
|
|
5
6
|
export const DEV_PORTAL_MANIFEST_FILENAME = "apitogo.local.json";
|
|
6
7
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
|
|
8
|
+
export const APITOGO_MANIFEST_BASE_FILENAME = "apitogo.json";
|
|
9
|
+
|
|
10
|
+
export const APITOGO_MANIFEST_ENV_FILES = {
|
|
11
|
+
development: "apitogo.local.json",
|
|
12
|
+
production: "apitogo.prod.json",
|
|
13
|
+
} as const;
|
|
14
|
+
|
|
15
|
+
export type ApitogoManifestEnv = keyof typeof APITOGO_MANIFEST_ENV_FILES;
|
|
16
|
+
|
|
17
|
+
const BillingPeriodSchema = z.enum(["month", "year", "monthly", "annual"]);
|
|
13
18
|
|
|
14
19
|
export const ManifestPlanInputSchema = z.object({
|
|
15
20
|
sku: z.string().min(1),
|
|
@@ -56,7 +61,9 @@ export const DevPortalLocalManifestSchema = z.object({
|
|
|
56
61
|
});
|
|
57
62
|
|
|
58
63
|
export type ManifestPlanInput = z.infer<typeof ManifestPlanInputSchema>;
|
|
59
|
-
export type DevPortalLocalManifest = z.infer<
|
|
64
|
+
export type DevPortalLocalManifest = z.infer<
|
|
65
|
+
typeof DevPortalLocalManifestSchema
|
|
66
|
+
>;
|
|
60
67
|
|
|
61
68
|
export type DevPortalPreviewPlan = {
|
|
62
69
|
sku: string;
|
|
@@ -109,8 +116,70 @@ export function plansToPreviewCatalog(
|
|
|
109
116
|
};
|
|
110
117
|
}
|
|
111
118
|
|
|
112
|
-
export function
|
|
113
|
-
return
|
|
119
|
+
export function resolveManifestEnv(viteMode: string): ApitogoManifestEnv {
|
|
120
|
+
return viteMode === "production" ? "production" : "development";
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function mergePlansBySku(
|
|
124
|
+
existing: ManifestPlanInput[] | undefined,
|
|
125
|
+
patch: ManifestPlanInput[],
|
|
126
|
+
): ManifestPlanInput[] {
|
|
127
|
+
const bySku = new Map<string, ManifestPlanInput>();
|
|
128
|
+
for (const plan of existing ?? []) {
|
|
129
|
+
bySku.set(plan.sku, plan);
|
|
130
|
+
}
|
|
131
|
+
for (const plan of patch) {
|
|
132
|
+
const prior = bySku.get(plan.sku);
|
|
133
|
+
bySku.set(plan.sku, prior ? { ...prior, ...plan } : plan);
|
|
134
|
+
}
|
|
135
|
+
return Array.from(bySku.values());
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function mergeManifest(
|
|
139
|
+
base: DevPortalLocalManifest,
|
|
140
|
+
override: DevPortalLocalManifest,
|
|
141
|
+
): DevPortalLocalManifest {
|
|
142
|
+
const merged: DevPortalLocalManifest = { ...base, ...override };
|
|
143
|
+
|
|
144
|
+
if (override.branding) {
|
|
145
|
+
merged.branding = { ...base.branding, ...override.branding };
|
|
146
|
+
}
|
|
147
|
+
if (override.backend) {
|
|
148
|
+
merged.backend = { ...base.backend, ...override.backend };
|
|
149
|
+
}
|
|
150
|
+
if (override.gateway) {
|
|
151
|
+
merged.gateway = { ...base.gateway, ...override.gateway };
|
|
152
|
+
}
|
|
153
|
+
if (override.plans) {
|
|
154
|
+
merged.plans = mergePlansBySku(base.plans, override.plans);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return merged;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export function manifestFilePath(rootDir: string, filename?: string): string {
|
|
161
|
+
return path.join(
|
|
162
|
+
path.resolve(rootDir),
|
|
163
|
+
filename ?? DEV_PORTAL_MANIFEST_FILENAME,
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export function manifestPathsForEnv(
|
|
168
|
+
rootDir: string,
|
|
169
|
+
env: ApitogoManifestEnv,
|
|
170
|
+
): { basePath: string; overridePath: string; watchPaths: string[] } {
|
|
171
|
+
const resolvedRoot = path.resolve(rootDir);
|
|
172
|
+
const basePath = path.join(resolvedRoot, APITOGO_MANIFEST_BASE_FILENAME);
|
|
173
|
+
const overridePath = path.join(
|
|
174
|
+
resolvedRoot,
|
|
175
|
+
APITOGO_MANIFEST_ENV_FILES[env],
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
basePath,
|
|
180
|
+
overridePath,
|
|
181
|
+
watchPaths: [basePath, overridePath],
|
|
182
|
+
};
|
|
114
183
|
}
|
|
115
184
|
|
|
116
185
|
export function parseLocalManifestJson(
|
|
@@ -128,10 +197,20 @@ export function parseLocalManifestJson(
|
|
|
128
197
|
}
|
|
129
198
|
}
|
|
130
199
|
|
|
131
|
-
|
|
200
|
+
async function fileExists(filePath: string): Promise<boolean> {
|
|
201
|
+
try {
|
|
202
|
+
await access(filePath);
|
|
203
|
+
return true;
|
|
204
|
+
} catch {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export async function readManifestFile(
|
|
132
210
|
rootDir: string,
|
|
211
|
+
filename: string,
|
|
133
212
|
): Promise<DevPortalLocalManifest | null> {
|
|
134
|
-
const filePath = manifestFilePath(rootDir);
|
|
213
|
+
const filePath = manifestFilePath(rootDir, filename);
|
|
135
214
|
|
|
136
215
|
try {
|
|
137
216
|
const raw = await readFile(filePath, "utf8");
|
|
@@ -140,3 +219,53 @@ export async function readLocalManifest(
|
|
|
140
219
|
return null;
|
|
141
220
|
}
|
|
142
221
|
}
|
|
222
|
+
|
|
223
|
+
export async function readEffectiveManifest(
|
|
224
|
+
rootDir: string,
|
|
225
|
+
env: ApitogoManifestEnv,
|
|
226
|
+
): Promise<DevPortalLocalManifest | null> {
|
|
227
|
+
const { basePath, overridePath } = manifestPathsForEnv(rootDir, env);
|
|
228
|
+
const hasBase = await fileExists(basePath);
|
|
229
|
+
const hasOverride = await fileExists(overridePath);
|
|
230
|
+
|
|
231
|
+
if (!hasBase) {
|
|
232
|
+
const legacy = await readManifestFile(
|
|
233
|
+
rootDir,
|
|
234
|
+
APITOGO_MANIFEST_ENV_FILES.development,
|
|
235
|
+
);
|
|
236
|
+
if (legacy) {
|
|
237
|
+
return legacy;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (hasOverride) {
|
|
241
|
+
return readManifestFile(rootDir, APITOGO_MANIFEST_ENV_FILES[env]);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const base = await readManifestFile(rootDir, APITOGO_MANIFEST_BASE_FILENAME);
|
|
248
|
+
if (!base) {
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (!hasOverride) {
|
|
253
|
+
return base;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const override = await readManifestFile(
|
|
257
|
+
rootDir,
|
|
258
|
+
APITOGO_MANIFEST_ENV_FILES[env],
|
|
259
|
+
);
|
|
260
|
+
if (!override) {
|
|
261
|
+
return base;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return mergeManifest(base, override);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export async function readLocalManifest(
|
|
268
|
+
rootDir: string,
|
|
269
|
+
): Promise<DevPortalLocalManifest | null> {
|
|
270
|
+
return readEffectiveManifest(rootDir, "development");
|
|
271
|
+
}
|
|
@@ -1,26 +1,30 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import type { Plugin, ResolvedConfig } from "vite";
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
manifestFilePath,
|
|
6
|
-
parseLocalManifestJson,
|
|
4
|
+
manifestPathsForEnv,
|
|
7
5
|
plansToPreviewCatalog,
|
|
6
|
+
readEffectiveManifest,
|
|
7
|
+
resolveManifestEnv,
|
|
8
8
|
} from "../config/local-manifest.js";
|
|
9
9
|
|
|
10
|
-
export const APITOGO_LOCAL_MANIFEST_VIRTUAL_ID =
|
|
10
|
+
export const APITOGO_LOCAL_MANIFEST_VIRTUAL_ID =
|
|
11
|
+
"virtual:apitogo-local-manifest";
|
|
12
|
+
|
|
11
13
|
const resolvedVirtualModuleId = `\0${APITOGO_LOCAL_MANIFEST_VIRTUAL_ID}`;
|
|
12
14
|
|
|
13
15
|
const viteLocalManifestPlugin = (): Plugin => {
|
|
14
16
|
let rootDir = "";
|
|
15
|
-
let
|
|
17
|
+
let viteMode = "development";
|
|
18
|
+
let watchPaths: string[] = [];
|
|
16
19
|
|
|
17
20
|
const loadManifestModule = async (): Promise<string> => {
|
|
18
|
-
const
|
|
19
|
-
let catalog = {
|
|
21
|
+
const env = resolveManifestEnv(viteMode);
|
|
22
|
+
let catalog = {
|
|
23
|
+
plans: [] as ReturnType<typeof plansToPreviewCatalog>["plans"],
|
|
24
|
+
};
|
|
20
25
|
|
|
21
26
|
try {
|
|
22
|
-
const
|
|
23
|
-
const manifest = parseLocalManifestJson(raw);
|
|
27
|
+
const manifest = await readEffectiveManifest(rootDir, env);
|
|
24
28
|
catalog = plansToPreviewCatalog(manifest?.plans);
|
|
25
29
|
} catch {
|
|
26
30
|
// Missing or invalid manifest — empty catalog for preview.
|
|
@@ -33,7 +37,9 @@ const viteLocalManifestPlugin = (): Plugin => {
|
|
|
33
37
|
name: "apitogo-local-manifest-plugin",
|
|
34
38
|
configResolved(resolvedConfig: ResolvedConfig) {
|
|
35
39
|
rootDir = resolvedConfig.root;
|
|
36
|
-
|
|
40
|
+
viteMode = resolvedConfig.mode;
|
|
41
|
+
const env = resolveManifestEnv(viteMode);
|
|
42
|
+
watchPaths = manifestPathsForEnv(rootDir, env).watchPaths;
|
|
37
43
|
},
|
|
38
44
|
resolveId(id) {
|
|
39
45
|
if (id === APITOGO_LOCAL_MANIFEST_VIRTUAL_ID) {
|
|
@@ -48,11 +54,13 @@ const viteLocalManifestPlugin = (): Plugin => {
|
|
|
48
54
|
return loadManifestModule();
|
|
49
55
|
},
|
|
50
56
|
configureServer(server) {
|
|
51
|
-
const watchPath
|
|
57
|
+
for (const watchPath of watchPaths) {
|
|
58
|
+
server.watcher.add(watchPath);
|
|
59
|
+
}
|
|
52
60
|
|
|
53
|
-
server.watcher.add(watchPath);
|
|
54
61
|
server.watcher.on("change", async (changedPath) => {
|
|
55
|
-
|
|
62
|
+
const resolvedChanged = path.resolve(changedPath);
|
|
63
|
+
if (!watchPaths.some((p) => path.resolve(p) === resolvedChanged)) {
|
|
56
64
|
return;
|
|
57
65
|
}
|
|
58
66
|
|
|
@@ -106,32 +106,43 @@ const viteModulesPlugin = (): Plugin => {
|
|
|
106
106
|
);
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
const configuredPlugins: string[] = [];
|
|
110
|
+
|
|
111
|
+
if (landing.enabled) {
|
|
112
|
+
code.push(`import { landingModule } from "${landingImport}";`);
|
|
113
|
+
code.push(
|
|
114
|
+
`const landing = landingModule({`,
|
|
115
|
+
` ...${JSON.stringify(landingConfig)},`,
|
|
116
|
+
` component: config.modules?.landing?.component${landingPagePath ? " ?? LandingPage" : ""},`,
|
|
117
|
+
`});`,
|
|
118
|
+
);
|
|
119
|
+
configuredPlugins.push("...(landing ? [landing] : [])");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (userPanel.enabled) {
|
|
123
|
+
code.push(`import { userPanelModule } from "${userPanelImport}";`);
|
|
124
|
+
code.push(
|
|
125
|
+
`const userPanel = userPanelModule({`,
|
|
126
|
+
` ...${JSON.stringify(userPanelConfig)},`,
|
|
127
|
+
` dashboard: {`,
|
|
128
|
+
` ...${JSON.stringify(userPanelConfig.dashboard)},`,
|
|
129
|
+
` component: config.modules?.userPanel?.dashboard?.component${dashboardPagePath ? " ?? UserPanelDashboardPage" : ""},`,
|
|
130
|
+
` },`,
|
|
131
|
+
` userManagement: {`,
|
|
132
|
+
` ...${JSON.stringify(userPanelConfig.userManagement)},`,
|
|
133
|
+
` component: config.modules?.userPanel?.userManagement?.component${profilePagePath ? " ?? UserPanelProfilePage" : ""},`,
|
|
134
|
+
` },`,
|
|
135
|
+
` plans: {`,
|
|
136
|
+
` ...${JSON.stringify(userPanelConfig.plans)},`,
|
|
137
|
+
` component: config.modules?.userPanel?.plans?.component${plansPagePath ? " ?? UserPanelPlansPage" : ""},`,
|
|
138
|
+
` },`,
|
|
139
|
+
`});`,
|
|
140
|
+
);
|
|
141
|
+
configuredPlugins.push("...(userPanel ? [userPanel] : [])");
|
|
142
|
+
}
|
|
143
|
+
|
|
109
144
|
code.push(
|
|
110
|
-
`
|
|
111
|
-
`import { userPanelModule } from "${userPanelImport}";`,
|
|
112
|
-
`const landing = landingModule({`,
|
|
113
|
-
` ...${JSON.stringify(landingConfig)},`,
|
|
114
|
-
` component: config.modules?.landing?.component${landingPagePath ? " ?? LandingPage" : ""},`,
|
|
115
|
-
`});`,
|
|
116
|
-
`const userPanel = userPanelModule({`,
|
|
117
|
-
` ...${JSON.stringify(userPanelConfig)},`,
|
|
118
|
-
` dashboard: {`,
|
|
119
|
-
` ...${JSON.stringify(userPanelConfig.dashboard)},`,
|
|
120
|
-
` component: config.modules?.userPanel?.dashboard?.component${dashboardPagePath ? " ?? UserPanelDashboardPage" : ""},`,
|
|
121
|
-
` },`,
|
|
122
|
-
` userManagement: {`,
|
|
123
|
-
` ...${JSON.stringify(userPanelConfig.userManagement)},`,
|
|
124
|
-
` component: config.modules?.userPanel?.userManagement?.component${profilePagePath ? " ?? UserPanelProfilePage" : ""},`,
|
|
125
|
-
` },`,
|
|
126
|
-
` plans: {`,
|
|
127
|
-
` ...${JSON.stringify(userPanelConfig.plans)},`,
|
|
128
|
-
` component: config.modules?.userPanel?.plans?.component${plansPagePath ? " ?? UserPanelPlansPage" : ""},`,
|
|
129
|
-
` },`,
|
|
130
|
-
`});`,
|
|
131
|
-
`export const configuredModulesPlugins = [`,
|
|
132
|
-
` ...(landing ? [landing] : []),`,
|
|
133
|
-
` ...(userPanel ? [userPanel] : []),`,
|
|
134
|
-
`];`,
|
|
145
|
+
`export const configuredModulesPlugins = [${configuredPlugins.join(", ")}];`,
|
|
135
146
|
);
|
|
136
147
|
|
|
137
148
|
await writePluginDebugCode(config.__meta.rootDir, "modules-plugin", code);
|
package/src/vite/plugin.ts
CHANGED
|
@@ -11,13 +11,13 @@ import viteConfigPlugin from "./plugin-config.js";
|
|
|
11
11
|
import viteCustomPagesPlugin from "./plugin-custom-pages.js";
|
|
12
12
|
import { viteDocMetadataPlugin } from "./plugin-doc-metadata.js";
|
|
13
13
|
import viteDocsPlugin from "./plugin-docs.js";
|
|
14
|
+
import viteLocalManifestPlugin from "./plugin-local-manifest.js";
|
|
14
15
|
import viteMarkdownExportPlugin from "./plugin-markdown-export.js";
|
|
15
16
|
import viteMdxPlugin from "./plugin-mdx.js";
|
|
16
17
|
import viteModulesPlugin from "./plugin-modules.js";
|
|
17
18
|
import { viteNavigationPlugin } from "./plugin-navigation.js";
|
|
18
19
|
import { viteSearchPlugin } from "./plugin-search.js";
|
|
19
20
|
import { viteShikiRegisterPlugin } from "./plugin-shiki-register.js";
|
|
20
|
-
import viteLocalManifestPlugin from "./plugin-local-manifest.js";
|
|
21
21
|
import { viteThemePlugin } from "./plugin-theme.js";
|
|
22
22
|
|
|
23
23
|
export default function vitePlugin(): PluginOption {
|