@lukoweb/apitogo 0.1.47 → 0.1.49
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 +307 -192
- package/dist/declarations/config/local-manifest.d.ts +24 -2
- package/docs/configuration/authentication.md +7 -7
- package/docs/configuration/manifest.md +116 -0
- package/docs/quickstart.md +2 -2
- package/package.json +1 -1
- package/src/config/local-manifest.ts +165 -13
- package/src/vite/dev-portal-env.ts +1 -1
- package/src/vite/plugin-local-manifest.ts +21 -15
- 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.49",
|
|
4137
4137
|
type: "module",
|
|
4138
4138
|
sideEffects: [
|
|
4139
4139
|
"**/*.css",
|
|
@@ -7085,12 +7085,282 @@ 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
|
+
pricing: z10.object({
|
|
7119
|
+
enabled: z10.boolean().optional()
|
|
7120
|
+
}).optional(),
|
|
7121
|
+
plans: z10.array(ManifestPlanInputSchema).optional(),
|
|
7122
|
+
backend: z10.object({
|
|
7123
|
+
sourceDirectory: z10.string().optional(),
|
|
7124
|
+
publishDirectory: z10.string().optional(),
|
|
7125
|
+
openApiPath: z10.string().optional(),
|
|
7126
|
+
runtime: z10.string().optional(),
|
|
7127
|
+
runtimeVersion: z10.string().optional(),
|
|
7128
|
+
deployed: z10.boolean().optional()
|
|
7129
|
+
}).optional(),
|
|
7130
|
+
gateway: z10.object({
|
|
7131
|
+
authMode: z10.enum(["platformManagedEntra", "bringYourOwnOidc"]).optional(),
|
|
7132
|
+
oidcMetadataUrl: z10.string().optional(),
|
|
7133
|
+
oidcAllowedIssuers: z10.array(z10.string()).optional(),
|
|
7134
|
+
oidcAudiences: z10.array(z10.string()).optional(),
|
|
7135
|
+
limitsJson: z10.string().optional(),
|
|
7136
|
+
publicHealthActionKey: z10.string().optional()
|
|
7137
|
+
}).optional(),
|
|
7138
|
+
projectId: z10.string().optional(),
|
|
7139
|
+
projectName: z10.string().optional()
|
|
7140
|
+
});
|
|
7141
|
+
function isPricingEnabled(manifest) {
|
|
7142
|
+
return manifest?.pricing?.enabled === true;
|
|
7143
|
+
}
|
|
7144
|
+
function manifestToPreviewCatalog(manifest) {
|
|
7145
|
+
const plans = manifest?.plans;
|
|
7146
|
+
const catalog = plansToPreviewCatalog(plans);
|
|
7147
|
+
return {
|
|
7148
|
+
pricingEnabled: isPricingEnabled(manifest),
|
|
7149
|
+
plans: catalog.plans
|
|
7150
|
+
};
|
|
7151
|
+
}
|
|
7152
|
+
function normalizeBillingPeriod(period) {
|
|
7153
|
+
if (!period) {
|
|
7154
|
+
return "monthly";
|
|
7155
|
+
}
|
|
7156
|
+
const normalized = period.toLowerCase();
|
|
7157
|
+
if (normalized === "month") {
|
|
7158
|
+
return "monthly";
|
|
7159
|
+
}
|
|
7160
|
+
if (normalized === "year") {
|
|
7161
|
+
return "annual";
|
|
7162
|
+
}
|
|
7163
|
+
return normalized;
|
|
7164
|
+
}
|
|
7165
|
+
function plansToPreviewCatalog(plans) {
|
|
7166
|
+
if (!plans?.length) {
|
|
7167
|
+
return { plans: [] };
|
|
7168
|
+
}
|
|
7169
|
+
return {
|
|
7170
|
+
plans: plans.map((plan) => ({
|
|
7171
|
+
sku: plan.sku,
|
|
7172
|
+
displayName: plan.displayName,
|
|
7173
|
+
isFree: plan.isFree,
|
|
7174
|
+
priceAmount: plan.priceAmount ?? 0,
|
|
7175
|
+
priceCurrency: plan.priceCurrency ?? "usd",
|
|
7176
|
+
billingPeriod: normalizeBillingPeriod(plan.billingPeriod),
|
|
7177
|
+
limitsJson: plan.limitsJson ?? null,
|
|
7178
|
+
includedActionKeys: plan.includedActionKeys ?? []
|
|
7179
|
+
}))
|
|
7180
|
+
};
|
|
7181
|
+
}
|
|
7182
|
+
function resolveManifestEnv(viteMode) {
|
|
7183
|
+
return viteMode === "production" ? "production" : "development";
|
|
7184
|
+
}
|
|
7185
|
+
function mergePlansBySku(existing, patch) {
|
|
7186
|
+
const bySku = /* @__PURE__ */ new Map();
|
|
7187
|
+
for (const plan of existing ?? []) {
|
|
7188
|
+
bySku.set(plan.sku, plan);
|
|
7189
|
+
}
|
|
7190
|
+
for (const plan of patch) {
|
|
7191
|
+
const prior = bySku.get(plan.sku);
|
|
7192
|
+
bySku.set(plan.sku, prior ? { ...prior, ...plan } : plan);
|
|
7193
|
+
}
|
|
7194
|
+
return Array.from(bySku.values());
|
|
7195
|
+
}
|
|
7196
|
+
function mergeManifest(base, override) {
|
|
7197
|
+
const merged = { ...base, ...override };
|
|
7198
|
+
if (override.branding) {
|
|
7199
|
+
merged.branding = { ...base.branding, ...override.branding };
|
|
7200
|
+
}
|
|
7201
|
+
if (override.pricing) {
|
|
7202
|
+
merged.pricing = { ...base.pricing, ...override.pricing };
|
|
7203
|
+
}
|
|
7204
|
+
if (override.backend) {
|
|
7205
|
+
merged.backend = { ...base.backend, ...override.backend };
|
|
7206
|
+
}
|
|
7207
|
+
if (override.gateway) {
|
|
7208
|
+
merged.gateway = { ...base.gateway, ...override.gateway };
|
|
7209
|
+
}
|
|
7210
|
+
if (override.plans) {
|
|
7211
|
+
merged.plans = mergePlansBySku(base.plans, override.plans);
|
|
7212
|
+
}
|
|
7213
|
+
return merged;
|
|
7214
|
+
}
|
|
7215
|
+
function manifestFilePath(rootDir, filename) {
|
|
7216
|
+
return path15.join(
|
|
7217
|
+
path15.resolve(rootDir),
|
|
7218
|
+
filename ?? DEV_PORTAL_MANIFEST_FILENAME
|
|
7219
|
+
);
|
|
7220
|
+
}
|
|
7221
|
+
function manifestPathsForEnv(rootDir, env) {
|
|
7222
|
+
const resolvedRoot = path15.resolve(rootDir);
|
|
7223
|
+
const basePath = path15.join(resolvedRoot, APITOGO_MANIFEST_BASE_FILENAME);
|
|
7224
|
+
const overridePath = path15.join(resolvedRoot, APITOGO_MANIFEST_ENV_FILES[env]);
|
|
7225
|
+
return {
|
|
7226
|
+
basePath,
|
|
7227
|
+
overridePath,
|
|
7228
|
+
watchPaths: [basePath, overridePath]
|
|
7229
|
+
};
|
|
7230
|
+
}
|
|
7231
|
+
function parseLocalManifestJson(raw) {
|
|
7232
|
+
try {
|
|
7233
|
+
const parsed = JSON.parse(raw);
|
|
7234
|
+
const result = DevPortalLocalManifestSchema.safeParse(parsed);
|
|
7235
|
+
if (!result.success) {
|
|
7236
|
+
return null;
|
|
7237
|
+
}
|
|
7238
|
+
return result.data;
|
|
7239
|
+
} catch {
|
|
7240
|
+
return null;
|
|
7241
|
+
}
|
|
7242
|
+
}
|
|
7243
|
+
async function fileExists2(filePath) {
|
|
7244
|
+
try {
|
|
7245
|
+
await access(filePath);
|
|
7246
|
+
return true;
|
|
7247
|
+
} catch {
|
|
7248
|
+
return false;
|
|
7249
|
+
}
|
|
7250
|
+
}
|
|
7251
|
+
async function readManifestFile(rootDir, filename) {
|
|
7252
|
+
const filePath = manifestFilePath(rootDir, filename);
|
|
7253
|
+
try {
|
|
7254
|
+
const raw = await readFile2(filePath, "utf8");
|
|
7255
|
+
return parseLocalManifestJson(raw);
|
|
7256
|
+
} catch {
|
|
7257
|
+
return null;
|
|
7258
|
+
}
|
|
7259
|
+
}
|
|
7260
|
+
async function readEffectiveManifest(rootDir, env) {
|
|
7261
|
+
const { basePath, overridePath } = manifestPathsForEnv(rootDir, env);
|
|
7262
|
+
const hasBase = await fileExists2(basePath);
|
|
7263
|
+
const hasOverride = await fileExists2(overridePath);
|
|
7264
|
+
if (!hasBase) {
|
|
7265
|
+
const legacy = await readManifestFile(
|
|
7266
|
+
rootDir,
|
|
7267
|
+
APITOGO_MANIFEST_ENV_FILES.development
|
|
7268
|
+
);
|
|
7269
|
+
if (legacy) {
|
|
7270
|
+
return legacy;
|
|
7271
|
+
}
|
|
7272
|
+
if (hasOverride) {
|
|
7273
|
+
return readManifestFile(rootDir, APITOGO_MANIFEST_ENV_FILES[env]);
|
|
7274
|
+
}
|
|
7275
|
+
return null;
|
|
7276
|
+
}
|
|
7277
|
+
const base = await readManifestFile(rootDir, APITOGO_MANIFEST_BASE_FILENAME);
|
|
7278
|
+
if (!base) {
|
|
7279
|
+
return null;
|
|
7280
|
+
}
|
|
7281
|
+
if (!hasOverride) {
|
|
7282
|
+
return base;
|
|
7283
|
+
}
|
|
7284
|
+
const override = await readManifestFile(
|
|
7285
|
+
rootDir,
|
|
7286
|
+
APITOGO_MANIFEST_ENV_FILES[env]
|
|
7287
|
+
);
|
|
7288
|
+
if (!override) {
|
|
7289
|
+
return base;
|
|
7290
|
+
}
|
|
7291
|
+
return mergeManifest(base, override);
|
|
7292
|
+
}
|
|
7293
|
+
|
|
7294
|
+
// src/vite/plugin-local-manifest.ts
|
|
7295
|
+
var APITOGO_LOCAL_MANIFEST_VIRTUAL_ID = "virtual:apitogo-local-manifest";
|
|
7296
|
+
var resolvedVirtualModuleId4 = `\0${APITOGO_LOCAL_MANIFEST_VIRTUAL_ID}`;
|
|
7297
|
+
var viteLocalManifestPlugin = () => {
|
|
7298
|
+
let rootDir = "";
|
|
7299
|
+
let viteMode = "development";
|
|
7300
|
+
let watchPaths = [];
|
|
7301
|
+
const loadManifestModule = async () => {
|
|
7302
|
+
const env = resolveManifestEnv(viteMode);
|
|
7303
|
+
let catalog = manifestToPreviewCatalog(null);
|
|
7304
|
+
try {
|
|
7305
|
+
const manifest = await readEffectiveManifest(rootDir, env);
|
|
7306
|
+
catalog = manifestToPreviewCatalog(manifest);
|
|
7307
|
+
} catch {
|
|
7308
|
+
}
|
|
7309
|
+
return `export default ${JSON.stringify(catalog)};`;
|
|
7310
|
+
};
|
|
7311
|
+
return {
|
|
7312
|
+
name: "apitogo-local-manifest-plugin",
|
|
7313
|
+
configResolved(resolvedConfig) {
|
|
7314
|
+
rootDir = resolvedConfig.root;
|
|
7315
|
+
viteMode = resolvedConfig.mode;
|
|
7316
|
+
const env = resolveManifestEnv(viteMode);
|
|
7317
|
+
watchPaths = manifestPathsForEnv(rootDir, env).watchPaths;
|
|
7318
|
+
},
|
|
7319
|
+
resolveId(id) {
|
|
7320
|
+
if (id === APITOGO_LOCAL_MANIFEST_VIRTUAL_ID) {
|
|
7321
|
+
return resolvedVirtualModuleId4;
|
|
7322
|
+
}
|
|
7323
|
+
},
|
|
7324
|
+
async load(id) {
|
|
7325
|
+
if (id !== resolvedVirtualModuleId4) {
|
|
7326
|
+
return;
|
|
7327
|
+
}
|
|
7328
|
+
return loadManifestModule();
|
|
7329
|
+
},
|
|
7330
|
+
configureServer(server) {
|
|
7331
|
+
for (const watchPath of watchPaths) {
|
|
7332
|
+
server.watcher.add(watchPath);
|
|
7333
|
+
}
|
|
7334
|
+
server.watcher.on("change", async (changedPath) => {
|
|
7335
|
+
const resolvedChanged = path16.resolve(changedPath);
|
|
7336
|
+
if (!watchPaths.some((p) => path16.resolve(p) === resolvedChanged)) {
|
|
7337
|
+
return;
|
|
7338
|
+
}
|
|
7339
|
+
const module = server.moduleGraph.getModuleById(
|
|
7340
|
+
resolvedVirtualModuleId4
|
|
7341
|
+
);
|
|
7342
|
+
if (module) {
|
|
7343
|
+
server.moduleGraph.invalidateModule(module);
|
|
7344
|
+
}
|
|
7345
|
+
const mod = await server.moduleGraph.getModuleByUrl(
|
|
7346
|
+
APITOGO_LOCAL_MANIFEST_VIRTUAL_ID
|
|
7347
|
+
);
|
|
7348
|
+
if (mod) {
|
|
7349
|
+
server.reloadModule(mod);
|
|
7350
|
+
}
|
|
7351
|
+
server.ws.send({ type: "full-reload", path: "*" });
|
|
7352
|
+
});
|
|
7353
|
+
}
|
|
7354
|
+
};
|
|
7355
|
+
};
|
|
7356
|
+
var plugin_local_manifest_default = viteLocalManifestPlugin;
|
|
7357
|
+
|
|
7088
7358
|
// src/vite/plugin-markdown-export.ts
|
|
7089
7359
|
init_loader();
|
|
7090
7360
|
init_ProtectedRoutesSchema();
|
|
7091
7361
|
init_joinUrl();
|
|
7092
7362
|
import { mkdir as mkdir2, writeFile as writeFile2 } from "node:fs/promises";
|
|
7093
|
-
import
|
|
7363
|
+
import path17 from "node:path";
|
|
7094
7364
|
import { matchPath } from "react-router";
|
|
7095
7365
|
var processMarkdownFile = async (filePath) => {
|
|
7096
7366
|
const { content: markdownContent, data: frontmatter } = await readFrontmatter(filePath);
|
|
@@ -7178,7 +7448,7 @@ var viteMarkdownExportPlugin = () => {
|
|
|
7178
7448
|
if (process.env.NODE_ENV !== "production" || Object.keys(markdownFiles).length === 0 || !needsMdFiles) {
|
|
7179
7449
|
return;
|
|
7180
7450
|
}
|
|
7181
|
-
const distDir =
|
|
7451
|
+
const distDir = path17.join(
|
|
7182
7452
|
config2.__meta.rootDir,
|
|
7183
7453
|
"dist",
|
|
7184
7454
|
config2.basePath ?? ""
|
|
@@ -7199,15 +7469,15 @@ var viteMarkdownExportPlugin = () => {
|
|
|
7199
7469
|
content: finalMarkdown
|
|
7200
7470
|
});
|
|
7201
7471
|
const segments = routePath === "/" ? ["index"] : routePath.split("/").filter(Boolean);
|
|
7202
|
-
const outputPath = `${
|
|
7203
|
-
await mkdir2(
|
|
7472
|
+
const outputPath = `${path17.join(distDir, ...segments)}.md`;
|
|
7473
|
+
await mkdir2(path17.dirname(outputPath), { recursive: true });
|
|
7204
7474
|
await writeFile2(outputPath, finalMarkdown, "utf-8");
|
|
7205
7475
|
} catch (error) {
|
|
7206
7476
|
console.warn(`Failed to export markdown for ${routePath}:`, error);
|
|
7207
7477
|
}
|
|
7208
7478
|
}
|
|
7209
7479
|
if (config2.docs?.llms?.llmsTxt || config2.docs?.llms?.llmsTxtFull) {
|
|
7210
|
-
const markdownInfoPath =
|
|
7480
|
+
const markdownInfoPath = path17.join(
|
|
7211
7481
|
config2.__meta.rootDir,
|
|
7212
7482
|
"node_modules/.apitogo/markdown-info.json"
|
|
7213
7483
|
);
|
|
@@ -7359,9 +7629,9 @@ var remarkCodeTabs = () => (tree) => {
|
|
|
7359
7629
|
};
|
|
7360
7630
|
|
|
7361
7631
|
// src/vite/mdx/remark-inject-filepath.ts
|
|
7362
|
-
import
|
|
7632
|
+
import path18 from "node:path";
|
|
7363
7633
|
var remarkInjectFilepath = (rootDir) => (tree, vfile) => {
|
|
7364
|
-
const relativePath =
|
|
7634
|
+
const relativePath = path18.relative(rootDir, vfile.path).split(path18.sep).join(path18.posix.sep);
|
|
7365
7635
|
tree.children.unshift(exportMdxjsConst("__filepath", relativePath));
|
|
7366
7636
|
};
|
|
7367
7637
|
|
|
@@ -7448,18 +7718,18 @@ var remarkLastModified = () => {
|
|
|
7448
7718
|
};
|
|
7449
7719
|
|
|
7450
7720
|
// src/vite/mdx/remark-link-rewrite.ts
|
|
7451
|
-
import
|
|
7721
|
+
import path19 from "node:path";
|
|
7452
7722
|
import { visit as visit5 } from "unist-util-visit";
|
|
7453
7723
|
var remarkLinkRewrite = (basePath = "") => (tree) => {
|
|
7454
7724
|
visit5(tree, "link", (node) => {
|
|
7455
7725
|
if (!node.url) return;
|
|
7456
7726
|
if (node.url.startsWith("http") || node.url.startsWith("mailto:")) return;
|
|
7457
7727
|
node.url = node.url.replace(/\\/g, "/");
|
|
7458
|
-
const base =
|
|
7728
|
+
const base = path19.posix.join(basePath);
|
|
7459
7729
|
if (basePath && node.url.startsWith(base)) {
|
|
7460
7730
|
node.url = node.url.slice(base.length);
|
|
7461
7731
|
} else if (!node.url.startsWith("/") && !node.url.startsWith("#")) {
|
|
7462
|
-
node.url =
|
|
7732
|
+
node.url = path19.posix.join("..", node.url);
|
|
7463
7733
|
}
|
|
7464
7734
|
node.url = node.url.replace(/\.mdx?(#.*)?$/, "$1");
|
|
7465
7735
|
});
|
|
@@ -7679,11 +7949,11 @@ var plugin_mdx_default = viteMdxPlugin;
|
|
|
7679
7949
|
|
|
7680
7950
|
// src/vite/plugin-modules.ts
|
|
7681
7951
|
init_loader();
|
|
7682
|
-
import
|
|
7952
|
+
import path20 from "node:path";
|
|
7683
7953
|
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(
|
|
7954
|
+
var getLandingModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path20.join(moduleDir, "../module-landing/src/index.tsx")) : "@lukoweb/apitogo-module-landing";
|
|
7955
|
+
var getUserPanelModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path20.join(moduleDir, "../module-user-panel/src/index.tsx")) : "@lukoweb/apitogo-module-user-panel";
|
|
7956
|
+
var resolveProjectPageImport = (rootDir, pagePath) => normalizePath2(path20.resolve(rootDir, pagePath));
|
|
7687
7957
|
var viteModulesPlugin = () => {
|
|
7688
7958
|
const virtualModuleId4 = "virtual:zudoku-modules-plugin";
|
|
7689
7959
|
const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
|
|
@@ -7804,7 +8074,7 @@ var plugin_modules_default = viteModulesPlugin;
|
|
|
7804
8074
|
|
|
7805
8075
|
// src/vite/plugin-search.ts
|
|
7806
8076
|
init_loader();
|
|
7807
|
-
import
|
|
8077
|
+
import path21 from "node:path";
|
|
7808
8078
|
var viteSearchPlugin = () => {
|
|
7809
8079
|
const virtualModuleId4 = "virtual:zudoku-search-plugin";
|
|
7810
8080
|
const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
|
|
@@ -7822,7 +8092,7 @@ var viteSearchPlugin = () => {
|
|
|
7822
8092
|
return resolvedVirtualModuleId5;
|
|
7823
8093
|
}
|
|
7824
8094
|
if (id === "/pagefind/pagefind.js" && resolvedViteConfig?.publicDir) {
|
|
7825
|
-
return
|
|
8095
|
+
return path21.join(resolvedViteConfig.publicDir, "pagefind/pagefind.js");
|
|
7826
8096
|
}
|
|
7827
8097
|
},
|
|
7828
8098
|
async load(id) {
|
|
@@ -7933,161 +8203,6 @@ var viteShikiRegisterPlugin = () => {
|
|
|
7933
8203
|
};
|
|
7934
8204
|
};
|
|
7935
8205
|
|
|
7936
|
-
// src/vite/plugin-local-manifest.ts
|
|
7937
|
-
import path21 from "node:path";
|
|
7938
|
-
|
|
7939
|
-
// src/config/local-manifest.ts
|
|
7940
|
-
import path20 from "node:path";
|
|
7941
|
-
import { z as z10 } from "zod";
|
|
7942
|
-
var DEV_PORTAL_MANIFEST_FILENAME = "apitogo.local.json";
|
|
7943
|
-
var BillingPeriodSchema = z10.enum([
|
|
7944
|
-
"month",
|
|
7945
|
-
"year",
|
|
7946
|
-
"monthly",
|
|
7947
|
-
"annual"
|
|
7948
|
-
]);
|
|
7949
|
-
var ManifestPlanInputSchema = z10.object({
|
|
7950
|
-
sku: z10.string().min(1),
|
|
7951
|
-
displayName: z10.string().min(1),
|
|
7952
|
-
isFree: z10.boolean(),
|
|
7953
|
-
priceAmount: z10.number().optional(),
|
|
7954
|
-
priceCurrency: z10.string().optional(),
|
|
7955
|
-
billingPeriod: BillingPeriodSchema.optional(),
|
|
7956
|
-
limitsJson: z10.string().optional(),
|
|
7957
|
-
includedActionKeys: z10.array(z10.string()).optional()
|
|
7958
|
-
});
|
|
7959
|
-
var DevPortalLocalManifestSchema = z10.object({
|
|
7960
|
-
siteName: z10.string().optional(),
|
|
7961
|
-
branding: z10.object({
|
|
7962
|
-
title: z10.string().optional(),
|
|
7963
|
-
logoUrl: z10.string().optional()
|
|
7964
|
-
}).optional(),
|
|
7965
|
-
plans: z10.array(ManifestPlanInputSchema).optional(),
|
|
7966
|
-
backend: z10.object({
|
|
7967
|
-
sourceDirectory: z10.string().optional(),
|
|
7968
|
-
publishDirectory: z10.string().optional(),
|
|
7969
|
-
openApiPath: z10.string().optional(),
|
|
7970
|
-
runtime: z10.string().optional(),
|
|
7971
|
-
runtimeVersion: z10.string().optional(),
|
|
7972
|
-
deployed: z10.boolean().optional()
|
|
7973
|
-
}).optional(),
|
|
7974
|
-
gateway: z10.object({
|
|
7975
|
-
authMode: z10.enum(["platformManagedEntra", "bringYourOwnOidc"]).optional(),
|
|
7976
|
-
oidcMetadataUrl: z10.string().optional(),
|
|
7977
|
-
oidcAllowedIssuers: z10.array(z10.string()).optional(),
|
|
7978
|
-
oidcAudiences: z10.array(z10.string()).optional(),
|
|
7979
|
-
limitsJson: z10.string().optional(),
|
|
7980
|
-
publicHealthActionKey: z10.string().optional()
|
|
7981
|
-
}).optional(),
|
|
7982
|
-
projectId: z10.string().optional(),
|
|
7983
|
-
projectName: z10.string().optional()
|
|
7984
|
-
});
|
|
7985
|
-
function normalizeBillingPeriod(period) {
|
|
7986
|
-
if (!period) {
|
|
7987
|
-
return "monthly";
|
|
7988
|
-
}
|
|
7989
|
-
const normalized = period.toLowerCase();
|
|
7990
|
-
if (normalized === "month") {
|
|
7991
|
-
return "monthly";
|
|
7992
|
-
}
|
|
7993
|
-
if (normalized === "year") {
|
|
7994
|
-
return "annual";
|
|
7995
|
-
}
|
|
7996
|
-
return normalized;
|
|
7997
|
-
}
|
|
7998
|
-
function plansToPreviewCatalog(plans) {
|
|
7999
|
-
if (!plans?.length) {
|
|
8000
|
-
return { plans: [] };
|
|
8001
|
-
}
|
|
8002
|
-
return {
|
|
8003
|
-
plans: plans.map((plan) => ({
|
|
8004
|
-
sku: plan.sku,
|
|
8005
|
-
displayName: plan.displayName,
|
|
8006
|
-
isFree: plan.isFree,
|
|
8007
|
-
priceAmount: plan.priceAmount ?? 0,
|
|
8008
|
-
priceCurrency: plan.priceCurrency ?? "usd",
|
|
8009
|
-
billingPeriod: normalizeBillingPeriod(plan.billingPeriod),
|
|
8010
|
-
limitsJson: plan.limitsJson ?? null,
|
|
8011
|
-
includedActionKeys: plan.includedActionKeys ?? []
|
|
8012
|
-
}))
|
|
8013
|
-
};
|
|
8014
|
-
}
|
|
8015
|
-
function manifestFilePath(rootDir) {
|
|
8016
|
-
return path20.join(path20.resolve(rootDir), DEV_PORTAL_MANIFEST_FILENAME);
|
|
8017
|
-
}
|
|
8018
|
-
function parseLocalManifestJson(raw) {
|
|
8019
|
-
try {
|
|
8020
|
-
const parsed = JSON.parse(raw);
|
|
8021
|
-
const result = DevPortalLocalManifestSchema.safeParse(parsed);
|
|
8022
|
-
if (!result.success) {
|
|
8023
|
-
return null;
|
|
8024
|
-
}
|
|
8025
|
-
return result.data;
|
|
8026
|
-
} catch {
|
|
8027
|
-
return null;
|
|
8028
|
-
}
|
|
8029
|
-
}
|
|
8030
|
-
|
|
8031
|
-
// src/vite/plugin-local-manifest.ts
|
|
8032
|
-
var APITOGO_LOCAL_MANIFEST_VIRTUAL_ID = "virtual:apitogo-local-manifest";
|
|
8033
|
-
var resolvedVirtualModuleId4 = `\0${APITOGO_LOCAL_MANIFEST_VIRTUAL_ID}`;
|
|
8034
|
-
var viteLocalManifestPlugin = () => {
|
|
8035
|
-
let rootDir = "";
|
|
8036
|
-
let manifestPath = "";
|
|
8037
|
-
const loadManifestModule = async () => {
|
|
8038
|
-
const { readFile: readFile8 } = await import("node:fs/promises");
|
|
8039
|
-
let catalog = { plans: [] };
|
|
8040
|
-
try {
|
|
8041
|
-
const raw = await readFile8(manifestPath, "utf8");
|
|
8042
|
-
const manifest = parseLocalManifestJson(raw);
|
|
8043
|
-
catalog = plansToPreviewCatalog(manifest?.plans);
|
|
8044
|
-
} catch {
|
|
8045
|
-
}
|
|
8046
|
-
return `export default ${JSON.stringify(catalog)};`;
|
|
8047
|
-
};
|
|
8048
|
-
return {
|
|
8049
|
-
name: "apitogo-local-manifest-plugin",
|
|
8050
|
-
configResolved(resolvedConfig) {
|
|
8051
|
-
rootDir = resolvedConfig.root;
|
|
8052
|
-
manifestPath = manifestFilePath(rootDir);
|
|
8053
|
-
},
|
|
8054
|
-
resolveId(id) {
|
|
8055
|
-
if (id === APITOGO_LOCAL_MANIFEST_VIRTUAL_ID) {
|
|
8056
|
-
return resolvedVirtualModuleId4;
|
|
8057
|
-
}
|
|
8058
|
-
},
|
|
8059
|
-
async load(id) {
|
|
8060
|
-
if (id !== resolvedVirtualModuleId4) {
|
|
8061
|
-
return;
|
|
8062
|
-
}
|
|
8063
|
-
return loadManifestModule();
|
|
8064
|
-
},
|
|
8065
|
-
configureServer(server) {
|
|
8066
|
-
const watchPath = path21.join(rootDir, DEV_PORTAL_MANIFEST_FILENAME);
|
|
8067
|
-
server.watcher.add(watchPath);
|
|
8068
|
-
server.watcher.on("change", async (changedPath) => {
|
|
8069
|
-
if (path21.resolve(changedPath) !== path21.resolve(manifestPath)) {
|
|
8070
|
-
return;
|
|
8071
|
-
}
|
|
8072
|
-
const module = server.moduleGraph.getModuleById(
|
|
8073
|
-
resolvedVirtualModuleId4
|
|
8074
|
-
);
|
|
8075
|
-
if (module) {
|
|
8076
|
-
server.moduleGraph.invalidateModule(module);
|
|
8077
|
-
}
|
|
8078
|
-
const mod = await server.moduleGraph.getModuleByUrl(
|
|
8079
|
-
APITOGO_LOCAL_MANIFEST_VIRTUAL_ID
|
|
8080
|
-
);
|
|
8081
|
-
if (mod) {
|
|
8082
|
-
server.reloadModule(mod);
|
|
8083
|
-
}
|
|
8084
|
-
server.ws.send({ type: "full-reload", path: "*" });
|
|
8085
|
-
});
|
|
8086
|
-
}
|
|
8087
|
-
};
|
|
8088
|
-
};
|
|
8089
|
-
var plugin_local_manifest_default = viteLocalManifestPlugin;
|
|
8090
|
-
|
|
8091
8206
|
// src/vite/plugin.ts
|
|
8092
8207
|
init_plugin_theme();
|
|
8093
8208
|
function vitePlugin() {
|
|
@@ -8419,7 +8534,7 @@ async function writeOutput(dir, {
|
|
|
8419
8534
|
// src/vite/prerender/prerender.ts
|
|
8420
8535
|
init_logger();
|
|
8421
8536
|
init_file_exists();
|
|
8422
|
-
import { readFile as
|
|
8537
|
+
import { readFile as readFile3, rm } from "node:fs/promises";
|
|
8423
8538
|
import os from "node:os";
|
|
8424
8539
|
import path26 from "node:path";
|
|
8425
8540
|
import { pathToFileURL } from "node:url";
|
|
@@ -8695,7 +8810,7 @@ var prerender = async ({
|
|
|
8695
8810
|
);
|
|
8696
8811
|
let markdownFileInfos = [];
|
|
8697
8812
|
if (await fileExists(markdownInfoPath)) {
|
|
8698
|
-
const markdownInfoContent = await
|
|
8813
|
+
const markdownInfoContent = await readFile3(markdownInfoPath, "utf-8");
|
|
8699
8814
|
markdownFileInfos = JSON.parse(markdownInfoContent);
|
|
8700
8815
|
}
|
|
8701
8816
|
if (llmsConfig.llmsTxt || llmsConfig.llmsTxtFull) {
|
|
@@ -8846,7 +8961,7 @@ var bundleSSREntry = async (options) => {
|
|
|
8846
8961
|
const { dir, adapter, serverOutDir, serverConfigFilename, html, basePath } = options;
|
|
8847
8962
|
const tempEntryPath = path27.join(dir, "__ssr-entry.ts");
|
|
8848
8963
|
const packageRoot = getZudokuRootDir();
|
|
8849
|
-
const templateContent = await
|
|
8964
|
+
const templateContent = await readFile4(
|
|
8850
8965
|
path27.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
|
|
8851
8966
|
"utf-8"
|
|
8852
8967
|
);
|
|
@@ -9123,7 +9238,7 @@ var build_default = {
|
|
|
9123
9238
|
|
|
9124
9239
|
// src/cli/configure-github-workflow/handler.ts
|
|
9125
9240
|
import { constants } from "node:fs";
|
|
9126
|
-
import { access, mkdir as mkdir6, writeFile as writeFile6 } from "node:fs/promises";
|
|
9241
|
+
import { access as access2, mkdir as mkdir6, writeFile as writeFile6 } from "node:fs/promises";
|
|
9127
9242
|
import path30 from "node:path";
|
|
9128
9243
|
var APITOGO_DEPLOY_WORKFLOW_YAML = `name: Build and Deploy
|
|
9129
9244
|
|
|
@@ -9240,7 +9355,7 @@ async function configureGithubWorkflow(argv) {
|
|
|
9240
9355
|
const workflowPath = path30.join(workflowDir, "apitogo-deploy.yml");
|
|
9241
9356
|
try {
|
|
9242
9357
|
try {
|
|
9243
|
-
await
|
|
9358
|
+
await access2(workflowPath, constants.F_OK);
|
|
9244
9359
|
if (!argv.force) {
|
|
9245
9360
|
await printCriticalFailureToConsoleAndExit(
|
|
9246
9361
|
`Workflow file already exists: ${workflowPath}. Pass --force to overwrite.`
|
|
@@ -9309,14 +9424,14 @@ function applyJsonOnlyDeployQuietMode() {
|
|
|
9309
9424
|
}
|
|
9310
9425
|
|
|
9311
9426
|
// src/cli/deploy/handler.ts
|
|
9312
|
-
import { access as
|
|
9427
|
+
import { access as access3, readFile as readFile5 } from "node:fs/promises";
|
|
9313
9428
|
import path31 from "node:path";
|
|
9314
9429
|
import { create as createTar } from "tar";
|
|
9315
9430
|
var DEPLOY_ENDPOINT = "https://deploy-server-dotnet2-b3fkcaaraydbckfe.canadacentral-01.azurewebsites.net/deploy";
|
|
9316
9431
|
var ARCHIVE_NAME = "dist.tgz";
|
|
9317
9432
|
var createDeploymentArchive = async (dir) => {
|
|
9318
9433
|
const distDir = path31.join(dir, "dist");
|
|
9319
|
-
await
|
|
9434
|
+
await access3(distDir);
|
|
9320
9435
|
const archivePath = path31.join(dir, ARCHIVE_NAME);
|
|
9321
9436
|
await createTar(
|
|
9322
9437
|
{
|
|
@@ -9347,7 +9462,7 @@ async function deploy(argv) {
|
|
|
9347
9462
|
`Uploading ${path31.basename(archivePath)} to ${env}...`
|
|
9348
9463
|
);
|
|
9349
9464
|
}
|
|
9350
|
-
const archiveBuffer = await
|
|
9465
|
+
const archiveBuffer = await readFile5(archivePath);
|
|
9351
9466
|
const formData = new FormData();
|
|
9352
9467
|
formData.append(
|
|
9353
9468
|
"file",
|
|
@@ -9834,14 +9949,14 @@ var dev_default = {
|
|
|
9834
9949
|
|
|
9835
9950
|
// src/cli/make-config/handler.ts
|
|
9836
9951
|
import { constants as constants3 } from "node:fs";
|
|
9837
|
-
import { access as
|
|
9952
|
+
import { access as access5, mkdir as mkdir7, readFile as readFile7, writeFile as writeFile8 } from "node:fs/promises";
|
|
9838
9953
|
import path36 from "node:path";
|
|
9839
9954
|
import { glob as glob5 } from "glob";
|
|
9840
9955
|
|
|
9841
9956
|
// src/cli/make-config/scaffold-project.ts
|
|
9842
9957
|
init_package_json();
|
|
9843
9958
|
import { constants as constants2 } from "node:fs";
|
|
9844
|
-
import { access as
|
|
9959
|
+
import { access as access4, readFile as readFile6, writeFile as writeFile7 } from "node:fs/promises";
|
|
9845
9960
|
import path35 from "node:path";
|
|
9846
9961
|
import { glob as glob4 } from "glob";
|
|
9847
9962
|
var OPENAPI_GLOBS = [
|
|
@@ -9916,7 +10031,7 @@ async function findOpenApiSpecPath(dir) {
|
|
|
9916
10031
|
for (const rel of OPENAPI_GLOBS) {
|
|
9917
10032
|
const full = path35.join(dir, rel);
|
|
9918
10033
|
try {
|
|
9919
|
-
await
|
|
10034
|
+
await access4(full, constants2.R_OK);
|
|
9920
10035
|
return toPosix(rel);
|
|
9921
10036
|
} catch {
|
|
9922
10037
|
}
|
|
@@ -9942,7 +10057,7 @@ async function ensurePackageJson(dir) {
|
|
|
9942
10057
|
preview: "apitogo preview"
|
|
9943
10058
|
};
|
|
9944
10059
|
try {
|
|
9945
|
-
await
|
|
10060
|
+
await access4(pkgPath, constants2.R_OK);
|
|
9946
10061
|
} catch (err) {
|
|
9947
10062
|
const code = err.code;
|
|
9948
10063
|
if (code !== "ENOENT") throw err;
|
|
@@ -9964,7 +10079,7 @@ async function ensurePackageJson(dir) {
|
|
|
9964
10079
|
`, "utf8");
|
|
9965
10080
|
return true;
|
|
9966
10081
|
}
|
|
9967
|
-
const raw = await
|
|
10082
|
+
const raw = await readFile6(pkgPath, "utf8");
|
|
9968
10083
|
let pkg;
|
|
9969
10084
|
try {
|
|
9970
10085
|
pkg = JSON.parse(raw);
|
|
@@ -9994,7 +10109,7 @@ async function ensurePackageJson(dir) {
|
|
|
9994
10109
|
async function ensureTsconfigJson(dir) {
|
|
9995
10110
|
const tsPath = path35.join(dir, "tsconfig.json");
|
|
9996
10111
|
try {
|
|
9997
|
-
await
|
|
10112
|
+
await access4(tsPath, constants2.R_OK);
|
|
9998
10113
|
return false;
|
|
9999
10114
|
} catch {
|
|
10000
10115
|
const tsconfig = {
|
|
@@ -10326,7 +10441,7 @@ var ensureApitogoDeployWorkflow = async (dir) => {
|
|
|
10326
10441
|
"apitogo-deploy.yml"
|
|
10327
10442
|
);
|
|
10328
10443
|
try {
|
|
10329
|
-
await
|
|
10444
|
+
await access5(workflowPath, constants3.F_OK);
|
|
10330
10445
|
return false;
|
|
10331
10446
|
} catch {
|
|
10332
10447
|
}
|
|
@@ -10338,7 +10453,7 @@ var findExistingConfigPath = async (dir) => {
|
|
|
10338
10453
|
for (const filename of CONFIG_FILENAMES) {
|
|
10339
10454
|
const fullPath = path36.join(dir, filename);
|
|
10340
10455
|
try {
|
|
10341
|
-
await
|
|
10456
|
+
await readFile7(fullPath, "utf8");
|
|
10342
10457
|
return fullPath;
|
|
10343
10458
|
} catch {
|
|
10344
10459
|
}
|
|
@@ -10385,7 +10500,7 @@ async function makeConfig(argv) {
|
|
|
10385
10500
|
if (routePaths.length === 0) {
|
|
10386
10501
|
throw new Error(`No .md or .mdx files found under '${pagesDir}'.`);
|
|
10387
10502
|
}
|
|
10388
|
-
let originalConfig = await
|
|
10503
|
+
let originalConfig = await readFile7(configPath, "utf8");
|
|
10389
10504
|
if (!createdNew && openApiSpecPath) {
|
|
10390
10505
|
originalConfig = insertApisIfMissing(
|
|
10391
10506
|
originalConfig,
|
|
@@ -10549,7 +10664,7 @@ var remove_default = {
|
|
|
10549
10664
|
|
|
10550
10665
|
// src/cli/common/outdated.ts
|
|
10551
10666
|
import { existsSync as existsSync2, mkdirSync } from "node:fs";
|
|
10552
|
-
import { readFile as
|
|
10667
|
+
import { readFile as readFile8, writeFile as writeFile9 } from "node:fs/promises";
|
|
10553
10668
|
import { join } from "node:path";
|
|
10554
10669
|
import colors10 from "picocolors";
|
|
10555
10670
|
import { gt } from "semver";
|
|
@@ -10679,7 +10794,7 @@ async function getVersionCheckInfo() {
|
|
|
10679
10794
|
let versionCheckInfo;
|
|
10680
10795
|
if (existsSync2(versionCheckPath)) {
|
|
10681
10796
|
try {
|
|
10682
|
-
versionCheckInfo = await
|
|
10797
|
+
versionCheckInfo = await readFile8(versionCheckPath, "utf-8").then(
|
|
10683
10798
|
JSON.parse
|
|
10684
10799
|
);
|
|
10685
10800
|
} 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;
|
|
@@ -21,6 +27,9 @@ export declare const DevPortalLocalManifestSchema: z.ZodObject<{
|
|
|
21
27
|
title: z.ZodOptional<z.ZodString>;
|
|
22
28
|
logoUrl: z.ZodOptional<z.ZodString>;
|
|
23
29
|
}, z.core.$strip>>;
|
|
30
|
+
pricing: z.ZodOptional<z.ZodObject<{
|
|
31
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
32
|
+
}, z.core.$strip>>;
|
|
24
33
|
plans: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
25
34
|
sku: z.ZodString;
|
|
26
35
|
displayName: z.ZodString;
|
|
@@ -71,10 +80,23 @@ export type DevPortalPreviewPlan = {
|
|
|
71
80
|
includedActionKeys: string[];
|
|
72
81
|
};
|
|
73
82
|
export type DevPortalPreviewPlanCatalog = {
|
|
83
|
+
pricingEnabled: boolean;
|
|
74
84
|
plans: DevPortalPreviewPlan[];
|
|
75
85
|
};
|
|
86
|
+
export declare function isPricingEnabled(manifest: DevPortalLocalManifest | null | undefined): boolean;
|
|
87
|
+
export declare function manifestToPreviewCatalog(manifest: DevPortalLocalManifest | null | undefined): DevPortalPreviewPlanCatalog;
|
|
76
88
|
export declare function normalizeBillingPeriod(period?: string): string;
|
|
77
|
-
export declare function plansToPreviewCatalog(plans: ManifestPlanInput[] | undefined): DevPortalPreviewPlanCatalog
|
|
78
|
-
export declare function
|
|
89
|
+
export declare function plansToPreviewCatalog(plans: ManifestPlanInput[] | undefined): Pick<DevPortalPreviewPlanCatalog, "plans">;
|
|
90
|
+
export declare function resolveManifestEnv(viteMode: string): ApitogoManifestEnv;
|
|
91
|
+
export declare function mergePlansBySku(existing: ManifestPlanInput[] | undefined, patch: ManifestPlanInput[]): ManifestPlanInput[];
|
|
92
|
+
export declare function mergeManifest(base: DevPortalLocalManifest, override: DevPortalLocalManifest): DevPortalLocalManifest;
|
|
93
|
+
export declare function manifestFilePath(rootDir: string, filename?: string): string;
|
|
94
|
+
export declare function manifestPathsForEnv(rootDir: string, env: ApitogoManifestEnv): {
|
|
95
|
+
basePath: string;
|
|
96
|
+
overridePath: string;
|
|
97
|
+
watchPaths: string[];
|
|
98
|
+
};
|
|
79
99
|
export declare function parseLocalManifestJson(raw: string): DevPortalLocalManifest | null;
|
|
100
|
+
export declare function readManifestFile(rootDir: string, filename: string): Promise<DevPortalLocalManifest | null>;
|
|
101
|
+
export declare function readEffectiveManifest(rootDir: string, env: ApitogoManifestEnv): Promise<DevPortalLocalManifest | null>;
|
|
80
102
|
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
|
|
111
|
+
`VITE_APITOGO_DEV_PORTAL_API_URL` 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/docs/quickstart.md
CHANGED
|
@@ -25,8 +25,8 @@ have you up and running with a modern, customizable site that your developers wi
|
|
|
25
25
|
npm create @lukoweb/apitogo@latest
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
The CLI will walk you through setting up your project with interactive prompts.
|
|
29
|
-
|
|
28
|
+
The CLI will walk you through setting up your project with interactive prompts. By default you
|
|
29
|
+
get an empty dev-portal site; opt in to include starter example docs and an OpenAPI spec.
|
|
30
30
|
|
|
31
31
|
1. **Navigate to your project:**
|
|
32
32
|
|
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),
|
|
@@ -30,6 +35,11 @@ export const DevPortalLocalManifestSchema = z.object({
|
|
|
30
35
|
logoUrl: z.string().optional(),
|
|
31
36
|
})
|
|
32
37
|
.optional(),
|
|
38
|
+
pricing: z
|
|
39
|
+
.object({
|
|
40
|
+
enabled: z.boolean().optional(),
|
|
41
|
+
})
|
|
42
|
+
.optional(),
|
|
33
43
|
plans: z.array(ManifestPlanInputSchema).optional(),
|
|
34
44
|
backend: z
|
|
35
45
|
.object({
|
|
@@ -56,7 +66,9 @@ export const DevPortalLocalManifestSchema = z.object({
|
|
|
56
66
|
});
|
|
57
67
|
|
|
58
68
|
export type ManifestPlanInput = z.infer<typeof ManifestPlanInputSchema>;
|
|
59
|
-
export type DevPortalLocalManifest = z.infer<
|
|
69
|
+
export type DevPortalLocalManifest = z.infer<
|
|
70
|
+
typeof DevPortalLocalManifestSchema
|
|
71
|
+
>;
|
|
60
72
|
|
|
61
73
|
export type DevPortalPreviewPlan = {
|
|
62
74
|
sku: string;
|
|
@@ -70,9 +82,27 @@ export type DevPortalPreviewPlan = {
|
|
|
70
82
|
};
|
|
71
83
|
|
|
72
84
|
export type DevPortalPreviewPlanCatalog = {
|
|
85
|
+
pricingEnabled: boolean;
|
|
73
86
|
plans: DevPortalPreviewPlan[];
|
|
74
87
|
};
|
|
75
88
|
|
|
89
|
+
export function isPricingEnabled(
|
|
90
|
+
manifest: DevPortalLocalManifest | null | undefined,
|
|
91
|
+
): boolean {
|
|
92
|
+
return manifest?.pricing?.enabled === true;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function manifestToPreviewCatalog(
|
|
96
|
+
manifest: DevPortalLocalManifest | null | undefined,
|
|
97
|
+
): DevPortalPreviewPlanCatalog {
|
|
98
|
+
const plans = manifest?.plans;
|
|
99
|
+
const catalog = plansToPreviewCatalog(plans);
|
|
100
|
+
return {
|
|
101
|
+
pricingEnabled: isPricingEnabled(manifest),
|
|
102
|
+
plans: catalog.plans,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
76
106
|
export function normalizeBillingPeriod(period?: string): string {
|
|
77
107
|
if (!period) {
|
|
78
108
|
return "monthly";
|
|
@@ -90,7 +120,7 @@ export function normalizeBillingPeriod(period?: string): string {
|
|
|
90
120
|
|
|
91
121
|
export function plansToPreviewCatalog(
|
|
92
122
|
plans: ManifestPlanInput[] | undefined,
|
|
93
|
-
): DevPortalPreviewPlanCatalog {
|
|
123
|
+
): Pick<DevPortalPreviewPlanCatalog, "plans"> {
|
|
94
124
|
if (!plans?.length) {
|
|
95
125
|
return { plans: [] };
|
|
96
126
|
}
|
|
@@ -109,8 +139,70 @@ export function plansToPreviewCatalog(
|
|
|
109
139
|
};
|
|
110
140
|
}
|
|
111
141
|
|
|
112
|
-
export function
|
|
113
|
-
return
|
|
142
|
+
export function resolveManifestEnv(viteMode: string): ApitogoManifestEnv {
|
|
143
|
+
return viteMode === "production" ? "production" : "development";
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function mergePlansBySku(
|
|
147
|
+
existing: ManifestPlanInput[] | undefined,
|
|
148
|
+
patch: ManifestPlanInput[],
|
|
149
|
+
): ManifestPlanInput[] {
|
|
150
|
+
const bySku = new Map<string, ManifestPlanInput>();
|
|
151
|
+
for (const plan of existing ?? []) {
|
|
152
|
+
bySku.set(plan.sku, plan);
|
|
153
|
+
}
|
|
154
|
+
for (const plan of patch) {
|
|
155
|
+
const prior = bySku.get(plan.sku);
|
|
156
|
+
bySku.set(plan.sku, prior ? { ...prior, ...plan } : plan);
|
|
157
|
+
}
|
|
158
|
+
return Array.from(bySku.values());
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export function mergeManifest(
|
|
162
|
+
base: DevPortalLocalManifest,
|
|
163
|
+
override: DevPortalLocalManifest,
|
|
164
|
+
): DevPortalLocalManifest {
|
|
165
|
+
const merged: DevPortalLocalManifest = { ...base, ...override };
|
|
166
|
+
|
|
167
|
+
if (override.branding) {
|
|
168
|
+
merged.branding = { ...base.branding, ...override.branding };
|
|
169
|
+
}
|
|
170
|
+
if (override.pricing) {
|
|
171
|
+
merged.pricing = { ...base.pricing, ...override.pricing };
|
|
172
|
+
}
|
|
173
|
+
if (override.backend) {
|
|
174
|
+
merged.backend = { ...base.backend, ...override.backend };
|
|
175
|
+
}
|
|
176
|
+
if (override.gateway) {
|
|
177
|
+
merged.gateway = { ...base.gateway, ...override.gateway };
|
|
178
|
+
}
|
|
179
|
+
if (override.plans) {
|
|
180
|
+
merged.plans = mergePlansBySku(base.plans, override.plans);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return merged;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function manifestFilePath(rootDir: string, filename?: string): string {
|
|
187
|
+
return path.join(
|
|
188
|
+
path.resolve(rootDir),
|
|
189
|
+
filename ?? DEV_PORTAL_MANIFEST_FILENAME,
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export function manifestPathsForEnv(
|
|
194
|
+
rootDir: string,
|
|
195
|
+
env: ApitogoManifestEnv,
|
|
196
|
+
): { basePath: string; overridePath: string; watchPaths: string[] } {
|
|
197
|
+
const resolvedRoot = path.resolve(rootDir);
|
|
198
|
+
const basePath = path.join(resolvedRoot, APITOGO_MANIFEST_BASE_FILENAME);
|
|
199
|
+
const overridePath = path.join(resolvedRoot, APITOGO_MANIFEST_ENV_FILES[env]);
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
basePath,
|
|
203
|
+
overridePath,
|
|
204
|
+
watchPaths: [basePath, overridePath],
|
|
205
|
+
};
|
|
114
206
|
}
|
|
115
207
|
|
|
116
208
|
export function parseLocalManifestJson(
|
|
@@ -128,10 +220,20 @@ export function parseLocalManifestJson(
|
|
|
128
220
|
}
|
|
129
221
|
}
|
|
130
222
|
|
|
131
|
-
|
|
223
|
+
async function fileExists(filePath: string): Promise<boolean> {
|
|
224
|
+
try {
|
|
225
|
+
await access(filePath);
|
|
226
|
+
return true;
|
|
227
|
+
} catch {
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export async function readManifestFile(
|
|
132
233
|
rootDir: string,
|
|
234
|
+
filename: string,
|
|
133
235
|
): Promise<DevPortalLocalManifest | null> {
|
|
134
|
-
const filePath = manifestFilePath(rootDir);
|
|
236
|
+
const filePath = manifestFilePath(rootDir, filename);
|
|
135
237
|
|
|
136
238
|
try {
|
|
137
239
|
const raw = await readFile(filePath, "utf8");
|
|
@@ -140,3 +242,53 @@ export async function readLocalManifest(
|
|
|
140
242
|
return null;
|
|
141
243
|
}
|
|
142
244
|
}
|
|
245
|
+
|
|
246
|
+
export async function readEffectiveManifest(
|
|
247
|
+
rootDir: string,
|
|
248
|
+
env: ApitogoManifestEnv,
|
|
249
|
+
): Promise<DevPortalLocalManifest | null> {
|
|
250
|
+
const { basePath, overridePath } = manifestPathsForEnv(rootDir, env);
|
|
251
|
+
const hasBase = await fileExists(basePath);
|
|
252
|
+
const hasOverride = await fileExists(overridePath);
|
|
253
|
+
|
|
254
|
+
if (!hasBase) {
|
|
255
|
+
const legacy = await readManifestFile(
|
|
256
|
+
rootDir,
|
|
257
|
+
APITOGO_MANIFEST_ENV_FILES.development,
|
|
258
|
+
);
|
|
259
|
+
if (legacy) {
|
|
260
|
+
return legacy;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (hasOverride) {
|
|
264
|
+
return readManifestFile(rootDir, APITOGO_MANIFEST_ENV_FILES[env]);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const base = await readManifestFile(rootDir, APITOGO_MANIFEST_BASE_FILENAME);
|
|
271
|
+
if (!base) {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (!hasOverride) {
|
|
276
|
+
return base;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const override = await readManifestFile(
|
|
280
|
+
rootDir,
|
|
281
|
+
APITOGO_MANIFEST_ENV_FILES[env],
|
|
282
|
+
);
|
|
283
|
+
if (!override) {
|
|
284
|
+
return base;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return mergeManifest(base, override);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export async function readLocalManifest(
|
|
291
|
+
rootDir: string,
|
|
292
|
+
): Promise<DevPortalLocalManifest | null> {
|
|
293
|
+
return readEffectiveManifest(rootDir, "development");
|
|
294
|
+
}
|
|
@@ -1,27 +1,29 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import type { Plugin, ResolvedConfig } from "vite";
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
manifestPathsForEnv,
|
|
5
|
+
manifestToPreviewCatalog,
|
|
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 = manifestToPreviewCatalog(null);
|
|
20
23
|
|
|
21
24
|
try {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
catalog = plansToPreviewCatalog(manifest?.plans);
|
|
25
|
+
const manifest = await readEffectiveManifest(rootDir, env);
|
|
26
|
+
catalog = manifestToPreviewCatalog(manifest);
|
|
25
27
|
} catch {
|
|
26
28
|
// Missing or invalid manifest — empty catalog for preview.
|
|
27
29
|
}
|
|
@@ -33,7 +35,9 @@ const viteLocalManifestPlugin = (): Plugin => {
|
|
|
33
35
|
name: "apitogo-local-manifest-plugin",
|
|
34
36
|
configResolved(resolvedConfig: ResolvedConfig) {
|
|
35
37
|
rootDir = resolvedConfig.root;
|
|
36
|
-
|
|
38
|
+
viteMode = resolvedConfig.mode;
|
|
39
|
+
const env = resolveManifestEnv(viteMode);
|
|
40
|
+
watchPaths = manifestPathsForEnv(rootDir, env).watchPaths;
|
|
37
41
|
},
|
|
38
42
|
resolveId(id) {
|
|
39
43
|
if (id === APITOGO_LOCAL_MANIFEST_VIRTUAL_ID) {
|
|
@@ -48,11 +52,13 @@ const viteLocalManifestPlugin = (): Plugin => {
|
|
|
48
52
|
return loadManifestModule();
|
|
49
53
|
},
|
|
50
54
|
configureServer(server) {
|
|
51
|
-
const watchPath
|
|
55
|
+
for (const watchPath of watchPaths) {
|
|
56
|
+
server.watcher.add(watchPath);
|
|
57
|
+
}
|
|
52
58
|
|
|
53
|
-
server.watcher.add(watchPath);
|
|
54
59
|
server.watcher.on("change", async (changedPath) => {
|
|
55
|
-
|
|
60
|
+
const resolvedChanged = path.resolve(changedPath);
|
|
61
|
+
if (!watchPaths.some((p) => path.resolve(p) === resolvedChanged)) {
|
|
56
62
|
return;
|
|
57
63
|
}
|
|
58
64
|
|
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 {
|