New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@frui.ts/generator

Package Overview
Dependencies
Maintainers
5
Versions
74
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@frui.ts/generator - npm Package Compare versions

Comparing version 1.0.0-beta.6 to 1.0.0-rc.1

2

dist/generator.umd.js
#!/usr/bin/env node
/* Frui.ts generator */
(function(h,l){typeof exports=="object"&&typeof module<"u"?l(require("commander"),require("lodash"),require("ts-morph"),require("fs"),require("path"),require("cli-progress"),require("handlebars"),require("@apidevtools/swagger-parser")):typeof define=="function"&&define.amd?define(["commander","lodash","ts-morph","fs","path","cli-progress","handlebars","@apidevtools/swagger-parser"],l):(h=typeof globalThis<"u"?globalThis:h||self,l(h.commander,h.lodash,h.tsMorph,h.fs,h.path,h.cliProgress,h.Handlebars,h.SwaggerParser))})(this,function(h,l,y,se,ne,ie,ae,oe){"use strict";var et=Object.defineProperty;var tt=(h,l,y)=>l in h?et(h,l,{enumerable:!0,configurable:!0,writable:!0,value:y}):h[l]=y;var m=(h,l,y)=>(tt(h,typeof l!="symbol"?l+"":l,y),y);const R=n=>n&&typeof n=="object"&&"default"in n?n:{default:n},M=R(se),$=R(ne),D=R(ae),W=R(oe),ce="999.0.0",pe="Frui.ts code generator";h.program.name("fruits-generate").version(ce).description(pe),h.program.command("inversify").description("Generate Inversify configuration files").option("-p, --project <fileName>","TS project file","./tsconfig.json").option("-c, --config <fileName>","Custom configuration file").option("-d, --debug","Output extra debugging").option("--no-decorators","Do not generate decorators file").option("--decorators-output <relativePath>","Decorators output file path","src/di.decorators.ts").option("--no-registry","Do not generate registry file").option("--registry-output <relativePath>","Registry output file path","src/di.registry.ts").action(async n=>{const e={project:n.project,config:n.config,debug:n.debug};console.log("Processing",e.config),n.decorators&&(e.decorators={output:n.decoratorsOutput}),n.registry&&(e.registry={output:n.registryOutput});const t=await Promise.resolve().then(()=>be),r=new t.default(e);await r.init(),await r.run()}),h.program.command("views").description("Generate view registrations").option("-p, --project <fileName>","TS project file","./tsconfig.json").option("-c, --config <fileName>","Custom configuration file").option("-d, --debug","Output extra debugging").option("-o, --output <relativePath>","Output file path","src/views/index.ts").action(async n=>{const e={project:n.project,config:n.config,output:n.output,debug:n.debug};console.log("Processing",e.config);const t=await Promise.resolve().then(()=>Oe),r=new t.default(e);await r.init(),await r.run()}),h.program.command("openapi").alias("swagger").description("Generate OpenAPI client files").option("-p, --project <fileName>","TS project file","./tsconfig.json").option("-c, --config <fileName>","Custom configuration file").option("-d, --debug","Output extra debugging").action(async n=>{const e={project:n.project,config:n.config,debug:n.debug};console.log("Processing",e.config);const t=await Promise.resolve().then(()=>Ye),r=new t.default(e);await r.init(),await r.run()}),h.program.parseAsync().catch(n=>{console.error(n)});function E(n){return l.upperFirst(l.camelCase(n))}async function le(n){const e=$.default.join(process.cwd(),n),t=await M.default.promises.readFile(e,"utf8");return JSON.parse(t)}function ue(n,e){if(n===e)return"./";const t=n.split("/"),r=e.split("/");let s=0;for(;t[s]===r[s]&&s<t.length&&s<r.length;)s++;return[...new Array(t.length-s).fill(".."),...r.slice(s-r.length)].join("/")}const me="// WARNING: This file has been generated. Do not edit it manually, your changes might get lost.";function fe(n,e){return{format:`${n.padEnd(e)} [{bar}] {percentage}% | ETA: {eta}s | {value}/{total}`}}function O(n,e=0){return new ie.SingleBar(fe(n,e))}class v{constructor(e){m(this,"project");m(this,"config");this.params=e}async init(){const e=O("Parsing");e.start(2,0),this.project=new y.Project({tsConfigFilePath:this.params.project,manipulationSettings:{indentationText:y.IndentationText.TwoSpaces}}),e.increment(),this.params.debug&&this.logDiagnostics();const t=await this.getDefaultConfig();if(this.params.config){const r=await le(this.params.config);this.config=Object.assign({},t,r)}else this.config=t;e.increment(),e.stop()}async saveFile(e){this.writeGeneratedHeader(e),e.organizeImports(),e.formatText(),await e.save()}static canOverwiteFile(e,t){var s;const r=e.getSourceFile(t);return!((s=r==null?void 0:r.getStatementByKind(y.ts.SyntaxKind.SingleLineCommentTrivia|y.ts.SyntaxKind.MultiLineCommentTrivia))!=null&&s.getText().includes("generator:ignore"))}writeGeneratedHeader(e){e.insertText(0,t=>t.writeLine(me))}getDiagnostics(){return this.project.getPreEmitDiagnostics().map(t=>({message:t.getMessageText(),source:t.getSource(),lineNumber:t.getLineNumber(),code:t.getCode(),category:t.getCategory}))}logDiagnostics(){for(const e of this.getDiagnostics())console.warn(e)}}const he={factoryName:"Factory",rules:[{pattern:"Service$",identifier:"$class",addDecorators:!0,registerAutoFactory:!1,scope:"singleton"},{pattern:"ViewModel$",identifier:"$class",addDecorators:!0,registerAutoFactory:!1,scope:"transient"},{pattern:"Repository$",identifier:"$class",addDecorators:!0,registerAutoFactory:!1,scope:"transient"}]};class ye{analyze(e,t){const r=[];return e.getSourceFiles().forEach(s=>{s.getExportedDeclarations().forEach((i,a)=>{const o=i[0];if(o instanceof y.ClassDeclaration&&!o.isAbstract()){const c=o.getName();if(c){const p=t.find(f=>f.regexPattern.test(c));p&&r.push({declaration:o,rule:p})}}})}),l.uniqBy(r,s=>s.declaration)}}function j(n,e){var s;const t=n.getSourceFile(),r=e.getRelativePathAsModuleSpecifierTo(t);if(n.isDefaultExport()){const i=l.camelCase(r);return{identifier:i,declaration:{defaultImport:i,moduleSpecifier:r}}}else{const i=l.camelCase(r)+((s=n.getName())!=null?s:""),a={namedImports:[{name:n.getNameOrThrow(),alias:i}],moduleSpecifier:r};return{identifier:i,declaration:a}}}function A(n){var t,r;let e=(t=n.getSymbol())!=null?t:n.getAliasSymbol();if(n.isUnion()){const s=n.getUnionTypes();for(const i of s)if(e=(r=i.getSymbol())!=null?r:i.getAliasSymbol(),e)break}return e&&(e.getValueDeclaration()||e.getDeclarations()[0])}class de{constructor(e,t,r){m(this,"decorators");m(this,"registrations");this.decoratorsFile=e,this.registrationFile=t,this.factoryName=r}process(e){return this.decorators=[],this.registrations=[],e.forEach(t=>this.processService(t)),{decorators:this.decorators,registrations:this.registrations}}processService(e){e.rule.addDecorators&&this.decorateServiceInjectable(e.declaration),e.rule.scope!=="none"&&this.registerService(e)}decorateServiceInjectable(e){const t=j(e,this.decoratorsFile);this.decorators.push({importStatements:[t.declaration],statements:[`decorate(injectable(), ${t.identifier});`]})}registerService({declaration:e,rule:t}){const r=e.getStaticMethod(this.factoryName);if(r)this.registerServiceFactory(e,t,r);else{const s=G(e);this.registerConstructor(e,t,s)}}registerServiceFactory(e,t,r){const s=j(e,this.registrationFile),i=`${s.identifier}.${r.getName()}`,a=t.identifier===void 0||t.identifier==="$class"?i:t.identifier;this.registrations.push({importStatements:[s.declaration],statements:["container",`.bind<interfaces.Factory<${s.identifier}>>(${a})`,`.toFactory(${i});`]})}registerConstructor(e,t,r){var o;const s=j(e,this.registrationFile);let i,a;switch(t.identifier){case void 0:case"$class":i=s.identifier,a="toSelf()";break;case"$interface":{const c=e.getImplements()[0];i=c?`"${c.getText()}"`:"NoInterfaceImplemented",a=`to(${s.identifier})`;break}default:i=`"${t.identifier}"`,a=`to(${s.identifier})`;break}t.scope==="singleton"&&(a+=".inSingletonScope()"),this.registrations.push({importStatements:[s.declaration],statements:[`container.bind<${s.identifier}>(${i}).${a};`]}),t.registerAutoFactory&&this.registrations.push({importStatements:[],statements:[`container.bind("Factory<${(o=e.getName())!=null?o:""}>").toAutoFactory(${i});`]}),r&&this.decorateConstructorParameterInject(e,r)}decorateConstructorParameterInject(e,t){const r=j(e,this.decoratorsFile);this.decorators.push({importStatements:[r.declaration],statements:[]});const s=t.getParameters();for(let i=0;i<s.length;i++){let o=s[i].getType(),c=!1;o.isArray()&&(o=o.getArrayElementTypeOrThrow(),c=!0);const p=A(o);if(p){const f=this.getConstructorParameterDecorator(r.identifier,i,p,c);f&&this.decorators.push(f)}}}getConstructorParameterDecorator(e,t,r,s){var a;const i=s?"multiInject":"inject";if(r instanceof y.ClassDeclaration){const o=j(r,this.decoratorsFile);return{importStatements:[o.declaration],statements:[`decorate(${i}(${o.identifier}) as any, ${e}, ${t});`]}}if(r instanceof y.InterfaceDeclaration)return{importStatements:[],statements:[`decorate(${i}("${r.getName()}") as any, ${e}, ${t});`]};if(r instanceof y.FunctionTypeNode){const o=A(r.getReturnType());if(o instanceof y.ClassDeclaration||o instanceof y.InterfaceDeclaration)return{importStatements:[],statements:[`decorate(${i}("Factory<${(a=o.getName())!=null?a:""}>") as any, ${e}, ${t});`]}}if(r instanceof y.ArrowFunction){const o=A(r.getReturnType());if(o instanceof y.ClassDeclaration){const c=this.factoryName&&o.getStaticMethod(this.factoryName);if(c){const p=j(o,this.decoratorsFile);return{importStatements:[p.declaration],statements:[`decorate(${i}(${p.identifier}.${c.getName()}) as any, ${e}, ${t});`]}}}}}}function G(n){const e=n.getConstructors()[0];if(e)return e;const t=n.getBaseClass();return t?G(t):void 0}class ge extends v{constructor(){super(...arguments);m(this,"decoratorsFile");m(this,"registryFile");m(this,"registrationFunction")}async run(){var c;const t=O("Generating");t.start(4,0);const r=this.parseRules(),s=new ye().analyze(this.project,r);t.increment();const i=new de(this.ensureDecoratorsFile(),this.ensureRegistryFile(),(c=this.config.factoryName)!=null?c:"Factory"),{decorators:a,registrations:o}=i.process(s);if(t.increment(),a.length){const p=a.flatMap(g=>g.importStatements);this.decoratorsFile.addImportDeclarations(p);const f=a.flatMap(g=>g.statements);this.decoratorsFile.addStatements(f),await this.saveFile(this.decoratorsFile)}if(t.increment(),o.length){const p=o.flatMap(g=>g.importStatements);this.registryFile.addImportDeclarations(p);const f=o.flatMap(g=>g.statements);this.registrationFunction.addStatements(f),await this.saveFile(this.registryFile)}t.increment(),t.stop()}getDefaultConfig(){return Promise.resolve(he)}ensureDecoratorsFile(){var t;return!this.decoratorsFile&&((t=this.params.decorators)==null?void 0:t.output)&&(this.decoratorsFile=this.project.createSourceFile(this.params.decorators.output,void 0,{overwrite:!0}),this.decoratorsFile.addImportDeclaration({namedImports:["decorate","inject","injectable","multiInject"],moduleSpecifier:"inversify"})),this.decoratorsFile}ensureRegistryFile(){var t;return!this.registryFile&&((t=this.params.registry)==null?void 0:t.output)&&(this.registryFile=this.project.createSourceFile(this.params.registry.output,void 0,{overwrite:!0}),this.registryFile.addImportDeclaration({namedImports:["Container","interfaces"],moduleSpecifier:"inversify"}),this.registrationFunction=this.registryFile.addFunction({isDefaultExport:!0,name:"registerServices",parameters:[{name:"container",type:"Container"}]})),this.registryFile}parseRules(){var t,r;return(r=(t=this.config.rules)==null?void 0:t.map(s=>({...s,regexPattern:new RegExp(s.pattern)})))!=null?r:[]}}const be=Object.freeze(Object.defineProperty({__proto__:null,default:ge},Symbol.toStringTag,{value:"Module"})),we={viewsPattern:"**/views/**/*.tsx"};class Ee{analyze(e,t){const r=[];return e.getSourceFiles(t).forEach(s=>{s.getImportDeclarations().some(a=>a.getNamedImports().some(o=>o.getName()==="registerView"||o.getName()==="registerViewComponent"))&&r.push(s)}),r}}class ve{constructor(e){this.targetFile=e}process(e){return{importStatements:e.map(s=>this.targetFile.getRelativePathAsModuleSpecifierTo(s)).map(s=>({moduleSpecifier:s})),statements:[]}}}class Fe extends v{constructor(){super(...arguments);m(this,"viewsFile")}async run(){const t=O("Generating");t.start(5,0);const r=new Ee().analyze(this.project,this.config.viewsPattern);t.increment();const i=new ve(this.ensureViewsFile()).process(r);t.increment(),this.viewsFile.addImportDeclarations(i.importStatements),t.increment(),this.viewsFile.addStatements(i.statements),t.increment(),await this.saveFile(this.viewsFile),t.increment(),t.stop()}ensureViewsFile(){return!this.viewsFile&&this.params.output&&(this.viewsFile=this.project.createSourceFile(this.params.output,void 0,{overwrite:!0})),this.viewsFile}getDefaultConfig(){return Promise.resolve(we)}}const Oe=Object.freeze(Object.defineProperty({__proto__:null,default:Fe},Symbol.toStringTag,{value:"Module"})),je={api:"https://fruits-demo.herokuapp.com/api/swagger-json",entitiesPath:"src/entities",repositoriesPath:"src/repositories",conversion:!0,observable:{entities:{EnumValue:!1,User:{exclude:["code"]},Partner:{include:["name"]}},properties:{exclude:["id","created"]}},enums:"enum",dates:"native",validations:{rules:{readOnly:!1}},endpointUrlPrefix:"/api/",templatesFolder:"class-transformer",templates:{enumEntity:"@enumEntity.hbs",enumEntityFile:"@enumEntityFile.hbs",objectEntityContent:"@objectEntityContent.hbs",objectEntityFile:"@objectEntityFile.hbs",entityImport:"@entityImport.hbs",generatedEntityHeader:"@generatedEntityHeader.hbs",repositoryAction:"@repositoryAction.hbs",repositoryFile:"@repositoryFile.hbs",stringLiteralEntity:"@stringLiteralEntity.hbs",stringLiteralEntityFile:"@stringLiteralEntityFile.hbs",unionEntity:"@unionEntity.hbs",unionEntityFile:"@unionEntityFile.hbs"},optionalAsNullable:!1};class F{constructor(e){m(this,"externalName");this.name=e}}class x extends F{constructor(e,t){super(e),this.items=t}}class b extends F{constructor(e,t){super(e),this.properties=t}addPropertyRestriction(e,t,r){var s;(s=this.properties.find(i=>i.name===e))==null||s.addRestriction(t,r)}}class C extends b{constructor(e,t,r){super(e,r),this.baseEntities=t}}class q extends F{constructor(e,t){super(e),this.entities=t}}class Te{constructor(e,t){this.parentDirectory=e,this.templates=t}write(e){const t=`${l.camelCase(e.name)}.ts`;if(!v.canOverwiteFile(this.parentDirectory,t))return;const r=this.parentDirectory.getSourceFile(t);return r?this.updateFile(r,e):this.createFile(t,e)}updateFile(e,t){var s;const r=(s=e.getFunction(`build${t.name}`))!=null?s:e.getEnum(t.name);if(!r)throw new Error(`Could not find node to replace (enum ${t.name}, or function build${t.name}) in file ${e.getFilePath()}`);return r.replaceWithText(this.getEnumContent(t)),e}createFile(e,t){const r=this.templates.enumEntityFile({content:()=>this.getEnumContent(t),enum:t});return this.parentDirectory.createSourceFile(e,r,{overwrite:!0})}getEnumContent(e){return this.templates.enumEntity(e)}}var k=(n=>(n[n.required=0]="required",n[n.number=1]="number",n[n.date=2]="date",n[n.maxLength=3]="maxLength",n[n.minLength=4]="minLength",n[n.pattern=5]="pattern",n[n.nullable=6]="nullable",n[n.readOnly=7]="readOnly",n[n.format=8]="format",n))(k||{});const u=k;class U{constructor(e){m(this,"globalExcludedProperties");var t,r;this.excludeConfig=e,this.globalExcludedProperties=(r=(t=e==null?void 0:e.properties)==null?void 0:t.exclude)!=null?r:[]}buildExcludeList(e){var r,s;const t=(s=(r=this.excludeConfig)==null?void 0:r.entities)==null?void 0:s[e];return t===!1?!1:typeof t=="object"&&t.exclude?this.globalExcludedProperties.concat(t.exclude):this.globalExcludedProperties}}const _=class extends U{constructor(e){super(typeof e=="object"?e:void 0),this.config=e}format(e){!this.config||e.type instanceof b&&this.formatEntity(e.type)}formatEntity(e){var r;const t=this.buildExcludeList(e.name);if(t!==!1)for(const s of e.properties){const i=t.includes(s.name),a=(r=s.restrictions)==null?void 0:r.has(u.readOnly);!i&&!a&&s.addTag(_.OBSERVABLE,!0)}}};let T=_;m(T,"OBSERVABLE",Symbol("observable"));class w extends F{constructor(e,t,r=!1){super(e),this.referencedEntity=t,this.isArray=r}}class Pe{constructor(e,t,r){this.parentDirectory=e,this.config=t,this.templates=r}write(e,t){const r=`${l.camelCase(e.name)}.ts`;if(!v.canOverwiteFile(this.parentDirectory,r))return;const s=this.parentDirectory.getSourceFile(r);return s?this.updateFile(s,e,t):this.createFile(r,e,t)}updateFile(e,t,r){const s=e.getClass(t.name);if(s){s.removeText(),s.insertText(s.getEnd()-1,o=>{o.newLineIfLastNot(),o.write(this.getEntityContent(t,r))});const a=r==null?void 0:r[0];return a&&s.setExtends(a.name),e}const i=e.getFunction(`build${t.name}`);return i&&(i.removeText(),i.insertText(i.getEnd()-1,a=>{a.newLineIfLastNot(),a.write(this.getEntityContent(t,r))})),e}createFile(e,t,r){const s=t.properties.filter(o=>o.type.isImportRequired).map(o=>o.type.getTypeName());r==null||r.forEach(o=>s.push(o.name));const i=l.uniq(s).sort().map(o=>this.templates.entityImport({entity:o,filePath:`./${l.camelCase(o)}`})),a=this.templates.objectEntityFile({imports:i,content:()=>this.getEntityContent(t,r),entity:t,baseClasses:r});return this.parentDirectory.createSourceFile(e,a,{overwrite:!0})}getEntityContent(e,t){const r={entity:e,baseClasses:t,properties:e.properties.map(s=>{var a,o,c,p,f;const i=(a=s.restrictions)==null?void 0:a.get(u.nullable);return{name:s.name,externalName:this.config.conversion!==!1&&s.externalName,type:s.type.getTypeDeclaration()||"UNKNOWN",typeName:s.type.getTypeName(),isArray:s.type.isArray,hasTypeImport:s.type.isImportRequired,description:s.description,example:s.example,isObservable:(o=s.tags)==null?void 0:o.get(T.OBSERVABLE),conversions:this.config.conversion!==!1&&this.getPropertyTypeConversions(s),readonly:(c=s.restrictions)==null?void 0:c.has(u.readOnly),nullable:i,required:i!==!0&&((p=s.restrictions)==null?void 0:p.has(u.required)),format:(f=s.restrictions)==null?void 0:f.get(u.format),validations:this.getPropertyValidations(s),rawValidations:this.getRawPropertyValidations(s)}}),validationEntity:this.config.validations!==!1&&z(e)&&{},useBaseClassValidation:!!(t!=null&&t.some(s=>z(s)))};return this.templates.objectEntityContent(r)}*getPropertyTypeConversions(e){var r;let t=e.type.type;t instanceof w&&(t=t.referencedEntity.type),!(t instanceof x)&&(typeof t=="object"&&(yield`@Type(() => ${e.type.getTypeName()})`),t==="Date"&&(this.config.dates==="date-fns"?(yield"@Transform(value => (value ? new Date(value) : undefined), { toClassOnly: true })",((r=e.restrictions)==null?void 0:r.get(u.format))==="date"?yield'@Transform(value => (value ? formatISO(value, { representation: "date" }) : undefined), { toPlainOnly: true })':yield"@Transform(value => (value ? formatISO(value) : undefined), { toPlainOnly: true })"):yield"@Type(() => Date)"))}getPropertyValidations(e){var t;if((t=e.validations)!=null&&t.size){const r=[];return e.validations.forEach((s,i)=>{const a=this.getValidationDefinition(i,s);a&&!r.includes(a)&&r.push(a)}),r}}getRawPropertyValidations(e){if(e.validations){const t=Array.from(e.validations.entries()).filter(r=>!!r[1]).map(r=>[u[r[0]],r[1]]);return Object.fromEntries(t)}}getValidationDefinition(e,t){var o,c;const r=u[e],s=typeof this.config.validations=="object"?(o=this.config.validations.rules)==null?void 0:o[r]:void 0;if(s===!1)return;const i=JSON.stringify(t);return $e(s,i)?`${(c=Se(s))!=null?c:r}: ${i}`:void 0}}function z(n){return n.properties.some(e=>{var t;return(t=e.restrictions)==null?void 0:t.size})}function Se(n){if(typeof n=="string")return n;if(typeof n=="object")return n.name}const H=new Map;function Re(n){const e=H.get(n);if(e)return e;const t=new RegExp(n);return H.set(n,t),t}function $e(n,e){return typeof n=="object"&&n.filter?!!Re(n.filter).exec(e):!0}class De{constructor(e,t,r){this.parentDirectory=e,this.config=t,this.templates=r}write(e,t){const r=`${E(e)}Repository`,s=`${l.camelCase(r)}.ts`;if(!v.canOverwiteFile(this.parentDirectory,s))return;const i=this.parentDirectory.getSourceFile(s);return i?this.updateFile(i,r,t):this.createFile(s,r,t)}updateFile(e,t,r){const s=e.getClassOrThrow(E(t));for(const i of r)s.getMethod(l.camelCase(i.name))||s.addMember(this.getActionContent(i));return e}createFile(e,t,r){const s=this.templates.repositoryFile({repositoryName:t,imports:this.getRequiredImports(r),actions:()=>r.map(i=>this.getActionContent(i))});return this.parentDirectory.createSourceFile(e,s,{overwrite:!0})}getRequiredImports(e){return l.uniq(e.flatMap(t=>{var r,s;return[t.queryParam,(r=t.requestBody)==null?void 0:r.typeReference,(s=K(t))==null?void 0:s.typeReference]}).filter(t=>!!t&&t.isImportRequired)).map(t=>{const r=t.getTypeName();return`import ${r} from "${this.config.entitiesRelativePath}/${l.camelCase(r)}";`})}getActionContent(e){var s;const t=K(e),r={action:e,path:xe(e),parameters:this.getMethodParameters(e),requestContentType:(s=e.requestBody)==null?void 0:s.contentType,response:t,isResponseArray:t==null?void 0:t.typeReference.isArray,responseType:t==null?void 0:t.typeReference.getTypeName(),responseTypeDeclaration:t==null?void 0:t.typeReference.getTypeDeclaration(),responses:e.responses&&Object.entries(e.responses).map(([i,a])=>({statusCode:i,returnType:a==null?void 0:a.typeReference.getTypeDeclaration()}))};return this.templates.repositoryAction(r)}*getMethodParameters(e){for(const t of e.pathParams)yield`${t.name}: ${t.type.getTypeDeclaration()}`;e.queryParam&&(yield`query: ${e.queryParam.getTypeDeclaration()}`),e.requestBody&&(yield`payload: ${e.requestBody.typeReference.getTypeDeclaration()}`)}}function K(n){if(!n.responses)return;const e=Object.keys(n.responses).filter(t=>t>="200").sort()[0];return n.responses[e]}function xe(n){let e=n.path;for(const t of n.pathParams)e=e.replace(`{${t.externalName||t.name}}`,"${"+t.name+"}");return e}class Ne{constructor(e,t){this.parentDirectory=e,this.templates=t}write(e){const t=`${l.camelCase(e.name)}.ts`;if(!v.canOverwiteFile(this.parentDirectory,t))return;const r=this.parentDirectory.getSourceFile(t);return r?this.updateFile(r,e):this.createFile(t,e)}updateFile(e,t){var s;const r=(s=e.getFunction(`build${t.name}`))!=null?s:e.getTypeAlias(t.name);if(!r)throw new Error(`Could not find node to replace (type ${t.name}, or function build${t.name}) in file ${e.getFilePath()}`);return r.replaceWithText(this.getEnumContent(t)),e}createFile(e,t){const r=this.templates.stringLiteralEntityFile({content:()=>this.getEnumContent(t),enum:t});return this.parentDirectory.createSourceFile(e,r,{overwrite:!0})}getEnumContent(e){return this.templates.stringLiteralEntity(e)}}class Ae{constructor(e,t){this.parentDirectory=e,this.templates=t}write(e){const t=`${l.camelCase(e.name)}.ts`;if(!v.canOverwiteFile(this.parentDirectory,t))return;const r=this.parentDirectory.getSourceFile(t);return r?this.updateFile(r,e):this.createFile(t,e)}updateFile(e,t){var r;try{const s=(r=e.getFunction(`build${t.name}`))!=null?r:e.getTypeAlias(t.name);if(!s)throw new Error(`Could not find node to replace (type ${t.name}, or function build${t.name}) in file ${e.getFilePath()}`);return s.replaceWithText(this.getEntityContent(t)),e}catch(s){throw console.error(`Error while updating union type ${t.name} in file ${e.getFilePath()}.`),s}}createFile(e,t){const r=t.entities.filter(i=>i.isImportRequired).map(i=>i.getTypeName()).map(i=>this.templates.entityImport({entity:i,filePath:`./${l.camelCase(i)}`})),s=this.templates.unionEntityFile({importedEntities:r,content:()=>this.getEntityContent(t),entity:t});return this.parentDirectory.createSourceFile(e,s,{overwrite:!0})}getEntityContent(e){const t={name:e.name,subEntities:e.entities.map(r=>({type:r.getTypeDeclaration()||"UNKNOWN",typeName:r.getTypeName(),isArray:r.isArray,hasTypeImport:r.isImportRequired}))};return this.templates.unionEntity(t)}}class Ce{constructor(e,t,r){this.project=e,this.config=r,this.initTemplates()}initTemplates(){D.default.registerHelper({camelCase:e=>l.camelCase(e),pascalCase:e=>E(e),rawText:e=>e,and:(...e)=>Array.prototype.every.call(e,Boolean),or:(...e)=>Array.prototype.slice.call(e,0,-1).some(Boolean),eq:(e,t)=>e==t,ne:(e,t)=>e!=t,coalesce:(...e)=>Array.prototype.find.call(e,t=>!!t),inline:e=>e?e.replaceAll(/\r?\n/g," ").trim():""})}async generateEntities(e){if(!this.config.entitiesPath)return;const t=O("Generating entities"),r=Math.ceil(e.length*.1+1);t.start(1+e.length+r,0);const s={enumEntity:await this.readTemplate("enumEntity"),enumEntityFile:await this.readTemplate("enumEntityFile"),objectEntityContent:await this.readTemplate("objectEntityContent"),objectEntityFile:await this.readTemplate("objectEntityFile"),entityImport:await this.readTemplate("entityImport"),stringLiteralEntity:await this.readTemplate("stringLiteralEntity"),stringLiteralEntityFile:await this.readTemplate("stringLiteralEntityFile"),unionEntity:await this.readTemplate("unionEntity"),unionEntityFile:await this.readTemplate("unionEntityFile")};D.default.registerPartial("generatedEntityHeader",await this.readTemplate("generatedEntityHeader"));const i=this.project.createDirectory(this.config.entitiesPath),a=this.config.enums==="enum"?new Te(i,s):new Ne(i,s),o=new Pe(i,this.config,s),c=new Ae(i,s);t.increment(1);for(const{type:p}of e){if(p instanceof x)a.write(p);else if(p instanceof C){const f=p.baseEntities.map(g=>g.type).filter(g=>g instanceof b);o.write(p,f)}else p instanceof b?o.write(p):p instanceof q&&c.write(p);t.increment()}await this.project.save(),t.increment(r),t.stop()}async generateRepositories(e){if(!this.config.repositoriesPath)return;const t=Object.entries(l.groupBy(e,c=>c.repository)),r=O("Generating repositories"),s=Math.ceil(t.length*.1+1);r.start(1+t.length+s,0);const i={repositoryAction:await this.readTemplate("repositoryAction"),repositoryFile:await this.readTemplate("repositoryFile")},a=this.project.createDirectory(this.config.repositoriesPath),o=new De(a,{entitiesRelativePath:ue(this.config.repositoriesPath,this.config.entitiesPath)},i);r.increment(1);for(const[c,p]of t)o.write(c,p),r.increment();await this.project.save(),r.increment(s),r.stop()}async readTemplate(e){const t=this.config.templates[e];if(!t)return D.default.compile(`// missing template ${e}`);const r=this.getFullPath(t),s=await M.default.promises.readFile(r);return D.default.compile(s.toString())}getFullPath(e){var t;if(e.startsWith("@")){const r=__filename.endsWith(".ts")?"./templates/":"./openapi/templates/",s=$.default.join(r,(t=this.config.templatesFolder)!=null?t:".","/");return $.default.resolve(__dirname,e.replace("@",s))}else return $.default.resolve(process.cwd(),e)}}class qe{constructor(e){this.config=e}format(e){this.config.optionalAsNullable===!0&&e.type instanceof b&&this.formatEntity(e.type)}formatEntity(e){var t;for(const r of e.properties)((t=r.restrictions)==null?void 0:t.has(u.required))||r.addRestriction(u.nullable,!0)}}class J{constructor(e){this.aliases=e}formatNames(e){e.type instanceof b?this.formatEntity(e.type):e.type&&typeof e.type!="string"&&P(E,e.type)}formatEntity(e){var r;P(E,e);const t=(r=this.aliases)==null?void 0:r[e.name];t&&(e.name=t);for(const s of e.properties)P(l.camelCase,s)}static toPascalCase(e){P(E,e)}static toCamelCase(e){P(l.camelCase,e)}}function P(n,e){const t=n(e.name);t!==e.name&&(e.externalName=e.name,e.name=t)}class Ie extends U{constructor(e){super(typeof e=="object"?e:void 0),this.config=e}format(e){!this.config||e.type instanceof b&&this.formatEntity(e.type)}formatEntity(e){var r,s;const t=this.buildExcludeList(e.name);if(t!==!1)for(const i of e.properties){if(t.includes(i.name))continue;if(!(i.type.type instanceof w&&i.type.type.isArray))switch(i.type.getTypeName()){case"number":i.addRestriction(u.number,!0);break;case"Date":i.addRestriction(u.date,!0);break}((r=i.restrictions)==null?void 0:r.get(u.nullable))===!1&&!((s=i.restrictions)!=null&&s.has(u.required))&&i.addRestriction(u.required,!0),i.validations=i.restrictions}}}function Le(n){return n.swagger==="2.0"}function Be(n){var e;return!!((e=n.openapi)!=null&&e.startsWith("3"))}function S(n){return!!n.$ref}function I(n){return!!n.$ref}function Ve(n){return!!n.type}function _e(n){return!n.$ref}class L extends F{constructor(t,r){super(t);m(this,"description");m(this,"example");m(this,"restrictions");m(this,"validations");m(this,"tags");this.type=r}addRestriction(t,r){this.restrictions||(this.restrictions=new Map),this.restrictions.set(t,r)}addTag(t,r){this.tags||(this.tags=new Map),this.tags.set(t,r)}}class Q extends F{constructor(e,t){super(e),this.fullName=t}}class X{constructor(e){this.type=e}getTypeName(){var e,t;return typeof this.type=="string"?this.type:this.type instanceof w?this.type.referencedEntity.getTypeName():(t=(e=this.type)==null?void 0:e.name)!=null?t:"ERR_UnsetTypeReference"}getTypeDeclaration(){const e=this.getTypeName();return this.isArray?`${e}[]`:e}get isArray(){return this.type instanceof w&&this.type.isArray}get isImportRequired(){return this.type instanceof w?this.type.referencedEntity.isImportRequired:typeof this.type=="object"}}class Me{constructor(e){m(this,"types",new Map);m(this,"endpoints");this.apiDocument=e}parse(){if(this.apiDocument.definitions)for(const[e,t]of Object.entries(this.apiDocument.definitions)){const r=this.parseSchemaObject(e,t);I(t)&&this.setTypeReference(e,new w(e,r))}}parseSchemaObject(e,t){if(I(t))return this.parseReferenceObject(t);if(t.enum)return this.parseEnum(e,t);switch(t.type){case"array":{if(l.isArray(t.items))throw new Error("Multiple 'items' types in array are not supported yet.");if(!t.items)throw new Error("'Array' definition is missing 'items' property.");const r=`${e}Item`,s=this.parseSchemaObject(r,t.items),i=new w(e,s,!0);return this.setTypeReference(e,i)}case"object":return this.parseObject(e,t);case"string":switch(t.format){case"binary":return this.setTypeReference(e,"Blob");case"date":case"datetime":case"date-time":return this.setTypeReference(e,"Date");default:return this.setTypeReference(e,"string")}case"integer":case"number":return this.setTypeReference(e,"number");case"boolean":return this.setTypeReference(e,t.type)}if(t.oneOf||t.allOf)return this.parseObject(e,t);throw new Error(`Could not parse object '${e}'`)}parseReferenceObject(e){const t=We(e.$ref),r=Ge(e.$ref)?void 0:new Q(t,e.$ref);return this.setTypeReference(t,r)}parseEnum(e,t){const r=t.enum?new x(e,t.enum):void 0;return this.setTypeReference(e,r)}parseObject(e,t){return t.allOf?this.parseAllOfObject(e,t):t.oneOf?this.parseOneOfObject(e,t):this.parseObjectWithProperties(e,t)}parseAllOfObject(e,t){const r=t.allOf,s=r.filter(c=>!I(c)&&c.type==="object"&&!c.allOf&&!c.oneOf);t.properties&&s.push(t);const i=r.filter(c=>!s.includes(c)).map((c,p)=>this.parseSchemaObject(`${e}Parent${p+1}`,c)),a=s.flatMap(c=>this.extractObjectProperties(e,c)),o=new C(e,i,a);return s.forEach(c=>{var p;return(p=c.required)==null?void 0:p.forEach(f=>o.addPropertyRestriction(f,u.required,!0))}),this.setTypeReference(e,o)}parseOneOfObject(e,t){const s=t.oneOf.map((a,o)=>this.parseSchemaObject(`${e}Option${o+1}`,a)),i=new q(e,s);return this.setTypeReference(e,i)}parseObjectWithProperties(e,t){var i;const r=this.extractObjectProperties(e,t),s=new b(e,r);return(i=t.required)==null||i.forEach(a=>s.addPropertyRestriction(a,u.required,!0)),this.setTypeReference(e,s)}extractObjectProperties(e,t){return t.properties?Object.entries(t.properties).map(r=>this.parseEntityProperty(e,r[0],r[1])):[]}parseEntityProperty(e,t,r){const s=e+E(t),i=this.parseSchemaObject(s,r),a=new L(t,i);return _e(r)&&(a.description=r.description,a.example=r.example,r.maxLength&&a.addRestriction(u.maxLength,r.maxLength),r.minLength&&a.addRestriction(u.minLength,r.minLength),r.pattern&&a.addRestriction(u.pattern,r.pattern),r.format&&a.addRestriction(u.format,r.format)),a}setTypeReference(e,t){var i;const r=this.types.get(e);if(r)return r.type=(i=r.type)!=null?i:t,r;const s=new X(t);return this.types.set(e,s),s}}const B="#/definitions/";function We(n){const e=n.indexOf(B,0);return e>=0?n.substring(e+B.length):n}function Ge(n){return n.startsWith(B)}class ke extends F{constructor(t){super(t);m(this,"repository");m(this,"method");m(this,"path");m(this,"description");m(this,"pathParams");m(this,"queryParam");m(this,"requestBody");m(this,"responses")}}class Ue{constructor(e,t){m(this,"types",new Map);m(this,"endpoints");this.apiDocument=e,this.config=t}parse(){var e;if((e=this.apiDocument.components)!=null&&e.schemas)for(const[t,r]of Object.entries(this.apiDocument.components.schemas)){const s=this.parseSchemaObject(t,r);S(r)&&this.setTypeReference(t,new w(t,s))}this.parsePaths(this.apiDocument.paths)}parseSchemaObject(e,t){if(console.debug("Parsing object",e),S(t))return this.parseReferenceObject(t);if(t.enum)return this.parseEnum(e,t);switch(t.type){case"array":{const r=`${e}Item`,s=this.parseSchemaObject(r,t.items),i=new w(e,s,!0);return this.setTypeReference(e,i)}case"object":return this.parseObject(e,t);case"string":switch(t.format){case"binary":return this.setTypeReference(e,"Blob");case"date":case"datetime":case"date-time":return this.setTypeReference(e,"Date");default:return this.setTypeReference(e,"string")}case"integer":case"number":return this.setTypeReference(e,"number");case"boolean":return this.setTypeReference(e,t.type)}if(t.oneOf||t.anyOf||t.allOf)return this.parseObject(e,t);throw new Error(`Could not parse object '${e}'`)}parseReferenceObject(e){const t=ze(e.$ref),r=He(e.$ref)?void 0:new Q(t,e.$ref);return this.setTypeReference(t,r)}parseEnum(e,t){const r=t.enum?new x(e,t.enum):void 0;return this.setTypeReference(e,r)}parseObject(e,t){return t.allOf?this.parseAllOfObject(e,t):t.oneOf?this.parseOneOfObject(e,t):t.anyOf?(t.oneOf=t.anyOf,this.parseOneOfObject(e,t)):this.parseObjectWithProperties(e,t)}parseAllOfObject(e,t){const r=t.allOf,s=r.filter(c=>!S(c)&&c.type==="object"&&!c.allOf&&!c.oneOf);t.properties&&s.push(t);const i=r.filter(c=>!s.includes(c)).map((c,p)=>this.parseSchemaObject(`${e}Parent${p+1}`,c)),a=s.flatMap(c=>this.extractObjectProperties(e,c)),o=new C(e,i,a);return s.forEach(c=>{var p;return(p=c.required)==null?void 0:p.forEach(f=>o.addPropertyRestriction(f,u.required,!0))}),this.setTypeReference(e,o)}parseOneOfObject(e,t){const s=t.oneOf.map((a,o)=>this.parseSchemaObject(`${e}Option${o+1}`,a)),i=new q(e,s);return this.setTypeReference(e,i)}parseObjectWithProperties(e,t){var i;const r=this.extractObjectProperties(e,t),s=new b(e,r);return(i=t.required)==null||i.forEach(a=>s.addPropertyRestriction(a,u.required,!0)),this.setTypeReference(e,s)}extractObjectProperties(e,t){return t.properties?Object.entries(t.properties).map(r=>this.parseEntityProperty(e,r[0],r[1])):[]}parseEntityProperty(e,t,r){const s=e+E(t),i=this.parseSchemaObject(s,r),a=new L(t,i);return Ve(r)&&(a.description=r.description,a.example=r.example,r.maxLength&&a.addRestriction(u.maxLength,r.maxLength),r.minLength&&a.addRestriction(u.minLength,r.minLength),r.pattern&&a.addRestriction(u.pattern,r.pattern),r.nullable!==void 0&&a.addRestriction(u.nullable,r.nullable),r.readOnly&&a.addRestriction(u.readOnly,r.readOnly),r.format&&a.addRestriction(u.format,r.format)),a}setTypeReference(e,t){var i;const r=this.types.get(e);if(r)return r.type=(i=r.type)!=null?i:t,r;const s=new X(t);return this.types.set(e,s),s}parsePaths(e){this.endpoints=Object.entries(e).flatMap(([t,r])=>Object.entries(r!=null?r:{}).map(([s,i])=>({path:t,method:s.toLowerCase(),action:i}))).filter(t=>Ke(t.method)).map(t=>this.parseEndpoint(t))}parseEndpoint({path:e,method:t,action:r}){var c,p,f,g,Y,Z,ee,te,re;console.debug("Parsing endpoint",t,e),e=(c=this.config)!=null&&c.endpointUrlPrefix?e.replace(this.config.endpointUrlPrefix,""):e;const s=(p=r.operationId)!=null?p:l.camelCase(t+"-"+e.replace(/\{(\D*?)\}/,"By-$1")),i=new ke(s);i.path=e,i.method=t,i.repository=(g=(f=r.tags)==null?void 0:f[0])!=null?g:"General",i.description=(ee=(Y=r.description)==null?void 0:Y.trim())!=null?ee:(Z=r.summary)==null?void 0:Z.trim();const a=(re=(te=r.parameters)==null?void 0:te.filter(d=>!!d.schema))!=null?re:[];i.pathParams=a.filter(d=>d.in==="path").map(d=>{const N=this.parseEndpointParameter(s,d);return J.toCamelCase(N),N});const o=a.filter(d=>d.in==="query").map(d=>this.parseEndpointParameter(s,d));if(o.length){const d=new b(s+"Query",o);i.queryParam=this.setTypeReference(d.name,d)}return r.requestBody&&(i.requestBody=this.getRequestBodyType(s+"Request",r.requestBody)),i.responses={},r.responses&&Object.entries(r.responses).forEach(([d,N])=>{const Ze=this.getResponseBodyType(`${s}Response${d}`,N);i.responses[d]=Ze}),i}parseEndpointParameter(e,t){const r=this.parseSchemaObject(e,t.schema),s=new L(Je(t.name),r);return s.description=t.description,t.required&&s.addRestriction(u.required,!0),s}getRequestBodyType(e,t){var r,s;if(S(t)){const i=t.$ref.substr(t.$ref.lastIndexOf("/")+1),a=(s=(r=this.apiDocument.components)==null?void 0:r.requestBodies)==null?void 0:s[i];return a?this.getRequestBodyType(i,a):void 0}else{const i=Object.keys(t.content)[0],a=t.content[i].schema,o=a&&this.parseSchemaObject(e,a);return o?{contentType:i,typeReference:o}:void 0}}getResponseBodyType(e,t){var r,s,i;if(S(t)){const a=t.$ref.substr(t.$ref.lastIndexOf("/")+1),o=(s=(r=this.apiDocument.components)==null?void 0:r.responses)==null?void 0:s[a];return o?this.getResponseBodyType(a,o):void 0}else{if(!t.content)return;const a=Object.keys(t.content)[0],o=(i=t.content[a])==null?void 0:i.schema,c=o&&this.parseSchemaObject(e,o);return c?{contentType:a,typeReference:c}:void 0}}}const V="#/components/schemas/";function ze(n){const e=n.indexOf(V,0);return e>=0?n.substring(e+V.length):n}function He(n){return n.startsWith(V)}function Ke(n){switch(n){case"get":case"put":case"post":case"delete":case"option":case"head":case"patch":case"trace":return!0;default:return!1}}function Je(n){return n.endsWith("[]")?n.substring(0,n.length-2):n}class Qe{async process(e,t){const r=O("Analysing");r.start(2,0);const s=t!=null&&t.bundleReferences?await W.default.bundle(e):await W.default.parse(e);r.increment();const i=this.parseModel(s,t);return r.increment(),r.stop(),i}parseModel(e,t){if(Le(e)){const r=new Me(e);return r.parse(),r}if(Be(e)){const r=new Ue(e,t);return r.parse(),r}throw console.error("Unknown api format",e),new Error("Unknown api format")}}class Xe extends v{async run(){if(!this.config.api){console.warn("Api definition is missing");return}const e=new Qe,{types:t,endpoints:r}=await e.process(this.config.api,this.config),s=new J(this.config.aliases),i=new T(this.config.observable),a=new qe(this.config),o=this.config.validations&&Object.assign({},this.config.observable||void 0,this.config.validations),c=new Ie(o);t.forEach(f=>{s.formatNames(f),i.format(f),c.format(f),a.format(f)});const p=new Ce(this.project,this.params,this.config);await p.generateEntities(Array.from(t.values())),await p.generateRepositories(r)}getDefaultConfig(){return Promise.resolve(je)}}const Ye=Object.freeze(Object.defineProperty({__proto__:null,default:Xe},Symbol.toStringTag,{value:"Module"}))});
(function(h,l){typeof exports=="object"&&typeof module<"u"?l(require("commander"),require("lodash"),require("ts-morph"),require("fs"),require("path"),require("cli-progress"),require("handlebars"),require("@apidevtools/swagger-parser")):typeof define=="function"&&define.amd?define(["commander","lodash","ts-morph","fs","path","cli-progress","handlebars","@apidevtools/swagger-parser"],l):(h=typeof globalThis<"u"?globalThis:h||self,l(h.commander,h.lodash,h.tsMorph,h.fs,h.path,h.cliProgress,h.Handlebars,h.SwaggerParser))})(this,function(h,l,y,M,R,Y,$,W){"use strict";var Ue=Object.defineProperty;var ze=(h,l,y)=>l in h?Ue(h,l,{enumerable:!0,configurable:!0,writable:!0,value:y}):h[l]=y;var f=(h,l,y)=>(ze(h,typeof l!="symbol"?l+"":l,y),y);const Z="999.0.0",ee="Frui.ts code generator";h.program.name("fruits-generate").version(Z).description(ee),h.program.command("inversify").description("Generate Inversify configuration files").option("-p, --project <fileName>","TS project file","./tsconfig.json").option("-c, --config <fileName>","Custom configuration file").option("-d, --debug","Output extra debugging").option("--no-decorators","Do not generate decorators file").option("--decorators-output <relativePath>","Decorators output file path","src/di.decorators.ts").option("--no-registry","Do not generate registry file").option("--registry-output <relativePath>","Registry output file path","src/di.registry.ts").action(async i=>{const e={project:i.project,config:i.config,debug:i.debug};console.log("Processing",e.config),i.decorators&&(e.decorators={output:i.decoratorsOutput}),i.registry&&(e.registry={output:i.registryOutput});const t=await Promise.resolve().then(()=>pe),r=new t.default(e);await r.init(),await r.run()}),h.program.command("views").description("Generate view registrations").option("-p, --project <fileName>","TS project file","./tsconfig.json").option("-c, --config <fileName>","Custom configuration file").option("-d, --debug","Output extra debugging").option("-o, --output <relativePath>","Output file path","src/views/index.ts").action(async i=>{const e={project:i.project,config:i.config,output:i.output,debug:i.debug};console.log("Processing",e.config);const t=await Promise.resolve().then(()=>he),r=new t.default(e);await r.init(),await r.run()}),h.program.command("openapi").alias("swagger").description("Generate OpenAPI client files").option("-p, --project <fileName>","TS project file","./tsconfig.json").option("-c, --config <fileName>","Custom configuration file").option("-d, --debug","Output extra debugging").action(async i=>{const e={project:i.project,config:i.config,debug:i.debug};console.log("Processing",e.config);const t=await Promise.resolve().then(()=>_e),r=new t.default(e);await r.init(),await r.run()}),h.program.parseAsync().catch(i=>{console.error(i)});function w(i){return l.upperFirst(l.camelCase(i))}async function te(i){const e=R.join(process.cwd(),i),t=await M.promises.readFile(e,"utf8");return JSON.parse(t)}function re(i,e){if(i===e)return"./";const t=i.split("/"),r=e.split("/");let s=0;for(;t[s]===r[s]&&s<t.length&&s<r.length;)s++;return[...new Array(t.length-s).fill(".."),...r.slice(s-r.length)].join("/")}const se="// WARNING: This file has been generated. Do not edit it manually, your changes might get lost.";function ie(i,e){return{format:`${i.padEnd(e)} [{bar}] {percentage}% | ETA: {eta}s | {value}/{total}`}}function F(i,e=0){return new Y.SingleBar(ie(i,e))}class E{constructor(e){f(this,"project");f(this,"config");this.params=e}async init(){const e=F("Parsing");e.start(2,0),this.project=new y.Project({tsConfigFilePath:this.params.project,manipulationSettings:{indentationText:y.IndentationText.TwoSpaces}}),e.increment(),this.params.debug&&this.logDiagnostics();const t=await this.getDefaultConfig();if(this.params.config){const r=await te(this.params.config);this.config=Object.assign({},t,r)}else this.config=t;e.increment(),e.stop()}async saveFile(e){this.writeGeneratedHeader(e),e.organizeImports(),e.formatText(),await e.save()}static canOverwiteFile(e,t){var s;const r=e.getSourceFile(t);return!((s=r==null?void 0:r.getStatementByKind(y.ts.SyntaxKind.SingleLineCommentTrivia|y.ts.SyntaxKind.MultiLineCommentTrivia))!=null&&s.getText().includes("generator:ignore"))}writeGeneratedHeader(e){e.insertText(0,t=>t.writeLine(se))}getDiagnostics(){return this.project.getPreEmitDiagnostics().map(t=>({message:t.getMessageText(),source:t.getSource(),lineNumber:t.getLineNumber(),code:t.getCode(),category:t.getCategory}))}logDiagnostics(){for(const e of this.getDiagnostics())console.warn(e)}}const ne={factoryName:"Factory",rules:[{pattern:"Service$",identifier:"$class",addDecorators:!0,registerAutoFactory:!1,scope:"singleton"},{pattern:"ViewModel$",identifier:"$class",addDecorators:!0,registerAutoFactory:!1,scope:"transient"},{pattern:"Repository$",identifier:"$class",addDecorators:!0,registerAutoFactory:!1,scope:"transient"}]};class oe{analyze(e,t){const r=[];return e.getSourceFiles().forEach(s=>{s.getExportedDeclarations().forEach((n,o)=>{const a=n[0];if(a instanceof y.ClassDeclaration&&!a.isAbstract()){const c=a.getName();if(c){const p=t.find(m=>m.regexPattern.test(c));p&&r.push({declaration:a,rule:p})}}})}),l.uniqBy(r,s=>s.declaration)}}function O(i,e){const t=i.getSourceFile(),r=e.getRelativePathAsModuleSpecifierTo(t);if(i.isDefaultExport()){const s=l.camelCase(r);return{identifier:s,declaration:{defaultImport:s,moduleSpecifier:r}}}else{const s=l.camelCase(r)+(i.getName()??""),n={namedImports:[{name:i.getNameOrThrow(),alias:s}],moduleSpecifier:r};return{identifier:s,declaration:n}}}function N(i){let e=i.getSymbol()??i.getAliasSymbol();if(i.isUnion()){const t=i.getUnionTypes();for(const r of t)if(e=r.getSymbol()??r.getAliasSymbol(),e)break}return e&&(e.getValueDeclaration()||e.getDeclarations()[0])}class ae{constructor(e,t,r){f(this,"decorators");f(this,"registrations");this.decoratorsFile=e,this.registrationFile=t,this.factoryName=r}process(e){return this.decorators=[],this.registrations=[],e.forEach(t=>this.processService(t)),{decorators:this.decorators,registrations:this.registrations}}processService(e){e.rule.addDecorators&&this.decorateServiceInjectable(e.declaration),e.rule.scope!=="none"&&this.registerService(e)}decorateServiceInjectable(e){const t=O(e,this.decoratorsFile);this.decorators.push({importStatements:[t.declaration],statements:[`decorate(injectable(), ${t.identifier});`]})}registerService({declaration:e,rule:t}){const r=e.getStaticMethod(this.factoryName);if(r)this.registerServiceFactory(e,t,r);else{const s=G(e);this.registerConstructor(e,t,s)}}registerServiceFactory(e,t,r){const s=O(e,this.registrationFile),n=`${s.identifier}.${r.getName()}`,o=t.identifier===void 0||t.identifier==="$class"?n:t.identifier;this.registrations.push({importStatements:[s.declaration],statements:["container",`.bind<interfaces.Factory<${s.identifier}>>(${o})`,`.toFactory(${n});`]})}registerConstructor(e,t,r){const s=O(e,this.registrationFile);let n,o;switch(t.identifier){case void 0:case"$class":n=s.identifier,o="toSelf()";break;case"$interface":{const a=e.getImplements()[0];n=a?`"${a.getText()}"`:"NoInterfaceImplemented",o=`to(${s.identifier})`;break}default:n=`"${t.identifier}"`,o=`to(${s.identifier})`;break}t.scope==="singleton"&&(o+=".inSingletonScope()"),this.registrations.push({importStatements:[s.declaration],statements:[`container.bind<${s.identifier}>(${n}).${o};`]}),t.registerAutoFactory&&this.registrations.push({importStatements:[],statements:[`container.bind("Factory<${e.getName()??""}>").toAutoFactory(${n});`]}),r&&this.decorateConstructorParameterInject(e,r)}decorateConstructorParameterInject(e,t){const r=O(e,this.decoratorsFile);this.decorators.push({importStatements:[r.declaration],statements:[]});const s=t.getParameters();for(let n=0;n<s.length;n++){let a=s[n].getType(),c=!1;a.isArray()&&(a=a.getArrayElementTypeOrThrow(),c=!0);const p=N(a);if(p){const m=this.getConstructorParameterDecorator(r.identifier,n,p,c);m&&this.decorators.push(m)}}}getConstructorParameterDecorator(e,t,r,s){const n=s?"multiInject":"inject";if(r instanceof y.ClassDeclaration){const o=O(r,this.decoratorsFile);return{importStatements:[o.declaration],statements:[`decorate(${n}(${o.identifier}) as any, ${e}, ${t});`]}}if(r instanceof y.InterfaceDeclaration)return{importStatements:[],statements:[`decorate(${n}("${r.getName()}") as any, ${e}, ${t});`]};if(r instanceof y.FunctionTypeNode){const o=N(r.getReturnType());if(o instanceof y.ClassDeclaration||o instanceof y.InterfaceDeclaration)return{importStatements:[],statements:[`decorate(${n}("Factory<${o.getName()??""}>") as any, ${e}, ${t});`]}}if(r instanceof y.ArrowFunction){const o=N(r.getReturnType());if(o instanceof y.ClassDeclaration){const a=this.factoryName&&o.getStaticMethod(this.factoryName);if(a){const c=O(o,this.decoratorsFile);return{importStatements:[c.declaration],statements:[`decorate(${n}(${c.identifier}.${a.getName()}) as any, ${e}, ${t});`]}}}}}}function G(i){const e=i.getConstructors()[0];if(e)return e;const t=i.getBaseClass();return t?G(t):void 0}class ce extends E{constructor(){super(...arguments);f(this,"decoratorsFile");f(this,"registryFile");f(this,"registrationFunction")}async run(){const t=F("Generating");t.start(4,0);const r=this.parseRules(),s=new oe().analyze(this.project,r);t.increment();const n=new ae(this.ensureDecoratorsFile(),this.ensureRegistryFile(),this.config.factoryName??"Factory"),{decorators:o,registrations:a}=n.process(s);if(t.increment(),o.length){const c=o.flatMap(m=>m.importStatements);this.decoratorsFile.addImportDeclarations(c);const p=o.flatMap(m=>m.statements);this.decoratorsFile.addStatements(p),await this.saveFile(this.decoratorsFile)}if(t.increment(),a.length){const c=a.flatMap(m=>m.importStatements);this.registryFile.addImportDeclarations(c);const p=a.flatMap(m=>m.statements);this.registrationFunction.addStatements(p),await this.saveFile(this.registryFile)}t.increment(),t.stop()}getDefaultConfig(){return Promise.resolve(ne)}ensureDecoratorsFile(){var t;return!this.decoratorsFile&&((t=this.params.decorators)!=null&&t.output)&&(this.decoratorsFile=this.project.createSourceFile(this.params.decorators.output,void 0,{overwrite:!0}),this.decoratorsFile.addImportDeclaration({namedImports:["decorate","inject","injectable","multiInject"],moduleSpecifier:"inversify"})),this.decoratorsFile}ensureRegistryFile(){var t;return!this.registryFile&&((t=this.params.registry)!=null&&t.output)&&(this.registryFile=this.project.createSourceFile(this.params.registry.output,void 0,{overwrite:!0}),this.registryFile.addImportDeclaration({namedImports:["Container","interfaces"],moduleSpecifier:"inversify"}),this.registrationFunction=this.registryFile.addFunction({isDefaultExport:!0,name:"registerServices",parameters:[{name:"container",type:"Container"}]})),this.registryFile}parseRules(){var t;return((t=this.config.rules)==null?void 0:t.map(r=>({...r,regexPattern:new RegExp(r.pattern)})))??[]}}const pe=Object.freeze(Object.defineProperty({__proto__:null,default:ce},Symbol.toStringTag,{value:"Module"})),le={viewsPattern:"**/views/**/*.tsx"};class ue{analyze(e,t){const r=[];return e.getSourceFiles(t).forEach(s=>{s.getImportDeclarations().some(o=>o.getNamedImports().some(a=>a.getName()==="registerView"||a.getName()==="registerViewComponent"))&&r.push(s)}),r}}class me{constructor(e){this.targetFile=e}process(e){return{importStatements:e.map(s=>this.targetFile.getRelativePathAsModuleSpecifierTo(s)).map(s=>({moduleSpecifier:s})),statements:[]}}}class fe extends E{constructor(){super(...arguments);f(this,"viewsFile")}async run(){const t=F("Generating");t.start(5,0);const r=new ue().analyze(this.project,this.config.viewsPattern);t.increment();const n=new me(this.ensureViewsFile()).process(r);t.increment(),this.viewsFile.addImportDeclarations(n.importStatements),t.increment(),this.viewsFile.addStatements(n.statements),t.increment(),await this.saveFile(this.viewsFile),t.increment(),t.stop()}ensureViewsFile(){return!this.viewsFile&&this.params.output&&(this.viewsFile=this.project.createSourceFile(this.params.output,void 0,{overwrite:!0})),this.viewsFile}getDefaultConfig(){return Promise.resolve(le)}}const he=Object.freeze(Object.defineProperty({__proto__:null,default:fe},Symbol.toStringTag,{value:"Module"})),ye={api:"https://fruits-demo.herokuapp.com/api/swagger-json",entitiesPath:"src/entities",repositoriesPath:"src/repositories",conversion:!0,observable:{entities:{EnumValue:!1,User:{exclude:["code"]},Partner:{include:["name"]}},properties:{exclude:["id","created"]}},enums:"enum",dates:"native",validations:{rules:{readOnly:!1}},endpointUrlPrefix:"/api/",templatesFolder:"class-transformer",templates:{enumEntity:"@enumEntity.hbs",enumEntityFile:"@enumEntityFile.hbs",objectEntityContent:"@objectEntityContent.hbs",objectEntityFile:"@objectEntityFile.hbs",entityImport:"@entityImport.hbs",generatedEntityHeader:"@generatedEntityHeader.hbs",repositoryAction:"@repositoryAction.hbs",repositoryFile:"@repositoryFile.hbs",stringLiteralEntity:"@stringLiteralEntity.hbs",stringLiteralEntityFile:"@stringLiteralEntityFile.hbs",unionEntity:"@unionEntity.hbs",unionEntityFile:"@unionEntityFile.hbs"},optionalAsNullable:!1};class v{constructor(e){f(this,"externalName");this.name=e}}class x extends v{constructor(e,t){super(e),this.items=t}}class g extends v{constructor(e,t){super(e),this.properties=t}addPropertyRestriction(e,t,r){var s;(s=this.properties.find(n=>n.name===e))==null||s.addRestriction(t,r)}}class A extends g{constructor(e,t,r){super(e,r),this.baseEntities=t}}class C extends v{constructor(e,t){super(e),this.entities=t}}class de{constructor(e,t){this.parentDirectory=e,this.templates=t}write(e){const t=`${l.camelCase(e.name)}.ts`;if(!E.canOverwiteFile(this.parentDirectory,t))return;const r=this.parentDirectory.getSourceFile(t);return r?this.updateFile(r,e):this.createFile(t,e)}updateFile(e,t){const r=e.getFunction(`build${t.name}`)??e.getEnum(t.name);if(!r)throw new Error(`Could not find node to replace (enum ${t.name}, or function build${t.name}) in file ${e.getFilePath()}`);return r.replaceWithText(this.getEnumContent(t)),e}createFile(e,t){const r=this.templates.enumEntityFile({content:()=>this.getEnumContent(t),enum:t});return this.parentDirectory.createSourceFile(e,r,{overwrite:!0})}getEnumContent(e){return this.templates.enumEntity(e)}}var _=(i=>(i[i.required=0]="required",i[i.number=1]="number",i[i.date=2]="date",i[i.maxLength=3]="maxLength",i[i.minLength=4]="minLength",i[i.pattern=5]="pattern",i[i.nullable=6]="nullable",i[i.readOnly=7]="readOnly",i[i.format=8]="format",i))(_||{});const u=_;class k{constructor(e){f(this,"globalExcludedProperties");var t;this.excludeConfig=e,this.globalExcludedProperties=((t=e==null?void 0:e.properties)==null?void 0:t.exclude)??[]}buildExcludeList(e){var r,s;const t=(s=(r=this.excludeConfig)==null?void 0:r.entities)==null?void 0:s[e];return t===!1?!1:typeof t=="object"&&t.exclude?this.globalExcludedProperties.concat(t.exclude):this.globalExcludedProperties}}const V=class extends k{constructor(e){super(typeof e=="object"?e:void 0),this.config=e}format(e){this.config&&e.type instanceof g&&this.formatEntity(e.type)}formatEntity(e){var r;const t=this.buildExcludeList(e.name);if(t!==!1)for(const s of e.properties){const n=t.includes(s.name),o=(r=s.restrictions)==null?void 0:r.has(u.readOnly);!n&&!o&&s.addTag(V.OBSERVABLE,!0)}}};let T=V;f(T,"OBSERVABLE",Symbol("observable"));class b extends v{constructor(e,t,r=!1){super(e),this.referencedEntity=t,this.isArray=r}}class ge{constructor(e,t,r){this.parentDirectory=e,this.config=t,this.templates=r}write(e,t){const r=`${l.camelCase(e.name)}.ts`;if(!E.canOverwiteFile(this.parentDirectory,r))return;const s=this.parentDirectory.getSourceFile(r);return s?this.updateFile(s,e,t):this.createFile(r,e,t)}updateFile(e,t,r){const s=e.getClass(t.name);if(s){s.removeText(),s.insertText(s.getEnd()-1,a=>{a.newLineIfLastNot(),a.write(this.getEntityContent(t,r))});const o=r==null?void 0:r[0];return o&&s.setExtends(o.name),e}const n=e.getFunction(`build${t.name}`);return n&&(n.removeText(),n.insertText(n.getEnd()-1,o=>{o.newLineIfLastNot(),o.write(this.getEntityContent(t,r))})),e}createFile(e,t,r){const s=t.properties.filter(a=>a.type.isImportRequired).map(a=>a.type.getTypeName());r==null||r.forEach(a=>s.push(a.name));const n=l.uniq(s).sort().map(a=>this.templates.entityImport({entity:a,filePath:`./${l.camelCase(a)}`})),o=this.templates.objectEntityFile({imports:n,content:()=>this.getEntityContent(t,r),entity:t,baseClasses:r});return this.parentDirectory.createSourceFile(e,o,{overwrite:!0})}getEntityContent(e,t){const r={entity:e,baseClasses:t,properties:e.properties.map(s=>{var o,a,c,p,m;const n=(o=s.restrictions)==null?void 0:o.get(u.nullable);return{name:s.name,externalName:this.config.conversion!==!1&&s.externalName,type:s.type.getTypeDeclaration()||"UNKNOWN",typeName:s.type.getTypeName(),isArray:s.type.isArray,hasTypeImport:s.type.isImportRequired,description:s.description,example:s.example,isObservable:(a=s.tags)==null?void 0:a.get(T.OBSERVABLE),conversions:this.config.conversion!==!1&&this.getPropertyTypeConversions(s),readonly:(c=s.restrictions)==null?void 0:c.has(u.readOnly),nullable:n,required:n!==!0&&((p=s.restrictions)==null?void 0:p.has(u.required)),format:(m=s.restrictions)==null?void 0:m.get(u.format),validations:this.getPropertyValidations(s),rawValidations:this.getRawPropertyValidations(s)}}),validationEntity:this.config.validations!==!1&&U(e)&&{},useBaseClassValidation:!!(t!=null&&t.some(s=>U(s)))};return this.templates.objectEntityContent(r)}*getPropertyTypeConversions(e){var r;let t=e.type.type;t instanceof b&&(t=t.referencedEntity.type),!(t instanceof x)&&(typeof t=="object"&&(yield`@Type(() => ${e.type.getTypeName()})`),t==="Date"&&(this.config.dates==="date-fns"?(yield"@Transform(value => (value ? new Date(value) : undefined), { toClassOnly: true })",((r=e.restrictions)==null?void 0:r.get(u.format))==="date"?yield'@Transform(value => (value ? formatISO(value, { representation: "date" }) : undefined), { toPlainOnly: true })':yield"@Transform(value => (value ? formatISO(value) : undefined), { toPlainOnly: true })"):yield"@Type(() => Date)"))}getPropertyValidations(e){var t;if((t=e.validations)!=null&&t.size){const r=[];return e.validations.forEach((s,n)=>{const o=this.getValidationDefinition(n,s);o&&!r.includes(o)&&r.push(o)}),r}}getRawPropertyValidations(e){if(e.validations){const t=Array.from(e.validations.entries()).filter(r=>!!r[1]).map(r=>[u[r[0]],r[1]]);return Object.fromEntries(t)}}getValidationDefinition(e,t){var a;const r=u[e],s=typeof this.config.validations=="object"?(a=this.config.validations.rules)==null?void 0:a[r]:void 0;if(s===!1)return;const n=JSON.stringify(t);return Ee(s,n)?`${be(s)??r}: ${n}`:void 0}}function U(i){return i.properties.some(e=>{var t;return(t=e.restrictions)==null?void 0:t.size})}function be(i){if(typeof i=="string")return i;if(typeof i=="object")return i.name}const z=new Map;function we(i){const e=z.get(i);if(e)return e;const t=new RegExp(i);return z.set(i,t),t}function Ee(i,e){return typeof i=="object"&&i.filter?!!we(i.filter).exec(e):!0}class ve{constructor(e,t,r){this.parentDirectory=e,this.config=t,this.templates=r}write(e,t){const r=`${w(e)}Repository`,s=`${l.camelCase(r)}.ts`;if(!E.canOverwiteFile(this.parentDirectory,s))return;const n=this.parentDirectory.getSourceFile(s);return n?this.updateFile(n,r,t):this.createFile(s,r,t)}updateFile(e,t,r){const s=e.getClassOrThrow(w(t));for(const n of r)s.getMethod(l.camelCase(n.name))||s.addMember(this.getActionContent(n));return e}createFile(e,t,r){const s=this.templates.repositoryFile({repositoryName:t,imports:this.getRequiredImports(r),actions:()=>r.map(n=>this.getActionContent(n))});return this.parentDirectory.createSourceFile(e,s,{overwrite:!0})}getRequiredImports(e){return l.uniq(e.flatMap(t=>{var r,s;return[t.queryParam,(r=t.requestBody)==null?void 0:r.typeReference,(s=H(t))==null?void 0:s.typeReference]}).filter(t=>!!t&&t.isImportRequired)).map(t=>{const r=t.getTypeName();return`import ${r} from "${this.config.entitiesRelativePath}/${l.camelCase(r)}";`})}getActionContent(e){var s;const t=H(e),r={action:e,path:Fe(e),parameters:this.getMethodParameters(e),requestContentType:(s=e.requestBody)==null?void 0:s.contentType,response:t,isResponseArray:t==null?void 0:t.typeReference.isArray,responseType:t==null?void 0:t.typeReference.getTypeName(),responseTypeDeclaration:t==null?void 0:t.typeReference.getTypeDeclaration(),responses:e.responses&&Object.entries(e.responses).map(([n,o])=>({statusCode:n,returnType:o==null?void 0:o.typeReference.getTypeDeclaration()}))};return this.templates.repositoryAction(r)}*getMethodParameters(e){for(const t of e.pathParams)yield`${t.name}: ${t.type.getTypeDeclaration()}`;e.queryParam&&(yield`query: ${e.queryParam.getTypeDeclaration()}`),e.requestBody&&(yield`payload: ${e.requestBody.typeReference.getTypeDeclaration()}`)}}function H(i){if(!i.responses)return;const e=Object.keys(i.responses).filter(t=>t>="200").sort()[0];return i.responses[e]}function Fe(i){let e=i.path;for(const t of i.pathParams)e=e.replace(`{${t.externalName||t.name}}`,"${"+t.name+"}");return e}class Oe{constructor(e,t){this.parentDirectory=e,this.templates=t}write(e){const t=`${l.camelCase(e.name)}.ts`;if(!E.canOverwiteFile(this.parentDirectory,t))return;const r=this.parentDirectory.getSourceFile(t);return r?this.updateFile(r,e):this.createFile(t,e)}updateFile(e,t){const r=e.getFunction(`build${t.name}`)??e.getTypeAlias(t.name);if(!r)throw new Error(`Could not find node to replace (type ${t.name}, or function build${t.name}) in file ${e.getFilePath()}`);return r.replaceWithText(this.getEnumContent(t)),e}createFile(e,t){const r=this.templates.stringLiteralEntityFile({content:()=>this.getEnumContent(t),enum:t});return this.parentDirectory.createSourceFile(e,r,{overwrite:!0})}getEnumContent(e){return this.templates.stringLiteralEntity(e)}}class je{constructor(e,t){this.parentDirectory=e,this.templates=t}write(e){const t=`${l.camelCase(e.name)}.ts`;if(!E.canOverwiteFile(this.parentDirectory,t))return;const r=this.parentDirectory.getSourceFile(t);return r?this.updateFile(r,e):this.createFile(t,e)}updateFile(e,t){try{const r=e.getFunction(`build${t.name}`)??e.getTypeAlias(t.name);if(!r)throw new Error(`Could not find node to replace (type ${t.name}, or function build${t.name}) in file ${e.getFilePath()}`);return r.replaceWithText(this.getEntityContent(t)),e}catch(r){throw console.error(`Error while updating union type ${t.name} in file ${e.getFilePath()}.`),r}}createFile(e,t){const r=t.entities.filter(n=>n.isImportRequired).map(n=>n.getTypeName()).map(n=>this.templates.entityImport({entity:n,filePath:`./${l.camelCase(n)}`})),s=this.templates.unionEntityFile({importedEntities:r,content:()=>this.getEntityContent(t),entity:t});return this.parentDirectory.createSourceFile(e,s,{overwrite:!0})}getEntityContent(e){const t={name:e.name,subEntities:e.entities.map(r=>({type:r.getTypeDeclaration()||"UNKNOWN",typeName:r.getTypeName(),isArray:r.isArray,hasTypeImport:r.isImportRequired}))};return this.templates.unionEntity(t)}}class Te{constructor(e,t,r){this.project=e,this.config=r,this.initTemplates()}initTemplates(){$.registerHelper({camelCase:e=>l.camelCase(e),pascalCase:e=>w(e),rawText:e=>e,and:(...e)=>Array.prototype.every.call(e,Boolean),or:(...e)=>Array.prototype.slice.call(e,0,-1).some(Boolean),eq:(e,t)=>e==t,ne:(e,t)=>e!=t,coalesce:(...e)=>Array.prototype.find.call(e,t=>!!t),inline:e=>e?e.replaceAll(/\r?\n/g," ").trim():""})}async generateEntities(e){if(!this.config.entitiesPath)return;const t=F("Generating entities"),r=Math.ceil(e.length*.1+1);t.start(1+e.length+r,0);const s={enumEntity:await this.readTemplate("enumEntity"),enumEntityFile:await this.readTemplate("enumEntityFile"),objectEntityContent:await this.readTemplate("objectEntityContent"),objectEntityFile:await this.readTemplate("objectEntityFile"),entityImport:await this.readTemplate("entityImport"),stringLiteralEntity:await this.readTemplate("stringLiteralEntity"),stringLiteralEntityFile:await this.readTemplate("stringLiteralEntityFile"),unionEntity:await this.readTemplate("unionEntity"),unionEntityFile:await this.readTemplate("unionEntityFile")};$.registerPartial("generatedEntityHeader",await this.readTemplate("generatedEntityHeader"));const n=this.project.createDirectory(this.config.entitiesPath),o=this.config.enums==="enum"?new de(n,s):new Oe(n,s),a=new ge(n,this.config,s),c=new je(n,s);t.increment(1);for(const{type:p}of e){if(p instanceof x)o.write(p);else if(p instanceof A){const m=p.baseEntities.map(j=>j.type).filter(j=>j instanceof g);a.write(p,m)}else p instanceof g?a.write(p):p instanceof C&&c.write(p);t.increment()}await this.project.save(),t.increment(r),t.stop()}async generateRepositories(e){if(!this.config.repositoriesPath)return;const t=Object.entries(l.groupBy(e,c=>c.repository)),r=F("Generating repositories"),s=Math.ceil(t.length*.1+1);r.start(1+t.length+s,0);const n={repositoryAction:await this.readTemplate("repositoryAction"),repositoryFile:await this.readTemplate("repositoryFile")},o=this.project.createDirectory(this.config.repositoriesPath),a=new ve(o,{entitiesRelativePath:re(this.config.repositoriesPath,this.config.entitiesPath)},n);r.increment(1);for(const[c,p]of t)a.write(c,p),r.increment();await this.project.save(),r.increment(s),r.stop()}async readTemplate(e){const t=this.config.templates[e];if(!t)return $.compile(`// missing template ${e}`);const r=this.getFullPath(t),s=await M.promises.readFile(r);return $.compile(s.toString())}getFullPath(e){if(e.startsWith("@")){const t=__filename.endsWith(".ts")?"./templates/":"./openapi/templates/",r=R.join(t,this.config.templatesFolder??".","/");return R.resolve(__dirname,e.replace("@",r))}else return R.resolve(process.cwd(),e)}}class Pe{constructor(e){this.config=e}format(e){this.config.optionalAsNullable===!0&&e.type instanceof g&&this.formatEntity(e.type)}formatEntity(e){var t;for(const r of e.properties)((t=r.restrictions)==null?void 0:t.has(u.required))||r.addRestriction(u.nullable,!0)}}class K{constructor(e){this.aliases=e}formatNames(e){e.type instanceof g?this.formatEntity(e.type):e.type&&typeof e.type!="string"&&P(w,e.type)}formatEntity(e){var r;P(w,e);const t=(r=this.aliases)==null?void 0:r[e.name];t&&(e.name=t);for(const s of e.properties)P(l.camelCase,s)}static toPascalCase(e){P(w,e)}static toCamelCase(e){P(l.camelCase,e)}}function P(i,e){const t=i(e.name);t!==e.name&&(e.externalName=e.name,e.name=t)}class Se extends k{constructor(e){super(typeof e=="object"?e:void 0),this.config=e}format(e){this.config&&e.type instanceof g&&this.formatEntity(e.type)}formatEntity(e){var r,s;const t=this.buildExcludeList(e.name);if(t!==!1)for(const n of e.properties){if(t.includes(n.name))continue;if(!(n.type.type instanceof b&&n.type.type.isArray))switch(n.type.getTypeName()){case"number":n.addRestriction(u.number,!0);break;case"Date":n.addRestriction(u.date,!0);break}((r=n.restrictions)==null?void 0:r.get(u.nullable))===!1&&!((s=n.restrictions)!=null&&s.has(u.required))&&n.addRestriction(u.required,!0),n.validations=n.restrictions}}}function Re(i){return i.swagger==="2.0"}function $e(i){var e;return!!((e=i.openapi)!=null&&e.startsWith("3"))}function S(i){return!!i.$ref}function q(i){return!!i.$ref}function xe(i){return!!i.type}function De(i){return!i.$ref}class I extends v{constructor(t,r){super(t);f(this,"description");f(this,"example");f(this,"restrictions");f(this,"validations");f(this,"tags");this.type=r}addRestriction(t,r){this.restrictions||(this.restrictions=new Map),this.restrictions.set(t,r)}addTag(t,r){this.tags||(this.tags=new Map),this.tags.set(t,r)}}class J extends v{constructor(e,t){super(e),this.fullName=t}}class Q{constructor(e){this.type=e}getTypeName(){var e;return typeof this.type=="string"?this.type:this.type instanceof b?this.type.referencedEntity.getTypeName():((e=this.type)==null?void 0:e.name)??"ERR_UnsetTypeReference"}getTypeDeclaration(){const e=this.getTypeName();return this.isArray?`${e}[]`:e}get isArray(){return this.type instanceof b&&this.type.isArray}get isImportRequired(){return this.type instanceof b?this.type.referencedEntity.isImportRequired:typeof this.type=="object"}}class Ne{constructor(e){f(this,"types",new Map);f(this,"endpoints");this.apiDocument=e}parse(){if(this.apiDocument.definitions)for(const[e,t]of Object.entries(this.apiDocument.definitions)){const r=this.parseSchemaObject(e,t);q(t)&&this.setTypeReference(e,new b(e,r))}}parseSchemaObject(e,t){if(q(t))return this.parseReferenceObject(t);if(t.enum)return this.parseEnum(e,t);switch(t.type){case"array":{if(l.isArray(t.items))throw new Error("Multiple 'items' types in array are not supported yet.");if(!t.items)throw new Error("'Array' definition is missing 'items' property.");const r=`${e}Item`,s=this.parseSchemaObject(r,t.items),n=new b(e,s,!0);return this.setTypeReference(e,n)}case"object":return this.parseObject(e,t);case"string":switch(t.format){case"binary":return this.setTypeReference(e,"Blob");case"date":case"datetime":case"date-time":return this.setTypeReference(e,"Date");default:return this.setTypeReference(e,"string")}case"integer":case"number":return this.setTypeReference(e,"number");case"boolean":return this.setTypeReference(e,t.type)}if(t.oneOf||t.allOf)return this.parseObject(e,t);throw new Error(`Could not parse object '${e}'`)}parseReferenceObject(e){const t=Ae(e.$ref),r=Ce(e.$ref)?void 0:new J(t,e.$ref);return this.setTypeReference(t,r)}parseEnum(e,t){const r=t.enum?new x(e,t.enum):void 0;return this.setTypeReference(e,r)}parseObject(e,t){return t.allOf?this.parseAllOfObject(e,t):t.oneOf?this.parseOneOfObject(e,t):this.parseObjectWithProperties(e,t)}parseAllOfObject(e,t){const r=t.allOf,s=r.filter(c=>!q(c)&&c.type==="object"&&!c.allOf&&!c.oneOf);t.properties&&s.push(t);const n=r.filter(c=>!s.includes(c)).map((c,p)=>this.parseSchemaObject(`${e}Parent${p+1}`,c)),o=s.flatMap(c=>this.extractObjectProperties(e,c)),a=new A(e,n,o);return s.forEach(c=>{var p;return(p=c.required)==null?void 0:p.forEach(m=>a.addPropertyRestriction(m,u.required,!0))}),this.setTypeReference(e,a)}parseOneOfObject(e,t){const s=t.oneOf.map((o,a)=>this.parseSchemaObject(`${e}Option${a+1}`,o)),n=new C(e,s);return this.setTypeReference(e,n)}parseObjectWithProperties(e,t){var n;const r=this.extractObjectProperties(e,t),s=new g(e,r);return(n=t.required)==null||n.forEach(o=>s.addPropertyRestriction(o,u.required,!0)),this.setTypeReference(e,s)}extractObjectProperties(e,t){return t.properties?Object.entries(t.properties).map(r=>this.parseEntityProperty(e,r[0],r[1])):[]}parseEntityProperty(e,t,r){const s=e+w(t),n=this.parseSchemaObject(s,r),o=new I(t,n);return De(r)&&(o.description=r.description,o.example=r.example,r.maxLength&&o.addRestriction(u.maxLength,r.maxLength),r.minLength&&o.addRestriction(u.minLength,r.minLength),r.pattern&&o.addRestriction(u.pattern,r.pattern),r.format&&o.addRestriction(u.format,r.format)),o}setTypeReference(e,t){const r=this.types.get(e);if(r)return r.type=r.type??t,r;const s=new Q(t);return this.types.set(e,s),s}}const L="#/definitions/";function Ae(i){const e=i.indexOf(L,0);return e>=0?i.substring(e+L.length):i}function Ce(i){return i.startsWith(L)}class qe extends v{constructor(t){super(t);f(this,"repository");f(this,"method");f(this,"path");f(this,"description");f(this,"pathParams");f(this,"queryParam");f(this,"requestBody");f(this,"responses")}}class Ie{constructor(e,t){f(this,"types",new Map);f(this,"endpoints");this.apiDocument=e,this.config=t}parse(){var e;if((e=this.apiDocument.components)!=null&&e.schemas)for(const[t,r]of Object.entries(this.apiDocument.components.schemas)){const s=this.parseSchemaObject(t,r);S(r)&&this.setTypeReference(t,new b(t,s))}this.parsePaths(this.apiDocument.paths)}parseSchemaObject(e,t){if(console.debug("Parsing object",e),S(t))return this.parseReferenceObject(t);if(t.enum)return this.parseEnum(e,t);switch(t.type){case"array":{const r=`${e}Item`,s=this.parseSchemaObject(r,t.items),n=new b(e,s,!0);return this.setTypeReference(e,n)}case"object":return this.parseObject(e,t);case"string":switch(t.format){case"binary":return this.setTypeReference(e,"Blob");case"date":case"datetime":case"date-time":return this.setTypeReference(e,"Date");default:return this.setTypeReference(e,"string")}case"integer":case"number":return this.setTypeReference(e,"number");case"boolean":return this.setTypeReference(e,t.type)}if(t.oneOf||t.anyOf||t.allOf)return this.parseObject(e,t);throw new Error(`Could not parse object '${e}'`)}parseReferenceObject(e){const t=Le(e.$ref),r=Be(e.$ref)?void 0:new J(t,e.$ref);return this.setTypeReference(t,r)}parseEnum(e,t){const r=t.enum?new x(e,t.enum):void 0;return this.setTypeReference(e,r)}parseObject(e,t){return t.allOf?this.parseAllOfObject(e,t):t.oneOf?this.parseOneOfObject(e,t):t.anyOf?(t.oneOf=t.anyOf,this.parseOneOfObject(e,t)):this.parseObjectWithProperties(e,t)}parseAllOfObject(e,t){const r=t.allOf,s=r.filter(c=>!S(c)&&c.type==="object"&&!c.allOf&&!c.oneOf);t.properties&&s.push(t);const n=r.filter(c=>!s.includes(c)).map((c,p)=>this.parseSchemaObject(`${e}Parent${p+1}`,c)),o=s.flatMap(c=>this.extractObjectProperties(e,c)),a=new A(e,n,o);return s.forEach(c=>{var p;return(p=c.required)==null?void 0:p.forEach(m=>a.addPropertyRestriction(m,u.required,!0))}),this.setTypeReference(e,a)}parseOneOfObject(e,t){const s=t.oneOf.map((o,a)=>this.parseSchemaObject(`${e}Option${a+1}`,o)),n=new C(e,s);return this.setTypeReference(e,n)}parseObjectWithProperties(e,t){var n;const r=this.extractObjectProperties(e,t),s=new g(e,r);return(n=t.required)==null||n.forEach(o=>s.addPropertyRestriction(o,u.required,!0)),this.setTypeReference(e,s)}extractObjectProperties(e,t){return t.properties?Object.entries(t.properties).map(r=>this.parseEntityProperty(e,r[0],r[1])):[]}parseEntityProperty(e,t,r){const s=e+w(t),n=this.parseSchemaObject(s,r),o=new I(t,n);return xe(r)&&(o.description=r.description,o.example=r.example,r.maxLength&&o.addRestriction(u.maxLength,r.maxLength),r.minLength&&o.addRestriction(u.minLength,r.minLength),r.pattern&&o.addRestriction(u.pattern,r.pattern),r.nullable!==void 0&&o.addRestriction(u.nullable,r.nullable),r.readOnly&&o.addRestriction(u.readOnly,r.readOnly),r.format&&o.addRestriction(u.format,r.format)),o}setTypeReference(e,t){const r=this.types.get(e);if(r)return r.type=r.type??t,r;const s=new Q(t);return this.types.set(e,s),s}parsePaths(e){this.endpoints=Object.entries(e).flatMap(([t,r])=>Object.entries(r??{}).map(([s,n])=>({path:t,method:s.toLowerCase(),action:n}))).filter(t=>Ve(t.method)).map(t=>this.parseEndpoint(t))}parseEndpoint({path:e,method:t,action:r}){var c,p,m,j,X;console.debug("Parsing endpoint",t,e),e=(c=this.config)!=null&&c.endpointUrlPrefix?e.replace(this.config.endpointUrlPrefix,""):e;const s=r.operationId??l.camelCase(t+"-"+e.replace(/\{(\D*?)\}/,"By-$1")),n=new qe(s);n.path=e,n.method=t,n.repository=((p=r.tags)==null?void 0:p[0])??"General",n.description=((m=r.description)==null?void 0:m.trim())??((j=r.summary)==null?void 0:j.trim());const o=((X=r.parameters)==null?void 0:X.filter(d=>!!d.schema))??[];n.pathParams=o.filter(d=>d.in==="path").map(d=>{const D=this.parseEndpointParameter(s,d);return K.toCamelCase(D),D});const a=o.filter(d=>d.in==="query").map(d=>this.parseEndpointParameter(s,d));if(a.length){const d=new g(s+"Query",a);n.queryParam=this.setTypeReference(d.name,d)}return r.requestBody&&(n.requestBody=this.getRequestBodyType(s+"Request",r.requestBody)),n.responses={},r.responses&&Object.entries(r.responses).forEach(([d,D])=>{const ke=this.getResponseBodyType(`${s}Response${d}`,D);n.responses[d]=ke}),n}parseEndpointParameter(e,t){const r=this.parseSchemaObject(e,t.schema),s=new I(Me(t.name),r);return s.description=t.description,t.required&&s.addRestriction(u.required,!0),s}getRequestBodyType(e,t){var r,s;if(S(t)){const n=t.$ref.substr(t.$ref.lastIndexOf("/")+1),o=(s=(r=this.apiDocument.components)==null?void 0:r.requestBodies)==null?void 0:s[n];return o?this.getRequestBodyType(n,o):void 0}else{const n=Object.keys(t.content)[0],o=t.content[n].schema,a=o&&this.parseSchemaObject(e,o);return a?{contentType:n,typeReference:a}:void 0}}getResponseBodyType(e,t){var r,s,n;if(S(t)){const o=t.$ref.substr(t.$ref.lastIndexOf("/")+1),a=(s=(r=this.apiDocument.components)==null?void 0:r.responses)==null?void 0:s[o];return a?this.getResponseBodyType(o,a):void 0}else{if(!t.content)return;const o=Object.keys(t.content)[0],a=(n=t.content[o])==null?void 0:n.schema,c=a&&this.parseSchemaObject(e,a);return c?{contentType:o,typeReference:c}:void 0}}}const B="#/components/schemas/";function Le(i){const e=i.indexOf(B,0);return e>=0?i.substring(e+B.length):i}function Be(i){return i.startsWith(B)}function Ve(i){switch(i){case"get":case"put":case"post":case"delete":case"option":case"head":case"patch":case"trace":return!0;default:return!1}}function Me(i){return i.endsWith("[]")?i.substring(0,i.length-2):i}class We{async process(e,t){const r=F("Analysing");r.start(2,0);const s=t!=null&&t.bundleReferences?await W.bundle(e):await W.parse(e);r.increment();const n=this.parseModel(s,t);return r.increment(),r.stop(),n}parseModel(e,t){if(Re(e)){const r=new Ne(e);return r.parse(),r}if($e(e)){const r=new Ie(e,t);return r.parse(),r}throw console.error("Unknown api format",e),new Error("Unknown api format")}}class Ge extends E{async run(){if(!this.config.api){console.warn("Api definition is missing");return}const e=new We,{types:t,endpoints:r}=await e.process(this.config.api,this.config),s=new K(this.config.aliases),n=new T(this.config.observable),o=new Pe(this.config),a=this.config.validations&&Object.assign({},this.config.observable||void 0,this.config.validations),c=new Se(a);t.forEach(m=>{s.formatNames(m),n.format(m),c.format(m),o.format(m)});const p=new Te(this.project,this.params,this.config);await p.generateEntities(Array.from(t.values())),await p.generateRepositories(r)}getDefaultConfig(){return Promise.resolve(ye)}}const _e=Object.freeze(Object.defineProperty({__proto__:null,default:Ge},Symbol.toStringTag,{value:"Module"}))});
//# sourceMappingURL=generator.umd.js.map

@@ -6,3 +6,3 @@ {

},
"version": "1.0.0-beta.6",
"version": "1.0.0-rc.1",
"description": "Frui.ts code generator",

@@ -42,20 +42,20 @@ "keywords": [

"@apidevtools/swagger-parser": "^10.1.0",
"cli-progress": "^3.11.2",
"commander": "^9.4.1",
"cli-progress": "^3.12.0",
"commander": "^10.0.1",
"handlebars": "^4.7.7",
"lodash": "^4.17.21",
"openapi-types": "^12.0.2",
"ts-morph": "^17.0.1"
"openapi-types": "^12.1.3",
"ts-morph": "^18.0.0"
},
"devDependencies": {
"@types/cli-progress": "^3.11.0",
"@types/lodash": "4.14.190",
"@types/node": "18.11.9",
"nodemon": "2.0.20",
"rimraf": "^3.0.2",
"@types/lodash": "4.14.195",
"@types/node": "20.3.0",
"nodemon": "2.0.22",
"rimraf": "^5.0.1",
"shx": "^0.3.4",
"ts-node": "^10.9.1",
"vite-plugin-banner": "^0.6.1"
"vite-plugin-banner": "^0.7.0"
},
"gitHead": "adf52b1d60660fc686182547cca34af079bdecf4"
"gitHead": "c17e77c7246207827d09d34cadbb54b07ebbd82e"
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc