moonflower 1.3.0 → 1.3.1

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 (38) hide show
  1. package/cli/entry.cjs +1 -1
  2. package/dist/cli/cli.cjs +2 -0
  3. package/dist/cli/cli.cjs.map +1 -0
  4. package/dist/cli/cli.d.ts +2 -0
  5. package/dist/cli/cli.d.ts.map +1 -0
  6. package/dist/cli/cli.mjs +62 -0
  7. package/dist/cli/cli.mjs.map +1 -0
  8. package/dist/cli/prettyprint.cjs +2 -0
  9. package/dist/cli/prettyprint.cjs.map +1 -0
  10. package/dist/cli/prettyprint.d.ts +5 -0
  11. package/dist/cli/prettyprint.d.ts.map +1 -0
  12. package/dist/cli/prettyprint.mjs +15 -0
  13. package/dist/cli/prettyprint.mjs.map +1 -0
  14. package/dist/openapi/initOpenApiEngine.cjs +1 -1
  15. package/dist/openapi/initOpenApiEngine.cjs.map +1 -1
  16. package/dist/openapi/initOpenApiEngine.d.ts +7 -2
  17. package/dist/openapi/initOpenApiEngine.d.ts.map +1 -1
  18. package/dist/openapi/initOpenApiEngine.mjs +13 -7
  19. package/dist/openapi/initOpenApiEngine.mjs.map +1 -1
  20. package/dist/openapi/manager/OpenApiManager.cjs +1 -1
  21. package/dist/openapi/manager/OpenApiManager.cjs.map +1 -1
  22. package/dist/openapi/manager/OpenApiManager.d.ts +4 -0
  23. package/dist/openapi/manager/OpenApiManager.d.ts.map +1 -1
  24. package/dist/openapi/manager/OpenApiManager.mjs +11 -2
  25. package/dist/openapi/manager/OpenApiManager.mjs.map +1 -1
  26. package/dist/openapi/router/OpenApiRouter.cjs +1 -1
  27. package/dist/openapi/router/OpenApiRouter.cjs.map +1 -1
  28. package/dist/openapi/router/OpenApiRouter.d.ts.map +1 -1
  29. package/dist/openapi/router/OpenApiRouter.mjs +9 -6
  30. package/dist/openapi/router/OpenApiRouter.mjs.map +1 -1
  31. package/package.json +4 -4
  32. package/{cli → src/cli}/cli.ts +26 -6
  33. package/{cli → src/cli}/prettyprint.ts +2 -2
  34. package/src/openapi/initOpenApiEngine.ts +48 -6
  35. package/src/openapi/manager/OpenApiManager.ts +16 -0
  36. package/src/openapi/router/OpenApiRouter.ts +6 -1
  37. package/src/test/app.spec.ts +27 -0
  38. package/vite.config.ts +3 -0
package/cli/entry.cjs CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- require('../dist/cli/cli.js')
3
+ require('../dist/cli/cli.cjs')
@@ -0,0 +1,2 @@
1
+ "use strict";const i=require("fs"),c=require("path"),p=require("yargs"),f=require("yargs/helpers"),l=require("../openapi/analyzerModule/analyzerModule.cjs"),u=require("../openapi/generatorModule/generatorModule.cjs"),d=require("../openapi/manager/OpenApiManager.cjs"),g=require("./prettyprint.cjs");function a(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const n in e)if(n!=="default"){const o=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,o.get?o:{enumerable:!0,get:()=>e[n]})}}return t.default=e,Object.freeze(t)}const r=a(i),s=a(c),h=console.info;console.info=(e,...t)=>{h(`${e}`,...t)};p(f.hideBin(process.argv)).showHelpOnFail(!0).command({command:"openapi <targetPath>",describe:"Generates the current openapi spec into a specified file path",builder:{targetPath:{describe:"Target path",demandOption:!0,type:"string",coerce:e=>s.resolve(e)},tsConfigPath:{describe:"tsconfig",type:"string",coerce:e=>s.resolve(e)},force:{describe:"Overwrite existing file",type:"boolean",default:!1}},handler(e){if(r.existsSync(e.targetPath)&&!e.force&&!y(e.targetPath)){console.error(`[Error] File already exists at ${e.targetPath} and does not appear to be a moonflower output. Use --force to overwrite.`);return}if(e.tsConfigPath&&!r.existsSync(e.tsConfigPath)){console.error(`[Error] Unable to find a tsconfig file at ${e.tsConfigPath}`);return}l.prepareOpenApiSpec({tsconfigPath:e.tsConfigPath??"tsconfig.json"});const t=d.OpenApiManager.getInstance();g.printAnalysisStats(t.getStats());const n=u.generateOpenApiSpec(t);r.writeFileSync(e.targetPath,JSON.stringify(n))}}).demandCommand().parse();function y(e){try{const t=r.readFileSync(e,"utf-8"),n=JSON.parse(t);return typeof n=="object"&&n!==null&&typeof n.openapi=="string"}catch{return!1}}
2
+ //# sourceMappingURL=cli.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.cjs","sources":["../../src/cli/cli.ts"],"sourcesContent":["import * as fs from 'fs'\nimport * as path from 'path'\nimport yargs, { ArgumentsCamelCase } from 'yargs'\nimport { hideBin } from 'yargs/helpers'\n\nimport { prepareOpenApiSpec } from '../openapi/analyzerModule/analyzerModule'\nimport { generateOpenApiSpec } from '../openapi/generatorModule'\nimport { OpenApiManager } from '../openapi/manager/OpenApiManager'\nimport { printAnalysisStats } from './prettyprint'\n\nconst originalConsole = console.info\nconsole.info = (message, ...args) => {\n\toriginalConsole(`${message}`, ...args)\n}\n\nyargs(hideBin(process.argv))\n\t.showHelpOnFail(true)\n\t.command({\n\t\tcommand: 'openapi <targetPath>',\n\t\tdescribe: 'Generates the current openapi spec into a specified file path',\n\t\tbuilder: {\n\t\t\ttargetPath: {\n\t\t\t\tdescribe: 'Target path',\n\t\t\t\tdemandOption: true,\n\t\t\t\ttype: 'string',\n\t\t\t\tcoerce: (f) => path.resolve(f),\n\t\t\t},\n\n\t\t\ttsConfigPath: {\n\t\t\t\tdescribe: 'tsconfig',\n\t\t\t\ttype: 'string',\n\t\t\t\tcoerce: (f) => path.resolve(f),\n\t\t\t},\n\n\t\t\tforce: {\n\t\t\t\tdescribe: 'Overwrite existing file',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t},\n\t\t},\n\n\t\thandler(argv: ArgumentsCamelCase<{ targetPath: string; tsConfigPath?: string; force: boolean }>) {\n\t\t\tif (fs.existsSync(argv.targetPath)) {\n\t\t\t\tif (!argv.force && !isValidMoonflowerOutput(argv.targetPath)) {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`[Error] File already exists at ${argv.targetPath} and does not appear to be a moonflower output. Use --force to overwrite.`,\n\t\t\t\t\t)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (argv.tsConfigPath && !fs.existsSync(argv.tsConfigPath)) {\n\t\t\t\tconsole.error(`[Error] Unable to find a tsconfig file at ${argv.tsConfigPath}`)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tprepareOpenApiSpec({\n\t\t\t\ttsconfigPath: argv.tsConfigPath ?? 'tsconfig.json',\n\t\t\t})\n\n\t\t\tconst manager = OpenApiManager.getInstance()\n\t\t\tprintAnalysisStats(manager.getStats())\n\n\t\t\tconst spec = generateOpenApiSpec(manager)\n\t\t\tfs.writeFileSync(argv.targetPath, JSON.stringify(spec))\n\t\t},\n\t})\n\t.demandCommand()\n\t.parse()\n\nfunction isValidMoonflowerOutput(filePath: string): boolean {\n\ttry {\n\t\tconst content = fs.readFileSync(filePath, 'utf-8')\n\t\tconst parsed = JSON.parse(content)\n\t\treturn typeof parsed === 'object' && parsed !== null && typeof parsed.openapi === 'string'\n\t} catch {\n\t\treturn false\n\t}\n}\n"],"names":["originalConsole","message","args","yargs","hideBin","f","path","argv","fs","isValidMoonflowerOutput","prepareOpenApiSpec","manager","OpenApiManager","printAnalysisStats","spec","generateOpenApiSpec","filePath","content","parsed"],"mappings":"4kBAUMA,EAAkB,QAAQ,KAChC,QAAQ,KAAO,CAACC,KAAYC,IAAS,CACpCF,EAAgB,GAAGC,CAAO,GAAI,GAAGC,CAAI,CACtC,EAEAC,EAAMC,EAAAA,QAAQ,QAAQ,IAAI,CAAC,EACzB,eAAe,EAAI,EACnB,QAAQ,CACR,QAAS,uBACT,SAAU,gEACV,QAAS,CACR,WAAY,CACX,SAAU,cACV,aAAc,GACd,KAAM,SACN,OAASC,GAAMC,EAAK,QAAQD,CAAC,CAC9B,EAEA,aAAc,CACb,SAAU,WACV,KAAM,SACN,OAASA,GAAMC,EAAK,QAAQD,CAAC,CAC9B,EAEA,MAAO,CACN,SAAU,0BACV,KAAM,UACN,QAAS,EAAA,CAEX,EAEA,QAAQE,EAAyF,CAChG,GAAIC,EAAG,WAAWD,EAAK,UAAU,GAC5B,CAACA,EAAK,OAAS,CAACE,EAAwBF,EAAK,UAAU,EAAG,CACrD,QAAA,MACP,kCAAkCA,EAAK,UAAU,2EAClD,EACA,MAAA,CAIF,GAAIA,EAAK,cAAgB,CAACC,EAAG,WAAWD,EAAK,YAAY,EAAG,CAC3D,QAAQ,MAAM,6CAA6CA,EAAK,YAAY,EAAE,EAC9E,MAAA,CAGkBG,qBAAA,CAClB,aAAcH,EAAK,cAAgB,eAAA,CACnC,EAEK,MAAAI,EAAUC,iBAAe,YAAY,EACxBC,qBAAAF,EAAQ,UAAU,EAE/B,MAAAG,EAAOC,sBAAoBJ,CAAO,EACxCH,EAAG,cAAcD,EAAK,WAAY,KAAK,UAAUO,CAAI,CAAC,CAAA,CAExD,CAAC,EACA,cAAc,EACd,MAAM,EAER,SAASL,EAAwBO,EAA2B,CACvD,GAAA,CACH,MAAMC,EAAUT,EAAG,aAAaQ,EAAU,OAAO,EAC3CE,EAAS,KAAK,MAAMD,CAAO,EACjC,OAAO,OAAOC,GAAW,UAAYA,IAAW,MAAQ,OAAOA,EAAO,SAAY,QAAA,MAC3E,CACA,MAAA,EAAA,CAET"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli/cli.ts"],"names":[],"mappings":""}
@@ -0,0 +1,62 @@
1
+ import * as r from "fs";
2
+ import * as n from "path";
3
+ import i from "yargs";
4
+ import { hideBin as a } from "yargs/helpers";
5
+ import { prepareOpenApiSpec as s } from "../openapi/analyzerModule/analyzerModule.mjs";
6
+ import { generateOpenApiSpec as p } from "../openapi/generatorModule/generatorModule.mjs";
7
+ import { OpenApiManager as c } from "../openapi/manager/OpenApiManager.mjs";
8
+ import { printAnalysisStats as f } from "./prettyprint.mjs";
9
+ const l = console.info;
10
+ console.info = (e, ...t) => {
11
+ l(`${e}`, ...t);
12
+ };
13
+ i(a(process.argv)).showHelpOnFail(!0).command({
14
+ command: "openapi <targetPath>",
15
+ describe: "Generates the current openapi spec into a specified file path",
16
+ builder: {
17
+ targetPath: {
18
+ describe: "Target path",
19
+ demandOption: !0,
20
+ type: "string",
21
+ coerce: (e) => n.resolve(e)
22
+ },
23
+ tsConfigPath: {
24
+ describe: "tsconfig",
25
+ type: "string",
26
+ coerce: (e) => n.resolve(e)
27
+ },
28
+ force: {
29
+ describe: "Overwrite existing file",
30
+ type: "boolean",
31
+ default: !1
32
+ }
33
+ },
34
+ handler(e) {
35
+ if (r.existsSync(e.targetPath) && !e.force && !m(e.targetPath)) {
36
+ console.error(
37
+ `[Error] File already exists at ${e.targetPath} and does not appear to be a moonflower output. Use --force to overwrite.`
38
+ );
39
+ return;
40
+ }
41
+ if (e.tsConfigPath && !r.existsSync(e.tsConfigPath)) {
42
+ console.error(`[Error] Unable to find a tsconfig file at ${e.tsConfigPath}`);
43
+ return;
44
+ }
45
+ s({
46
+ tsconfigPath: e.tsConfigPath ?? "tsconfig.json"
47
+ });
48
+ const t = c.getInstance();
49
+ f(t.getStats());
50
+ const o = p(t);
51
+ r.writeFileSync(e.targetPath, JSON.stringify(o));
52
+ }
53
+ }).demandCommand().parse();
54
+ function m(e) {
55
+ try {
56
+ const t = r.readFileSync(e, "utf-8"), o = JSON.parse(t);
57
+ return typeof o == "object" && o !== null && typeof o.openapi == "string";
58
+ } catch {
59
+ return !1;
60
+ }
61
+ }
62
+ //# sourceMappingURL=cli.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.mjs","sources":["../../src/cli/cli.ts"],"sourcesContent":["import * as fs from 'fs'\nimport * as path from 'path'\nimport yargs, { ArgumentsCamelCase } from 'yargs'\nimport { hideBin } from 'yargs/helpers'\n\nimport { prepareOpenApiSpec } from '../openapi/analyzerModule/analyzerModule'\nimport { generateOpenApiSpec } from '../openapi/generatorModule'\nimport { OpenApiManager } from '../openapi/manager/OpenApiManager'\nimport { printAnalysisStats } from './prettyprint'\n\nconst originalConsole = console.info\nconsole.info = (message, ...args) => {\n\toriginalConsole(`${message}`, ...args)\n}\n\nyargs(hideBin(process.argv))\n\t.showHelpOnFail(true)\n\t.command({\n\t\tcommand: 'openapi <targetPath>',\n\t\tdescribe: 'Generates the current openapi spec into a specified file path',\n\t\tbuilder: {\n\t\t\ttargetPath: {\n\t\t\t\tdescribe: 'Target path',\n\t\t\t\tdemandOption: true,\n\t\t\t\ttype: 'string',\n\t\t\t\tcoerce: (f) => path.resolve(f),\n\t\t\t},\n\n\t\t\ttsConfigPath: {\n\t\t\t\tdescribe: 'tsconfig',\n\t\t\t\ttype: 'string',\n\t\t\t\tcoerce: (f) => path.resolve(f),\n\t\t\t},\n\n\t\t\tforce: {\n\t\t\t\tdescribe: 'Overwrite existing file',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t},\n\t\t},\n\n\t\thandler(argv: ArgumentsCamelCase<{ targetPath: string; tsConfigPath?: string; force: boolean }>) {\n\t\t\tif (fs.existsSync(argv.targetPath)) {\n\t\t\t\tif (!argv.force && !isValidMoonflowerOutput(argv.targetPath)) {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`[Error] File already exists at ${argv.targetPath} and does not appear to be a moonflower output. Use --force to overwrite.`,\n\t\t\t\t\t)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (argv.tsConfigPath && !fs.existsSync(argv.tsConfigPath)) {\n\t\t\t\tconsole.error(`[Error] Unable to find a tsconfig file at ${argv.tsConfigPath}`)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tprepareOpenApiSpec({\n\t\t\t\ttsconfigPath: argv.tsConfigPath ?? 'tsconfig.json',\n\t\t\t})\n\n\t\t\tconst manager = OpenApiManager.getInstance()\n\t\t\tprintAnalysisStats(manager.getStats())\n\n\t\t\tconst spec = generateOpenApiSpec(manager)\n\t\t\tfs.writeFileSync(argv.targetPath, JSON.stringify(spec))\n\t\t},\n\t})\n\t.demandCommand()\n\t.parse()\n\nfunction isValidMoonflowerOutput(filePath: string): boolean {\n\ttry {\n\t\tconst content = fs.readFileSync(filePath, 'utf-8')\n\t\tconst parsed = JSON.parse(content)\n\t\treturn typeof parsed === 'object' && parsed !== null && typeof parsed.openapi === 'string'\n\t} catch {\n\t\treturn false\n\t}\n}\n"],"names":["originalConsole","message","args","yargs","hideBin","f","path","argv","fs","isValidMoonflowerOutput","prepareOpenApiSpec","manager","OpenApiManager","printAnalysisStats","spec","generateOpenApiSpec","filePath","content","parsed"],"mappings":";;;;;;;;AAUA,MAAMA,IAAkB,QAAQ;AAChC,QAAQ,OAAO,CAACC,MAAYC,MAAS;AACpC,EAAAF,EAAgB,GAAGC,CAAO,IAAI,GAAGC,CAAI;AACtC;AAEAC,EAAMC,EAAQ,QAAQ,IAAI,CAAC,EACzB,eAAe,EAAI,EACnB,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,UAAU;AAAA,EACV,SAAS;AAAA,IACR,YAAY;AAAA,MACX,UAAU;AAAA,MACV,cAAc;AAAA,MACd,MAAM;AAAA,MACN,QAAQ,CAACC,MAAMC,EAAK,QAAQD,CAAC;AAAA,IAC9B;AAAA,IAEA,cAAc;AAAA,MACb,UAAU;AAAA,MACV,MAAM;AAAA,MACN,QAAQ,CAACA,MAAMC,EAAK,QAAQD,CAAC;AAAA,IAC9B;AAAA,IAEA,OAAO;AAAA,MACN,UAAU;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA,IAAA;AAAA,EAEX;AAAA,EAEA,QAAQE,GAAyF;AAChG,QAAIC,EAAG,WAAWD,EAAK,UAAU,KAC5B,CAACA,EAAK,SAAS,CAACE,EAAwBF,EAAK,UAAU,GAAG;AACrD,cAAA;AAAA,QACP,kCAAkCA,EAAK,UAAU;AAAA,MAClD;AACA;AAAA,IAAA;AAIF,QAAIA,EAAK,gBAAgB,CAACC,EAAG,WAAWD,EAAK,YAAY,GAAG;AAC3D,cAAQ,MAAM,6CAA6CA,EAAK,YAAY,EAAE;AAC9E;AAAA,IAAA;AAGkB,IAAAG,EAAA;AAAA,MAClB,cAAcH,EAAK,gBAAgB;AAAA,IAAA,CACnC;AAEK,UAAAI,IAAUC,EAAe,YAAY;AACxB,IAAAC,EAAAF,EAAQ,UAAU;AAE/B,UAAAG,IAAOC,EAAoBJ,CAAO;AACxC,IAAAH,EAAG,cAAcD,EAAK,YAAY,KAAK,UAAUO,CAAI,CAAC;AAAA,EAAA;AAExD,CAAC,EACA,cAAc,EACd,MAAM;AAER,SAASL,EAAwBO,GAA2B;AACvD,MAAA;AACH,UAAMC,IAAUT,EAAG,aAAaQ,GAAU,OAAO,GAC3CE,IAAS,KAAK,MAAMD,CAAO;AACjC,WAAO,OAAOC,KAAW,YAAYA,MAAW,QAAQ,OAAOA,EAAO,WAAY;AAAA,EAAA,QAC3E;AACA,WAAA;AAAA,EAAA;AAET;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("../utils/logger.cjs"),n=o=>{o.explicitRouterFiles.forEach(e=>t(e)),o.discoveredRouterFiles.forEach(e=>t(e))},t=o=>{r.Logger.info(`${o.path}`),o.routers.forEach(e=>{r.Logger.info(`└ ${e.name}`),e.endpoints.forEach(i=>{r.Logger.info(` └ ${i}`)})})};exports.printAnalysisStats=n;exports.printRouterFile=t;
2
+ //# sourceMappingURL=prettyprint.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prettyprint.cjs","sources":["../../src/cli/prettyprint.ts"],"sourcesContent":["import { ApiAnalysisStats } from '../openapi/manager/OpenApiManager'\nimport { Logger } from '../utils/logger'\n\nexport const printAnalysisStats = (stats: ApiAnalysisStats) => {\n\tstats.explicitRouterFiles.forEach((file) => printRouterFile(file))\n\tstats.discoveredRouterFiles.forEach((file) => printRouterFile(file))\n}\n\nexport const printRouterFile = (file: ApiAnalysisStats['discoveredRouterFiles'][number]) => {\n\tLogger.info(`${file.path}`)\n\tfile.routers.forEach((r) => {\n\t\tLogger.info(`└ ${r.name}`)\n\t\tr.endpoints.forEach((e) => {\n\t\t\tLogger.info(` └ ${e}`)\n\t\t})\n\t})\n}\n"],"names":["printAnalysisStats","stats","file","printRouterFile","Logger","r","e"],"mappings":"uHAGaA,EAAsBC,GAA4B,CAC9DA,EAAM,oBAAoB,QAASC,GAASC,EAAgBD,CAAI,CAAC,EACjED,EAAM,sBAAsB,QAASC,GAASC,EAAgBD,CAAI,CAAC,CACpE,EAEaC,EAAmBD,GAA4D,CAC3FE,EAAAA,OAAO,KAAK,GAAGF,EAAK,IAAI,EAAE,EACrBA,EAAA,QAAQ,QAASG,GAAM,CAC3BD,EAAA,OAAO,KAAK,KAAKC,EAAE,IAAI,EAAE,EACvBA,EAAA,UAAU,QAASC,GAAM,CACnBF,EAAAA,OAAA,KAAK,OAAOE,CAAC,EAAE,CAAA,CACtB,CAAA,CACD,CACF"}
@@ -0,0 +1,5 @@
1
+ import { ApiAnalysisStats } from '../openapi/manager/OpenApiManager';
2
+
3
+ export declare const printAnalysisStats: (stats: ApiAnalysisStats) => void;
4
+ export declare const printRouterFile: (file: ApiAnalysisStats["discoveredRouterFiles"][number]) => void;
5
+ //# sourceMappingURL=prettyprint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prettyprint.d.ts","sourceRoot":"","sources":["../../src/cli/prettyprint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAA;AAGpE,eAAO,MAAM,kBAAkB,UAAW,gBAAgB,SAGzD,CAAA;AAED,eAAO,MAAM,eAAe,SAAU,gBAAgB,CAAC,uBAAuB,CAAC,CAAC,MAAM,CAAC,SAQtF,CAAA"}
@@ -0,0 +1,15 @@
1
+ import { Logger as e } from "../utils/logger.mjs";
2
+ const c = (r) => {
3
+ r.explicitRouterFiles.forEach((o) => i(o)), r.discoveredRouterFiles.forEach((o) => i(o));
4
+ }, i = (r) => {
5
+ e.info(`${r.path}`), r.routers.forEach((o) => {
6
+ e.info(`└ ${o.name}`), o.endpoints.forEach((t) => {
7
+ e.info(` └ ${t}`);
8
+ });
9
+ });
10
+ };
11
+ export {
12
+ c as printAnalysisStats,
13
+ i as printRouterFile
14
+ };
15
+ //# sourceMappingURL=prettyprint.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prettyprint.mjs","sources":["../../src/cli/prettyprint.ts"],"sourcesContent":["import { ApiAnalysisStats } from '../openapi/manager/OpenApiManager'\nimport { Logger } from '../utils/logger'\n\nexport const printAnalysisStats = (stats: ApiAnalysisStats) => {\n\tstats.explicitRouterFiles.forEach((file) => printRouterFile(file))\n\tstats.discoveredRouterFiles.forEach((file) => printRouterFile(file))\n}\n\nexport const printRouterFile = (file: ApiAnalysisStats['discoveredRouterFiles'][number]) => {\n\tLogger.info(`${file.path}`)\n\tfile.routers.forEach((r) => {\n\t\tLogger.info(`└ ${r.name}`)\n\t\tr.endpoints.forEach((e) => {\n\t\t\tLogger.info(` └ ${e}`)\n\t\t})\n\t})\n}\n"],"names":["printAnalysisStats","stats","file","printRouterFile","Logger","r","e"],"mappings":";AAGa,MAAAA,IAAqB,CAACC,MAA4B;AAC9D,EAAAA,EAAM,oBAAoB,QAAQ,CAACC,MAASC,EAAgBD,CAAI,CAAC,GACjED,EAAM,sBAAsB,QAAQ,CAACC,MAASC,EAAgBD,CAAI,CAAC;AACpE,GAEaC,IAAkB,CAACD,MAA4D;AAC3F,EAAAE,EAAO,KAAK,GAAGF,EAAK,IAAI,EAAE,GACrBA,EAAA,QAAQ,QAAQ,CAACG,MAAM;AAC3B,IAAAD,EAAO,KAAK,KAAKC,EAAE,IAAI,EAAE,GACvBA,EAAA,UAAU,QAAQ,CAACC,MAAM;AACnB,MAAAF,EAAA,KAAK,OAAOE,CAAC,EAAE;AAAA,IAAA,CACtB;AAAA,EAAA,CACD;AACF;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("./analyzerModule/analyzerModule.cjs"),n=require("./router/OpenApiRouter.cjs"),u=t=>{p.prepareOpenApiSpec(t);const i=n.OpenApiRouter.routes(),o=n.OpenApiRouter.allowedMethods();return(e,r)=>i(e,()=>o(e,r))};exports.initOpenApiEngine=u;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("fs"),a=require("./manager/OpenApiManager.cjs"),i=require("./router/OpenApiRouter.cjs");function u(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const n in e)if(n!=="default"){const r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:()=>e[n]})}}return t.default=e,Object.freeze(t)}const l=u(c),p=e=>{const t="specPath"in e?d(e.specPath):Promise.resolve().then(()=>require("./analyzerModule/analyzerModule.cjs")).then(({prepareOpenApiSpec:o})=>o(e)),n=i.OpenApiRouter.routes(),r=i.OpenApiRouter.allowedMethods();return async(o,s)=>(await t,n(o,()=>r(o,s)))},d=e=>{const t=a.OpenApiManager.getInstance();if(t.isReady())return;const n=l.readFileSync(e,"utf-8"),r=JSON.parse(n);t.setPrebuiltSpec(r),t.markAsReady()};exports.initOpenApiEngine=p;
2
2
  //# sourceMappingURL=initOpenApiEngine.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"initOpenApiEngine.cjs","sources":["../../src/openapi/initOpenApiEngine.ts"],"sourcesContent":["import Koa from 'koa'\n\nimport { prepareOpenApiSpec } from './analyzerModule/analyzerModule'\nimport { OpenApiRouter } from './router/OpenApiRouter'\n\n/**\n * Middleware to initialize the openApi engine.\n * Can be at any position in the middleware execution order.\n * All files with routers or exposed models must be included in `props.sourceFilePaths`.\n * @param props Paths to files to analyze, relative to project root.\n */\nexport const initOpenApiEngine = (props: Parameters<typeof prepareOpenApiSpec>[0]) => {\n\tprepareOpenApiSpec(props)\n\n\tconst builtInRoutes = OpenApiRouter.routes()\n\tconst builtInAllowedMethods = OpenApiRouter.allowedMethods()\n\treturn (ctx: Koa.ParameterizedContext<any, any>, next: Koa.Next) => {\n\t\treturn builtInRoutes(ctx, () => builtInAllowedMethods(ctx, next))\n\t}\n}\n"],"names":["initOpenApiEngine","props","prepareOpenApiSpec","builtInRoutes","OpenApiRouter","builtInAllowedMethods","ctx","next"],"mappings":"+KAWaA,EAAqBC,GAAoD,CACrFC,EAAAA,mBAAmBD,CAAK,EAElB,MAAAE,EAAgBC,gBAAc,OAAO,EACrCC,EAAwBD,gBAAc,eAAe,EACpD,MAAA,CAACE,EAAyCC,IACzCJ,EAAcG,EAAK,IAAMD,EAAsBC,EAAKC,CAAI,CAAC,CAElE"}
1
+ {"version":3,"file":"initOpenApiEngine.cjs","sources":["../../src/openapi/initOpenApiEngine.ts"],"sourcesContent":["import * as fs from 'fs'\nimport Koa from 'koa'\n\nimport type * as AnalyzerModule from './analyzerModule/analyzerModule'\nimport { OpenApiManager } from './manager/OpenApiManager'\nimport { OpenApiRouter } from './router/OpenApiRouter'\n\ntype AnalyzerProps = Parameters<typeof AnalyzerModule.prepareOpenApiSpec>[0]\n\ntype PrebuiltSpecProps = {\n\t/**\n\t * Path to a pre-built OpenAPI spec JSON file.\n\t * When provided, the analyzer is skipped entirely and the spec is served from this file.\n\t * Use this in production to avoid running the TypeScript analyzer on startup.\n\t *\n\t * Generate the spec file at build time using the CLI:\n\t * ```\n\t * moonflower openapi ./openapi-spec.json\n\t * ```\n\t */\n\tspecPath: string\n}\n\n/**\n * Middleware to initialize the openApi engine.\n * Can be at any position in the middleware execution order.\n *\n * In development, pass analyzer options to generate the spec on startup:\n * ```\n * initOpenApiEngine({ tsconfigPath: 'tsconfig.json', sourceFileDiscovery: true })\n * ```\n *\n * In production, pass a pre-built spec file to skip analysis:\n * ```\n * initOpenApiEngine({ specPath: './openapi-spec.json' })\n * ```\n */\nexport const initOpenApiEngine = (props: AnalyzerProps | PrebuiltSpecProps) => {\n\tconst ready =\n\t\t'specPath' in props\n\t\t\t? loadPrebuiltSpec(props.specPath)\n\t\t\t: import('./analyzerModule/analyzerModule').then(({ prepareOpenApiSpec }) => prepareOpenApiSpec(props))\n\n\tconst builtInRoutes = OpenApiRouter.routes()\n\tconst builtInAllowedMethods = OpenApiRouter.allowedMethods()\n\treturn async (ctx: Koa.ParameterizedContext<any, any>, next: Koa.Next) => {\n\t\tawait ready\n\t\treturn builtInRoutes(ctx, () => builtInAllowedMethods(ctx, next))\n\t}\n}\n\nconst loadPrebuiltSpec = (specPath: string) => {\n\tconst manager = OpenApiManager.getInstance()\n\tif (manager.isReady()) {\n\t\treturn\n\t}\n\n\tconst content = fs.readFileSync(specPath, 'utf-8')\n\tconst spec = JSON.parse(content)\n\tmanager.setPrebuiltSpec(spec)\n\tmanager.markAsReady()\n}\n"],"names":["initOpenApiEngine","props","ready","loadPrebuiltSpec","prepareOpenApiSpec","builtInRoutes","OpenApiRouter","builtInAllowedMethods","ctx","next","specPath","manager","OpenApiManager","content","fs","spec"],"mappings":"kdAqCaA,EAAqBC,GAA6C,CAC9E,MAAMC,EACL,aAAcD,EACXE,EAAiBF,EAAM,QAAQ,EAC/B,QAAO,QAAA,EAAA,KAAA,IAAA,QAAA,qCAAiC,CAAA,EAAE,KAAK,CAAC,CAAE,mBAAAG,KAAyBA,EAAmBH,CAAK,CAAC,EAElGI,EAAgBC,gBAAc,OAAO,EACrCC,EAAwBD,gBAAc,eAAe,EACpD,MAAA,OAAOE,EAAyCC,KAChD,MAAAP,EACCG,EAAcG,EAAK,IAAMD,EAAsBC,EAAKC,CAAI,CAAC,EAElE,EAEMN,EAAoBO,GAAqB,CACxC,MAAAC,EAAUC,iBAAe,YAAY,EACvC,GAAAD,EAAQ,UACX,OAGD,MAAME,EAAUC,EAAG,aAAaJ,EAAU,OAAO,EAC3CK,EAAO,KAAK,MAAMF,CAAO,EAC/BF,EAAQ,gBAAgBI,CAAI,EAC5BJ,EAAQ,YAAY,CACrB"}
@@ -1,5 +1,10 @@
1
1
  import { default as Koa } from 'koa';
2
- import { prepareOpenApiSpec } from './analyzerModule/analyzerModule';
3
2
 
4
- export declare const initOpenApiEngine: (props: Parameters<typeof prepareOpenApiSpec>[0]) => (ctx: Koa.ParameterizedContext<any, any>, next: Koa.Next) => any;
3
+ import type * as AnalyzerModule from './analyzerModule/analyzerModule';
4
+ type AnalyzerProps = Parameters<typeof AnalyzerModule.prepareOpenApiSpec>[0];
5
+ type PrebuiltSpecProps = {
6
+ specPath: string;
7
+ };
8
+ export declare const initOpenApiEngine: (props: AnalyzerProps | PrebuiltSpecProps) => (ctx: Koa.ParameterizedContext<any, any>, next: Koa.Next) => Promise<any>;
9
+ export {};
5
10
  //# sourceMappingURL=initOpenApiEngine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"initOpenApiEngine.d.ts","sourceRoot":"","sources":["../../src/openapi/initOpenApiEngine.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAA;AAErB,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AASpE,eAAO,MAAM,iBAAiB,UAAW,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,CAAC,CAAC,WAKnE,GAAG,CAAC,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,QAAQ,GAAG,CAAC,IAAI,QAG/D,CAAA"}
1
+ {"version":3,"file":"initOpenApiEngine.d.ts","sourceRoot":"","sources":["../../src/openapi/initOpenApiEngine.ts"],"names":[],"mappings":"AACA,OAAO,GAAG,MAAM,KAAK,CAAA;AAErB,OAAO,KAAK,KAAK,cAAc,MAAM,iCAAiC,CAAA;AAItE,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAA;AAE5E,KAAK,iBAAiB,GAAG;IAWxB,QAAQ,EAAE,MAAM,CAAA;CAChB,CAAA;AAgBD,eAAO,MAAM,iBAAiB,UAAW,aAAa,GAAG,iBAAiB,WAQtD,GAAG,CAAC,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,QAAQ,GAAG,CAAC,IAAI,iBAIrE,CAAA"}
@@ -1,11 +1,17 @@
1
- import { prepareOpenApiSpec as i } from "./analyzerModule/analyzerModule.mjs";
2
- import { OpenApiRouter as o } from "./router/OpenApiRouter.mjs";
3
- const l = (t) => {
4
- i(t);
5
- const n = o.routes(), r = o.allowedMethods();
6
- return (e, p) => n(e, () => r(e, p));
1
+ import * as i from "fs";
2
+ import { OpenApiManager as c } from "./manager/OpenApiManager.mjs";
3
+ import { OpenApiRouter as s } from "./router/OpenApiRouter.mjs";
4
+ const d = (e) => {
5
+ const t = "specPath" in e ? p(e.specPath) : import("./analyzerModule/analyzerModule.mjs").then(({ prepareOpenApiSpec: n }) => n(e)), o = s.routes(), r = s.allowedMethods();
6
+ return async (n, a) => (await t, o(n, () => r(n, a)));
7
+ }, p = (e) => {
8
+ const t = c.getInstance();
9
+ if (t.isReady())
10
+ return;
11
+ const o = i.readFileSync(e, "utf-8"), r = JSON.parse(o);
12
+ t.setPrebuiltSpec(r), t.markAsReady();
7
13
  };
8
14
  export {
9
- l as initOpenApiEngine
15
+ d as initOpenApiEngine
10
16
  };
11
17
  //# sourceMappingURL=initOpenApiEngine.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"initOpenApiEngine.mjs","sources":["../../src/openapi/initOpenApiEngine.ts"],"sourcesContent":["import Koa from 'koa'\n\nimport { prepareOpenApiSpec } from './analyzerModule/analyzerModule'\nimport { OpenApiRouter } from './router/OpenApiRouter'\n\n/**\n * Middleware to initialize the openApi engine.\n * Can be at any position in the middleware execution order.\n * All files with routers or exposed models must be included in `props.sourceFilePaths`.\n * @param props Paths to files to analyze, relative to project root.\n */\nexport const initOpenApiEngine = (props: Parameters<typeof prepareOpenApiSpec>[0]) => {\n\tprepareOpenApiSpec(props)\n\n\tconst builtInRoutes = OpenApiRouter.routes()\n\tconst builtInAllowedMethods = OpenApiRouter.allowedMethods()\n\treturn (ctx: Koa.ParameterizedContext<any, any>, next: Koa.Next) => {\n\t\treturn builtInRoutes(ctx, () => builtInAllowedMethods(ctx, next))\n\t}\n}\n"],"names":["initOpenApiEngine","props","prepareOpenApiSpec","builtInRoutes","OpenApiRouter","builtInAllowedMethods","ctx","next"],"mappings":";;AAWa,MAAAA,IAAoB,CAACC,MAAoD;AACrF,EAAAC,EAAmBD,CAAK;AAElB,QAAAE,IAAgBC,EAAc,OAAO,GACrCC,IAAwBD,EAAc,eAAe;AACpD,SAAA,CAACE,GAAyCC,MACzCJ,EAAcG,GAAK,MAAMD,EAAsBC,GAAKC,CAAI,CAAC;AAElE;"}
1
+ {"version":3,"file":"initOpenApiEngine.mjs","sources":["../../src/openapi/initOpenApiEngine.ts"],"sourcesContent":["import * as fs from 'fs'\nimport Koa from 'koa'\n\nimport type * as AnalyzerModule from './analyzerModule/analyzerModule'\nimport { OpenApiManager } from './manager/OpenApiManager'\nimport { OpenApiRouter } from './router/OpenApiRouter'\n\ntype AnalyzerProps = Parameters<typeof AnalyzerModule.prepareOpenApiSpec>[0]\n\ntype PrebuiltSpecProps = {\n\t/**\n\t * Path to a pre-built OpenAPI spec JSON file.\n\t * When provided, the analyzer is skipped entirely and the spec is served from this file.\n\t * Use this in production to avoid running the TypeScript analyzer on startup.\n\t *\n\t * Generate the spec file at build time using the CLI:\n\t * ```\n\t * moonflower openapi ./openapi-spec.json\n\t * ```\n\t */\n\tspecPath: string\n}\n\n/**\n * Middleware to initialize the openApi engine.\n * Can be at any position in the middleware execution order.\n *\n * In development, pass analyzer options to generate the spec on startup:\n * ```\n * initOpenApiEngine({ tsconfigPath: 'tsconfig.json', sourceFileDiscovery: true })\n * ```\n *\n * In production, pass a pre-built spec file to skip analysis:\n * ```\n * initOpenApiEngine({ specPath: './openapi-spec.json' })\n * ```\n */\nexport const initOpenApiEngine = (props: AnalyzerProps | PrebuiltSpecProps) => {\n\tconst ready =\n\t\t'specPath' in props\n\t\t\t? loadPrebuiltSpec(props.specPath)\n\t\t\t: import('./analyzerModule/analyzerModule').then(({ prepareOpenApiSpec }) => prepareOpenApiSpec(props))\n\n\tconst builtInRoutes = OpenApiRouter.routes()\n\tconst builtInAllowedMethods = OpenApiRouter.allowedMethods()\n\treturn async (ctx: Koa.ParameterizedContext<any, any>, next: Koa.Next) => {\n\t\tawait ready\n\t\treturn builtInRoutes(ctx, () => builtInAllowedMethods(ctx, next))\n\t}\n}\n\nconst loadPrebuiltSpec = (specPath: string) => {\n\tconst manager = OpenApiManager.getInstance()\n\tif (manager.isReady()) {\n\t\treturn\n\t}\n\n\tconst content = fs.readFileSync(specPath, 'utf-8')\n\tconst spec = JSON.parse(content)\n\tmanager.setPrebuiltSpec(spec)\n\tmanager.markAsReady()\n}\n"],"names":["initOpenApiEngine","props","ready","loadPrebuiltSpec","prepareOpenApiSpec","builtInRoutes","OpenApiRouter","builtInAllowedMethods","ctx","next","specPath","manager","OpenApiManager","content","fs","spec"],"mappings":";;;AAqCa,MAAAA,IAAoB,CAACC,MAA6C;AAC9E,QAAMC,IACL,cAAcD,IACXE,EAAiBF,EAAM,QAAQ,IAC/B,OAAO,qCAAiC,EAAE,KAAK,CAAC,EAAE,oBAAAG,QAAyBA,EAAmBH,CAAK,CAAC,GAElGI,IAAgBC,EAAc,OAAO,GACrCC,IAAwBD,EAAc,eAAe;AACpD,SAAA,OAAOE,GAAyCC,OAChD,MAAAP,GACCG,EAAcG,GAAK,MAAMD,EAAsBC,GAAKC,CAAI,CAAC;AAElE,GAEMN,IAAmB,CAACO,MAAqB;AACxC,QAAAC,IAAUC,EAAe,YAAY;AACvC,MAAAD,EAAQ;AACX;AAGD,QAAME,IAAUC,EAAG,aAAaJ,GAAU,OAAO,GAC3CK,IAAO,KAAK,MAAMF,CAAO;AAC/B,EAAAF,EAAQ,gBAAgBI,CAAI,GAC5BJ,EAAQ,YAAY;AACrB;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class t{constructor(e,s,i,r,n){this.apiDocsHeader=e,this.exposedModels=s,this.endpoints=i,this.preferences=r,this.stats=n,this.isInitialized=!1,this.registeredRouters=[]}static{this.instance=null}isReady(){return this.isInitialized}hasExposedModel(e){return this.exposedModels.some(s=>s.name===e)}getExposedModels(){return this.exposedModels}setExposedModels(e){return this.exposedModels=e,this}setEndpoints(e){return this.endpoints=e,this}markAsReady(){return this.isInitialized=!0,this}getHeader(){return this.apiDocsHeader}setHeader(e){return this.apiDocsHeader=e,this}getEndpoints(){return this.endpoints}getPreferences(){return this.preferences}setPreferences(e){return this.preferences={...e},this}getStats(){return this.stats}setStats(e){return this.stats={...e},this}getRouters(){return this.registeredRouters}registerRouters(e){return e.forEach(s=>this.registeredRouters.push(s)),this}reset(){this.exposedModels=[],this.endpoints=[]}static getInstance(){return t.instance||(t.instance=new t({title:"Default title",version:"1.0.0"},[],[],{allowOptionalPathParams:!1},{discoveredRouterFiles:[],explicitRouterFiles:[]})),t.instance}}exports.OpenApiManager=t;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class t{constructor(e,s,i,r,n){this.apiDocsHeader=e,this.exposedModels=s,this.endpoints=i,this.preferences=r,this.stats=n,this.isInitialized=!1,this.registeredRouters=[],this.prebuiltSpec=null}static{this.instance=null}isReady(){return this.isInitialized}hasExposedModel(e){return this.exposedModels.some(s=>s.name===e)}getExposedModels(){return this.exposedModels}setExposedModels(e){return this.exposedModels=e,this}setEndpoints(e){return this.endpoints=e,this}markAsReady(){return this.isInitialized=!0,this}getHeader(){return this.apiDocsHeader}setHeader(e){return this.apiDocsHeader=e,this}getEndpoints(){return this.endpoints}getPreferences(){return this.preferences}setPreferences(e){return this.preferences={...e},this}getStats(){return this.stats}setStats(e){return this.stats={...e},this}getRouters(){return this.registeredRouters}registerRouters(e){return e.forEach(s=>this.registeredRouters.push(s)),this}getPrebuiltSpec(){return this.prebuiltSpec}setPrebuiltSpec(e){return this.prebuiltSpec=e,this}clearPrebuiltSpec(){return this.prebuiltSpec=null,this}reset(){this.exposedModels=[],this.endpoints=[],this.prebuiltSpec=null}static getInstance(){return t.instance||(t.instance=new t({title:"Default title",version:"1.0.0"},[],[],{allowOptionalPathParams:!1},{discoveredRouterFiles:[],explicitRouterFiles:[]})),t.instance}}exports.OpenApiManager=t;
2
2
  //# sourceMappingURL=OpenApiManager.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"OpenApiManager.cjs","sources":["../../../src/openapi/manager/OpenApiManager.ts"],"sourcesContent":["import { Router } from '../../router/Router'\nimport { EndpointData, ExposedModelData } from '../types'\n\ntype UrlType = `${'http' | 'https'}://${string}.${string}`\n\nexport type ApiDocsHeader = {\n\ttitle: string\n\tversion: string\n\tdescription?: string\n\ttermsOfService?: UrlType\n\tcontact?: {\n\t\tname?: string\n\t\turl?: UrlType\n\t\temail?: string\n\t}\n\tlicense?: {\n\t\tname?: string\n\t\turl?: UrlType\n\t}\n}\n\nexport type ApiDocsPreferences = {\n\tallowOptionalPathParams: boolean\n}\n\nexport type ApiAnalysisStats = {\n\texplicitRouterFiles: {\n\t\tpath: string\n\t\trouters: {\n\t\t\tname: string\n\t\t\tendpoints: string[]\n\t\t}[]\n\t}[]\n\tdiscoveredRouterFiles: {\n\t\tpath: string\n\t\trouters: {\n\t\t\tname: string\n\t\t\tendpoints: string[]\n\t\t}[]\n\t}[]\n}\n\nexport class OpenApiManager {\n\tprivate static instance: OpenApiManager | null = null\n\n\tprivate isInitialized = false\n\tprivate registeredRouters: Router[] = []\n\n\tconstructor(\n\t\tprivate apiDocsHeader: ApiDocsHeader,\n\t\tprivate exposedModels: ExposedModelData[],\n\t\tprivate endpoints: EndpointData[],\n\t\tprivate preferences: ApiDocsPreferences,\n\t\tprivate stats: ApiAnalysisStats,\n\t) {}\n\n\tpublic isReady(): boolean {\n\t\treturn this.isInitialized\n\t}\n\n\tpublic hasExposedModel(name: string) {\n\t\treturn this.exposedModels.some((model) => model.name === name)\n\t}\n\n\tpublic getExposedModels() {\n\t\treturn this.exposedModels\n\t}\n\n\tpublic setExposedModels(models: ExposedModelData[]) {\n\t\tthis.exposedModels = models\n\t\treturn this\n\t}\n\n\tpublic setEndpoints(endpoints: EndpointData[]) {\n\t\tthis.endpoints = endpoints\n\t\treturn this\n\t}\n\n\tpublic markAsReady() {\n\t\tthis.isInitialized = true\n\t\treturn this\n\t}\n\n\tpublic getHeader(): ApiDocsHeader {\n\t\treturn this.apiDocsHeader\n\t}\n\n\tpublic setHeader(docs: ApiDocsHeader) {\n\t\tthis.apiDocsHeader = docs\n\t\treturn this\n\t}\n\n\tpublic getEndpoints() {\n\t\treturn this.endpoints\n\t}\n\n\tpublic getPreferences() {\n\t\treturn this.preferences\n\t}\n\n\tpublic setPreferences(preferences: ApiDocsPreferences) {\n\t\tthis.preferences = {\n\t\t\t...preferences,\n\t\t}\n\t\treturn this\n\t}\n\n\tpublic getStats() {\n\t\treturn this.stats\n\t}\n\n\tpublic setStats(stats: ApiAnalysisStats) {\n\t\tthis.stats = {\n\t\t\t...stats,\n\t\t}\n\t\treturn this\n\t}\n\n\tpublic getRouters(): readonly Router[] {\n\t\treturn this.registeredRouters\n\t}\n\n\tpublic registerRouters(routers: Router<any, any>[]) {\n\t\trouters.forEach((r) => this.registeredRouters.push(r))\n\t\treturn this\n\t}\n\n\tpublic reset() {\n\t\tthis.exposedModels = []\n\t\tthis.endpoints = []\n\t}\n\n\tpublic static getInstance() {\n\t\tif (!OpenApiManager.instance) {\n\t\t\tOpenApiManager.instance = new OpenApiManager(\n\t\t\t\t{\n\t\t\t\t\ttitle: 'Default title',\n\t\t\t\t\tversion: '1.0.0',\n\t\t\t\t},\n\t\t\t\t[],\n\t\t\t\t[],\n\t\t\t\t{\n\t\t\t\t\tallowOptionalPathParams: false,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdiscoveredRouterFiles: [],\n\t\t\t\t\texplicitRouterFiles: [],\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t\treturn OpenApiManager.instance\n\t}\n}\n"],"names":["OpenApiManager","apiDocsHeader","exposedModels","endpoints","preferences","stats","name","model","models","docs","routers","r"],"mappings":"gFA0CO,MAAMA,CAAe,CAM3B,YACSC,EACAC,EACAC,EACAC,EACAC,EACP,CALO,KAAA,cAAAJ,EACA,KAAA,cAAAC,EACA,KAAA,UAAAC,EACA,KAAA,YAAAC,EACA,KAAA,MAAAC,EART,KAAQ,cAAgB,GACxB,KAAQ,kBAA8B,CAAC,CAAA,CAHvC,MAAA,CAAA,KAAe,SAAkC,IAAA,CAa1C,SAAmB,CACzB,OAAO,KAAK,aAAA,CAGN,gBAAgBC,EAAc,CACpC,OAAO,KAAK,cAAc,KAAMC,GAAUA,EAAM,OAASD,CAAI,CAAA,CAGvD,kBAAmB,CACzB,OAAO,KAAK,aAAA,CAGN,iBAAiBE,EAA4B,CACnD,YAAK,cAAgBA,EACd,IAAA,CAGD,aAAaL,EAA2B,CAC9C,YAAK,UAAYA,EACV,IAAA,CAGD,aAAc,CACpB,YAAK,cAAgB,GACd,IAAA,CAGD,WAA2B,CACjC,OAAO,KAAK,aAAA,CAGN,UAAUM,EAAqB,CACrC,YAAK,cAAgBA,EACd,IAAA,CAGD,cAAe,CACrB,OAAO,KAAK,SAAA,CAGN,gBAAiB,CACvB,OAAO,KAAK,WAAA,CAGN,eAAeL,EAAiC,CACtD,YAAK,YAAc,CAClB,GAAGA,CACJ,EACO,IAAA,CAGD,UAAW,CACjB,OAAO,KAAK,KAAA,CAGN,SAASC,EAAyB,CACxC,YAAK,MAAQ,CACZ,GAAGA,CACJ,EACO,IAAA,CAGD,YAAgC,CACtC,OAAO,KAAK,iBAAA,CAGN,gBAAgBK,EAA6B,CACnD,OAAAA,EAAQ,QAASC,GAAM,KAAK,kBAAkB,KAAKA,CAAC,CAAC,EAC9C,IAAA,CAGD,OAAQ,CACd,KAAK,cAAgB,CAAC,EACtB,KAAK,UAAY,CAAC,CAAA,CAGnB,OAAc,aAAc,CACvB,OAACX,EAAe,WACnBA,EAAe,SAAW,IAAIA,EAC7B,CACC,MAAO,gBACP,QAAS,OACV,EACA,CAAC,EACD,CAAC,EACD,CACC,wBAAyB,EAC1B,EACA,CACC,sBAAuB,CAAC,EACxB,oBAAqB,CAAA,CAAC,CAExB,GAEMA,EAAe,QAAA,CAExB"}
1
+ {"version":3,"file":"OpenApiManager.cjs","sources":["../../../src/openapi/manager/OpenApiManager.ts"],"sourcesContent":["import { Router } from '../../router/Router'\nimport { EndpointData, ExposedModelData } from '../types'\n\ntype UrlType = `${'http' | 'https'}://${string}.${string}`\n\nexport type ApiDocsHeader = {\n\ttitle: string\n\tversion: string\n\tdescription?: string\n\ttermsOfService?: UrlType\n\tcontact?: {\n\t\tname?: string\n\t\turl?: UrlType\n\t\temail?: string\n\t}\n\tlicense?: {\n\t\tname?: string\n\t\turl?: UrlType\n\t}\n}\n\nexport type ApiDocsPreferences = {\n\tallowOptionalPathParams: boolean\n}\n\nexport type ApiAnalysisStats = {\n\texplicitRouterFiles: {\n\t\tpath: string\n\t\trouters: {\n\t\t\tname: string\n\t\t\tendpoints: string[]\n\t\t}[]\n\t}[]\n\tdiscoveredRouterFiles: {\n\t\tpath: string\n\t\trouters: {\n\t\t\tname: string\n\t\t\tendpoints: string[]\n\t\t}[]\n\t}[]\n}\n\nexport class OpenApiManager {\n\tprivate static instance: OpenApiManager | null = null\n\n\tprivate isInitialized = false\n\tprivate registeredRouters: Router[] = []\n\tprivate prebuiltSpec: Record<string, unknown> | null = null\n\n\tconstructor(\n\t\tprivate apiDocsHeader: ApiDocsHeader,\n\t\tprivate exposedModels: ExposedModelData[],\n\t\tprivate endpoints: EndpointData[],\n\t\tprivate preferences: ApiDocsPreferences,\n\t\tprivate stats: ApiAnalysisStats,\n\t) {}\n\n\tpublic isReady(): boolean {\n\t\treturn this.isInitialized\n\t}\n\n\tpublic hasExposedModel(name: string) {\n\t\treturn this.exposedModels.some((model) => model.name === name)\n\t}\n\n\tpublic getExposedModels() {\n\t\treturn this.exposedModels\n\t}\n\n\tpublic setExposedModels(models: ExposedModelData[]) {\n\t\tthis.exposedModels = models\n\t\treturn this\n\t}\n\n\tpublic setEndpoints(endpoints: EndpointData[]) {\n\t\tthis.endpoints = endpoints\n\t\treturn this\n\t}\n\n\tpublic markAsReady() {\n\t\tthis.isInitialized = true\n\t\treturn this\n\t}\n\n\tpublic getHeader(): ApiDocsHeader {\n\t\treturn this.apiDocsHeader\n\t}\n\n\tpublic setHeader(docs: ApiDocsHeader) {\n\t\tthis.apiDocsHeader = docs\n\t\treturn this\n\t}\n\n\tpublic getEndpoints() {\n\t\treturn this.endpoints\n\t}\n\n\tpublic getPreferences() {\n\t\treturn this.preferences\n\t}\n\n\tpublic setPreferences(preferences: ApiDocsPreferences) {\n\t\tthis.preferences = {\n\t\t\t...preferences,\n\t\t}\n\t\treturn this\n\t}\n\n\tpublic getStats() {\n\t\treturn this.stats\n\t}\n\n\tpublic setStats(stats: ApiAnalysisStats) {\n\t\tthis.stats = {\n\t\t\t...stats,\n\t\t}\n\t\treturn this\n\t}\n\n\tpublic getRouters(): readonly Router[] {\n\t\treturn this.registeredRouters\n\t}\n\n\tpublic registerRouters(routers: Router<any, any>[]) {\n\t\trouters.forEach((r) => this.registeredRouters.push(r))\n\t\treturn this\n\t}\n\n\tpublic getPrebuiltSpec(): Record<string, unknown> | null {\n\t\treturn this.prebuiltSpec\n\t}\n\n\tpublic setPrebuiltSpec(spec: Record<string, unknown>) {\n\t\tthis.prebuiltSpec = spec\n\t\treturn this\n\t}\n\n\tpublic clearPrebuiltSpec() {\n\t\tthis.prebuiltSpec = null\n\t\treturn this\n\t}\n\n\tpublic reset() {\n\t\tthis.exposedModels = []\n\t\tthis.endpoints = []\n\t\tthis.prebuiltSpec = null\n\t}\n\n\tpublic static getInstance() {\n\t\tif (!OpenApiManager.instance) {\n\t\t\tOpenApiManager.instance = new OpenApiManager(\n\t\t\t\t{\n\t\t\t\t\ttitle: 'Default title',\n\t\t\t\t\tversion: '1.0.0',\n\t\t\t\t},\n\t\t\t\t[],\n\t\t\t\t[],\n\t\t\t\t{\n\t\t\t\t\tallowOptionalPathParams: false,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdiscoveredRouterFiles: [],\n\t\t\t\t\texplicitRouterFiles: [],\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t\treturn OpenApiManager.instance\n\t}\n}\n"],"names":["OpenApiManager","apiDocsHeader","exposedModels","endpoints","preferences","stats","name","model","models","docs","routers","r","spec"],"mappings":"gFA0CO,MAAMA,CAAe,CAO3B,YACSC,EACAC,EACAC,EACAC,EACAC,EACP,CALO,KAAA,cAAAJ,EACA,KAAA,cAAAC,EACA,KAAA,UAAAC,EACA,KAAA,YAAAC,EACA,KAAA,MAAAC,EATT,KAAQ,cAAgB,GACxB,KAAQ,kBAA8B,CAAC,EACvC,KAAQ,aAA+C,IAAA,CAJvD,MAAA,CAAA,KAAe,SAAkC,IAAA,CAc1C,SAAmB,CACzB,OAAO,KAAK,aAAA,CAGN,gBAAgBC,EAAc,CACpC,OAAO,KAAK,cAAc,KAAMC,GAAUA,EAAM,OAASD,CAAI,CAAA,CAGvD,kBAAmB,CACzB,OAAO,KAAK,aAAA,CAGN,iBAAiBE,EAA4B,CACnD,YAAK,cAAgBA,EACd,IAAA,CAGD,aAAaL,EAA2B,CAC9C,YAAK,UAAYA,EACV,IAAA,CAGD,aAAc,CACpB,YAAK,cAAgB,GACd,IAAA,CAGD,WAA2B,CACjC,OAAO,KAAK,aAAA,CAGN,UAAUM,EAAqB,CACrC,YAAK,cAAgBA,EACd,IAAA,CAGD,cAAe,CACrB,OAAO,KAAK,SAAA,CAGN,gBAAiB,CACvB,OAAO,KAAK,WAAA,CAGN,eAAeL,EAAiC,CACtD,YAAK,YAAc,CAClB,GAAGA,CACJ,EACO,IAAA,CAGD,UAAW,CACjB,OAAO,KAAK,KAAA,CAGN,SAASC,EAAyB,CACxC,YAAK,MAAQ,CACZ,GAAGA,CACJ,EACO,IAAA,CAGD,YAAgC,CACtC,OAAO,KAAK,iBAAA,CAGN,gBAAgBK,EAA6B,CACnD,OAAAA,EAAQ,QAASC,GAAM,KAAK,kBAAkB,KAAKA,CAAC,CAAC,EAC9C,IAAA,CAGD,iBAAkD,CACxD,OAAO,KAAK,YAAA,CAGN,gBAAgBC,EAA+B,CACrD,YAAK,aAAeA,EACb,IAAA,CAGD,mBAAoB,CAC1B,YAAK,aAAe,KACb,IAAA,CAGD,OAAQ,CACd,KAAK,cAAgB,CAAC,EACtB,KAAK,UAAY,CAAC,EAClB,KAAK,aAAe,IAAA,CAGrB,OAAc,aAAc,CACvB,OAACZ,EAAe,WACnBA,EAAe,SAAW,IAAIA,EAC7B,CACC,MAAO,gBACP,QAAS,OACV,EACA,CAAC,EACD,CAAC,EACD,CACC,wBAAyB,EAC1B,EACA,CACC,sBAAuB,CAAC,EACxB,oBAAqB,CAAA,CAAC,CAExB,GAEMA,EAAe,QAAA,CAExB"}
@@ -45,6 +45,7 @@ export declare class OpenApiManager {
45
45
  private static instance;
46
46
  private isInitialized;
47
47
  private registeredRouters;
48
+ private prebuiltSpec;
48
49
  constructor(apiDocsHeader: ApiDocsHeader, exposedModels: ExposedModelData[], endpoints: EndpointData[], preferences: ApiDocsPreferences, stats: ApiAnalysisStats);
49
50
  isReady(): boolean;
50
51
  hasExposedModel(name: string): boolean;
@@ -61,6 +62,9 @@ export declare class OpenApiManager {
61
62
  setStats(stats: ApiAnalysisStats): this;
62
63
  getRouters(): readonly Router[];
63
64
  registerRouters(routers: Router<any, any>[]): this;
65
+ getPrebuiltSpec(): Record<string, unknown> | null;
66
+ setPrebuiltSpec(spec: Record<string, unknown>): this;
67
+ clearPrebuiltSpec(): this;
64
68
  reset(): void;
65
69
  static getInstance(): OpenApiManager;
66
70
  }
@@ -1 +1 @@
1
- {"version":3,"file":"OpenApiManager.d.ts","sourceRoot":"","sources":["../../../src/openapi/manager/OpenApiManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAEzD,KAAK,OAAO,GAAG,GAAG,MAAM,GAAG,OAAO,MAAM,MAAM,IAAI,MAAM,EAAE,CAAA;AAE1D,MAAM,MAAM,aAAa,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,OAAO,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,GAAG,CAAC,EAAE,OAAO,CAAA;QACb,KAAK,CAAC,EAAE,MAAM,CAAA;KACd,CAAA;IACD,OAAO,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,GAAG,CAAC,EAAE,OAAO,CAAA;KACb,CAAA;CACD,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAChC,uBAAuB,EAAE,OAAO,CAAA;CAChC,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC9B,mBAAmB,EAAE;QACpB,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE;YACR,IAAI,EAAE,MAAM,CAAA;YACZ,SAAS,EAAE,MAAM,EAAE,CAAA;SACnB,EAAE,CAAA;KACH,EAAE,CAAA;IACH,qBAAqB,EAAE;QACtB,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE;YACR,IAAI,EAAE,MAAM,CAAA;YACZ,SAAS,EAAE,MAAM,EAAE,CAAA;SACnB,EAAE,CAAA;KACH,EAAE,CAAA;CACH,CAAA;AAED,qBAAa,cAAc;IAOzB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,KAAK;IAVd,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA8B;IAErD,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,iBAAiB,CAAe;gBAG/B,aAAa,EAAE,aAAa,EAC5B,aAAa,EAAE,gBAAgB,EAAE,EACjC,SAAS,EAAE,YAAY,EAAE,EACzB,WAAW,EAAE,kBAAkB,EAC/B,KAAK,EAAE,gBAAgB;IAGzB,OAAO,IAAI,OAAO;IAIlB,eAAe,CAAC,IAAI,EAAE,MAAM;IAI5B,gBAAgB;IAIhB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,EAAE;IAK3C,YAAY,CAAC,SAAS,EAAE,YAAY,EAAE;IAKtC,WAAW;IAKX,SAAS,IAAI,aAAa;IAI1B,SAAS,CAAC,IAAI,EAAE,aAAa;IAK7B,YAAY;IAIZ,cAAc;IAId,cAAc,CAAC,WAAW,EAAE,kBAAkB;IAO9C,QAAQ;IAIR,QAAQ,CAAC,KAAK,EAAE,gBAAgB;IAOhC,UAAU,IAAI,SAAS,MAAM,EAAE;IAI/B,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE;IAK3C,KAAK;WAKE,WAAW;CAoBzB"}
1
+ {"version":3,"file":"OpenApiManager.d.ts","sourceRoot":"","sources":["../../../src/openapi/manager/OpenApiManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAEzD,KAAK,OAAO,GAAG,GAAG,MAAM,GAAG,OAAO,MAAM,MAAM,IAAI,MAAM,EAAE,CAAA;AAE1D,MAAM,MAAM,aAAa,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,OAAO,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,GAAG,CAAC,EAAE,OAAO,CAAA;QACb,KAAK,CAAC,EAAE,MAAM,CAAA;KACd,CAAA;IACD,OAAO,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,GAAG,CAAC,EAAE,OAAO,CAAA;KACb,CAAA;CACD,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAChC,uBAAuB,EAAE,OAAO,CAAA;CAChC,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC9B,mBAAmB,EAAE;QACpB,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE;YACR,IAAI,EAAE,MAAM,CAAA;YACZ,SAAS,EAAE,MAAM,EAAE,CAAA;SACnB,EAAE,CAAA;KACH,EAAE,CAAA;IACH,qBAAqB,EAAE;QACtB,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE;YACR,IAAI,EAAE,MAAM,CAAA;YACZ,SAAS,EAAE,MAAM,EAAE,CAAA;SACnB,EAAE,CAAA;KACH,EAAE,CAAA;CACH,CAAA;AAED,qBAAa,cAAc;IAQzB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,KAAK;IAXd,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA8B;IAErD,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,iBAAiB,CAAe;IACxC,OAAO,CAAC,YAAY,CAAuC;gBAGlD,aAAa,EAAE,aAAa,EAC5B,aAAa,EAAE,gBAAgB,EAAE,EACjC,SAAS,EAAE,YAAY,EAAE,EACzB,WAAW,EAAE,kBAAkB,EAC/B,KAAK,EAAE,gBAAgB;IAGzB,OAAO,IAAI,OAAO;IAIlB,eAAe,CAAC,IAAI,EAAE,MAAM;IAI5B,gBAAgB;IAIhB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,EAAE;IAK3C,YAAY,CAAC,SAAS,EAAE,YAAY,EAAE;IAKtC,WAAW;IAKX,SAAS,IAAI,aAAa;IAI1B,SAAS,CAAC,IAAI,EAAE,aAAa;IAK7B,YAAY;IAIZ,cAAc;IAId,cAAc,CAAC,WAAW,EAAE,kBAAkB;IAO9C,QAAQ;IAIR,QAAQ,CAAC,KAAK,EAAE,gBAAgB;IAOhC,UAAU,IAAI,SAAS,MAAM,EAAE;IAI/B,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE;IAK3C,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIjD,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAK7C,iBAAiB;IAKjB,KAAK;WAME,WAAW;CAoBzB"}
@@ -1,6 +1,6 @@
1
1
  class s {
2
2
  constructor(e, t, i, r, n) {
3
- this.apiDocsHeader = e, this.exposedModels = t, this.endpoints = i, this.preferences = r, this.stats = n, this.isInitialized = !1, this.registeredRouters = [];
3
+ this.apiDocsHeader = e, this.exposedModels = t, this.endpoints = i, this.preferences = r, this.stats = n, this.isInitialized = !1, this.registeredRouters = [], this.prebuiltSpec = null;
4
4
  }
5
5
  static {
6
6
  this.instance = null;
@@ -54,8 +54,17 @@ class s {
54
54
  registerRouters(e) {
55
55
  return e.forEach((t) => this.registeredRouters.push(t)), this;
56
56
  }
57
+ getPrebuiltSpec() {
58
+ return this.prebuiltSpec;
59
+ }
60
+ setPrebuiltSpec(e) {
61
+ return this.prebuiltSpec = e, this;
62
+ }
63
+ clearPrebuiltSpec() {
64
+ return this.prebuiltSpec = null, this;
65
+ }
57
66
  reset() {
58
- this.exposedModels = [], this.endpoints = [];
67
+ this.exposedModels = [], this.endpoints = [], this.prebuiltSpec = null;
59
68
  }
60
69
  static getInstance() {
61
70
  return s.instance || (s.instance = new s(
@@ -1 +1 @@
1
- {"version":3,"file":"OpenApiManager.mjs","sources":["../../../src/openapi/manager/OpenApiManager.ts"],"sourcesContent":["import { Router } from '../../router/Router'\nimport { EndpointData, ExposedModelData } from '../types'\n\ntype UrlType = `${'http' | 'https'}://${string}.${string}`\n\nexport type ApiDocsHeader = {\n\ttitle: string\n\tversion: string\n\tdescription?: string\n\ttermsOfService?: UrlType\n\tcontact?: {\n\t\tname?: string\n\t\turl?: UrlType\n\t\temail?: string\n\t}\n\tlicense?: {\n\t\tname?: string\n\t\turl?: UrlType\n\t}\n}\n\nexport type ApiDocsPreferences = {\n\tallowOptionalPathParams: boolean\n}\n\nexport type ApiAnalysisStats = {\n\texplicitRouterFiles: {\n\t\tpath: string\n\t\trouters: {\n\t\t\tname: string\n\t\t\tendpoints: string[]\n\t\t}[]\n\t}[]\n\tdiscoveredRouterFiles: {\n\t\tpath: string\n\t\trouters: {\n\t\t\tname: string\n\t\t\tendpoints: string[]\n\t\t}[]\n\t}[]\n}\n\nexport class OpenApiManager {\n\tprivate static instance: OpenApiManager | null = null\n\n\tprivate isInitialized = false\n\tprivate registeredRouters: Router[] = []\n\n\tconstructor(\n\t\tprivate apiDocsHeader: ApiDocsHeader,\n\t\tprivate exposedModels: ExposedModelData[],\n\t\tprivate endpoints: EndpointData[],\n\t\tprivate preferences: ApiDocsPreferences,\n\t\tprivate stats: ApiAnalysisStats,\n\t) {}\n\n\tpublic isReady(): boolean {\n\t\treturn this.isInitialized\n\t}\n\n\tpublic hasExposedModel(name: string) {\n\t\treturn this.exposedModels.some((model) => model.name === name)\n\t}\n\n\tpublic getExposedModels() {\n\t\treturn this.exposedModels\n\t}\n\n\tpublic setExposedModels(models: ExposedModelData[]) {\n\t\tthis.exposedModels = models\n\t\treturn this\n\t}\n\n\tpublic setEndpoints(endpoints: EndpointData[]) {\n\t\tthis.endpoints = endpoints\n\t\treturn this\n\t}\n\n\tpublic markAsReady() {\n\t\tthis.isInitialized = true\n\t\treturn this\n\t}\n\n\tpublic getHeader(): ApiDocsHeader {\n\t\treturn this.apiDocsHeader\n\t}\n\n\tpublic setHeader(docs: ApiDocsHeader) {\n\t\tthis.apiDocsHeader = docs\n\t\treturn this\n\t}\n\n\tpublic getEndpoints() {\n\t\treturn this.endpoints\n\t}\n\n\tpublic getPreferences() {\n\t\treturn this.preferences\n\t}\n\n\tpublic setPreferences(preferences: ApiDocsPreferences) {\n\t\tthis.preferences = {\n\t\t\t...preferences,\n\t\t}\n\t\treturn this\n\t}\n\n\tpublic getStats() {\n\t\treturn this.stats\n\t}\n\n\tpublic setStats(stats: ApiAnalysisStats) {\n\t\tthis.stats = {\n\t\t\t...stats,\n\t\t}\n\t\treturn this\n\t}\n\n\tpublic getRouters(): readonly Router[] {\n\t\treturn this.registeredRouters\n\t}\n\n\tpublic registerRouters(routers: Router<any, any>[]) {\n\t\trouters.forEach((r) => this.registeredRouters.push(r))\n\t\treturn this\n\t}\n\n\tpublic reset() {\n\t\tthis.exposedModels = []\n\t\tthis.endpoints = []\n\t}\n\n\tpublic static getInstance() {\n\t\tif (!OpenApiManager.instance) {\n\t\t\tOpenApiManager.instance = new OpenApiManager(\n\t\t\t\t{\n\t\t\t\t\ttitle: 'Default title',\n\t\t\t\t\tversion: '1.0.0',\n\t\t\t\t},\n\t\t\t\t[],\n\t\t\t\t[],\n\t\t\t\t{\n\t\t\t\t\tallowOptionalPathParams: false,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdiscoveredRouterFiles: [],\n\t\t\t\t\texplicitRouterFiles: [],\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t\treturn OpenApiManager.instance\n\t}\n}\n"],"names":["OpenApiManager","apiDocsHeader","exposedModels","endpoints","preferences","stats","name","model","models","docs","routers","r"],"mappings":"AA0CO,MAAMA,EAAe;AAAA,EAM3B,YACSC,GACAC,GACAC,GACAC,GACAC,GACP;AALO,SAAA,gBAAAJ,GACA,KAAA,gBAAAC,GACA,KAAA,YAAAC,GACA,KAAA,cAAAC,GACA,KAAA,QAAAC,GART,KAAQ,gBAAgB,IACxB,KAAQ,oBAA8B,CAAC;AAAA,EAAA;AAAA,EAHvC,OAAA;AAAA,SAAe,WAAkC;AAAA,EAAA;AAAA,EAa1C,UAAmB;AACzB,WAAO,KAAK;AAAA,EAAA;AAAA,EAGN,gBAAgBC,GAAc;AACpC,WAAO,KAAK,cAAc,KAAK,CAACC,MAAUA,EAAM,SAASD,CAAI;AAAA,EAAA;AAAA,EAGvD,mBAAmB;AACzB,WAAO,KAAK;AAAA,EAAA;AAAA,EAGN,iBAAiBE,GAA4B;AACnD,gBAAK,gBAAgBA,GACd;AAAA,EAAA;AAAA,EAGD,aAAaL,GAA2B;AAC9C,gBAAK,YAAYA,GACV;AAAA,EAAA;AAAA,EAGD,cAAc;AACpB,gBAAK,gBAAgB,IACd;AAAA,EAAA;AAAA,EAGD,YAA2B;AACjC,WAAO,KAAK;AAAA,EAAA;AAAA,EAGN,UAAUM,GAAqB;AACrC,gBAAK,gBAAgBA,GACd;AAAA,EAAA;AAAA,EAGD,eAAe;AACrB,WAAO,KAAK;AAAA,EAAA;AAAA,EAGN,iBAAiB;AACvB,WAAO,KAAK;AAAA,EAAA;AAAA,EAGN,eAAeL,GAAiC;AACtD,gBAAK,cAAc;AAAA,MAClB,GAAGA;AAAA,IACJ,GACO;AAAA,EAAA;AAAA,EAGD,WAAW;AACjB,WAAO,KAAK;AAAA,EAAA;AAAA,EAGN,SAASC,GAAyB;AACxC,gBAAK,QAAQ;AAAA,MACZ,GAAGA;AAAA,IACJ,GACO;AAAA,EAAA;AAAA,EAGD,aAAgC;AACtC,WAAO,KAAK;AAAA,EAAA;AAAA,EAGN,gBAAgBK,GAA6B;AACnD,WAAAA,EAAQ,QAAQ,CAACC,MAAM,KAAK,kBAAkB,KAAKA,CAAC,CAAC,GAC9C;AAAA,EAAA;AAAA,EAGD,QAAQ;AACd,SAAK,gBAAgB,CAAC,GACtB,KAAK,YAAY,CAAC;AAAA,EAAA;AAAA,EAGnB,OAAc,cAAc;AACvB,WAACX,EAAe,aACnBA,EAAe,WAAW,IAAIA;AAAA,MAC7B;AAAA,QACC,OAAO;AAAA,QACP,SAAS;AAAA,MACV;AAAA,MACA,CAAC;AAAA,MACD,CAAC;AAAA,MACD;AAAA,QACC,yBAAyB;AAAA,MAC1B;AAAA,MACA;AAAA,QACC,uBAAuB,CAAC;AAAA,QACxB,qBAAqB,CAAA;AAAA,MAAC;AAAA,IAExB,IAEMA,EAAe;AAAA,EAAA;AAExB;"}
1
+ {"version":3,"file":"OpenApiManager.mjs","sources":["../../../src/openapi/manager/OpenApiManager.ts"],"sourcesContent":["import { Router } from '../../router/Router'\nimport { EndpointData, ExposedModelData } from '../types'\n\ntype UrlType = `${'http' | 'https'}://${string}.${string}`\n\nexport type ApiDocsHeader = {\n\ttitle: string\n\tversion: string\n\tdescription?: string\n\ttermsOfService?: UrlType\n\tcontact?: {\n\t\tname?: string\n\t\turl?: UrlType\n\t\temail?: string\n\t}\n\tlicense?: {\n\t\tname?: string\n\t\turl?: UrlType\n\t}\n}\n\nexport type ApiDocsPreferences = {\n\tallowOptionalPathParams: boolean\n}\n\nexport type ApiAnalysisStats = {\n\texplicitRouterFiles: {\n\t\tpath: string\n\t\trouters: {\n\t\t\tname: string\n\t\t\tendpoints: string[]\n\t\t}[]\n\t}[]\n\tdiscoveredRouterFiles: {\n\t\tpath: string\n\t\trouters: {\n\t\t\tname: string\n\t\t\tendpoints: string[]\n\t\t}[]\n\t}[]\n}\n\nexport class OpenApiManager {\n\tprivate static instance: OpenApiManager | null = null\n\n\tprivate isInitialized = false\n\tprivate registeredRouters: Router[] = []\n\tprivate prebuiltSpec: Record<string, unknown> | null = null\n\n\tconstructor(\n\t\tprivate apiDocsHeader: ApiDocsHeader,\n\t\tprivate exposedModels: ExposedModelData[],\n\t\tprivate endpoints: EndpointData[],\n\t\tprivate preferences: ApiDocsPreferences,\n\t\tprivate stats: ApiAnalysisStats,\n\t) {}\n\n\tpublic isReady(): boolean {\n\t\treturn this.isInitialized\n\t}\n\n\tpublic hasExposedModel(name: string) {\n\t\treturn this.exposedModels.some((model) => model.name === name)\n\t}\n\n\tpublic getExposedModels() {\n\t\treturn this.exposedModels\n\t}\n\n\tpublic setExposedModels(models: ExposedModelData[]) {\n\t\tthis.exposedModels = models\n\t\treturn this\n\t}\n\n\tpublic setEndpoints(endpoints: EndpointData[]) {\n\t\tthis.endpoints = endpoints\n\t\treturn this\n\t}\n\n\tpublic markAsReady() {\n\t\tthis.isInitialized = true\n\t\treturn this\n\t}\n\n\tpublic getHeader(): ApiDocsHeader {\n\t\treturn this.apiDocsHeader\n\t}\n\n\tpublic setHeader(docs: ApiDocsHeader) {\n\t\tthis.apiDocsHeader = docs\n\t\treturn this\n\t}\n\n\tpublic getEndpoints() {\n\t\treturn this.endpoints\n\t}\n\n\tpublic getPreferences() {\n\t\treturn this.preferences\n\t}\n\n\tpublic setPreferences(preferences: ApiDocsPreferences) {\n\t\tthis.preferences = {\n\t\t\t...preferences,\n\t\t}\n\t\treturn this\n\t}\n\n\tpublic getStats() {\n\t\treturn this.stats\n\t}\n\n\tpublic setStats(stats: ApiAnalysisStats) {\n\t\tthis.stats = {\n\t\t\t...stats,\n\t\t}\n\t\treturn this\n\t}\n\n\tpublic getRouters(): readonly Router[] {\n\t\treturn this.registeredRouters\n\t}\n\n\tpublic registerRouters(routers: Router<any, any>[]) {\n\t\trouters.forEach((r) => this.registeredRouters.push(r))\n\t\treturn this\n\t}\n\n\tpublic getPrebuiltSpec(): Record<string, unknown> | null {\n\t\treturn this.prebuiltSpec\n\t}\n\n\tpublic setPrebuiltSpec(spec: Record<string, unknown>) {\n\t\tthis.prebuiltSpec = spec\n\t\treturn this\n\t}\n\n\tpublic clearPrebuiltSpec() {\n\t\tthis.prebuiltSpec = null\n\t\treturn this\n\t}\n\n\tpublic reset() {\n\t\tthis.exposedModels = []\n\t\tthis.endpoints = []\n\t\tthis.prebuiltSpec = null\n\t}\n\n\tpublic static getInstance() {\n\t\tif (!OpenApiManager.instance) {\n\t\t\tOpenApiManager.instance = new OpenApiManager(\n\t\t\t\t{\n\t\t\t\t\ttitle: 'Default title',\n\t\t\t\t\tversion: '1.0.0',\n\t\t\t\t},\n\t\t\t\t[],\n\t\t\t\t[],\n\t\t\t\t{\n\t\t\t\t\tallowOptionalPathParams: false,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdiscoveredRouterFiles: [],\n\t\t\t\t\texplicitRouterFiles: [],\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t\treturn OpenApiManager.instance\n\t}\n}\n"],"names":["OpenApiManager","apiDocsHeader","exposedModels","endpoints","preferences","stats","name","model","models","docs","routers","r","spec"],"mappings":"AA0CO,MAAMA,EAAe;AAAA,EAO3B,YACSC,GACAC,GACAC,GACAC,GACAC,GACP;AALO,SAAA,gBAAAJ,GACA,KAAA,gBAAAC,GACA,KAAA,YAAAC,GACA,KAAA,cAAAC,GACA,KAAA,QAAAC,GATT,KAAQ,gBAAgB,IACxB,KAAQ,oBAA8B,CAAC,GACvC,KAAQ,eAA+C;AAAA,EAAA;AAAA,EAJvD,OAAA;AAAA,SAAe,WAAkC;AAAA,EAAA;AAAA,EAc1C,UAAmB;AACzB,WAAO,KAAK;AAAA,EAAA;AAAA,EAGN,gBAAgBC,GAAc;AACpC,WAAO,KAAK,cAAc,KAAK,CAACC,MAAUA,EAAM,SAASD,CAAI;AAAA,EAAA;AAAA,EAGvD,mBAAmB;AACzB,WAAO,KAAK;AAAA,EAAA;AAAA,EAGN,iBAAiBE,GAA4B;AACnD,gBAAK,gBAAgBA,GACd;AAAA,EAAA;AAAA,EAGD,aAAaL,GAA2B;AAC9C,gBAAK,YAAYA,GACV;AAAA,EAAA;AAAA,EAGD,cAAc;AACpB,gBAAK,gBAAgB,IACd;AAAA,EAAA;AAAA,EAGD,YAA2B;AACjC,WAAO,KAAK;AAAA,EAAA;AAAA,EAGN,UAAUM,GAAqB;AACrC,gBAAK,gBAAgBA,GACd;AAAA,EAAA;AAAA,EAGD,eAAe;AACrB,WAAO,KAAK;AAAA,EAAA;AAAA,EAGN,iBAAiB;AACvB,WAAO,KAAK;AAAA,EAAA;AAAA,EAGN,eAAeL,GAAiC;AACtD,gBAAK,cAAc;AAAA,MAClB,GAAGA;AAAA,IACJ,GACO;AAAA,EAAA;AAAA,EAGD,WAAW;AACjB,WAAO,KAAK;AAAA,EAAA;AAAA,EAGN,SAASC,GAAyB;AACxC,gBAAK,QAAQ;AAAA,MACZ,GAAGA;AAAA,IACJ,GACO;AAAA,EAAA;AAAA,EAGD,aAAgC;AACtC,WAAO,KAAK;AAAA,EAAA;AAAA,EAGN,gBAAgBK,GAA6B;AACnD,WAAAA,EAAQ,QAAQ,CAACC,MAAM,KAAK,kBAAkB,KAAKA,CAAC,CAAC,GAC9C;AAAA,EAAA;AAAA,EAGD,kBAAkD;AACxD,WAAO,KAAK;AAAA,EAAA;AAAA,EAGN,gBAAgBC,GAA+B;AACrD,gBAAK,eAAeA,GACb;AAAA,EAAA;AAAA,EAGD,oBAAoB;AAC1B,gBAAK,eAAe,MACb;AAAA,EAAA;AAAA,EAGD,QAAQ;AACd,SAAK,gBAAgB,CAAC,GACtB,KAAK,YAAY,CAAC,GAClB,KAAK,eAAe;AAAA,EAAA;AAAA,EAGrB,OAAc,cAAc;AACvB,WAACZ,EAAe,aACnBA,EAAe,WAAW,IAAIA;AAAA,MAC7B;AAAA,QACC,OAAO;AAAA,QACP,SAAS;AAAA,MACV;AAAA,MACA,CAAC;AAAA,MACD,CAAC;AAAA,MACD;AAAA,QACC,yBAAyB;AAAA,MAC1B;AAAA,MACA;AAAA,QACC,uBAAuB,CAAC;AAAA,QACxB,qBAAqB,CAAA;AAAA,MAAC;AAAA,IAExB,IAEMA,EAAe;AAAA,EAAA;AAExB;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("../../router/Router.cjs"),t=require("../generatorModule/generatorModule.cjs"),n=require("../manager/OpenApiManager.cjs"),e=new r.Router({skipOpenApiAnalysis:!0});e.get("/api-json",()=>t.generateOpenApiSpec(n.OpenApiManager.getInstance()));const o=e;exports.OpenApiRouter=o;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("../../router/Router.cjs"),o=require("../generatorModule/generatorModule.cjs"),i=require("../manager/OpenApiManager.cjs"),t=new n.Router({skipOpenApiAnalysis:!0});t.get("/api-json",()=>{const e=i.OpenApiManager.getInstance(),r=e.getPrebuiltSpec();return r||o.generateOpenApiSpec(e)});const p=t;exports.OpenApiRouter=p;
2
2
  //# sourceMappingURL=OpenApiRouter.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"OpenApiRouter.cjs","sources":["../../../src/openapi/router/OpenApiRouter.ts"],"sourcesContent":["import { Router } from '../../router/Router'\nimport { generateOpenApiSpec } from '../generatorModule/generatorModule'\nimport { OpenApiManager } from '../manager/OpenApiManager'\n\nconst router = new Router({ skipOpenApiAnalysis: true })\n\nrouter.get('/api-json', () => {\n\treturn generateOpenApiSpec(OpenApiManager.getInstance())\n})\n\nexport const OpenApiRouter = router\n"],"names":["router","Router","generateOpenApiSpec","OpenApiManager","OpenApiRouter"],"mappings":"0NAIMA,EAAS,IAAIC,EAAA,OAAO,CAAE,oBAAqB,GAAM,EAEvDD,EAAO,IAAI,YAAa,IAChBE,EAAA,oBAAoBC,iBAAe,aAAa,CACvD,EAEM,MAAMC,EAAgBJ"}
1
+ {"version":3,"file":"OpenApiRouter.cjs","sources":["../../../src/openapi/router/OpenApiRouter.ts"],"sourcesContent":["import { Router } from '../../router/Router'\nimport { generateOpenApiSpec } from '../generatorModule/generatorModule'\nimport { OpenApiManager } from '../manager/OpenApiManager'\n\nconst router = new Router({ skipOpenApiAnalysis: true })\n\nrouter.get('/api-json', () => {\n\tconst manager = OpenApiManager.getInstance()\n\tconst prebuilt = manager.getPrebuiltSpec()\n\tif (prebuilt) {\n\t\treturn prebuilt\n\t}\n\treturn generateOpenApiSpec(manager)\n})\n\nexport const OpenApiRouter = router\n"],"names":["router","Router","manager","OpenApiManager","prebuilt","generateOpenApiSpec","OpenApiRouter"],"mappings":"0NAIMA,EAAS,IAAIC,EAAA,OAAO,CAAE,oBAAqB,GAAM,EAEvDD,EAAO,IAAI,YAAa,IAAM,CACvB,MAAAE,EAAUC,iBAAe,YAAY,EACrCC,EAAWF,EAAQ,gBAAgB,EACzC,OAAIE,GAGGC,EAAAA,oBAAoBH,CAAO,CACnC,CAAC,EAEM,MAAMI,EAAgBN"}
@@ -1 +1 @@
1
- {"version":3,"file":"OpenApiRouter.d.ts","sourceRoot":"","sources":["../../../src/openapi/router/OpenApiRouter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAU5C,eAAO,MAAM,aAAa,kEAAS,CAAA"}
1
+ {"version":3,"file":"OpenApiRouter.d.ts","sourceRoot":"","sources":["../../../src/openapi/router/OpenApiRouter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAe5C,eAAO,MAAM,aAAa,kEAAS,CAAA"}
@@ -1,10 +1,13 @@
1
- import { Router as r } from "../../router/Router.mjs";
1
+ import { Router as n } from "../../router/Router.mjs";
2
2
  import { generateOpenApiSpec as p } from "../generatorModule/generatorModule.mjs";
3
- import { OpenApiManager as t } from "../manager/OpenApiManager.mjs";
4
- const e = new r({ skipOpenApiAnalysis: !0 });
5
- e.get("/api-json", () => p(t.getInstance()));
6
- const s = e;
3
+ import { OpenApiManager as o } from "../manager/OpenApiManager.mjs";
4
+ const t = new n({ skipOpenApiAnalysis: !0 });
5
+ t.get("/api-json", () => {
6
+ const e = o.getInstance(), r = e.getPrebuiltSpec();
7
+ return r || p(e);
8
+ });
9
+ const u = t;
7
10
  export {
8
- s as OpenApiRouter
11
+ u as OpenApiRouter
9
12
  };
10
13
  //# sourceMappingURL=OpenApiRouter.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"OpenApiRouter.mjs","sources":["../../../src/openapi/router/OpenApiRouter.ts"],"sourcesContent":["import { Router } from '../../router/Router'\nimport { generateOpenApiSpec } from '../generatorModule/generatorModule'\nimport { OpenApiManager } from '../manager/OpenApiManager'\n\nconst router = new Router({ skipOpenApiAnalysis: true })\n\nrouter.get('/api-json', () => {\n\treturn generateOpenApiSpec(OpenApiManager.getInstance())\n})\n\nexport const OpenApiRouter = router\n"],"names":["router","Router","generateOpenApiSpec","OpenApiManager","OpenApiRouter"],"mappings":";;;AAIA,MAAMA,IAAS,IAAIC,EAAO,EAAE,qBAAqB,IAAM;AAEvDD,EAAO,IAAI,aAAa,MAChBE,EAAoBC,EAAe,aAAa,CACvD;AAEM,MAAMC,IAAgBJ;"}
1
+ {"version":3,"file":"OpenApiRouter.mjs","sources":["../../../src/openapi/router/OpenApiRouter.ts"],"sourcesContent":["import { Router } from '../../router/Router'\nimport { generateOpenApiSpec } from '../generatorModule/generatorModule'\nimport { OpenApiManager } from '../manager/OpenApiManager'\n\nconst router = new Router({ skipOpenApiAnalysis: true })\n\nrouter.get('/api-json', () => {\n\tconst manager = OpenApiManager.getInstance()\n\tconst prebuilt = manager.getPrebuiltSpec()\n\tif (prebuilt) {\n\t\treturn prebuilt\n\t}\n\treturn generateOpenApiSpec(manager)\n})\n\nexport const OpenApiRouter = router\n"],"names":["router","Router","manager","OpenApiManager","prebuilt","generateOpenApiSpec","OpenApiRouter"],"mappings":";;;AAIA,MAAMA,IAAS,IAAIC,EAAO,EAAE,qBAAqB,IAAM;AAEvDD,EAAO,IAAI,aAAa,MAAM;AACvB,QAAAE,IAAUC,EAAe,YAAY,GACrCC,IAAWF,EAAQ,gBAAgB;AACzC,SAAIE,KAGGC,EAAoBH,CAAO;AACnC,CAAC;AAEM,MAAMI,IAAgBN;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moonflower",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "",
5
5
  "author": "tenebrie",
6
6
  "license": "MIT",
@@ -124,7 +124,8 @@
124
124
  },
125
125
  "dependencies": {
126
126
  "ts-morph": "^24.0.0",
127
- "typescript": "^5.7.2"
127
+ "typescript": "^5.7.2",
128
+ "yargs": "^17.7.2"
128
129
  },
129
130
  "peerDependencies": {
130
131
  "@koa/router": "^13.1.0",
@@ -166,7 +167,6 @@
166
167
  "tsconfig-paths": "4.2.0",
167
168
  "vite": "^6.2.2",
168
169
  "vite-plugin-dts": "^3.7.3",
169
- "vitest": "^3.0.9",
170
- "yargs": "^17.7.2"
170
+ "vitest": "^3.0.9"
171
171
  }
172
172
  }
@@ -3,9 +3,9 @@ import * as path from 'path'
3
3
  import yargs, { ArgumentsCamelCase } from 'yargs'
4
4
  import { hideBin } from 'yargs/helpers'
5
5
 
6
- import { prepareOpenApiSpec } from '../src/openapi/analyzerModule/analyzerModule'
7
- import { generateOpenApiSpec } from '../src/openapi/generatorModule'
8
- import { OpenApiManager } from '../src/openapi/manager/OpenApiManager'
6
+ import { prepareOpenApiSpec } from '../openapi/analyzerModule/analyzerModule'
7
+ import { generateOpenApiSpec } from '../openapi/generatorModule'
8
+ import { OpenApiManager } from '../openapi/manager/OpenApiManager'
9
9
  import { printAnalysisStats } from './prettyprint'
10
10
 
11
11
  const originalConsole = console.info
@@ -31,12 +31,22 @@ yargs(hideBin(process.argv))
31
31
  type: 'string',
32
32
  coerce: (f) => path.resolve(f),
33
33
  },
34
+
35
+ force: {
36
+ describe: 'Overwrite existing file',
37
+ type: 'boolean',
38
+ default: false,
39
+ },
34
40
  },
35
41
 
36
- handler(argv: ArgumentsCamelCase<{ targetPath: string; tsConfigPath?: string }>) {
42
+ handler(argv: ArgumentsCamelCase<{ targetPath: string; tsConfigPath?: string; force: boolean }>) {
37
43
  if (fs.existsSync(argv.targetPath)) {
38
- console.error(`[Error] File already exists at ${argv.targetPath}`)
39
- return
44
+ if (!argv.force && !isValidMoonflowerOutput(argv.targetPath)) {
45
+ console.error(
46
+ `[Error] File already exists at ${argv.targetPath} and does not appear to be a moonflower output. Use --force to overwrite.`,
47
+ )
48
+ return
49
+ }
40
50
  }
41
51
 
42
52
  if (argv.tsConfigPath && !fs.existsSync(argv.tsConfigPath)) {
@@ -57,3 +67,13 @@ yargs(hideBin(process.argv))
57
67
  })
58
68
  .demandCommand()
59
69
  .parse()
70
+
71
+ function isValidMoonflowerOutput(filePath: string): boolean {
72
+ try {
73
+ const content = fs.readFileSync(filePath, 'utf-8')
74
+ const parsed = JSON.parse(content)
75
+ return typeof parsed === 'object' && parsed !== null && typeof parsed.openapi === 'string'
76
+ } catch {
77
+ return false
78
+ }
79
+ }
@@ -1,5 +1,5 @@
1
- import { ApiAnalysisStats } from '../src/openapi/manager/OpenApiManager'
2
- import { Logger } from '../src/utils/logger'
1
+ import { ApiAnalysisStats } from '../openapi/manager/OpenApiManager'
2
+ import { Logger } from '../utils/logger'
3
3
 
4
4
  export const printAnalysisStats = (stats: ApiAnalysisStats) => {
5
5
  stats.explicitRouterFiles.forEach((file) => printRouterFile(file))
@@ -1,20 +1,62 @@
1
+ import * as fs from 'fs'
1
2
  import Koa from 'koa'
2
3
 
3
- import { prepareOpenApiSpec } from './analyzerModule/analyzerModule'
4
+ import type * as AnalyzerModule from './analyzerModule/analyzerModule'
5
+ import { OpenApiManager } from './manager/OpenApiManager'
4
6
  import { OpenApiRouter } from './router/OpenApiRouter'
5
7
 
8
+ type AnalyzerProps = Parameters<typeof AnalyzerModule.prepareOpenApiSpec>[0]
9
+
10
+ type PrebuiltSpecProps = {
11
+ /**
12
+ * Path to a pre-built OpenAPI spec JSON file.
13
+ * When provided, the analyzer is skipped entirely and the spec is served from this file.
14
+ * Use this in production to avoid running the TypeScript analyzer on startup.
15
+ *
16
+ * Generate the spec file at build time using the CLI:
17
+ * ```
18
+ * moonflower openapi ./openapi-spec.json
19
+ * ```
20
+ */
21
+ specPath: string
22
+ }
23
+
6
24
  /**
7
25
  * Middleware to initialize the openApi engine.
8
26
  * Can be at any position in the middleware execution order.
9
- * All files with routers or exposed models must be included in `props.sourceFilePaths`.
10
- * @param props Paths to files to analyze, relative to project root.
27
+ *
28
+ * In development, pass analyzer options to generate the spec on startup:
29
+ * ```
30
+ * initOpenApiEngine({ tsconfigPath: 'tsconfig.json', sourceFileDiscovery: true })
31
+ * ```
32
+ *
33
+ * In production, pass a pre-built spec file to skip analysis:
34
+ * ```
35
+ * initOpenApiEngine({ specPath: './openapi-spec.json' })
36
+ * ```
11
37
  */
12
- export const initOpenApiEngine = (props: Parameters<typeof prepareOpenApiSpec>[0]) => {
13
- prepareOpenApiSpec(props)
38
+ export const initOpenApiEngine = (props: AnalyzerProps | PrebuiltSpecProps) => {
39
+ const ready =
40
+ 'specPath' in props
41
+ ? loadPrebuiltSpec(props.specPath)
42
+ : import('./analyzerModule/analyzerModule').then(({ prepareOpenApiSpec }) => prepareOpenApiSpec(props))
14
43
 
15
44
  const builtInRoutes = OpenApiRouter.routes()
16
45
  const builtInAllowedMethods = OpenApiRouter.allowedMethods()
17
- return (ctx: Koa.ParameterizedContext<any, any>, next: Koa.Next) => {
46
+ return async (ctx: Koa.ParameterizedContext<any, any>, next: Koa.Next) => {
47
+ await ready
18
48
  return builtInRoutes(ctx, () => builtInAllowedMethods(ctx, next))
19
49
  }
20
50
  }
51
+
52
+ const loadPrebuiltSpec = (specPath: string) => {
53
+ const manager = OpenApiManager.getInstance()
54
+ if (manager.isReady()) {
55
+ return
56
+ }
57
+
58
+ const content = fs.readFileSync(specPath, 'utf-8')
59
+ const spec = JSON.parse(content)
60
+ manager.setPrebuiltSpec(spec)
61
+ manager.markAsReady()
62
+ }
@@ -45,6 +45,7 @@ export class OpenApiManager {
45
45
 
46
46
  private isInitialized = false
47
47
  private registeredRouters: Router[] = []
48
+ private prebuiltSpec: Record<string, unknown> | null = null
48
49
 
49
50
  constructor(
50
51
  private apiDocsHeader: ApiDocsHeader,
@@ -125,9 +126,24 @@ export class OpenApiManager {
125
126
  return this
126
127
  }
127
128
 
129
+ public getPrebuiltSpec(): Record<string, unknown> | null {
130
+ return this.prebuiltSpec
131
+ }
132
+
133
+ public setPrebuiltSpec(spec: Record<string, unknown>) {
134
+ this.prebuiltSpec = spec
135
+ return this
136
+ }
137
+
138
+ public clearPrebuiltSpec() {
139
+ this.prebuiltSpec = null
140
+ return this
141
+ }
142
+
128
143
  public reset() {
129
144
  this.exposedModels = []
130
145
  this.endpoints = []
146
+ this.prebuiltSpec = null
131
147
  }
132
148
 
133
149
  public static getInstance() {
@@ -5,7 +5,12 @@ import { OpenApiManager } from '../manager/OpenApiManager'
5
5
  const router = new Router({ skipOpenApiAnalysis: true })
6
6
 
7
7
  router.get('/api-json', () => {
8
- return generateOpenApiSpec(OpenApiManager.getInstance())
8
+ const manager = OpenApiManager.getInstance()
9
+ const prebuilt = manager.getPrebuiltSpec()
10
+ if (prebuilt) {
11
+ return prebuilt
12
+ }
13
+ return generateOpenApiSpec(manager)
9
14
  })
10
15
 
11
16
  export const OpenApiRouter = router
@@ -1,7 +1,13 @@
1
+ import * as fs from 'fs'
2
+ import Koa from 'koa'
3
+ import * as os from 'os'
4
+ import * as path from 'path'
1
5
  import request from 'supertest'
2
6
  import { vi } from 'vitest'
3
7
 
4
8
  import { generateOpenApiSpec } from '../openapi/generatorModule/generatorModule'
9
+ import { initOpenApiEngine } from '../openapi/initOpenApiEngine'
10
+ import { OpenApiManager } from '../openapi/manager/OpenApiManager'
5
11
  import { app } from './app'
6
12
 
7
13
  describe('TestAppRouter', () => {
@@ -148,4 +154,25 @@ describe('OpenApiRouter', () => {
148
154
  },
149
155
  })
150
156
  })
157
+
158
+ it('serves a prebuilt spec from file', async () => {
159
+ const manager = OpenApiManager.getInstance()
160
+ const liveSpec = generateOpenApiSpec(manager)
161
+
162
+ const specPath = path.join(os.tmpdir(), `moonflower-test-spec-${Date.now()}.json`)
163
+ fs.writeFileSync(specPath, JSON.stringify(liveSpec))
164
+
165
+ try {
166
+ const prebuiltApp = new Koa()
167
+ prebuiltApp.use(initOpenApiEngine({ specPath }))
168
+
169
+ const response = await request(prebuiltApp.callback()).get('/api-json')
170
+ expect(response.status).toBe(200)
171
+ const responseJson = JSON.parse(response.text)
172
+ expect(responseJson).toEqual(liveSpec)
173
+ } finally {
174
+ manager.clearPrebuiltSpec()
175
+ fs.unlinkSync(specPath)
176
+ }
177
+ })
151
178
  })
package/vite.config.ts CHANGED
@@ -23,6 +23,7 @@ const entries = {
23
23
  'router/Router': resolve(__dirname, 'src/router/Router.ts'),
24
24
  'validators/BuiltInValidators': resolve(__dirname, 'src/validators/BuiltInValidators.ts'),
25
25
  'validators/ParamWrappers': resolve(__dirname, 'src/validators/ParamWrappers.ts'),
26
+ 'cli/cli': resolve(__dirname, 'src/cli/cli.ts'),
26
27
  }
27
28
 
28
29
  export const baseViteConfig: ViteUserConfig = {
@@ -53,6 +54,8 @@ export const baseViteConfig: ViteUserConfig = {
53
54
  '@ts-morph/common',
54
55
  'typescript',
55
56
  'ts-morph',
57
+ 'yargs',
58
+ 'yargs/helpers',
56
59
  ],
57
60
  output: {
58
61
  globals: {