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.
- package/cli/entry.cjs +1 -1
- package/dist/cli/cli.cjs +2 -0
- package/dist/cli/cli.cjs.map +1 -0
- package/dist/cli/cli.d.ts +2 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/cli/cli.mjs +62 -0
- package/dist/cli/cli.mjs.map +1 -0
- package/dist/cli/prettyprint.cjs +2 -0
- package/dist/cli/prettyprint.cjs.map +1 -0
- package/dist/cli/prettyprint.d.ts +5 -0
- package/dist/cli/prettyprint.d.ts.map +1 -0
- package/dist/cli/prettyprint.mjs +15 -0
- package/dist/cli/prettyprint.mjs.map +1 -0
- package/dist/openapi/initOpenApiEngine.cjs +1 -1
- package/dist/openapi/initOpenApiEngine.cjs.map +1 -1
- package/dist/openapi/initOpenApiEngine.d.ts +7 -2
- package/dist/openapi/initOpenApiEngine.d.ts.map +1 -1
- package/dist/openapi/initOpenApiEngine.mjs +13 -7
- package/dist/openapi/initOpenApiEngine.mjs.map +1 -1
- package/dist/openapi/manager/OpenApiManager.cjs +1 -1
- package/dist/openapi/manager/OpenApiManager.cjs.map +1 -1
- package/dist/openapi/manager/OpenApiManager.d.ts +4 -0
- package/dist/openapi/manager/OpenApiManager.d.ts.map +1 -1
- package/dist/openapi/manager/OpenApiManager.mjs +11 -2
- package/dist/openapi/manager/OpenApiManager.mjs.map +1 -1
- package/dist/openapi/router/OpenApiRouter.cjs +1 -1
- package/dist/openapi/router/OpenApiRouter.cjs.map +1 -1
- package/dist/openapi/router/OpenApiRouter.d.ts.map +1 -1
- package/dist/openapi/router/OpenApiRouter.mjs +9 -6
- package/dist/openapi/router/OpenApiRouter.mjs.map +1 -1
- package/package.json +4 -4
- package/{cli → src/cli}/cli.ts +26 -6
- package/{cli → src/cli}/prettyprint.ts +2 -2
- package/src/openapi/initOpenApiEngine.ts +48 -6
- package/src/openapi/manager/OpenApiManager.ts +16 -0
- package/src/openapi/router/OpenApiRouter.ts +6 -1
- package/src/test/app.spec.ts +27 -0
- package/vite.config.ts +3 -0
package/cli/entry.cjs
CHANGED
package/dist/cli/cli.cjs
ADDED
|
@@ -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 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli/cli.mjs
ADDED
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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":"
|
|
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
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const n =
|
|
6
|
-
return (
|
|
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
|
-
|
|
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
|
|
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,
|
|
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;
|
|
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,
|
|
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
|
|
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\
|
|
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;
|
|
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
|
|
1
|
+
import { Router as n } from "../../router/Router.mjs";
|
|
2
2
|
import { generateOpenApiSpec as p } from "../generatorModule/generatorModule.mjs";
|
|
3
|
-
import { OpenApiManager as
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
const
|
|
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
|
-
|
|
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\
|
|
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.
|
|
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
|
}
|
package/{cli → src/cli}/cli.ts
RENAMED
|
@@ -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 '../
|
|
7
|
-
import { generateOpenApiSpec } from '../
|
|
8
|
-
import { OpenApiManager } from '../
|
|
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
|
-
|
|
39
|
-
|
|
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 '../
|
|
2
|
-
import { Logger } from '../
|
|
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
|
|
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
|
-
*
|
|
10
|
-
*
|
|
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:
|
|
13
|
-
|
|
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
|
-
|
|
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
|
package/src/test/app.spec.ts
CHANGED
|
@@ -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: {
|