diff --git a/src/config.ts b/src/config.ts index f688ed6e..969f6fb7 100644 --- a/src/config.ts +++ b/src/config.ts @@ -3,18 +3,21 @@ export interface IClientConfig { type: "client"; name: string; language: "typescript" | "rust"; + outPath?: string; } export interface IServerConfig { type: "server"; name: string; language: "typescript"; + outPath?: string; } export interface IDocsConfig { type: "docs"; name: string; language: "gatsby"; + outPath?: string; } // Experimental @@ -24,6 +27,7 @@ export interface ICustomConfig { customComponent: string; customType?: string; openRPCPath?: string | null; + outPath?: string; language: "typescript" | "rust"; } diff --git a/src/index.test.ts b/src/index.test.ts index 4d31dd0d..96f1d59d 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -64,10 +64,21 @@ describe(`Examples to generate Js clients`, () => { return expect(genProm).rejects.toBeInstanceOf(OpenRPCDocumentDereferencingError); }); + forEach(examples, (example: OpenRPC, exampleName: string) => { + it(`rejects configurations without outDir or outPath`, async ()=>{ + const promGen = clientGen({ + openrpcDocument: await parseOpenRPCDocument(example), + components: [ + { type: "client", language: "typescript", name: "testclient-ts" }, + ] + }); + expect(promGen).rejects.toBeInstanceOf(Error); + }); + it(`creates a new client for example: ${exampleName} and regenerates after`, async () => { const exampleOutDir = `${testDir}/${exampleName}`; - expect.assertions(2); + expect.assertions(5); await clientGen({ openrpcDocument: await parseOpenRPCDocument(example), @@ -79,11 +90,14 @@ describe(`Examples to generate Js clients`, () => { { type: "docs", language: "gatsby", name: "testserver-gatsby" }, { type: "custom", language: "typescript", name: "custom-stuff", "customComponent":"./src/custom-test-component.js", customType:"client"}, { type: "custom", language: "typescript", name: "custom-stuff2", "customComponent":"./src/custom-test-component.js", customType:"client", openRPCPath: null}, - { type: "custom", language: "typescript", name: "custom-stuff3", "customComponent":"./src/custom-test-component.js", customType:"client", openRPCPath: "tmpz"} + { type: "custom", language: "typescript", name: "custom-stuff3", "customComponent":"./src/custom-test-component.js", customType:"client", openRPCPath: "tmpz"}, + { type: "custom", language: "typescript", name: "custom-stuff4", "customComponent":"./src/custom-test-component.js", customType:"client", + openRPCPath: "tmpy", outPath: `${exampleOutDir}/special`} ], }); await expect(stat(exampleOutDir)).resolves.toBeTruthy(); + await expect(stat(`${exampleOutDir}/special`)).resolves.toBeTruthy(); await clientGen({ openrpcDocument: await parseOpenRPCDocument(example), @@ -95,10 +109,14 @@ describe(`Examples to generate Js clients`, () => { { type: "docs", language: "gatsby", name: "testserver-gatsby" }, { type: "custom", language: "typescript", name: "custom-stuff", "customComponent":"./src/custom-test-component.js", customType:"client"}, { type: "custom", language: "typescript", name: "custom-stuff2", "customComponent":"./src/custom-test-component.js", customType:"client", openRPCPath: null}, - { type: "custom", language: "typescript", name: "custom-stuff3", "customComponent":"./src/custom-test-component.js", customType:"client", openRPCPath: "tmpz"} + { type: "custom", language: "typescript", name: "custom-stuff3", "customComponent":"./src/custom-test-component.js", customType:"client", openRPCPath: "tmpz"}, + { type: "custom", language: "typescript", name: "custom-stuff4", "customComponent":"./src/custom-test-component.js", customType:"client", + openRPCPath: "tmpy", outPath: `${exampleOutDir}/special`} ], }); + await expect(stat(`${exampleOutDir}/special`)).resolves.toBeTruthy(); + await expect(stat(exampleOutDir)).resolves.toBeTruthy(); }, 100000); }); diff --git a/src/index.ts b/src/index.ts index aa466d93..febe5e86 100644 --- a/src/index.ts +++ b/src/index.ts @@ -105,7 +105,7 @@ const copyStaticForComponent = async ( }; export interface IGeneratorOptions { - outDir: string; + outDir?: string; openrpcDocument: OpenRPC | string; components: TComponentConfig[]; } @@ -124,7 +124,7 @@ const writeOpenRpcDocument = async ( ): Promise => { if(component.openRPCPath === undefined) return; const toWrite = typeof doc === "string" ? await parseOpenRPCDocument(doc, { dereference: false }) : doc; - const openRPCPath = `${outDir}/${component.type}/${component.language}/${component.openRPCPath}` + const openRPCPath = `${outDir}/${component.openRPCPath}` await ensureDir(openRPCPath); const destinationDirectoryName = `${openRPCPath}/openrpc.json`; await writeFile(destinationDirectoryName, JSON.stringify(toWrite, undefined, " "), "utf8"); @@ -179,10 +179,20 @@ export default async (generatorOptions: IGeneratorOptions) => { const methodTypings = new Typings(dereffedDocument); for (const componentConfig of generatorOptions.components) { + const outPath = componentConfig.outPath; + if(outPath === undefined && outDir === undefined){ + console.error("No output path specified"); + throw new Error("No output path specified"); + } const component = await getComponentFromConfig(componentConfig) - const destDir = await prepareOutputDirectory(outDir, component); - await copyStaticForComponent(destDir, component, dereffedDocument, methodTypings); - await writeOpenRpcDocument(outDir, openrpcDocument, component); - await compileTemplate(destDir, component, dereffedDocument, methodTypings); + let destDir = outPath; + if(!outPath){ + destDir = await prepareOutputDirectory(outDir!, component); + }else { + await ensureDir(outPath); + } + await copyStaticForComponent(destDir!, component, dereffedDocument, methodTypings); + await writeOpenRpcDocument(destDir!, openrpcDocument, component); + await compileTemplate(destDir!, component, dereffedDocument, methodTypings); } };