@qlover/scripts-context 2.1.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var B=Object.create;var b=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var H=Object.getOwnPropertyNames;var U=Object.getPrototypeOf,M=Object.prototype.hasOwnProperty;var V=(n,e)=>{for(var t in e)b(n,t,{get:e[t],enumerable:!0})},L=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of H(e))!M.call(n,o)&&o!==t&&b(n,o,{get:()=>e[o],enumerable:!(r=q(e,o))||r.enumerable});return n};var z=(n,e,t)=>(t=n!=null?B(U(n)):{},L(e||!n||!n.__esModule?b(t,"default",{value:n,enumerable:!0}):t,n)),Z=n=>L(b({},"__esModule",{value:!0}),n);var Y={};V(Y,{ColorFormatter:()=>E,ConfigSearch:()=>u,ScriptContext:()=>R,ScriptPlugin:()=>F,Shell:()=>d,defaultFeConfig:()=>I});module.exports=Z(Y);var I={protectedBranches:["master","develop","main"],cleanFiles:["dist","node_modules","yarn.lock","package-lock.json",".eslintcache","*.log"],commitlint:{extends:["@commitlint/config-conventional"]},release:{publishPath:"",autoMergeReleasePR:!1,autoMergeType:"squash",branchName:"release-${pkgName}-${tagName}",PRTitle:"[${pkgName} Release] Branch:${branch}, Tag:${tagName}, Env:${env}",PRBody:`## Publish Details
1
+ "use strict";var B=Object.create;var b=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var H=Object.getOwnPropertyNames;var U=Object.getPrototypeOf,M=Object.prototype.hasOwnProperty;var V=(n,e)=>{for(var t in e)b(n,t,{get:e[t],enumerable:!0})},L=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of H(e))!M.call(n,o)&&o!==t&&b(n,o,{get:()=>e[o],enumerable:!(r=q(e,o))||r.enumerable});return n};var z=(n,e,t)=>(t=n!=null?B(U(n)):{},L(e||!n||!n.__esModule?b(t,"default",{value:n,enumerable:!0}):t,n)),Z=n=>L(b({},"__esModule",{value:!0}),n);var ee={};V(ee,{ColorFormatter:()=>E,ConfigSearch:()=>u,ScriptContext:()=>R,ScriptPlugin:()=>F,Shell:()=>d,defaultFeConfig:()=>I});module.exports=Z(ee);var I={protectedBranches:["master","develop","main"],cleanFiles:["dist","node_modules","yarn.lock","package-lock.json",".eslintcache","*.log"],commitlint:{extends:["@commitlint/config-conventional"]},release:{publishPath:"",autoMergeReleasePR:!1,autoMergeType:"squash",branchName:"release-${pkgName}-${tagName}",PRTitle:"[${pkgName} Release] Branch:${branch}, Tag:${tagName}, Env:${env}",PRBody:`## Publish Details
2
2
 
3
3
  - \u{1F3F7}\uFE0F Version: \${tagName}
4
4
  - \u{1F332} Branch: \${branch}
@@ -14,6 +14,6 @@
14
14
  - [ ] Please confirm all tests have passed
15
15
  - [ ] Please confirm the documentation has been updated
16
16
 
17
- > This PR is auto created by release process, please contact the frontend team if there are any questions.`,label:{color:"1A7F37",description:"Release PR",name:"CI-Release"},packagesDirectories:[],changePackagesLabel:"changes:${name}"},envOrder:[".env.local",".env.production",".env"]};var f=z(require("chalk"),1),E=class{constructor(e={fatal:f.default.bgRed.white.bold,error:f.default.red.bold,warn:f.default.yellow.bold,info:f.default.blue,debug:f.default.green,trace:f.default.gray,log:f.default.white}){this.levelColors=e}format(e){let{level:t,args:r}=e,o=this.levelColors[t]||f.default.white;return[typeof o=="function"?o(t.toUpperCase()):t.toUpperCase(),...r]}};var T=require("cosmiconfig"),C=require("lodash-es");function J(n){let e=["json","js","ts","cjs","yaml","yml"];return["package.json",...e.map(t=>`${n}.${t}`),...e.map(t=>`.${n}.${t}`)]}var u=class{name;searchPlaces;_config;loaders;searchCache;constructor(e){let{name:t,searchPlaces:r,defaultConfig:o,loaders:i}=e;if(!t&&!r)throw new Error("searchPlaces or name is required");this.name=t,this.searchPlaces=r||J(t),this._config=o||{},this.loaders=i}get config(){return(0,C.defaultsDeep)({},this.search(),this._config)}getSearchPlaces(){return this.searchPlaces}get(e={}){let{file:t,dir:r=process.cwd()}=e,o={};if(t===!1)return o;let i=(0,T.cosmiconfigSync)(this.name,{searchPlaces:this.searchPlaces,loaders:this.loaders}),s=t?i.load(t):i.search(r);if(s&&typeof s.config=="string")throw new Error(`Invalid configuration file at ${s.filepath}`);return s&&(0,C.isPlainObject)(s.config)?s.config:o}search(){return this.searchCache?this.searchCache:this.searchCache=this.get({})}};var O=require("lodash-es"),A=require("@qlover/fe-corekit");var v=require("lodash-es"),_=require("@qlover/env-loader"),K=[".env.local",".env"];function G(n,e,t){let r=n.env||_.Env.searchEnv({logger:t,preloadList:e.envOrder||K}),o=n.rootPath||process.cwd(),i=n.sourceBranch||r?.get("FE_RELEASE_BRANCH")||r?.get("FE_RELEASE_SOURCE_BRANCH")||"master";return{...n,sourceBranch:i,rootPath:o,env:r}}function Q(n,e,t){let r=n?(0,v.get)(e,n):e,o=typeof r=="object"&&r!==null,i=o?r:{};return o||t.warn(`rootProp ${n} is not an object, it will be overwritten by the default options`),i}function D(n,e,t,r){let o=Q(n,e,r),i=(0,v.merge)({},o,t);return G(i,e,r)}var $=require("child_process");var k=require("lodash-es");var y=class{constructor(e,t,r,o){this.level=e;this.args=t;this.loggerName=r;this.context=o;this.timestamp=Date.now()}timestamp};var h=class{constructor(e){this.value=e}};var W={fatal:0,error:10,warn:20,info:30,debug:40,trace:50,log:60},P=class{constructor(e={}){this.options=e;e.name=e.name||Date.now().toString(),e.levels=e.levels||W,e.handlers=Array.isArray(e.handlers)?e.handlers:e.handlers?[e.handlers]:[]}addAppender(e){this.options.handlers.push(e)}context(e){return new h(e)}print(e,t){let{levels:r,level:o,silent:i,handlers:s}=this.options;if(i)return;let a=t.slice(-1)[0],c=t.length>1&&a instanceof h;if(a=c?a:void 0,t=c?t.slice(0,-1):t,e=a?.value?.level??e,o&&r){let p=r[o],m=r[e];if(p!=null&&m!=null&&m>p)return}let l=new y(e,t,this.options.name,a),g=Array.isArray(s)?s:[s];for(let p of g)p&&p.append(l)}log(...e){this.print("info",e)}fatal(...e){this.print("fatal",e)}error(...e){this.print("error",e)}warn(...e){this.print("warn",e)}info(...e){this.print("info",e)}debug(...e){this.print("debug",e)}trace(...e){this.print("trace",e)}};var w=class{constructor(e=null){this.formatter=e}setFormatter(e){this.formatter=e}append(e){let{level:t,args:r}=e,o=this.formatter?this.formatter.format(e):r;(console[t]||console.log)(...Array.isArray(o)?o:[o])}};var X={hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1,timeZone:"UTC"},S=class{constructor(e={}){this.options=e}replacePrefix(e,t){return e.replace(/\{([^{}]+)\}/g,(r,o)=>t[o]||r)}format({timestamp:e,level:t,args:r,context:o,loggerName:i}){let{locale:s="zh-CN",localeOptions:a,prefixTemplate:c="[{formattedTimestamp} {level}]"}=this.options,l=o?.formatType??"datetime",g=l==="date"?"toLocaleDateString":l==="time"?"toLocaleTimeString":"toLocaleString",p=new Date(e)[g](s,{...X,...a});return[this.replacePrefix(c,{...o,timestamp:e.toString(),level:t,loggerName:i,formattedTimestamp:p,locale:s}),...r]}};var N=require("lodash-es"),d=class n{constructor(e,t=new Map){this.config=e;this.cache=t}get logger(){return this.config.logger}static format(e="",t={}){return(0,N.template)(e)(t)}format(e="",t={}){try{return n.format(e,t)}catch(r){throw this.logger.error(`Unable to render template with context:
17
+ > This PR is auto created by release process, please contact the frontend team if there are any questions.`,label:{color:"1A7F37",description:"Release PR",name:"CI-Release"},packagesDirectories:[],changePackagesLabel:"changes:${name}"},envOrder:[".env.local",".env.production",".env"]};var f=z(require("chalk"),1),E=class{constructor(e={fatal:f.default.bgRed.white.bold,error:f.default.red.bold,warn:f.default.yellow.bold,info:f.default.blue,debug:f.default.green,trace:f.default.gray,log:f.default.white}){this.levelColors=e}format(e){let{level:t,args:r}=e,o=this.levelColors[t]||f.default.white;return[typeof o=="function"?o(t.toUpperCase()):t.toUpperCase(),...r]}};var T=require("cosmiconfig"),C=require("lodash-es");function J(n){let e=["json","js","ts","cjs","yaml","yml"];return["package.json",...e.map(t=>`${n}.${t}`),...e.map(t=>`.${n}.${t}`)]}var u=class{name;searchPlaces;_config;loaders;searchCache;constructor(e){let{name:t,searchPlaces:r,defaultConfig:o,loaders:i}=e;if(!t&&!r)throw new Error("searchPlaces or name is required");this.name=t,this.searchPlaces=r||J(t),this._config=o||{},this.loaders=i}get config(){return(0,C.defaultsDeep)({},this.search(),this._config)}getSearchPlaces(){return this.searchPlaces}get(e={}){let{file:t,dir:r=process.cwd()}=e,o={};if(t===!1)return o;let i=(0,T.cosmiconfigSync)(this.name,{searchPlaces:this.searchPlaces,loaders:this.loaders}),s=t?i.load(t):i.search(r);if(s&&typeof s.config=="string")throw new Error(`Invalid configuration file at ${s.filepath}`);return s&&(0,C.isPlainObject)(s.config)?s.config:o}search(){return this.searchCache?this.searchCache:this.searchCache=this.get({})}};var O=require("lodash-es"),A=require("@qlover/fe-corekit");var v=require("lodash-es"),_=require("@qlover/env-loader"),K=[".env.local",".env"];function G(n,e,t){let r=n.env||_.Env.searchEnv({logger:t,preloadList:e.envOrder||K}),o=n.rootPath||process.cwd(),i=n.sourceBranch||r?.get("FE_RELEASE_BRANCH")||r?.get("FE_RELEASE_SOURCE_BRANCH")||"master";return{...n,sourceBranch:i,rootPath:o,env:r}}function Q(n,e,t){let r=n?(0,v.get)(e,n):e,o=typeof r=="object"&&r!==null,i=o?r:{};return o||t.warn(`rootProp ${n} is not an object, it will be overwritten by the default options`),i}function N(n,e,t,r){let o=Q(n,e,r),i=(0,v.merge)({},o,t);return G(i,e,r)}var D=require("child_process");var k=require("lodash-es");var y=class{constructor(e,t,r,o){this.level=e;this.args=t;this.loggerName=r;this.context=o;this.timestamp=Date.now()}timestamp};var h=class{constructor(e){this.value=e}};var W={fatal:0,error:10,warn:20,info:30,debug:40,trace:50,log:60},P=class{constructor(e={}){this.options=e;e.name=e.name||Date.now().toString(),e.levels=e.levels||W,e.handlers=Array.isArray(e.handlers)?e.handlers:e.handlers?[e.handlers]:[]}addAppender(e){this.options.handlers.push(e)}context(e){return new h(e)}print(e,t){let{levels:r,level:o,silent:i,handlers:s}=this.options;if(i)return;let a=t.slice(-1)[0],c=t.length>1&&a instanceof h;if(a=c?a:void 0,t=c?t.slice(0,-1):t,e=a?.value?.level??e,o&&r){let p=r[o],m=r[e];if(p!=null&&m!=null&&m>p)return}let l=new y(e,t,this.options.name,a),g=Array.isArray(s)?s:[s];for(let p of g)p&&p.append(l)}log(...e){this.print("info",e)}fatal(...e){this.print("fatal",e)}error(...e){this.print("error",e)}warn(...e){this.print("warn",e)}info(...e){this.print("info",e)}debug(...e){this.print("debug",e)}trace(...e){this.print("trace",e)}};var w=class{constructor(e=null){this.formatter=e}setFormatter(e){this.formatter=e}append(e){let{level:t,args:r,loggerName:o}=e,i=this.formatter?this.formatter.format(e):[o?`[${o}]`:null,...r].filter(s=>s!=null);(console[t]||console.log)(...Array.isArray(i)?i:[i])}};var X={hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1,timeZone:"UTC"},Y="[{loggerName}] [{formattedTimestamp} {level}]",S=class{constructor(e={}){this.options=e}updateOptions(e){this.options={...this.options,...e}}replacePrefix(e,t){return e.replace(/\{([^{}]+)\}/g,(r,o)=>o in t?String(t[o]??""):"")}format({timestamp:e,level:t,args:r,context:o,loggerName:i}){let{locale:s="zh-CN",localeOptions:a,prefixTemplate:c=Y}=this.options,l=o?.formatType??"datetime",g=l==="date"?"toLocaleDateString":l==="time"?"toLocaleTimeString":"toLocaleString",p=new Date(e)[g](s,{...X,...a});return[this.replacePrefix(c,{...o,timestamp:e.toString(),level:t,loggerName:i,formattedTimestamp:p,locale:s}),...r]}};var $=require("lodash-es"),d=class n{constructor(e,t=new Map){this.config=e;this.cache=t}get logger(){return this.config.logger}static format(e="",t={}){return(0,$.template)(e)(t)}format(e="",t={}){try{return n.format(e,t)}catch(r){throw this.logger.error(`Unable to render template with context:
18
18
  ${e}
19
- ${JSON.stringify(t)}`),this.logger.error(r),r}}exec(e,t={}){let{context:r,...o}=t;return typeof e=="string"?this.execFormattedCommand(this.format(e,r||{}),o):this.execFormattedCommand(e,o)}run(e,t={}){return this.exec(e,{silent:!0,...t})}async execFormattedCommand(e,t={}){let r=this.config.execPromise;if(!r)throw new Error("execPromise is not defined");let{dryRunResult:o,silent:i,dryRun:s,isCache:a}=t,c=s!==void 0?s:this.config.dryRun,l=a!==void 0?!!a:!!this.config.isCache,g=typeof e=="string"?e:e.join(" "),p=l&&this.cache.has(g);if(i||this.logger.debug(e),c)return Promise.resolve(o);if(p)return this.cache.get(g);let m=r(e,t);return this.cache.has(g)||this.cache.set(g,m),m}};var x={exec(n,e){let t=Array.isArray(n)?n.join(" "):n;return new Promise((r,o)=>{(0,$.exec)(t,{encoding:"utf-8",...e},(i,s,a)=>{let c;i?i.code===void 0?c=1:c=i.code:c=0,c===0?r(s.trim()):o(new Error(a||s))})})},getConfig(n){return new u({name:"fe-config",defaultConfig:(0,k.merge)({},I,n)})},logger(n,e){return new P({level:e?"debug":"info",name:n,handlers:new w(new S({prefixTemplate:"[{loggerName} {formattedTimestamp} {level}]",localeOptions:{timeZone:"Asia/Shanghai"}}))})},options(n,e){let{logger:t,shell:r,feConfig:o,dryRun:i,verbose:s,options:a}=e,c=a||{},l=t||x.logger(n,!!s),g=r||new d({logger:l,dryRun:i,execPromise:c.execPromise||x.exec}),p=(0,k.merge)({},o,{[n]:e.options});return{options:c,dryRun:!!i,shell:g,logger:l,verbose:!!s,feConfig:x.getConfig(p).config}}};var R=class extends A.ExecutorContextImpl{constructor(t,r={}){if(!t||typeof t!="string")throw new Error("ScriptContext name is required");let{feConfig:o,logger:i,shell:s,dryRun:a,verbose:c,options:l}=x.options(t,r);super(l);this.name=t;this.feConfig=o,this.logger=i,this.shell=s,this.dryRun=a,this.verbose=c,this.setOptions(D(t,o,l,i))}logger;shell;feConfig;dryRun;verbose;get options(){return this.parameters}get env(){if(!this.options.env)throw new Error("Environment is not initialized");return this.options.env}setOptions(t){this.setParameters((0,O.merge)(this.options,t))}getEnv(t,r){return this.env.get(t)??r}getOptions(t,r){return t?(0,O.get)(this.options,t,r):this.options}};var j=require("lodash-es"),F=class{constructor(e,t,r={}){this.context=e;this.pluginName=t;this.props=r;this.setConfig(this.getInitialProps(r))}onlyOne=!0;getInitialProps(e){if(typeof this.context.options!="object")return{};let t=this.context.options[this.pluginName],r=this.context.getOptions(this.pluginName),o=t||r;return e?(0,j.merge)({},o,e):o||{}}get logger(){return this.context.logger}get shell(){return this.context.shell}get options(){return this.context.getOptions(this.pluginName,{})}enabled(e,t){let r=this.getConfig("skip");return!(r===!0||typeof r=="string"&&e===r)}getConfig(e,t){return e?this.context.getOptions([this.pluginName,...Array.isArray(e)?e:[e]],t):this.context.getOptions(this.pluginName,t)}setConfig(e){this.context.setOptions({[this.pluginName]:e})}onBefore(e){}onExec(e){}onSuccess(e){}onError(e){}onFinally(e){}async step(e){this.logger.log(),this.logger.info(e.label),this.logger.log();try{let t=await e.task();return this.logger.info(`${e.label} - success`),t}catch(t){throw this.logger.error(t),t}}};0&&(module.exports={ColorFormatter,ConfigSearch,ScriptContext,ScriptPlugin,Shell,defaultFeConfig});
19
+ ${JSON.stringify(t)}`),this.logger.error(r),r}}exec(e,t={}){let{context:r,...o}=t;return typeof e=="string"?this.execFormattedCommand(this.format(e,r||{}),o):this.execFormattedCommand(e,o)}run(e,t={}){return this.exec(e,{silent:!0,...t})}async execFormattedCommand(e,t={}){let r=this.config.execPromise;if(!r)throw new Error("execPromise is not defined");let{dryRunResult:o,silent:i,dryRun:s,isCache:a}=t,c=s!==void 0?s:this.config.dryRun,l=a!==void 0?!!a:!!this.config.isCache,g=typeof e=="string"?e:e.join(" "),p=l&&this.cache.has(g);if(i||this.logger.debug(e),c)return Promise.resolve(o);if(p)return this.cache.get(g);let m=r(e,t);return this.cache.has(g)||this.cache.set(g,m),m}};var x={exec(n,e){let t=Array.isArray(n)?n.join(" "):n;return new Promise((r,o)=>{(0,D.exec)(t,{encoding:"utf-8",...e},(i,s,a)=>{let c;i?i.code===void 0?c=1:c=i.code:c=0,c===0?r(s.trim()):o(new Error(a||s))})})},getConfig(n){return new u({name:"fe-config",defaultConfig:(0,k.merge)({},I,n)})},logger(n,e){return new P({level:e?"debug":"info",name:n,handlers:new w(new S({prefixTemplate:"[{loggerName} {formattedTimestamp} {level}]",localeOptions:{timeZone:"Asia/Shanghai"}}))})},options(n,e){let{logger:t,shell:r,feConfig:o,dryRun:i,verbose:s,options:a}=e,c=a||{},l=t||x.logger(n,!!s),g=r||new d({logger:l,dryRun:i,execPromise:c.execPromise||x.exec}),p=(0,k.merge)({},o,{[n]:e.options});return{options:c,dryRun:!!i,shell:g,logger:l,verbose:!!s,feConfig:x.getConfig(p).config}}};var R=class extends A.ExecutorContextImpl{constructor(t,r={}){if(!t||typeof t!="string")throw new Error("ScriptContext name is required");let{feConfig:o,logger:i,shell:s,dryRun:a,verbose:c,options:l}=x.options(t,r);super(l);this.name=t;this.feConfig=o,this.logger=i,this.shell=s,this.dryRun=a,this.verbose=c,this.setOptions(N(t,o,l,i))}logger;shell;feConfig;dryRun;verbose;get options(){return this.parameters}get env(){if(!this.options.env)throw new Error("Environment is not initialized");return this.options.env}setOptions(t){this.setParameters((0,O.merge)(this.options,t))}getEnv(t,r){return this.env.get(t)??r}getOptions(t,r){return t?(0,O.get)(this.options,t,r):this.options}};var j=require("lodash-es"),F=class{constructor(e,t,r={}){this.context=e;this.pluginName=t;this.props=r;this.setConfig(this.getInitialProps(r))}onlyOne=!0;getInitialProps(e){if(typeof this.context.options!="object")return{};let t=this.context.options[this.pluginName],r=this.context.getOptions(this.pluginName),o=t||r;return e?(0,j.merge)({},o,e):o||{}}get logger(){return this.context.logger}get shell(){return this.context.shell}get options(){return this.context.getOptions(this.pluginName,{})}enabled(e,t){let r=this.getConfig("skip");return!(r===!0||typeof r=="string"&&e===r)}getConfig(e,t){return e?this.context.getOptions([this.pluginName,...Array.isArray(e)?e:[e]],t):this.context.getOptions(this.pluginName,t)}setConfig(e){this.context.setOptions({[this.pluginName]:e})}onBefore(e){}onExec(e){}onSuccess(e){}onError(e){}onFinally(e){}async step(e){this.logger.log(),this.logger.info(e.label),this.logger.log();try{let t=await e.task();return this.logger.info(`${e.label} - success`),t}catch(t){throw this.logger.error(t),t}}};0&&(module.exports={ColorFormatter,ConfigSearch,ScriptContext,ScriptPlugin,Shell,defaultFeConfig});
package/dist/index.js CHANGED
@@ -962,7 +962,7 @@ var ConsoleHandler = class {
962
962
  * @example Without formatter
963
963
  * ```typescript
964
964
  * const handler = new ConsoleHandler();
965
- * // Output: Raw message without formatting
965
+ * // Output: [loggerName] + raw message (logger name omitted if empty)
966
966
  * ```
967
967
  *
968
968
  * @example With timestamp formatter
@@ -1068,7 +1068,7 @@ var ConsoleHandler = class {
1068
1068
  * timestamp: Date.now(),
1069
1069
  * loggerName: 'app'
1070
1070
  * });
1071
- * // Console output: Application started
1071
+ * // Console output: [app] Application started
1072
1072
  *
1073
1073
  * // Message with context
1074
1074
  * handler.append({
@@ -1080,7 +1080,7 @@ var ConsoleHandler = class {
1080
1080
  * timestamp: Date.now(),
1081
1081
  * loggerName: 'db'
1082
1082
  * });
1083
- * // Console output: Database connection failed { host: 'localhost', ... }
1083
+ * // Console output: [db] Database connection failed { host: 'localhost', ... }
1084
1084
  * ```
1085
1085
  *
1086
1086
  * @example Formatted event handling
@@ -1138,8 +1138,10 @@ var ConsoleHandler = class {
1138
1138
  * ```
1139
1139
  */
1140
1140
  append(event) {
1141
- const { level, args } = event;
1142
- const formattedArgs = this.formatter ? this.formatter.format(event) : args;
1141
+ const { level, args, loggerName } = event;
1142
+ const formattedArgs = this.formatter ? this.formatter.format(event) : [loggerName ? `[${loggerName}]` : null, ...args].filter(
1143
+ (x) => x != null
1144
+ );
1143
1145
  (console[level] || console.log)(...Array.isArray(formattedArgs) ? formattedArgs : [formattedArgs]);
1144
1146
  }
1145
1147
  };
@@ -1152,6 +1154,7 @@ var defaultLocaleOptions = {
1152
1154
  hour12: false,
1153
1155
  timeZone: "UTC"
1154
1156
  };
1157
+ var defaultPrefixTemplate = "[{loggerName}] [{formattedTimestamp} {level}]";
1155
1158
  var TimestampFormatter = class {
1156
1159
  /**
1157
1160
  * Creates a new TimestampFormatter instance
@@ -1169,15 +1172,40 @@ var TimestampFormatter = class {
1169
1172
  constructor(options = {}) {
1170
1173
  this.options = options;
1171
1174
  }
1175
+ /**
1176
+ * Updates formatter options at runtime.
1177
+ * Merges the given partial options into the current options; subsequent formatting uses the updated values.
1178
+ *
1179
+ * @param partial - Partial options to merge (e.g. locale, prefixTemplate, localeOptions)
1180
+ * @since 1.1.0
1181
+ *
1182
+ * @example Update locale at runtime
1183
+ * ```typescript
1184
+ * const formatter = new TimestampFormatter({ locale: 'zh-CN' });
1185
+ * // later: switch to English
1186
+ * formatter.updateOptions({ locale: 'en-US' });
1187
+ * ```
1188
+ *
1189
+ * @example Update multiple options
1190
+ * ```typescript
1191
+ * formatter.updateOptions({
1192
+ * locale: 'ja-JP',
1193
+ * localeOptions: { timeZone: 'Asia/Tokyo', hour12: false }
1194
+ * });
1195
+ * ```
1196
+ */
1197
+ updateOptions(partial) {
1198
+ this.options = { ...this.options, ...partial };
1199
+ }
1172
1200
  /**
1173
1201
  * Replaces template variables in the prefix string with actual values
1174
1202
  *
1175
- * This internal method handles the variable substitution in prefix templates,
1176
- * replacing placeholders like {timestamp} with their corresponding values.
1203
+ * Placeholders like {timestamp} are replaced with values from vars.
1204
+ * Unknown or missing variables are skipped (replaced with empty string), not left as literal.
1177
1205
  *
1178
1206
  * @param template - The template string containing variables in curly braces
1179
1207
  * @param vars - Object containing variable names and their values
1180
- * @returns The template string with all variables replaced
1208
+ * @returns The template string with known variables replaced, unknowns removed
1181
1209
  *
1182
1210
  * @example Internal usage
1183
1211
  * ```typescript
@@ -1195,7 +1223,10 @@ var TimestampFormatter = class {
1195
1223
  * @protected
1196
1224
  */
1197
1225
  replacePrefix(template, vars) {
1198
- return template.replace(/\{([^{}]+)\}/g, (match, p1) => vars[p1] || match);
1226
+ return template.replace(
1227
+ /\{([^{}]+)\}/g,
1228
+ (_match, p1) => p1 in vars ? String(vars[p1] ?? "") : ""
1229
+ );
1199
1230
  }
1200
1231
  /**
1201
1232
  * Formats a log event by adding a timestamp prefix
@@ -1245,7 +1276,7 @@ var TimestampFormatter = class {
1245
1276
  const {
1246
1277
  locale = "zh-CN",
1247
1278
  localeOptions,
1248
- prefixTemplate = "[{formattedTimestamp} {level}]"
1279
+ prefixTemplate = defaultPrefixTemplate
1249
1280
  } = this.options;
1250
1281
  const formatType = context?.formatType ?? "datetime";
1251
1282
  const dateFormatMethod = formatType === "date" ? "toLocaleDateString" : formatType === "time" ? "toLocaleTimeString" : "toLocaleString";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@qlover/scripts-context",
3
3
  "description": "A scripts context for frontwork",
4
- "version": "2.1.0",
4
+ "version": "2.1.1",
5
5
  "type": "module",
6
6
  "private": false,
7
7
  "homepage": "https://github.com/qlover/fe-base/tree/master/packages/scripts-context#readme",
@@ -43,14 +43,14 @@
43
43
  "@commitlint/types": "^19.8.0",
44
44
  "@types/lodash-es": "^4.17.12",
45
45
  "@types/shelljs": "^0.8.15",
46
- "@qlover/logger": "1.0.0"
46
+ "@qlover/logger": "1.1.1"
47
47
  },
48
48
  "dependencies": {
49
49
  "chalk": "^5.3.0",
50
50
  "cosmiconfig": "^9.0.0",
51
51
  "lodash-es": "^4.17.22",
52
- "@qlover/env-loader": "1.0.0",
53
- "@qlover/fe-corekit": "3.2.0"
52
+ "@qlover/env-loader": "1.0.2",
53
+ "@qlover/fe-corekit": "3.2.1"
54
54
  },
55
55
  "scripts": {
56
56
  "lint": "eslint src --fix",