puredocs_v2 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/LICENSE +46 -0
  2. package/README.md +164 -0
  3. package/dist/api/http-client.d.ts +14 -0
  4. package/dist/api/snippets.d.ts +15 -0
  5. package/dist/components/app.d.ts +7 -0
  6. package/dist/components/layout/empty-state-page.d.ts +11 -0
  7. package/dist/components/layout/page-layout.d.ts +9 -0
  8. package/dist/components/modals/auth-modal.d.ts +17 -0
  9. package/dist/components/modals/modal-base.d.ts +15 -0
  10. package/dist/components/modals/search-modal.d.ts +6 -0
  11. package/dist/components/nav/route-nav.d.ts +2 -0
  12. package/dist/components/nav/sidebar.d.ts +13 -0
  13. package/dist/components/pages/endpoint.d.ts +3 -0
  14. package/dist/components/pages/overview.d.ts +2 -0
  15. package/dist/components/pages/tag-page.d.ts +2 -0
  16. package/dist/components/pages/webhook.d.ts +3 -0
  17. package/dist/components/shared/connection-settings.d.ts +2 -0
  18. package/dist/components/shared/copy-button.d.ts +12 -0
  19. package/dist/components/shared/editor-panel.d.ts +14 -0
  20. package/dist/components/shared/example-picker.d.ts +20 -0
  21. package/dist/components/shared/responses.d.ts +27 -0
  22. package/dist/components/shared/schema-viewer.d.ts +17 -0
  23. package/dist/components/shared/summary.d.ts +5 -0
  24. package/dist/components/shared/try-it.d.ts +20 -0
  25. package/dist/components/ui/badge.d.ts +24 -0
  26. package/dist/components/ui/breadcrumb.d.ts +12 -0
  27. package/dist/components/ui/button.d.ts +17 -0
  28. package/dist/components/ui/card.d.ts +25 -0
  29. package/dist/components/ui/index.d.ts +20 -0
  30. package/dist/components/ui/input.d.ts +20 -0
  31. package/dist/components/ui/lock-icon.d.ts +8 -0
  32. package/dist/components/ui/section.d.ts +8 -0
  33. package/dist/components/ui/select.d.ts +20 -0
  34. package/dist/core/auth-storage.d.ts +3 -0
  35. package/dist/core/effects.d.ts +33 -0
  36. package/dist/core/parser.d.ts +7 -0
  37. package/dist/core/persistence.d.ts +12 -0
  38. package/dist/core/router.d.ts +40 -0
  39. package/dist/core/search.d.ts +5 -0
  40. package/dist/core/security.d.ts +16 -0
  41. package/dist/core/state.d.ts +24 -0
  42. package/dist/core/theme.d.ts +9 -0
  43. package/dist/core/types.d.ts +291 -0
  44. package/dist/core/validation.d.ts +17 -0
  45. package/dist/helpers/debounce.d.ts +1 -0
  46. package/dist/helpers/schema-utils.d.ts +2 -0
  47. package/dist/helpers/text.d.ts +2 -0
  48. package/dist/helpers/validation-ui.d.ts +4 -0
  49. package/dist/index.d.ts +34 -0
  50. package/dist/lib/dom.d.ts +17 -0
  51. package/dist/lib/highlight.d.ts +8 -0
  52. package/dist/lib/icons.d.ts +24 -0
  53. package/dist/puredocs.cjs +49 -0
  54. package/dist/puredocs.cjs.map +1 -0
  55. package/dist/puredocs.css +1 -0
  56. package/dist/puredocs.js +5324 -0
  57. package/dist/puredocs.js.map +1 -0
  58. package/dist/puredocs.umd.js +49 -0
  59. package/dist/puredocs.umd.js.map +1 -0
  60. package/dist/server.cjs +117 -0
  61. package/dist/server.cjs.map +1 -0
  62. package/dist/server.d.ts +43 -0
  63. package/dist/server.js +116 -0
  64. package/dist/server.js.map +1 -0
  65. package/dist/services/env.d.ts +7 -0
  66. package/package.json +84 -0
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
+ const node_fs = require("node:fs");
4
+ const path = require("node:path");
5
+ const node_url = require("node:url");
6
+ var _documentCurrentScript = typeof document !== "undefined" ? document.currentScript : null;
7
+ const currentDir = typeof __dirname === "string" ? __dirname : path.dirname(node_url.fileURLToPath(typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("server.cjs", document.baseURI).href));
8
+ const cssPath = path.resolve(currentDir, "puredocs.css");
9
+ const umdPath = path.resolve(currentDir, "puredocs.umd.js");
10
+ let inlineAssetsCache = null;
11
+ function getInlineAssets() {
12
+ if (!inlineAssetsCache) {
13
+ const css = node_fs.readFileSync(cssPath, "utf8");
14
+ const umd = node_fs.readFileSync(umdPath, "utf8");
15
+ inlineAssetsCache = {
16
+ css: css.replace(/<\/style>/gi, "<\\/style>"),
17
+ umd: umd.replace(/<\/script>/gi, "<\\/script>")
18
+ };
19
+ }
20
+ return inlineAssetsCache;
21
+ }
22
+ function toSafeJson(value) {
23
+ return JSON.stringify(value).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
24
+ }
25
+ function escapeHtml(value) {
26
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
27
+ }
28
+ function buildClientConfig(options) {
29
+ if (!options.specUrl && !options.spec) {
30
+ throw new Error('[PureDocs] pureDocs.html() requires either "specUrl" or "spec".');
31
+ }
32
+ return {
33
+ specUrl: options.specUrl,
34
+ spec: options.spec,
35
+ title: options.title,
36
+ theme: options.theme ?? "auto",
37
+ primaryColor: options.primaryColor
38
+ };
39
+ }
40
+ function sendHtmlResponse(res, html) {
41
+ if (typeof res.type === "function") {
42
+ res.type("text/html");
43
+ } else if (typeof res.setHeader === "function") {
44
+ res.setHeader("content-type", "text/html; charset=utf-8");
45
+ }
46
+ if (typeof res.send === "function") {
47
+ return res.send(html);
48
+ }
49
+ if (typeof res.end === "function") {
50
+ return res.end(html);
51
+ }
52
+ throw new Error("[PureDocs] Unsupported response object: expected res.send() or res.end().");
53
+ }
54
+ function resolveRoute(options) {
55
+ const route = options.route || "/docs";
56
+ return route.startsWith("/") ? route : `/${route}`;
57
+ }
58
+ function pureDocsHtml(options, template) {
59
+ const { css, umd } = getInlineAssets();
60
+ const clientConfig = buildClientConfig(options);
61
+ const pageTitle = options.title ? `${options.title} — pureDocs` : "pureDocs";
62
+ const bootstrapScript = `PureDocs.bootstrap(${toSafeJson(clientConfig)});`;
63
+ const payload = {
64
+ css,
65
+ script: umd,
66
+ bootstrapScript,
67
+ pageTitle
68
+ };
69
+ if (template) {
70
+ return template(payload);
71
+ }
72
+ return [
73
+ "<!doctype html>",
74
+ '<html lang="en">',
75
+ "<head>",
76
+ ' <meta charset="utf-8" />',
77
+ ' <meta name="viewport" content="width=device-width, initial-scale=1" />',
78
+ ` <title>${escapeHtml(pageTitle)}</title>`,
79
+ ` <style>${css}</style>`,
80
+ "</head>",
81
+ "<body>",
82
+ ` <script>${umd}<\/script>`,
83
+ ` <script>${bootstrapScript}<\/script>`,
84
+ "</body>",
85
+ "</html>"
86
+ ].join("\n");
87
+ }
88
+ function pureDocsExpress(app, options) {
89
+ const html = pureDocsHtml(options);
90
+ const route = resolveRoute(options);
91
+ app.get(route, (_req, res) => sendHtmlResponse(res, html));
92
+ return html;
93
+ }
94
+ function pureDocsFastify(app, options) {
95
+ const html = pureDocsHtml(options);
96
+ const route = resolveRoute(options);
97
+ app.get(route, (_request, reply) => {
98
+ if (typeof reply.type === "function") {
99
+ reply.type("text/html");
100
+ } else if (typeof reply.header === "function") {
101
+ reply.header("content-type", "text/html; charset=utf-8");
102
+ }
103
+ return reply.send ? reply.send(html) : html;
104
+ });
105
+ return html;
106
+ }
107
+ const pureDocs = {
108
+ html: pureDocsHtml,
109
+ express: pureDocsExpress,
110
+ fastify: pureDocsFastify
111
+ };
112
+ exports.default = pureDocs;
113
+ exports.pureDocs = pureDocs;
114
+ exports.pureDocsExpress = pureDocsExpress;
115
+ exports.pureDocsFastify = pureDocsFastify;
116
+ exports.pureDocsHtml = pureDocsHtml;
117
+ //# sourceMappingURL=server.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.cjs","sources":["../src/server.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport interface PureDocsOptions {\n specUrl?: string;\n spec?: Record<string, unknown>;\n title?: string;\n theme?: 'light' | 'dark' | 'auto';\n primaryColor?: string;\n}\n\nexport interface PureDocsRouteOptions extends PureDocsOptions {\n route?: string;\n}\n\nexport interface PureDocsHtmlPayload {\n css: string;\n script: string;\n bootstrapScript: string;\n pageTitle: string;\n}\n\nexport type PureDocsHtmlTemplate = (payload: PureDocsHtmlPayload) => string;\n\ninterface ExpressLikeResponse {\n type?: (value: string) => unknown;\n setHeader?: (name: string, value: string) => unknown;\n send?: (body: string) => unknown;\n end?: (body?: string) => unknown;\n}\n\ninterface ExpressLikeApp {\n get: (path: string, handler: (_req: unknown, res: ExpressLikeResponse) => unknown) => unknown;\n}\n\ninterface FastifyLikeReply {\n type?: (value: string) => FastifyLikeReply;\n header?: (name: string, value: string) => FastifyLikeReply;\n send?: (body: string) => unknown;\n}\n\ninterface FastifyLikeApp {\n get: (path: string, handler: (_request: unknown, reply: FastifyLikeReply) => unknown) => unknown;\n}\n\ninterface PureDocsClientConfig {\n specUrl?: string;\n spec?: Record<string, unknown>;\n title?: string;\n theme?: 'light' | 'dark' | 'auto';\n primaryColor?: string;\n}\n\ninterface InlineAssets {\n css: string;\n umd: string;\n}\n\nconst currentDir = typeof __dirname === 'string'\n ? __dirname\n : path.dirname(fileURLToPath(import.meta.url));\n\nconst cssPath = path.resolve(currentDir, 'puredocs.css');\nconst umdPath = path.resolve(currentDir, 'puredocs.umd.js');\n\nlet inlineAssetsCache: InlineAssets | null = null;\n\nfunction getInlineAssets(): InlineAssets {\n if (!inlineAssetsCache) {\n const css = readFileSync(cssPath, 'utf8');\n const umd = readFileSync(umdPath, 'utf8');\n\n inlineAssetsCache = {\n css: css.replace(/<\\/style>/gi, '<\\\\/style>'),\n umd: umd.replace(/<\\/script>/gi, '<\\\\/script>'),\n };\n }\n\n return inlineAssetsCache;\n}\n\nfunction toSafeJson(value: unknown): string {\n return JSON.stringify(value)\n .replace(/</g, '\\\\u003c')\n .replace(/>/g, '\\\\u003e')\n .replace(/&/g, '\\\\u0026')\n .replace(/\\u2028/g, '\\\\u2028')\n .replace(/\\u2029/g, '\\\\u2029');\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\nfunction buildClientConfig(options: PureDocsOptions): PureDocsClientConfig {\n if (!options.specUrl && !options.spec) {\n throw new Error('[PureDocs] pureDocs.html() requires either \"specUrl\" or \"spec\".');\n }\n\n return {\n specUrl: options.specUrl,\n spec: options.spec,\n title: options.title,\n theme: options.theme ?? 'auto',\n primaryColor: options.primaryColor,\n };\n}\n\nfunction sendHtmlResponse(res: ExpressLikeResponse, html: string): unknown {\n if (typeof res.type === 'function') {\n res.type('text/html');\n } else if (typeof res.setHeader === 'function') {\n res.setHeader('content-type', 'text/html; charset=utf-8');\n }\n\n if (typeof res.send === 'function') {\n return res.send(html);\n }\n if (typeof res.end === 'function') {\n return res.end(html);\n }\n\n throw new Error('[PureDocs] Unsupported response object: expected res.send() or res.end().');\n}\n\nfunction resolveRoute(options: PureDocsRouteOptions): string {\n const route = options.route || '/docs';\n return route.startsWith('/') ? route : `/${route}`;\n}\n\nexport function pureDocsHtml(options: PureDocsOptions, template?: PureDocsHtmlTemplate): string {\n const { css, umd } = getInlineAssets();\n const clientConfig = buildClientConfig(options);\n const pageTitle = options.title ? `${options.title} — pureDocs` : 'pureDocs';\n const bootstrapScript = `PureDocs.bootstrap(${toSafeJson(clientConfig)});`;\n\n const payload: PureDocsHtmlPayload = {\n css,\n script: umd,\n bootstrapScript,\n pageTitle,\n };\n\n if (template) {\n return template(payload);\n }\n\n return [\n '<!doctype html>',\n '<html lang=\"en\">',\n '<head>',\n ' <meta charset=\"utf-8\" />',\n ' <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />',\n ` <title>${escapeHtml(pageTitle)}</title>`,\n ` <style>${css}</style>`,\n '</head>',\n '<body>',\n ` <script>${umd}</script>`,\n ` <script>${bootstrapScript}</script>`,\n '</body>',\n '</html>',\n ].join('\\n');\n}\n\nexport function pureDocsExpress(app: ExpressLikeApp, options: PureDocsRouteOptions): string {\n const html = pureDocsHtml(options);\n const route = resolveRoute(options);\n\n app.get(route, (_req, res) => sendHtmlResponse(res, html));\n return html;\n}\n\nexport function pureDocsFastify(app: FastifyLikeApp, options: PureDocsRouteOptions): string {\n const html = pureDocsHtml(options);\n const route = resolveRoute(options);\n\n app.get(route, (_request, reply) => {\n if (typeof reply.type === 'function') {\n reply.type('text/html');\n } else if (typeof reply.header === 'function') {\n reply.header('content-type', 'text/html; charset=utf-8');\n }\n return reply.send ? reply.send(html) : html;\n });\n\n return html;\n}\n\nexport const pureDocs = {\n html: pureDocsHtml,\n express: pureDocsExpress,\n fastify: pureDocsFastify,\n};\n\nexport default pureDocs;\n"],"names":["fileURLToPath","readFileSync"],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ export interface PureDocsOptions {
2
+ specUrl?: string;
3
+ spec?: Record<string, unknown>;
4
+ title?: string;
5
+ theme?: 'light' | 'dark' | 'auto';
6
+ primaryColor?: string;
7
+ }
8
+ export interface PureDocsRouteOptions extends PureDocsOptions {
9
+ route?: string;
10
+ }
11
+ export interface PureDocsHtmlPayload {
12
+ css: string;
13
+ script: string;
14
+ bootstrapScript: string;
15
+ pageTitle: string;
16
+ }
17
+ export type PureDocsHtmlTemplate = (payload: PureDocsHtmlPayload) => string;
18
+ interface ExpressLikeResponse {
19
+ type?: (value: string) => unknown;
20
+ setHeader?: (name: string, value: string) => unknown;
21
+ send?: (body: string) => unknown;
22
+ end?: (body?: string) => unknown;
23
+ }
24
+ interface ExpressLikeApp {
25
+ get: (path: string, handler: (_req: unknown, res: ExpressLikeResponse) => unknown) => unknown;
26
+ }
27
+ interface FastifyLikeReply {
28
+ type?: (value: string) => FastifyLikeReply;
29
+ header?: (name: string, value: string) => FastifyLikeReply;
30
+ send?: (body: string) => unknown;
31
+ }
32
+ interface FastifyLikeApp {
33
+ get: (path: string, handler: (_request: unknown, reply: FastifyLikeReply) => unknown) => unknown;
34
+ }
35
+ export declare function pureDocsHtml(options: PureDocsOptions, template?: PureDocsHtmlTemplate): string;
36
+ export declare function pureDocsExpress(app: ExpressLikeApp, options: PureDocsRouteOptions): string;
37
+ export declare function pureDocsFastify(app: FastifyLikeApp, options: PureDocsRouteOptions): string;
38
+ export declare const pureDocs: {
39
+ html: typeof pureDocsHtml;
40
+ express: typeof pureDocsExpress;
41
+ fastify: typeof pureDocsFastify;
42
+ };
43
+ export default pureDocs;
package/dist/server.js ADDED
@@ -0,0 +1,116 @@
1
+ import { readFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ const currentDir = typeof __dirname === "string" ? __dirname : path.dirname(fileURLToPath(import.meta.url));
5
+ const cssPath = path.resolve(currentDir, "puredocs.css");
6
+ const umdPath = path.resolve(currentDir, "puredocs.umd.js");
7
+ let inlineAssetsCache = null;
8
+ function getInlineAssets() {
9
+ if (!inlineAssetsCache) {
10
+ const css = readFileSync(cssPath, "utf8");
11
+ const umd = readFileSync(umdPath, "utf8");
12
+ inlineAssetsCache = {
13
+ css: css.replace(/<\/style>/gi, "<\\/style>"),
14
+ umd: umd.replace(/<\/script>/gi, "<\\/script>")
15
+ };
16
+ }
17
+ return inlineAssetsCache;
18
+ }
19
+ function toSafeJson(value) {
20
+ return JSON.stringify(value).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
21
+ }
22
+ function escapeHtml(value) {
23
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
24
+ }
25
+ function buildClientConfig(options) {
26
+ if (!options.specUrl && !options.spec) {
27
+ throw new Error('[PureDocs] pureDocs.html() requires either "specUrl" or "spec".');
28
+ }
29
+ return {
30
+ specUrl: options.specUrl,
31
+ spec: options.spec,
32
+ title: options.title,
33
+ theme: options.theme ?? "auto",
34
+ primaryColor: options.primaryColor
35
+ };
36
+ }
37
+ function sendHtmlResponse(res, html) {
38
+ if (typeof res.type === "function") {
39
+ res.type("text/html");
40
+ } else if (typeof res.setHeader === "function") {
41
+ res.setHeader("content-type", "text/html; charset=utf-8");
42
+ }
43
+ if (typeof res.send === "function") {
44
+ return res.send(html);
45
+ }
46
+ if (typeof res.end === "function") {
47
+ return res.end(html);
48
+ }
49
+ throw new Error("[PureDocs] Unsupported response object: expected res.send() or res.end().");
50
+ }
51
+ function resolveRoute(options) {
52
+ const route = options.route || "/docs";
53
+ return route.startsWith("/") ? route : `/${route}`;
54
+ }
55
+ function pureDocsHtml(options, template) {
56
+ const { css, umd } = getInlineAssets();
57
+ const clientConfig = buildClientConfig(options);
58
+ const pageTitle = options.title ? `${options.title} — pureDocs` : "pureDocs";
59
+ const bootstrapScript = `PureDocs.bootstrap(${toSafeJson(clientConfig)});`;
60
+ const payload = {
61
+ css,
62
+ script: umd,
63
+ bootstrapScript,
64
+ pageTitle
65
+ };
66
+ if (template) {
67
+ return template(payload);
68
+ }
69
+ return [
70
+ "<!doctype html>",
71
+ '<html lang="en">',
72
+ "<head>",
73
+ ' <meta charset="utf-8" />',
74
+ ' <meta name="viewport" content="width=device-width, initial-scale=1" />',
75
+ ` <title>${escapeHtml(pageTitle)}</title>`,
76
+ ` <style>${css}</style>`,
77
+ "</head>",
78
+ "<body>",
79
+ ` <script>${umd}<\/script>`,
80
+ ` <script>${bootstrapScript}<\/script>`,
81
+ "</body>",
82
+ "</html>"
83
+ ].join("\n");
84
+ }
85
+ function pureDocsExpress(app, options) {
86
+ const html = pureDocsHtml(options);
87
+ const route = resolveRoute(options);
88
+ app.get(route, (_req, res) => sendHtmlResponse(res, html));
89
+ return html;
90
+ }
91
+ function pureDocsFastify(app, options) {
92
+ const html = pureDocsHtml(options);
93
+ const route = resolveRoute(options);
94
+ app.get(route, (_request, reply) => {
95
+ if (typeof reply.type === "function") {
96
+ reply.type("text/html");
97
+ } else if (typeof reply.header === "function") {
98
+ reply.header("content-type", "text/html; charset=utf-8");
99
+ }
100
+ return reply.send ? reply.send(html) : html;
101
+ });
102
+ return html;
103
+ }
104
+ const pureDocs = {
105
+ html: pureDocsHtml,
106
+ express: pureDocsExpress,
107
+ fastify: pureDocsFastify
108
+ };
109
+ export {
110
+ pureDocs as default,
111
+ pureDocs,
112
+ pureDocsExpress,
113
+ pureDocsFastify,
114
+ pureDocsHtml
115
+ };
116
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sources":["../src/server.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport interface PureDocsOptions {\n specUrl?: string;\n spec?: Record<string, unknown>;\n title?: string;\n theme?: 'light' | 'dark' | 'auto';\n primaryColor?: string;\n}\n\nexport interface PureDocsRouteOptions extends PureDocsOptions {\n route?: string;\n}\n\nexport interface PureDocsHtmlPayload {\n css: string;\n script: string;\n bootstrapScript: string;\n pageTitle: string;\n}\n\nexport type PureDocsHtmlTemplate = (payload: PureDocsHtmlPayload) => string;\n\ninterface ExpressLikeResponse {\n type?: (value: string) => unknown;\n setHeader?: (name: string, value: string) => unknown;\n send?: (body: string) => unknown;\n end?: (body?: string) => unknown;\n}\n\ninterface ExpressLikeApp {\n get: (path: string, handler: (_req: unknown, res: ExpressLikeResponse) => unknown) => unknown;\n}\n\ninterface FastifyLikeReply {\n type?: (value: string) => FastifyLikeReply;\n header?: (name: string, value: string) => FastifyLikeReply;\n send?: (body: string) => unknown;\n}\n\ninterface FastifyLikeApp {\n get: (path: string, handler: (_request: unknown, reply: FastifyLikeReply) => unknown) => unknown;\n}\n\ninterface PureDocsClientConfig {\n specUrl?: string;\n spec?: Record<string, unknown>;\n title?: string;\n theme?: 'light' | 'dark' | 'auto';\n primaryColor?: string;\n}\n\ninterface InlineAssets {\n css: string;\n umd: string;\n}\n\nconst currentDir = typeof __dirname === 'string'\n ? __dirname\n : path.dirname(fileURLToPath(import.meta.url));\n\nconst cssPath = path.resolve(currentDir, 'puredocs.css');\nconst umdPath = path.resolve(currentDir, 'puredocs.umd.js');\n\nlet inlineAssetsCache: InlineAssets | null = null;\n\nfunction getInlineAssets(): InlineAssets {\n if (!inlineAssetsCache) {\n const css = readFileSync(cssPath, 'utf8');\n const umd = readFileSync(umdPath, 'utf8');\n\n inlineAssetsCache = {\n css: css.replace(/<\\/style>/gi, '<\\\\/style>'),\n umd: umd.replace(/<\\/script>/gi, '<\\\\/script>'),\n };\n }\n\n return inlineAssetsCache;\n}\n\nfunction toSafeJson(value: unknown): string {\n return JSON.stringify(value)\n .replace(/</g, '\\\\u003c')\n .replace(/>/g, '\\\\u003e')\n .replace(/&/g, '\\\\u0026')\n .replace(/\\u2028/g, '\\\\u2028')\n .replace(/\\u2029/g, '\\\\u2029');\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\nfunction buildClientConfig(options: PureDocsOptions): PureDocsClientConfig {\n if (!options.specUrl && !options.spec) {\n throw new Error('[PureDocs] pureDocs.html() requires either \"specUrl\" or \"spec\".');\n }\n\n return {\n specUrl: options.specUrl,\n spec: options.spec,\n title: options.title,\n theme: options.theme ?? 'auto',\n primaryColor: options.primaryColor,\n };\n}\n\nfunction sendHtmlResponse(res: ExpressLikeResponse, html: string): unknown {\n if (typeof res.type === 'function') {\n res.type('text/html');\n } else if (typeof res.setHeader === 'function') {\n res.setHeader('content-type', 'text/html; charset=utf-8');\n }\n\n if (typeof res.send === 'function') {\n return res.send(html);\n }\n if (typeof res.end === 'function') {\n return res.end(html);\n }\n\n throw new Error('[PureDocs] Unsupported response object: expected res.send() or res.end().');\n}\n\nfunction resolveRoute(options: PureDocsRouteOptions): string {\n const route = options.route || '/docs';\n return route.startsWith('/') ? route : `/${route}`;\n}\n\nexport function pureDocsHtml(options: PureDocsOptions, template?: PureDocsHtmlTemplate): string {\n const { css, umd } = getInlineAssets();\n const clientConfig = buildClientConfig(options);\n const pageTitle = options.title ? `${options.title} — pureDocs` : 'pureDocs';\n const bootstrapScript = `PureDocs.bootstrap(${toSafeJson(clientConfig)});`;\n\n const payload: PureDocsHtmlPayload = {\n css,\n script: umd,\n bootstrapScript,\n pageTitle,\n };\n\n if (template) {\n return template(payload);\n }\n\n return [\n '<!doctype html>',\n '<html lang=\"en\">',\n '<head>',\n ' <meta charset=\"utf-8\" />',\n ' <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />',\n ` <title>${escapeHtml(pageTitle)}</title>`,\n ` <style>${css}</style>`,\n '</head>',\n '<body>',\n ` <script>${umd}</script>`,\n ` <script>${bootstrapScript}</script>`,\n '</body>',\n '</html>',\n ].join('\\n');\n}\n\nexport function pureDocsExpress(app: ExpressLikeApp, options: PureDocsRouteOptions): string {\n const html = pureDocsHtml(options);\n const route = resolveRoute(options);\n\n app.get(route, (_req, res) => sendHtmlResponse(res, html));\n return html;\n}\n\nexport function pureDocsFastify(app: FastifyLikeApp, options: PureDocsRouteOptions): string {\n const html = pureDocsHtml(options);\n const route = resolveRoute(options);\n\n app.get(route, (_request, reply) => {\n if (typeof reply.type === 'function') {\n reply.type('text/html');\n } else if (typeof reply.header === 'function') {\n reply.header('content-type', 'text/html; charset=utf-8');\n }\n return reply.send ? reply.send(html) : html;\n });\n\n return html;\n}\n\nexport const pureDocs = {\n html: pureDocsHtml,\n express: pureDocsExpress,\n fastify: pureDocsFastify,\n};\n\nexport default pureDocs;\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { PortalState } from '../core/types';
2
+ export declare function getActiveEnvironment(state: PortalState): import("../core/types").PortalEnvironment;
3
+ export declare function getBaseUrl(state: PortalState): string;
4
+ export declare function normalizeBaseUrl(baseUrl: string): string;
5
+ export declare function formatBaseUrlForDisplay(baseUrl: string): string;
6
+ export declare function getNormalizedBaseUrl(state: PortalState): string;
7
+ export declare function getDisplayBaseUrl(state: PortalState): string;
package/package.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "name": "puredocs_v2",
3
+ "version": "1.0.0",
4
+ "description": "Beautiful API documentation portal from any OpenAPI 3.1 spec. One-liner for Express & Fastify. Standard Web Component for everything else.",
5
+ "author": "esurkov1",
6
+ "license": "SEE LICENSE IN LICENSE",
7
+ "homepage": "https://puredocs.dev",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/esurkov1/puredocs.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/esurkov1/puredocs/issues"
14
+ },
15
+ "keywords": [
16
+ "openapi",
17
+ "openapi-3.1",
18
+ "api-docs",
19
+ "api-documentation",
20
+ "documentation",
21
+ "swagger",
22
+ "web-components",
23
+ "api-portal",
24
+ "developer-portal",
25
+ "rest-api",
26
+ "express",
27
+ "fastify",
28
+ "api-reference"
29
+ ],
30
+ "type": "module",
31
+ "main": "dist/server.cjs",
32
+ "module": "dist/server.js",
33
+ "types": "dist/server.d.ts",
34
+ "unpkg": "dist/puredocs.umd.js",
35
+ "jsdelivr": "dist/puredocs.umd.js",
36
+ "exports": {
37
+ ".": {
38
+ "types": "./dist/server.d.ts",
39
+ "import": "./dist/server.js",
40
+ "require": "./dist/server.cjs"
41
+ },
42
+ "./server": {
43
+ "types": "./dist/server.d.ts",
44
+ "import": "./dist/server.js",
45
+ "require": "./dist/server.cjs"
46
+ },
47
+ "./web": {
48
+ "types": "./dist/index.d.ts",
49
+ "import": "./dist/puredocs.js",
50
+ "require": "./dist/puredocs.cjs"
51
+ },
52
+ "./style.css": "./dist/puredocs.css"
53
+ },
54
+ "sideEffects": [
55
+ "./dist/puredocs.css",
56
+ "./dist/puredocs.js",
57
+ "./dist/puredocs.umd.js"
58
+ ],
59
+ "files": [
60
+ "dist",
61
+ "README.md",
62
+ "LICENSE"
63
+ ],
64
+ "scripts": {
65
+ "dev": "vite",
66
+ "build": "vite build && vite build -c vite.server.config.ts && tsc --emitDeclarationOnly",
67
+ "preview": "vite preview",
68
+ "typecheck": "tsc --noEmit"
69
+ },
70
+ "dependencies": {
71
+ "js-yaml": "^4.1.0"
72
+ },
73
+ "devDependencies": {
74
+ "@types/js-yaml": "^4.0.9",
75
+ "@types/node": "^22.13.10",
76
+ "typescript": "^5.7.0",
77
+ "vite": "^6.1.0",
78
+ "vite-plugin-dts": "^4.5.0"
79
+ },
80
+ "engines": {
81
+ "node": ">=18",
82
+ "bun": ">=1.0.0"
83
+ }
84
+ }