nitro-graphql 2.0.0-beta.4 → 2.0.0-beta.41
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/README.md +438 -27
- package/dist/cli/commands/generate.d.mts +26 -0
- package/dist/cli/commands/generate.mjs +196 -0
- package/dist/cli/commands/index.d.mts +4 -0
- package/dist/cli/commands/index.mjs +5 -0
- package/dist/cli/commands/init.d.mts +46 -0
- package/dist/cli/commands/init.mjs +195 -0
- package/dist/cli/commands/validate.d.mts +10 -0
- package/dist/cli/commands/validate.mjs +69 -0
- package/dist/cli/completions.d.mts +7 -0
- package/dist/cli/completions.mjs +34 -0
- package/dist/cli/config.d.mts +75 -0
- package/dist/cli/config.mjs +20 -0
- package/dist/cli/index.d.mts +24 -0
- package/dist/cli/index.mjs +253 -0
- package/dist/config.d.mts +2 -0
- package/dist/config.mjs +3 -0
- package/dist/core/codegen/client.d.mts +23 -0
- package/dist/core/codegen/client.mjs +150 -0
- package/dist/core/codegen/document-loader.d.mts +10 -0
- package/dist/core/codegen/document-loader.mjs +18 -0
- package/dist/core/codegen/index.d.mts +8 -0
- package/dist/core/codegen/index.mjs +9 -0
- package/dist/core/codegen/plugin.d.mts +20 -0
- package/dist/core/codegen/plugin.mjs +30 -0
- package/dist/core/codegen/runtime.d.mts +20 -0
- package/dist/core/codegen/runtime.mjs +60 -0
- package/dist/core/codegen/schema-loader.d.mts +28 -0
- package/dist/core/codegen/schema-loader.mjs +128 -0
- package/dist/core/codegen/server.d.mts +28 -0
- package/dist/core/codegen/server.mjs +143 -0
- package/dist/core/codegen/validation.d.mts +13 -0
- package/dist/core/codegen/validation.mjs +96 -0
- package/dist/core/config.d.mts +50 -0
- package/dist/core/config.mjs +82 -0
- package/dist/core/constants.d.mts +188 -0
- package/dist/core/constants.mjs +210 -0
- package/dist/core/index.d.mts +33 -0
- package/dist/core/index.mjs +27 -0
- package/dist/core/manifest.d.mts +46 -0
- package/dist/core/manifest.mjs +76 -0
- package/dist/core/scanning/ast-scanner.d.mts +28 -0
- package/dist/core/scanning/ast-scanner.mjs +122 -0
- package/dist/core/scanning/common.d.mts +37 -0
- package/dist/core/scanning/common.mjs +60 -0
- package/dist/core/scanning/directives.d.mts +10 -0
- package/dist/core/scanning/directives.mjs +29 -0
- package/dist/core/scanning/documents.d.mts +21 -0
- package/dist/core/scanning/documents.mjs +43 -0
- package/dist/core/scanning/index.d.mts +7 -0
- package/dist/core/scanning/index.mjs +8 -0
- package/dist/core/scanning/resolvers.d.mts +15 -0
- package/dist/core/scanning/resolvers.mjs +59 -0
- package/dist/core/scanning/schemas.d.mts +14 -0
- package/dist/core/scanning/schemas.mjs +64 -0
- package/dist/core/schema/builder.d.mts +53 -0
- package/dist/core/schema/builder.mjs +70 -0
- package/dist/core/schema/federation.d.mts +34 -0
- package/dist/core/schema/federation.mjs +40 -0
- package/dist/core/schema/index.d.mts +3 -0
- package/dist/core/schema/index.mjs +4 -0
- package/dist/core/types/adapter.d.mts +58 -0
- package/dist/core/types/codegen.d.mts +133 -0
- package/dist/core/types/config.d.mts +210 -0
- package/dist/core/types/config.mjs +1 -0
- package/dist/{utils/define.d.ts → core/types/define.d.mts} +3 -30
- package/dist/core/types/define.mjs +1 -0
- package/dist/core/types/index.d.mts +5 -0
- package/dist/core/types/index.mjs +1 -0
- package/dist/core/types/scanning.d.mts +69 -0
- package/dist/core/types/scanning.mjs +1 -0
- package/dist/{utils/directive-parser.d.ts → core/utils/directive-parser.d.mts} +21 -4
- package/dist/{utils/directive-parser.js → core/utils/directive-parser.mjs} +25 -34
- package/dist/core/utils/errors.d.mts +77 -0
- package/dist/core/utils/errors.mjs +93 -0
- package/dist/core/utils/file-io.d.mts +24 -0
- package/dist/core/utils/file-io.mjs +47 -0
- package/dist/core/utils/imports.d.mts +15 -0
- package/dist/core/utils/imports.mjs +25 -0
- package/dist/core/utils/index.d.mts +7 -0
- package/dist/core/utils/index.mjs +8 -0
- package/dist/core/utils/logger.d.mts +19 -0
- package/dist/core/utils/logger.mjs +38 -0
- package/dist/core/utils/ofetch-templates.d.mts +30 -0
- package/dist/core/utils/ofetch-templates.mjs +135 -0
- package/dist/core/validation/external-services.d.mts +11 -0
- package/dist/core/validation/external-services.mjs +34 -0
- package/dist/core/validation/index.d.mts +2 -0
- package/dist/core/validation/index.mjs +3 -0
- package/dist/define.d.mts +294 -0
- package/dist/define.mjs +323 -0
- package/dist/index.d.mts +6 -0
- package/dist/index.mjs +6 -0
- package/dist/nitro/adapter.d.mts +30 -0
- package/dist/nitro/adapter.mjs +97 -0
- package/dist/{utils/apollo.d.ts → nitro/apollo.d.mts} +3 -3
- package/dist/nitro/apollo.mjs +59 -0
- package/dist/nitro/codegen.d.mts +19 -0
- package/dist/nitro/codegen.mjs +141 -0
- package/dist/nitro/config.d.mts +51 -0
- package/dist/nitro/config.mjs +57 -0
- package/dist/nitro/index.d.mts +46 -0
- package/dist/nitro/index.mjs +65 -0
- package/dist/nitro/paths.d.mts +54 -0
- package/dist/nitro/paths.mjs +92 -0
- package/dist/nitro/rollup.d.mts +6 -0
- package/dist/nitro/rollup.mjs +95 -0
- package/dist/nitro/routes/apollo-server.d.mts +6 -0
- package/dist/nitro/routes/apollo-server.mjs +71 -0
- package/dist/nitro/routes/debug-template.d.mts +15 -0
- package/dist/nitro/routes/debug-template.mjs +385 -0
- package/dist/nitro/routes/debug.d.mts +55 -0
- package/dist/nitro/routes/debug.mjs +102 -0
- package/dist/nitro/routes/graphql-yoga.d.mts +6 -0
- package/dist/nitro/routes/graphql-yoga.mjs +62 -0
- package/dist/nitro/routes/health.d.mts +10 -0
- package/dist/{routes/health.js → nitro/routes/health.mjs} +4 -3
- package/dist/nitro/setup/extend-loader.d.mts +19 -0
- package/dist/nitro/setup/extend-loader.mjs +129 -0
- package/dist/nitro/setup/file-watcher.d.mts +16 -0
- package/dist/nitro/setup/file-watcher.mjs +98 -0
- package/dist/nitro/setup/logging.d.mts +17 -0
- package/dist/nitro/setup/logging.mjs +66 -0
- package/dist/nitro/setup/rollup-integration.d.mts +16 -0
- package/dist/nitro/setup/rollup-integration.mjs +90 -0
- package/dist/nitro/setup/routes.d.mts +10 -0
- package/dist/nitro/setup/routes.mjs +35 -0
- package/dist/nitro/setup/ts-config.d.mts +11 -0
- package/dist/nitro/setup/ts-config.mjs +69 -0
- package/dist/nitro/setup.d.mts +12 -0
- package/dist/nitro/setup.mjs +234 -0
- package/dist/nitro/types.d.mts +374 -0
- package/dist/nitro/types.mjs +1 -0
- package/dist/nitro/virtual/generators.d.mts +31 -0
- package/dist/nitro/virtual/generators.mjs +113 -0
- package/dist/nitro/virtual/stubs.d.mts +20 -0
- package/dist/nitro/virtual/stubs.mjs +31 -0
- package/dist/{ecosystem/nuxt.d.ts → nuxt.d.mts} +1 -1
- package/dist/nuxt.mjs +109 -0
- package/dist/{graphql/server.d.ts → stubs/index.d.mts} +5 -1
- package/dist/stubs/index.mjs +1 -0
- package/package.json +102 -77
- package/dist/ecosystem/nuxt.js +0 -67
- package/dist/graphql/index.d.ts +0 -5
- package/dist/index.d.ts +0 -8
- package/dist/index.js +0 -264
- package/dist/rollup.js +0 -119
- package/dist/routes/apollo-server.d.ts +0 -6
- package/dist/routes/apollo-server.js +0 -89
- package/dist/routes/graphql-yoga.d.ts +0 -6
- package/dist/routes/graphql-yoga.js +0 -91
- package/dist/routes/health.d.ts +0 -6
- package/dist/types/index.d.ts +0 -128
- package/dist/types/standard-schema.d.ts +0 -59
- package/dist/utils/apollo.js +0 -61
- package/dist/utils/client-codegen.d.ts +0 -38
- package/dist/utils/client-codegen.js +0 -290
- package/dist/utils/define.js +0 -57
- package/dist/utils/index.d.ts +0 -39
- package/dist/utils/index.js +0 -250
- package/dist/utils/server-codegen.d.ts +0 -7
- package/dist/utils/server-codegen.js +0 -136
- package/dist/utils/type-generation.d.ts +0 -7
- package/dist/utils/type-generation.js +0 -287
- package/dist/vite.d.ts +0 -25
- package/dist/vite.js +0 -40
- /package/dist/{graphql/index.js → core/types/adapter.mjs} +0 -0
- /package/dist/{graphql/server.js → core/types/codegen.mjs} +0 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { isAbsolute, resolve } from "pathe";
|
|
2
|
+
|
|
3
|
+
//#region src/nitro/paths.ts
|
|
4
|
+
/**
|
|
5
|
+
* Replace placeholders in a path string
|
|
6
|
+
* Supports: {serviceName}, {buildDir}, {rootDir}, {framework}, {typesDir}, {serverDir}, {clientDir}
|
|
7
|
+
*/
|
|
8
|
+
function replacePlaceholders(path, placeholders) {
|
|
9
|
+
return path.replace(/\{serviceName\}/g, placeholders.serviceName || "default").replace(/\{buildDir\}/g, placeholders.buildDir).replace(/\{rootDir\}/g, placeholders.rootDir).replace(/\{framework\}/g, placeholders.framework).replace(/\{typesDir\}/g, placeholders.typesDir).replace(/\{serverDir\}/g, placeholders.serverDir).replace(/\{clientDir\}/g, placeholders.clientDir);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Get default paths based on framework and user configuration
|
|
13
|
+
*/
|
|
14
|
+
function getDefaultPaths(nitro) {
|
|
15
|
+
const isNuxt = nitro.options.framework?.name === "nuxt";
|
|
16
|
+
const rootDir = nitro.options.rootDir;
|
|
17
|
+
const buildDir = nitro.options.buildDir;
|
|
18
|
+
const graphqlConfig = nitro.options.graphql || {};
|
|
19
|
+
const defaultServerDir = graphqlConfig.serverDir || resolve(rootDir, "server", "graphql");
|
|
20
|
+
const defaultClientDir = graphqlConfig.clientDir || resolve(rootDir, isNuxt ? "app/graphql" : "graphql");
|
|
21
|
+
const defaultTypesDir = graphqlConfig.typesDir || resolve(buildDir, "types");
|
|
22
|
+
return {
|
|
23
|
+
serviceName: "default",
|
|
24
|
+
buildDir,
|
|
25
|
+
rootDir,
|
|
26
|
+
framework: isNuxt ? "nuxt" : "nitro",
|
|
27
|
+
typesDir: defaultTypesDir,
|
|
28
|
+
serverDir: defaultServerDir,
|
|
29
|
+
clientDir: defaultClientDir
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Check if a file should be generated based on config
|
|
34
|
+
* Returns: true if should generate, false if should skip
|
|
35
|
+
*/
|
|
36
|
+
function shouldGenerateFile(config, categoryEnabled, topLevelEnabled) {
|
|
37
|
+
if (config === false) return false;
|
|
38
|
+
if (config === true || typeof config === "string") return true;
|
|
39
|
+
if (categoryEnabled === false) return false;
|
|
40
|
+
if (categoryEnabled === true) return true;
|
|
41
|
+
return topLevelEnabled;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Resolve the file path based on configuration
|
|
45
|
+
* Returns: resolved absolute path or null if file should not be generated
|
|
46
|
+
*/
|
|
47
|
+
function resolveFilePath(config, categoryEnabled, topLevelEnabled, defaultPath, placeholders) {
|
|
48
|
+
if (!shouldGenerateFile(config, categoryEnabled, topLevelEnabled)) return null;
|
|
49
|
+
if (typeof config === "string") {
|
|
50
|
+
const customPath = replacePlaceholders(config, placeholders);
|
|
51
|
+
return isAbsolute(customPath) ? customPath : resolve(placeholders.rootDir, customPath);
|
|
52
|
+
}
|
|
53
|
+
const resolvedDefault = replacePlaceholders(defaultPath, placeholders);
|
|
54
|
+
return resolve(placeholders.rootDir, resolvedDefault);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Check if SDK files should be generated (category-level check)
|
|
58
|
+
*/
|
|
59
|
+
function shouldGenerateSdk(nitro) {
|
|
60
|
+
const sdkConfig = nitro.options.graphql?.sdk;
|
|
61
|
+
if (sdkConfig === false) return false;
|
|
62
|
+
if (sdkConfig && sdkConfig.enabled === false) return false;
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get SDK configuration (handles false case)
|
|
67
|
+
*/
|
|
68
|
+
function getSdkConfig(nitro) {
|
|
69
|
+
const sdkConfig = nitro.options.graphql?.sdk;
|
|
70
|
+
if (sdkConfig === false) return { enabled: false };
|
|
71
|
+
return sdkConfig || {};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Check if type files should be generated (category-level check)
|
|
75
|
+
*/
|
|
76
|
+
function shouldGenerateTypes(nitro) {
|
|
77
|
+
const typesConfig = nitro.options.graphql?.types;
|
|
78
|
+
if (typesConfig === false) return false;
|
|
79
|
+
if (typesConfig && typesConfig.enabled === false) return false;
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get types configuration (handles false case)
|
|
84
|
+
*/
|
|
85
|
+
function getTypesConfig(nitro) {
|
|
86
|
+
const typesConfig = nitro.options.graphql?.types;
|
|
87
|
+
if (typesConfig === false) return { enabled: false };
|
|
88
|
+
return typesConfig || {};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
//#endregion
|
|
92
|
+
export { getDefaultPaths, getSdkConfig, getTypesConfig, replacePlaceholders, resolveFilePath, shouldGenerateFile, shouldGenerateSdk, shouldGenerateTypes };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { NitroAdapter } from "./adapter.mjs";
|
|
2
|
+
import { generateClientTypes, generateServerTypes } from "./codegen.mjs";
|
|
3
|
+
import { registerAllVirtualModules } from "./virtual/generators.mjs";
|
|
4
|
+
import { readFile } from "node:fs/promises";
|
|
5
|
+
import { parse } from "graphql";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
|
|
8
|
+
//#region src/nitro/rollup.ts
|
|
9
|
+
async function rollupConfig(nitro) {
|
|
10
|
+
registerAllVirtualModules(nitro);
|
|
11
|
+
nitro.hooks.hook("rollup:before", (_, rollupConfig$1) => {
|
|
12
|
+
rollupConfig$1.plugins = rollupConfig$1.plugins || [];
|
|
13
|
+
const { include = /\.(?:graphql|gql)$/i, exclude, validate = false } = nitro.options.graphql?.loader || {};
|
|
14
|
+
if (Array.isArray(rollupConfig$1.plugins)) {
|
|
15
|
+
rollupConfig$1.plugins.push({
|
|
16
|
+
name: "nitro-graphql:virtual",
|
|
17
|
+
resolveId: {
|
|
18
|
+
order: "pre",
|
|
19
|
+
filter: { id: /^#nitro-graphql\// },
|
|
20
|
+
async handler(id, parent, _options) {
|
|
21
|
+
if (id.startsWith("#nitro-graphql/")) return `\0virtual:${id}`;
|
|
22
|
+
if (parent?.startsWith("\0virtual:#nitro-graphql")) {
|
|
23
|
+
const runtimeDir = fileURLToPath(new URL("routes", import.meta.url));
|
|
24
|
+
const internalRes = await this.resolve(id, runtimeDir, { skipSelf: true });
|
|
25
|
+
if (internalRes) return internalRes.id;
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
load: {
|
|
31
|
+
order: "pre",
|
|
32
|
+
filter: { id: /^\0virtual:#nitro-graphql\// },
|
|
33
|
+
async handler(id) {
|
|
34
|
+
if (id.startsWith("\0virtual:#nitro-graphql/")) {
|
|
35
|
+
const moduleName = id.slice(9);
|
|
36
|
+
const generator = nitro.options.virtual?.[moduleName];
|
|
37
|
+
if (typeof generator === "function") try {
|
|
38
|
+
return {
|
|
39
|
+
code: await generator(),
|
|
40
|
+
moduleType: "js"
|
|
41
|
+
};
|
|
42
|
+
} catch (error) {
|
|
43
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
44
|
+
this.error(`Failed to generate virtual module ${moduleName}: ${message}`);
|
|
45
|
+
}
|
|
46
|
+
else this.error(`No generator function found for virtual module ${moduleName}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
rollupConfig$1.plugins.push({
|
|
52
|
+
name: "nitro-graphql",
|
|
53
|
+
resolveId: {
|
|
54
|
+
order: "pre",
|
|
55
|
+
handler(id) {
|
|
56
|
+
if (/\.(?:graphql|gql)$/i.test(id)) return null;
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
load: {
|
|
60
|
+
order: "pre",
|
|
61
|
+
async handler(id) {
|
|
62
|
+
if (exclude?.test?.(id)) return null;
|
|
63
|
+
if (!include.test(id)) return null;
|
|
64
|
+
try {
|
|
65
|
+
const content = await readFile(id, "utf-8");
|
|
66
|
+
if (validate) parse(content);
|
|
67
|
+
return `export default ${JSON.stringify(content)}`;
|
|
68
|
+
} catch (error) {
|
|
69
|
+
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") return null;
|
|
70
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
71
|
+
this.error(`Failed to read GraphQL file ${id}: ${message}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
if (nitro.options.dev) rollupConfig$1.plugins.push({
|
|
77
|
+
name: "nitro-graphql-watcher",
|
|
78
|
+
buildStart: {
|
|
79
|
+
order: "pre",
|
|
80
|
+
async handler() {
|
|
81
|
+
const result = await NitroAdapter.scanGraphql(nitro);
|
|
82
|
+
for (const file of result.items) this.addWatchFile(file);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
nitro.hooks.hook("dev:reload", async () => {
|
|
89
|
+
await generateServerTypes(nitro, { silent: true });
|
|
90
|
+
await generateClientTypes(nitro, { silent: true });
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
//#endregion
|
|
95
|
+
export { rollupConfig };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { createMergedSchema } from "../../core/schema/builder.mjs";
|
|
2
|
+
import defu from "defu";
|
|
3
|
+
import { ApolloServer } from "@apollo/server";
|
|
4
|
+
import { defineEventHandler } from "nitro/h3";
|
|
5
|
+
import { importedConfig } from "#nitro-graphql/graphql-config";
|
|
6
|
+
import { moduleConfig } from "#nitro-graphql/module-config";
|
|
7
|
+
import { directives } from "#nitro-graphql/server-directives";
|
|
8
|
+
import { resolvers } from "#nitro-graphql/server-resolvers";
|
|
9
|
+
import { schemas } from "#nitro-graphql/server-schemas";
|
|
10
|
+
import { ApolloServerPluginLandingPageDisabled } from "@apollo/server/plugin/disabled";
|
|
11
|
+
import { ApolloServerPluginLandingPageLocalDefault } from "@apollo/server/plugin/landingPage/default";
|
|
12
|
+
import { startServerAndCreateH3Handler } from "nitro-graphql/apollo";
|
|
13
|
+
|
|
14
|
+
//#region src/nitro/routes/apollo-server.ts
|
|
15
|
+
let apolloServer = null;
|
|
16
|
+
let serverStarted = false;
|
|
17
|
+
async function createApolloServer() {
|
|
18
|
+
if (!apolloServer) {
|
|
19
|
+
const schema = await createMergedSchema({
|
|
20
|
+
schemas,
|
|
21
|
+
resolvers,
|
|
22
|
+
directives,
|
|
23
|
+
moduleConfig
|
|
24
|
+
});
|
|
25
|
+
const securityConfig = moduleConfig.security || {
|
|
26
|
+
introspection: true,
|
|
27
|
+
playground: true,
|
|
28
|
+
maskErrors: false,
|
|
29
|
+
disableSuggestions: false
|
|
30
|
+
};
|
|
31
|
+
const plugins = [];
|
|
32
|
+
if (securityConfig.playground) plugins.push(ApolloServerPluginLandingPageLocalDefault({ embed: true }));
|
|
33
|
+
else plugins.push(ApolloServerPluginLandingPageDisabled());
|
|
34
|
+
const userFacingCodes = [
|
|
35
|
+
"BAD_USER_INPUT",
|
|
36
|
+
"GRAPHQL_VALIDATION_FAILED",
|
|
37
|
+
"UNAUTHENTICATED",
|
|
38
|
+
"FORBIDDEN",
|
|
39
|
+
"BAD_REQUEST"
|
|
40
|
+
];
|
|
41
|
+
apolloServer = new ApolloServer(defu({
|
|
42
|
+
schema,
|
|
43
|
+
introspection: securityConfig.introspection,
|
|
44
|
+
plugins,
|
|
45
|
+
formatError: securityConfig.maskErrors ? (formattedError, _error) => {
|
|
46
|
+
const code = formattedError?.extensions?.code;
|
|
47
|
+
if (code && userFacingCodes.includes(code)) return formattedError;
|
|
48
|
+
return {
|
|
49
|
+
message: "Internal server error",
|
|
50
|
+
extensions: { code: "INTERNAL_SERVER_ERROR" }
|
|
51
|
+
};
|
|
52
|
+
} : void 0
|
|
53
|
+
}, importedConfig));
|
|
54
|
+
if (!serverStarted) {
|
|
55
|
+
await apolloServer.start();
|
|
56
|
+
serverStarted = true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return apolloServer;
|
|
60
|
+
}
|
|
61
|
+
let serverPromise = null;
|
|
62
|
+
var apollo_server_default = defineEventHandler(async (event) => {
|
|
63
|
+
if (!serverPromise) serverPromise = createApolloServer();
|
|
64
|
+
return startServerAndCreateH3Handler(await serverPromise, {
|
|
65
|
+
context: async () => ({ event }),
|
|
66
|
+
serverAlreadyStarted: true
|
|
67
|
+
})(event);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
//#endregion
|
|
71
|
+
export { apollo_server_default as default };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/nitro/routes/debug-template.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Debug dashboard HTML template
|
|
4
|
+
* Extracted from debug.ts to reduce file complexity
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Escape HTML special characters
|
|
8
|
+
*/
|
|
9
|
+
declare function escapeHtml(text: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Generate the HTML dashboard for the debug endpoint
|
|
12
|
+
*/
|
|
13
|
+
declare function generateHtmlDashboard(debugInfo: any): string;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { escapeHtml, generateHtmlDashboard };
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
//#region src/nitro/routes/debug-template.ts
|
|
2
|
+
/**
|
|
3
|
+
* Debug dashboard HTML template
|
|
4
|
+
* Extracted from debug.ts to reduce file complexity
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Escape HTML special characters
|
|
8
|
+
*/
|
|
9
|
+
function escapeHtml(text) {
|
|
10
|
+
const map = {
|
|
11
|
+
"&": "&",
|
|
12
|
+
"<": "<",
|
|
13
|
+
">": ">",
|
|
14
|
+
"\"": """,
|
|
15
|
+
"'": "'"
|
|
16
|
+
};
|
|
17
|
+
return text.replace(/[&<>"']/g, (m) => map[m] || m);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Type color configuration for resolver exports display
|
|
21
|
+
*/
|
|
22
|
+
const TYPE_CONFIG = {
|
|
23
|
+
query: {
|
|
24
|
+
bg: "bg-blue-500/10",
|
|
25
|
+
text: "text-blue-400",
|
|
26
|
+
border: "border-blue-500/30",
|
|
27
|
+
symbol: "◆",
|
|
28
|
+
label: "query"
|
|
29
|
+
},
|
|
30
|
+
mutation: {
|
|
31
|
+
bg: "bg-[#E535AB]/10",
|
|
32
|
+
text: "text-[#E535AB]",
|
|
33
|
+
border: "border-[#E535AB]/30",
|
|
34
|
+
symbol: "●",
|
|
35
|
+
label: "mutation"
|
|
36
|
+
},
|
|
37
|
+
type: {
|
|
38
|
+
bg: "bg-purple-500/10",
|
|
39
|
+
text: "text-purple-400",
|
|
40
|
+
border: "border-purple-500/30",
|
|
41
|
+
symbol: "▲",
|
|
42
|
+
label: "type"
|
|
43
|
+
},
|
|
44
|
+
directive: {
|
|
45
|
+
bg: "bg-amber-500/10",
|
|
46
|
+
text: "text-amber-400",
|
|
47
|
+
border: "border-amber-500/30",
|
|
48
|
+
symbol: "@",
|
|
49
|
+
label: "directive"
|
|
50
|
+
},
|
|
51
|
+
resolver: {
|
|
52
|
+
bg: "bg-emerald-500/10",
|
|
53
|
+
text: "text-emerald-400",
|
|
54
|
+
border: "border-emerald-500/30",
|
|
55
|
+
symbol: "◉",
|
|
56
|
+
label: "resolver"
|
|
57
|
+
},
|
|
58
|
+
subscription: {
|
|
59
|
+
bg: "bg-teal-500/10",
|
|
60
|
+
text: "text-teal-400",
|
|
61
|
+
border: "border-teal-500/30",
|
|
62
|
+
symbol: "↻",
|
|
63
|
+
label: "subscription"
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Module color configuration for virtual modules display
|
|
68
|
+
*/
|
|
69
|
+
const MODULE_COLORS = {
|
|
70
|
+
"server-schemas": {
|
|
71
|
+
bg: "bg-blue-500/5",
|
|
72
|
+
border: "border-blue-500/20",
|
|
73
|
+
text: "text-blue-400"
|
|
74
|
+
},
|
|
75
|
+
"server-resolvers": {
|
|
76
|
+
bg: "bg-[#E535AB]/5",
|
|
77
|
+
border: "border-[#E535AB]/20",
|
|
78
|
+
text: "text-[#E535AB]"
|
|
79
|
+
},
|
|
80
|
+
"server-directives": {
|
|
81
|
+
bg: "bg-amber-500/5",
|
|
82
|
+
border: "border-amber-500/20",
|
|
83
|
+
text: "text-amber-400"
|
|
84
|
+
},
|
|
85
|
+
"module-config": {
|
|
86
|
+
bg: "bg-purple-500/5",
|
|
87
|
+
border: "border-purple-500/20",
|
|
88
|
+
text: "text-purple-400"
|
|
89
|
+
},
|
|
90
|
+
"graphql-config": {
|
|
91
|
+
bg: "bg-emerald-500/5",
|
|
92
|
+
border: "border-emerald-500/20",
|
|
93
|
+
text: "text-emerald-400"
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* GraphQL logo SVG
|
|
98
|
+
*/
|
|
99
|
+
const GRAPHQL_LOGO = `<svg class="w-10 h-10" viewBox="0 0 400 400" fill="none">
|
|
100
|
+
<path d="M57.468 302.66l-14.376-8.3 160.15-277.38 14.376 8.3z" fill="#E535AB"/>
|
|
101
|
+
<path d="M39.8 272.2h320.3v16.6H39.8z" fill="#E535AB"/>
|
|
102
|
+
<path d="M206.348 374.026l-160.21-92.5 8.3-14.376 160.21 92.5z" fill="#E535AB"/>
|
|
103
|
+
<path d="M345.522 132.947l-160.21-92.5 8.3-14.376 160.21 92.5z" fill="#E535AB"/>
|
|
104
|
+
<path d="M54.482 132.883l-8.3-14.375 160.21-92.5 8.3 14.376z" fill="#E535AB"/>
|
|
105
|
+
<path d="M342.568 302.663l-160.15-277.38 14.376-8.3 160.15 277.38z" fill="#E535AB"/>
|
|
106
|
+
<path d="M52.5 107.5h16.6v185H52.5z" fill="#E535AB"/>
|
|
107
|
+
<path d="M330.9 107.5h16.6v185h-16.6z" fill="#E535AB"/>
|
|
108
|
+
<path d="M203.522 367l-7.25-12.558 139.34-80.45 7.25 12.557z" fill="#E535AB"/>
|
|
109
|
+
<path d="M369.5 297.9c-9.6 16.7-31 22.4-47.7 12.8-16.7-9.6-22.4-31-12.8-47.7 9.6-16.7 31-22.4 47.7-12.8 16.8 9.7 22.5 31 12.8 47.7M90.9 137c-9.6 16.7-31 22.4-47.7 12.8-16.7-9.6-22.4-31-12.8-47.7 9.6-16.7 31-22.4 47.7-12.8 16.7 9.7 22.4 31 12.8 47.7M30.5 297.9c-9.6-16.7-3.9-38 12.8-47.7 16.7-9.6 38-3.9 47.7 12.8 9.6 16.7 3.9 38-12.8 47.7-16.8 9.6-38.1 3.9-47.7-12.8M309.1 137c-9.6-16.7-3.9-38 12.8-47.7 16.7-9.6 38-3.9 47.7 12.8 9.6 16.7 3.9 38-12.8 47.7-16.7 9.6-38.1 3.9-47.7-12.8M200 395.8c-19.3 0-34.9-15.6-34.9-34.9 0-19.3 15.6-34.9 34.9-34.9 19.3 0 34.9 15.6 34.9 34.9 0 19.2-15.6 34.9-34.9 34.9M200 74c-19.3 0-34.9-15.6-34.9-34.9 0-19.3 15.6-34.9 34.9-34.9 19.3 0 34.9 15.6 34.9 34.9 0 19.3-15.6 34.9-34.9 34.9" fill="#E535AB"/>
|
|
110
|
+
</svg>`;
|
|
111
|
+
/**
|
|
112
|
+
* Render resolver exports section
|
|
113
|
+
*/
|
|
114
|
+
function renderResolverExports(resolverFiles) {
|
|
115
|
+
if (resolverFiles.length === 0) return "<p class=\"text-slate-500 text-sm\">No resolvers found</p>";
|
|
116
|
+
return `
|
|
117
|
+
<div class="max-h-96 overflow-y-auto space-y-2 pr-2">
|
|
118
|
+
${resolverFiles.map((r) => {
|
|
119
|
+
const totalExports = r.exports.length;
|
|
120
|
+
return `
|
|
121
|
+
<div class="border border-slate-700/50 rounded-lg p-4 hover:border-[#E535AB]/20 hover:bg-slate-800/30 transition-all">
|
|
122
|
+
<div class="flex justify-between items-center mb-3">
|
|
123
|
+
<span class="text-slate-300 font-mono text-xs truncate pr-2">${r.file}</span>
|
|
124
|
+
<span class="bg-slate-800/80 px-2.5 py-0.5 rounded text-[#E535AB] text-[10px] font-semibold whitespace-nowrap">
|
|
125
|
+
${totalExports} export${totalExports !== 1 ? "s" : ""}
|
|
126
|
+
</span>
|
|
127
|
+
</div>
|
|
128
|
+
<div class="flex flex-wrap gap-1.5">
|
|
129
|
+
${r.exports.map((e) => {
|
|
130
|
+
const config = TYPE_CONFIG[e.type] || TYPE_CONFIG.resolver;
|
|
131
|
+
return `<span class="px-2.5 py-1 rounded border text-[11px] font-mono ${config.bg} ${config.text} ${config.border} hover:scale-105 transition-transform inline-flex items-center gap-1.5">
|
|
132
|
+
<span class="font-bold">${config.symbol}</span>
|
|
133
|
+
<span class="font-medium">${e.name}</span>
|
|
134
|
+
<span class="opacity-60 text-[9px] uppercase tracking-wide">${config.label}</span>
|
|
135
|
+
</span>`;
|
|
136
|
+
}).join("")}
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
`;
|
|
140
|
+
}).join("")}
|
|
141
|
+
</div>
|
|
142
|
+
`;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Render virtual modules section
|
|
146
|
+
*/
|
|
147
|
+
function renderVirtualModules(virtualModules) {
|
|
148
|
+
return Object.entries(virtualModules).map(([moduleName, codeContent]) => {
|
|
149
|
+
const code = String(codeContent);
|
|
150
|
+
const colorConfig = MODULE_COLORS[moduleName] || MODULE_COLORS["module-config"];
|
|
151
|
+
const lineCount = code.split("\n").length;
|
|
152
|
+
const byteSize = new TextEncoder().encode(code).length;
|
|
153
|
+
return `
|
|
154
|
+
<details class="border ${colorConfig.border} ${colorConfig.bg} rounded-lg overflow-hidden group">
|
|
155
|
+
<summary class="cursor-pointer p-4 hover:bg-slate-800/30 transition-all flex justify-between items-center">
|
|
156
|
+
<div class="flex items-center gap-3">
|
|
157
|
+
<span class="${colorConfig.text} text-lg">▸</span>
|
|
158
|
+
<div>
|
|
159
|
+
<span class="font-mono text-sm ${colorConfig.text} font-semibold">#nitro-graphql/${moduleName}</span>
|
|
160
|
+
<div class="text-[10px] text-slate-500 mt-0.5">
|
|
161
|
+
${lineCount} lines · ${(byteSize / 1024).toFixed(2)} KB
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
<button
|
|
166
|
+
onclick="event.stopPropagation(); navigator.clipboard.writeText(this.getAttribute('data-code')); this.textContent = '✓ Copied!'; setTimeout(() => this.textContent = 'Copy', 1000)"
|
|
167
|
+
data-code="${escapeHtml(code).replace(/"/g, """)}"
|
|
168
|
+
class="text-xs px-3 py-1.5 bg-slate-800 hover:bg-slate-700 text-slate-300 rounded border border-slate-600/50 transition-colors"
|
|
169
|
+
>
|
|
170
|
+
Copy
|
|
171
|
+
</button>
|
|
172
|
+
</summary>
|
|
173
|
+
<div class="border-t ${colorConfig.border}">
|
|
174
|
+
<div class="bg-slate-950/80 p-4 max-h-96 overflow-auto">
|
|
175
|
+
<pre class="text-xs font-mono text-slate-300 leading-relaxed"><code>${escapeHtml(code)}</code></pre>
|
|
176
|
+
</div>
|
|
177
|
+
</div>
|
|
178
|
+
</details>
|
|
179
|
+
`;
|
|
180
|
+
}).join("");
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Render file list section
|
|
184
|
+
*/
|
|
185
|
+
function renderFileList(files, emptyMessage) {
|
|
186
|
+
if (files.length === 0) return `<li class="text-slate-500 text-sm">${emptyMessage}</li>`;
|
|
187
|
+
return files.map((f) => `<li class="text-slate-400 font-mono text-xs flex items-start gap-2 py-1.5 px-2 rounded hover:bg-slate-800/50 transition-colors group">
|
|
188
|
+
<span class="text-[#E535AB] text-[10px] mt-0.5 group-hover:scale-110 transition-transform">▸</span>
|
|
189
|
+
<span class="truncate group-hover:text-slate-300">${f}</span>
|
|
190
|
+
</li>`).join("");
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Generate the HTML dashboard for the debug endpoint
|
|
194
|
+
*/
|
|
195
|
+
function generateHtmlDashboard(debugInfo) {
|
|
196
|
+
return `<!DOCTYPE html>
|
|
197
|
+
<html lang="en">
|
|
198
|
+
<head>
|
|
199
|
+
<meta charset="UTF-8">
|
|
200
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
201
|
+
<title>Nitro GraphQL Debug Dashboard</title>
|
|
202
|
+
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"><\/script>
|
|
203
|
+
<style>
|
|
204
|
+
@keyframes fadeIn {
|
|
205
|
+
from { opacity: 0; transform: translateY(10px); }
|
|
206
|
+
to { opacity: 1; transform: translateY(0); }
|
|
207
|
+
}
|
|
208
|
+
.animate-fade-in {
|
|
209
|
+
animation: fadeIn 0.3s ease-out;
|
|
210
|
+
}
|
|
211
|
+
/* Custom Scrollbar */
|
|
212
|
+
::-webkit-scrollbar {
|
|
213
|
+
width: 8px;
|
|
214
|
+
height: 8px;
|
|
215
|
+
}
|
|
216
|
+
::-webkit-scrollbar-track {
|
|
217
|
+
background: #0f172a;
|
|
218
|
+
border-radius: 4px;
|
|
219
|
+
}
|
|
220
|
+
::-webkit-scrollbar-thumb {
|
|
221
|
+
background: #334155;
|
|
222
|
+
border-radius: 4px;
|
|
223
|
+
}
|
|
224
|
+
::-webkit-scrollbar-thumb:hover {
|
|
225
|
+
background: #475569;
|
|
226
|
+
}
|
|
227
|
+
</style>
|
|
228
|
+
</head>
|
|
229
|
+
<body class="bg-slate-950 text-slate-200 min-h-screen">
|
|
230
|
+
<div class="container mx-auto max-w-7xl p-6 space-y-6 animate-fade-in">
|
|
231
|
+
<!-- Header -->
|
|
232
|
+
<div class="mb-8 border-b border-slate-800 pb-6">
|
|
233
|
+
<div class="flex items-center gap-3 mb-2">
|
|
234
|
+
${GRAPHQL_LOGO}
|
|
235
|
+
<div>
|
|
236
|
+
<h1 class="text-3xl font-bold text-slate-100">
|
|
237
|
+
Nitro GraphQL Debug
|
|
238
|
+
</h1>
|
|
239
|
+
<p class="text-sm text-slate-500">Development Diagnostics Dashboard</p>
|
|
240
|
+
</div>
|
|
241
|
+
</div>
|
|
242
|
+
</div>
|
|
243
|
+
|
|
244
|
+
<!-- Top Stats Grid -->
|
|
245
|
+
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
246
|
+
<!-- Environment Card -->
|
|
247
|
+
<div class="bg-slate-900/50 border border-slate-700/50 rounded-lg p-6 hover:border-[#E535AB]/30 transition-all">
|
|
248
|
+
<h2 class="text-lg font-semibold mb-4 text-slate-200 flex items-center gap-2">
|
|
249
|
+
<span class="text-[#E535AB]">●</span> Environment
|
|
250
|
+
</h2>
|
|
251
|
+
<div class="space-y-3">
|
|
252
|
+
<div class="flex justify-between items-center py-2 border-b border-slate-800/50">
|
|
253
|
+
<span class="text-slate-400 text-sm">Mode</span>
|
|
254
|
+
<span class="text-slate-200 font-medium text-sm">${debugInfo.environment.dev ? "Development" : "Production"}</span>
|
|
255
|
+
</div>
|
|
256
|
+
<div class="flex justify-between items-center py-2 border-b border-slate-800/50">
|
|
257
|
+
<span class="text-slate-400 text-sm">Framework</span>
|
|
258
|
+
<span class="text-slate-200 font-medium text-sm">${debugInfo.environment.framework}</span>
|
|
259
|
+
</div>
|
|
260
|
+
<div class="flex justify-between items-center py-2">
|
|
261
|
+
<span class="text-slate-400 text-sm">GraphQL Server</span>
|
|
262
|
+
<span class="text-slate-200 font-medium text-sm">${debugInfo.graphql.framework || "Not configured"}</span>
|
|
263
|
+
</div>
|
|
264
|
+
</div>
|
|
265
|
+
</div>
|
|
266
|
+
|
|
267
|
+
<!-- Scanned Files Card -->
|
|
268
|
+
<div class="bg-slate-900/50 border border-slate-700/50 rounded-lg p-6 hover:border-[#E535AB]/30 transition-all">
|
|
269
|
+
<h2 class="text-lg font-semibold mb-4 text-slate-200 flex items-center gap-2">
|
|
270
|
+
<span class="text-[#E535AB]">●</span> Scanned Files
|
|
271
|
+
</h2>
|
|
272
|
+
<div class="space-y-3">
|
|
273
|
+
<div class="flex justify-between items-center py-2 border-b border-slate-800/50">
|
|
274
|
+
<span class="text-slate-400 text-sm">Schemas</span>
|
|
275
|
+
<span class="text-[#E535AB] font-semibold text-sm">${debugInfo.scanned.schemas}</span>
|
|
276
|
+
</div>
|
|
277
|
+
<div class="flex justify-between items-center py-2 border-b border-slate-800/50">
|
|
278
|
+
<span class="text-slate-400 text-sm">Resolvers</span>
|
|
279
|
+
<span class="text-[#E535AB] font-semibold text-sm">${debugInfo.scanned.resolvers}</span>
|
|
280
|
+
</div>
|
|
281
|
+
<div class="flex justify-between items-center py-2 border-b border-slate-800/50">
|
|
282
|
+
<span class="text-slate-400 text-sm">Directives</span>
|
|
283
|
+
<span class="text-[#E535AB] font-semibold text-sm">${debugInfo.scanned.directives}</span>
|
|
284
|
+
</div>
|
|
285
|
+
<div class="flex justify-between items-center py-2">
|
|
286
|
+
<span class="text-slate-400 text-sm">Documents</span>
|
|
287
|
+
<span class="text-[#E535AB] font-semibold text-sm">${debugInfo.scanned.documents}</span>
|
|
288
|
+
</div>
|
|
289
|
+
</div>
|
|
290
|
+
</div>
|
|
291
|
+
|
|
292
|
+
<!-- Runtime Info Card -->
|
|
293
|
+
<div class="bg-slate-900/50 border border-slate-700/50 rounded-lg p-6 hover:border-[#E535AB]/30 transition-all">
|
|
294
|
+
<h2 class="text-lg font-semibold mb-4 text-slate-200 flex items-center gap-2">
|
|
295
|
+
<span class="text-[#E535AB]">●</span> Runtime Loaded
|
|
296
|
+
</h2>
|
|
297
|
+
<div class="space-y-3">
|
|
298
|
+
<div class="flex justify-between items-center py-2 border-b border-slate-800/50">
|
|
299
|
+
<span class="text-slate-400 text-sm">Resolvers</span>
|
|
300
|
+
<span class="text-[#E535AB] font-semibold text-sm">${debugInfo.runtime.loadedResolvers}</span>
|
|
301
|
+
</div>
|
|
302
|
+
<div class="flex justify-between items-center py-2 border-b border-slate-800/50">
|
|
303
|
+
<span class="text-slate-400 text-sm">Schemas</span>
|
|
304
|
+
<span class="text-[#E535AB] font-semibold text-sm">${debugInfo.runtime.loadedSchemas}</span>
|
|
305
|
+
</div>
|
|
306
|
+
<div class="flex justify-between items-center py-2">
|
|
307
|
+
<span class="text-slate-400 text-sm">Directives</span>
|
|
308
|
+
<span class="text-[#E535AB] font-semibold text-sm">${debugInfo.runtime.loadedDirectives}</span>
|
|
309
|
+
</div>
|
|
310
|
+
</div>
|
|
311
|
+
</div>
|
|
312
|
+
</div>
|
|
313
|
+
|
|
314
|
+
<!-- Resolver Exports -->
|
|
315
|
+
<div class="bg-slate-900/50 border border-slate-700/50 rounded-lg p-6">
|
|
316
|
+
<div class="flex justify-between items-center mb-4">
|
|
317
|
+
<h2 class="text-xl font-semibold text-slate-200 flex items-center gap-2">
|
|
318
|
+
<span class="text-[#E535AB]">●</span> Resolver Exports
|
|
319
|
+
</h2>
|
|
320
|
+
${debugInfo.scanned.resolverFiles.length > 0 ? `<span class="text-xs text-slate-500 bg-slate-800/50 px-2 py-1 rounded">${debugInfo.scanned.resolverFiles.length} files</span>` : ""}
|
|
321
|
+
</div>
|
|
322
|
+
${renderResolverExports(debugInfo.scanned.resolverFiles)}
|
|
323
|
+
</div>
|
|
324
|
+
|
|
325
|
+
<!-- Generated Virtual Modules -->
|
|
326
|
+
<div class="bg-slate-900/50 border border-slate-700/50 rounded-lg p-6">
|
|
327
|
+
<div class="flex justify-between items-center mb-4">
|
|
328
|
+
<h2 class="text-xl font-semibold text-slate-200 flex items-center gap-2">
|
|
329
|
+
<span class="text-[#E535AB]">●</span> Generated Virtual Modules
|
|
330
|
+
</h2>
|
|
331
|
+
<span class="text-xs text-slate-500 bg-slate-800/50 px-2 py-1 rounded">
|
|
332
|
+
${Object.keys(debugInfo.virtualModules).length} modules
|
|
333
|
+
</span>
|
|
334
|
+
</div>
|
|
335
|
+
<div class="space-y-3">
|
|
336
|
+
${renderVirtualModules(debugInfo.virtualModules)}
|
|
337
|
+
</div>
|
|
338
|
+
</div>
|
|
339
|
+
|
|
340
|
+
<!-- Files Grid -->
|
|
341
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
342
|
+
<!-- Schema Files -->
|
|
343
|
+
<div class="bg-slate-900/50 border border-slate-700/50 rounded-lg p-6 hover:border-[#E535AB]/30 transition-all">
|
|
344
|
+
<div class="flex justify-between items-center mb-4">
|
|
345
|
+
<h2 class="text-lg font-semibold text-slate-200 flex items-center gap-2">
|
|
346
|
+
<span class="text-[#E535AB]">●</span> Schema Files
|
|
347
|
+
</h2>
|
|
348
|
+
${debugInfo.scanned.schemaFiles.length > 0 ? `<span class="text-xs text-slate-500 bg-slate-800/50 px-2 py-1 rounded">${debugInfo.scanned.schemaFiles.length} file${debugInfo.scanned.schemaFiles.length !== 1 ? "s" : ""}</span>` : ""}
|
|
349
|
+
</div>
|
|
350
|
+
<ul class="space-y-2 max-h-64 overflow-y-auto pr-2">
|
|
351
|
+
${renderFileList(debugInfo.scanned.schemaFiles, "No schemas found")}
|
|
352
|
+
</ul>
|
|
353
|
+
</div>
|
|
354
|
+
|
|
355
|
+
<!-- Document Files -->
|
|
356
|
+
<div class="bg-slate-900/50 border border-slate-700/50 rounded-lg p-6 hover:border-[#E535AB]/30 transition-all">
|
|
357
|
+
<div class="flex justify-between items-center mb-4">
|
|
358
|
+
<h2 class="text-lg font-semibold text-slate-200 flex items-center gap-2">
|
|
359
|
+
<span class="text-[#E535AB]">●</span> Document Files
|
|
360
|
+
</h2>
|
|
361
|
+
${debugInfo.scanned.documentFiles.length > 0 ? `<span class="text-xs text-slate-500 bg-slate-800/50 px-2 py-1 rounded">${debugInfo.scanned.documentFiles.length} file${debugInfo.scanned.documentFiles.length !== 1 ? "s" : ""}</span>` : ""}
|
|
362
|
+
</div>
|
|
363
|
+
<ul class="space-y-2 max-h-64 overflow-y-auto pr-2">
|
|
364
|
+
${renderFileList(debugInfo.scanned.documentFiles, "No documents found")}
|
|
365
|
+
</ul>
|
|
366
|
+
</div>
|
|
367
|
+
</div>
|
|
368
|
+
|
|
369
|
+
<!-- Reload Button -->
|
|
370
|
+
<button
|
|
371
|
+
onclick="location.reload()"
|
|
372
|
+
class="fixed bottom-8 right-8 bg-[#E535AB] hover:bg-[#d12a99] text-white font-semibold px-6 py-3 rounded-lg shadow-lg hover:shadow-xl hover:shadow-[#E535AB]/20 transform hover:-translate-y-1 transition-all duration-200 flex items-center gap-2 border border-[#E535AB]/20"
|
|
373
|
+
>
|
|
374
|
+
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
375
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
|
376
|
+
</svg>
|
|
377
|
+
Reload
|
|
378
|
+
</button>
|
|
379
|
+
</div>
|
|
380
|
+
</body>
|
|
381
|
+
</html>`;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
//#endregion
|
|
385
|
+
export { escapeHtml, generateHtmlDashboard };
|