16 | var t,e=(t=require("chalk"))&&"object"==typeof t&&"default"in t?t.default:t,s=require("semver"),i=require("path"),n=require("@agentframework/app"),o=require("fs"),r=require("rollup"),a=require("@agentframework/app-extras"),l=require("@agentframework/domain"),c=require("typescript"),p=require("child_process"),h=require("events");const g=require("fs-extra");function d(t,e,s){const n=i.join(t.settings.HOME_DIR,e),o=i.join(t.settings.RELEASE_DIR,s||e);return g.pathExistsSync(n)?(g.copySync(n,o),!0):!(!s||!g.pathExistsSync(i.join(t.settings.RELEASE_DIR,s)))&&(g.copySync(n,i.join(t.settings.RELEASE_DIR,s)),!0)}function u(t,e){const s=i.join(t.settings.RELEASE_DIR,"public",e);return!!g.pathExistsSync(s)&&(g.removeSync(s),!0)}const m=require("fs-extra"),y=require("fs");function S(t,e){let s={};for(let e=t.length-1;e>=0;--e)s[t[e]]=t[e];for(let t=e.length-1;t>=0;--t)s[e[t]]=e[t];let i=[];for(let t in s)s.hasOwnProperty(t)&&i.push(s[t]);return i}const f=["buffer","querystring","events","http","cluster","zlib","os","https","punycode","repl","readline","vm","child_process","url","dns","net","dgram","fs","path","string_decoder","tls","crypto","stream","util","assert","tty","domain","constants","module","process","v8","timers","console","async_hooks","http2","perf_hooks"];function E(t){const e=n.ParseJSON(n.Directory.withReadPermission(t.settings.HOME_DIR).file("package.json"));let s=f;if(e.dependencies){const t=Object.keys(e.dependencies);t.length&&(s=S(s,t))}if(e.devDependencies){const t=Object.keys(e.devDependencies);t.length&&(s=S(s,t))}for(let t=0;t<s.length;t++)if("tslib"===s[t]){s.splice(t,1);break}return s}const R=require("fs-extra"),v=require("rollup-plugin-typescript2");async function w(t,e,s,o="ES2018",r="cjs",a=!1){const l=n.ParseJSON(n.Directory.withReadPermission(t.settings.HOME_DIR).file(e)),c=i.join(t.settings.HOME_DIR,"tsconfig.release.json"),p=i.join(t.settings.HOME_DIR,"tsconfig.json");let h;h=R.pathExistsSync(c)?c:R.pathExistsSync(p)?p:"";const g={check:!1,cacheRoot:i.join(process.env.TMPDIR||"release",".rpt2_cache"),tsconfig:h,tsconfigOverride:{compilerOptions:{target:o,module:"es2015",declaration:!1}}},d={input:l.path,external:E(t),plugins:[v(g)]},u={file:i.join(t.settings.RELEASE_DIR,s),format:r,sourcemap:!0},m=l.path,y=u.file;return t.logger.info(`Building (${u.format} with ${o}) ${e} => ${s}`),{inputOptions:d,outputOptions:u,inputFile:m,outputFile:y}}function j(t,e,s){const n=i.join(t.path,e+"."+s);if(o.existsSync(n))try{return t.file(`${e}.${s}`)}catch(t){return}}class CustomApplicationSettingsLoader extends n.Resolvable{applySettings(t,e,s){if("object"!=typeof e)throw new n.InvalidSettingsFileException(t.path);const i=[];for(const t of Object.keys(e))s[t]=e[t],i.push(t);this.logger.info(`Applied ${i.length} key(s) from '${t.path}'`)}applyJsonFileSettings(t,e,s){const i=j(t,e,"json");return!!i&&(this.applySettings(i,n.ParseJSON(i),s),!0)}applyJsFileSettings(t,e,s){const i=j(t,e,"js");return!!i&&(this.applySettings(i,n.ParseJS(i),s),!0)}applyPropertiesFileSettings(t,e,s){const i=j(t,e,"properties");return!!i&&(this.applySettings(i,a.ParseProperties(i),s),!0)}applyYamlFileSettings(t,e,s){const i=j(t,e,"yaml")||j(t,e,"yml");return!!i&&(this.applySettings(i,a.ParseYAML(i),s),!0)}applyIniFileSettings(t,e,s){const i=j(t,e,"ini");return!!i&&(this.applySettings(i,a.ParseINI(i),s),!0)}applyJSON5FileSettings(t,e,s){const i=j(t,e,"json5");return!!i&&(this.applySettings(i,a.ParseJSON5(i),s),!0)}applyTypeScriptFileSettings(t,e,s){const i=j(t,e,"ts");return!!i&&(this.applySettings(i,a.ParseTypeScript(i),s),!0)}warnIgnoredSettingsFile(t,e,s){const n=i.resolve(t.path,e);this.logger.warn(`Application settings file '${n}.[${s}]' is not found, ignoring...`)}applyFileSettingsInSequence(t,e,s){this.applyJsonFileSettings(t,e,s)||this.applyJsFileSettings(t,e,s)||this.applyYamlFileSettings(t,e,s)||this.applyIniFileSettings(t,e,s)||this.applyJSON5FileSettings(t,e,s)||this.applyTypeScriptFileSettings(t,e,s)||this.applyPropertiesFileSettings(t,e,s)||this.applyJsonFileSettings(t,e,s)||this.applyJsFileSettings(t,e,s)||this.warnIgnoredSettingsFile(t,e,"yaml|yml|ini|json5|ts|properties|json|js")}loadSettings(t,e){let s;const i={};try{s=n.Directory.withReadPermission(t)}catch(t){return void this.logger.warn(`Settings folder '${t.directory}' is not found, ignoring...`)}return this.applyFileSettingsInSequence(s,"settings",i),"production"!==this.settings.CONF&&this.applyFileSettingsInSequence(s,"production",i),this.applyFileSettingsInSequence(s,e,i),this.applyFileSettingsInSequence(s,e+".local",i),i}}class CustomApplicationSettingsBuilder extends n.Resolvable{saveSettings(t,e){let s=["'use strict';"],i=null;const n=Object.keys(e).sort();for(const t of n){let n="";t[0]!==i&&(i=t[0],n="\n"),t.indexOf(".")>=0?n+=`exports["${t}"] = ${JSON.stringify(e[t])};`:n+=`exports.${t} = ${JSON.stringify(e[t])};`,s.push(n)}const r=s.join("\n");return o.writeFileSync(t,r,{encoding:"utf8"}),r}}const I=require("fs-extra");require("ts-node").register({transpileOnly:!0,compiler:function(t,e){try{return require.resolve(t,e)}catch(t){return""}}("typescript",{paths:[__dirname]})});class Compiler extends n.Application{async rollupStandalone(){const t=i.join(this.settings.HOME_DIR,"src/bin/standalone.ts");if(!o.existsSync(t))return void this.logger.warn(`ignore rollup bundle because '${t}' is not exists`);const{inputOptions:e,outputOptions:s,outputFile:n}=await w(this,"src/bin/standalone.ts","bin/standalone","ES2018"),a=await r.rollup(e);return await a.write(s),function(t,e){let s;const i={encoding:"utf8",mode:438,flags:"w"};try{s=o.readFileSync(t,i)}catch(t){s=""}o.writeFileSync(t,e+"\n"+s,i)}(n,"#!/usr/bin/env node")}async rollupServerless(){const t=i.join(this.settings.HOME_DIR,"handlers.ts");if(!o.existsSync(t))return void this.logger.warn(`ignore rollup bundle because '${t}' is not exists`);const e=this.settings.SERVERLESS;let s=this.settings.TARGET;e&&e.provider&&"nodejs8.10"===e.provider.runtime&&(s="ES2018");const{inputOptions:n,outputOptions:a}=await w(this,"handlers.ts","handlers.js",s),l=await r.rollup(n);await l.write(a)}async rollupLibrary(t){const e=t,s=i.join(this.settings.HOME_DIR,e);if(!o.existsSync(s))return void this.logger.warn(`ignore rollup cjs bundle because '${s}' is not exists`);const{inputOptions:n}=await w(this,e,"lib/index.js","ES2018","cjs",!0),a=await r.rollup(n);await a.write({file:i.join(this.settings.RELEASE_DIR,"lib/index.js"),format:"cjs",sourcemap:!0})}async buildConfiguration(t){I.ensureDirSync(i.join(this.settings.RELEASE_DIR,"conf"));const e=this.construct(CustomApplicationSettingsLoader).loadSettings(this.settings.CONF_DIR,t),s=this.construct(CustomApplicationSettingsBuilder),n=i.join(this.settings.RELEASE_DIR,"conf","settings.js");s.saveSettings(n,e),this.logger.info(`Load ${Object.keys(e).length} key(s) from ${t} and save to ${n}`)}async buildAssets(t){this.settings.PUBLIC_DIR&&I.pathExistsSync(this.settings.PUBLIC_DIR)&&(I.ensureDirSync(i.join(this.settings.RELEASE_DIR,"public")),I.copySync(this.settings.PUBLIC_DIR,i.join(this.settings.RELEASE_DIR,"public")))}async buildProject(t){if(await this.buildConfiguration(t),await this.buildAssets(t),d(this,"Dockerfile"),d(this,"COPYRIGHT"),d(this,"LICENSE"),d(this,"NOTICE"),d(this,"README.md"),d(this,"package-lock.json"),d(this,"yarn.lock"),function(t){const e=i.join(t.settings.HOME_DIR,"package.release.json"),s=i.join(t.settings.RELEASE_DIR,"package.json");if(m.pathExistsSync(e))m.copySync(e,s);else{const e=n.ParseJSON(n.Directory.withReadPermission(t.settings.HOME_DIR).file("package.json")),i={},o={name:e.name,version:e.version,engines:e.engines||{},bin:e.bin||i,description:e.description||"",author:e.author||"",main:e.main?"lib/index.js":void 0,module:e.module?"lib/index.mjs":void 0,typings:e.typings?"lib/index.d.ts":void 0,files:e.files||["lib"],dependencies:e.dependencies};o.bin===i&&delete o.bin,y.writeFileSync(s,JSON.stringify(o,null,2))}}(this),!d(this,"serverless.yml")){const e=await async function(t,e){let s={service:t.settings.NAME,package:{include:[`conf/${e}.js`]},functions:{server:{handler:"handlers.server",timeout:t.settings.SERVERLESS_TIMEOUT_IN_SECONDS,access:"public",events:[{http:{path:"",method:"get"}},{http:{path:"",method:"head"}},{http:{path:"",method:"options"}},{http:{path:"{route+}",method:"get"}},{http:{path:"{route+}",method:"head"}},{http:{path:"{route+}",method:"options"}},{http:{path:"{route+}",method:"post"}},{http:{path:"{route+}",method:"put"}},{http:{path:"{route+}",method:"delete"}}]}}};return t.settings.SERVERLESS&&Object.keys(t.settings.SERVERLESS).length&&(s=Object.assign(s,t.settings.SERVERLESS)),s}(this,t);a.DumpYAML(e,i.join(this.settings.RELEASE_DIR,"serverless.yml"))}u(this,"index.template.html"),u(this,".gitignore")}async build(t){I.removeSync(this.settings.RELEASE_DIR),I.ensureDirSync(this.settings.RELEASE_DIR);const e=require(this.settings.PACKAGE_FILE);e.main&&await this.rollupLibrary(e.main),"server"===t?await this.rollupStandalone():"serverless"===t?await this.rollupServerless():(await this.rollupStandalone(),await this.rollupServerless()),await this.buildProject("production")}}function b(t,e,s,i){var n,o=arguments.length,r=o<3?e:null===i?i=Object.getOwnPropertyDescriptor(e,s):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(t,e,s,i);else for(var a=t.length-1;a>=0;a--)(n=t[a])&&(r=(o<3?n(r):o>3?n(e,s,r):n(e,s))||r);return o>3&&r&&Object.defineProperty(e,s,r),r}function _(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)}class CompilerSettings extends n.ApplicationSettings{constructor(){super(...arguments),this.RELEASE_DIR="release",this.TITLE="",this.PUBLIC_DIR="",this.PUBLIC_URL="",this.USE_EXTERNAL_CDN=!0,this.TARGET="ES2018",this.SERVERLESS_TIMEOUT_IN_SECONDS=30}}b([n.mandatory(),_("design:type",String)],CompilerSettings.prototype,"RELEASE_DIR",void 0),b([n.optional(),_("design:type",String)],CompilerSettings.prototype,"TITLE",void 0),b([n.optional(),_("design:type",String)],CompilerSettings.prototype,"PUBLIC_DIR",void 0),b([n.optional(),_("design:type",String)],CompilerSettings.prototype,"PUBLIC_URL",void 0),b([n.optional(),_("design:type",Boolean)],CompilerSettings.prototype,"USE_EXTERNAL_CDN",void 0),b([n.optional(),_("design:type",String)],CompilerSettings.prototype,"TARGET",void 0),b([n.optional(),_("design:type",Object)],CompilerSettings.prototype,"SERVERLESS",void 0),b([n.optional(),_("design:type",Number)],CompilerSettings.prototype,"SERVERLESS_TIMEOUT_IN_SECONDS",void 0);class Thread extends h.EventEmitter{constructor(t,e,s){super();const i=this.handler=p.fork(t,e,s);let n,o;i.unref(),this.started=new Promise(t=>{n=t}),this.stopped=new Promise(t=>{o=t}),i.on("message",t=>{this.initialized=!0,"required"===t.type&&(this.handler.removeAllListeners("message"),this.emit("start"),this.handler.send({type:"rs"}),n())}),this.handler.once("error",t=>{this.initialized=!0,console.log("fork process error exited",t),this.emit("error",t),o()}),i.once("close",t=>{this.initialized=!0,this.emit("stop",t),o()}),i.once("exit",t=>{this.initialized=!0,this.emit("stop",t),o()})}cache(t){this.initialized=!0,this.handler.send({type:"cache",value:t})}require(t){this.initialized=!0,this.handler.send({type:"require",value:t})}serve(){this.initialized=!0,this.handler.send({type:"server"})}progress(t,e){this.handler.send({type:"progress",value:{method:t,options:e}})}stop(){this.initialized=!0,this.handler.kill("SIGTERM")}}class TypeScriptProgram{constructor(t,e,s=!1,n="tsconfig.json"){this.runtimeFile=t,this.entryFile=e,this.server=s,this.currentCommand="",this.commands=[],this.thread=this.create(),this.files=new Map;const o=i.dirname(e),r=c.findConfigFile(__dirname,c.sys.fileExists,"package.json");if(!r)throw new Error('Could not find "package.json"');this.pkgPath=r;const a=c.findConfigFile(o,c.sys.fileExists,n);if(!a)throw new Error('Could not find "tsconfig.json"');this.configPath=a,this.thread.progress("info","(1/5) Load: "+a),this.sys=Object.assign({},c.sys,{writeFile:(t,e)=>{const s=t.slice(0,t.length-3)+".ts";this.files.set(s,e),3===this.phase&&this.progress("info","(3/5) Analysing...done",4),this.progress("start","(4/5) Compiling "+s)}})}create(){const t=this.thread=new Thread(this.runtimeFile,[this.entryFile],{cwd:process.cwd(),env:process.env});return t.on("start",()=>{this.started()}),t.on("error",t=>{this.stopped(t)}),t.on("stop",t=>{this.stopped(t)}),t}start(){if(this.currentCommand)return;if(this.thread&&this.thread.initialized)return;this.currentCommand="start";const t=this.thread=this.thread||this.create();for(const e of this.files.entries())t.cache(e);this.progress("info","(5/5) Executing "+this.entryFile),this.server?t.serve():t.require(this.entryFile)}started(){this.state="started",this.currentCommand="",this.next()}stop(){this.currentCommand||(this.thread?(this.currentCommand="stop",this.thread.stop()):this.stopped())}stopped(t){"started"!==this.state||this.currentCommand||12!==t&&null!==t||this.commands.push("start"),this.state="stopped",this.thread=void 0,this.currentCommand="",this.next()}progress(t,e,s){s&&(this.phase=s),this.thread&&this.thread.progress(t,e)}touch(t){"started"===this.state&&this.commands.push("stop"),t&&this.commands.push("start"),this.currentCommand||this.next()}next(){if(this.commands.length){const t=this.commands.shift();"start"===t?this.start():"stop"===t&&this.stop()}}}class TypeScriptWatcher{constructor(t){this.program=t,this.format={getCanonicalFileName:t=>t,getCurrentDirectory:c.sys.getCurrentDirectory,getNewLine:()=>c.sys.newLine}}start(){const t=c.createEmitAndSemanticDiagnosticsBuilderProgram,e=c.createWatchCompilerHost(this.program.configPath,{noEmit:!1,declaration:!1,sourceMap:!1,inlineSourceMap:!0,incremental:!0,tsBuildInfoFile:".tsbuildinfo.js"},this.program.sys,t,t=>{console.error("Compilation Error",t.code,":",c.flattenDiagnosticMessageText(t.messageText,this.format.getNewLine()))},t=>{t.code,6032===t.code&&this.program.touch(),6194===t.code&&"string"==typeof t.messageText&&t.messageText.startsWith("Found 0 errors")&&(this.program.progress("info","(4/5) Compiling...done"),setImmediate(()=>{this.program.touch(!0)}))}),s=e.createProgram;e.createProgram=((t,e,i,n)=>(this.program.progress("start","(2/5) Initializing..."),s(t,e,i,n)));const i=e.afterProgramCreate;e.afterProgramCreate=(t=>{this.program.progress("info","(2/5) Initializing...done"),this.program.progress("start","(3/5) Analysing...",3),i(t)}),this.watcher=c.createWatchProgram(e)}}const C=require("../package.json");s.satisfies(process.version,">=8")||(console.log(e.red(`You are using Node ${process.version}, but this version of @agentframework/cli `+"requires Node >=8.\nPlease upgrade your Node version.")),process.exit(1)),C&&C.version||(console.log(e.red("Package.json is not found. Please reinstall @agentframework/cli")),process.exit(1));const x=require("commander");x.version(C.version).usage("<command> [options]"),x.command("dev [file]").description("execute typescript file with incremental build and hot reload").action(t=>(function(t,s){const n=!t;if(n)try{const e=require(i.resolve(process.cwd(),"package.json"));e&&e.main?t=e.main:(console.log("Main file not found"),process.exit(1))}catch(t){console.log("Package file not found"),process.exit(1)}const r=i.isAbsolute(t)?t:i.resolve(process.cwd(),t),a=i.resolve(__dirname,s);o.existsSync(r)||(console.log("Entry file not found"),process.exit(1));const l=new TypeScriptProgram(a,r,n);console.log(e.yellow("[dev] agentframework "+require(l.pkgPath).version+", typescript "+require("typescript").version)),new TypeScriptWatcher(l).start()})(t,"../lib/index.js")),x.command("build").description("build current project").action(()=>(function(){process.env.NODE_ENV="build";const t=new l.InMemoryDomain;t.setType(n.SettingsLoader,a.ModernApplicationSettingsFileLoader);const e=t.construct(Compiler,[CompilerSettings]);return e.build().then(t=>{e.logger.info("Build project successfully"),process.exit(0)}).catch(t=>{e.logger.info(t,"Error build project"),process.exit(t.code||1)})})()),x.arguments("<command>").action(t=>{x.outputHelp(),console.log(" "+e.red(`Unknown command ${e.yellow(t)}.`)),console.log()}),x.on("--help",()=>{console.log(),console.log(` Current directory: ${process.cwd()}`),console.log(),console.log(` Run ${e.cyan("agent <command> --help")} for detailed usage of given command.`),console.log()}),x.commands.forEach(t=>t.on("--help",()=>console.log()));const O=(t,s)=>{x.Command.prototype[t]=function(...i){"unknownOption"===t&&this._allowUnknownOption||(this.outputHelp(),console.log(" "+e.red(s(...i))),console.log(),process.exit(1))}};O("missingArgument",t=>`Missing required argument ${e.yellow(`<${t}>`)}.`),O("unknownOption",t=>`Unknown option ${e.yellow(t)}.`),O("optionMissingArgument",(t,s)=>`Missing required argument for option ${e.yellow(t.flags)}`+(s?`, got ${e.yellow(s)}`:"")),x.parse(process.argv),process.argv.slice(2).length||x.outputHelp();
|