develog 1.0.2
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/LICENSE.md +21 -0
- package/README.md +64 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +186 -0
- package/dist/index.d.ts +186 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +76 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 전준연
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# develog
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/develog)
|
|
4
|
+
[](https://github.com/junjuny0227/develog)
|
|
5
|
+
[](https://www.npmjs.com/package/develog)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
> A lightweight frontend logger that runs only in local/dev environments
|
|
9
|
+
|
|
10
|
+
A smart logging library that automatically detects the environment based on the browser's hostname and outputs logs only in development environments.
|
|
11
|
+
|
|
12
|
+
## Documentation
|
|
13
|
+
|
|
14
|
+
- [English Documentation](./docs/README.en.md)
|
|
15
|
+
- [한국어 문서](./docs/README.ko.md)
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
### Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# npm
|
|
23
|
+
npm install develog
|
|
24
|
+
|
|
25
|
+
# yarn
|
|
26
|
+
yarn add develog
|
|
27
|
+
|
|
28
|
+
# pnpm
|
|
29
|
+
pnpm add develog
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Basic Usage
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { develog } from 'develog';
|
|
36
|
+
|
|
37
|
+
develog.log('This log appears only in development environments');
|
|
38
|
+
develog.info('Info message');
|
|
39
|
+
develog.warn('Warning message');
|
|
40
|
+
develog.error('Error message');
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Features
|
|
44
|
+
|
|
45
|
+
- **Automatic Environment Detection** - Based on hostname patterns
|
|
46
|
+
- **Namespace Support** - Separate logs by module
|
|
47
|
+
- **Timestamp Support** - 4 format options
|
|
48
|
+
- **TypeScript Support** - Full type safety
|
|
49
|
+
- **Zero Dependencies** - Lightweight package
|
|
50
|
+
- **Production Safe** - Automatically disabled in production
|
|
51
|
+
|
|
52
|
+
## Links
|
|
53
|
+
|
|
54
|
+
- [GitHub Repository](https://github.com/junjuny0227/develog)
|
|
55
|
+
- [npm Package](https://www.npmjs.com/package/develog)
|
|
56
|
+
- [Issues](https://github.com/junjuny0227/develog/issues)
|
|
57
|
+
|
|
58
|
+
## License
|
|
59
|
+
|
|
60
|
+
MIT License - See [LICENSE.md](LICENSE.md)
|
|
61
|
+
|
|
62
|
+
## Author
|
|
63
|
+
|
|
64
|
+
**junjuny** - [@junjuny0227](https://github.com/junjuny0227)
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var v={local:/^(localhost|127\.0\.0\.1|0\.0\.0\.0|::1|\[::1\])/,dev:/(^|\.)(dev|development)\./,stage:/(^|\.)(stage|staging)\./,production:/(^|\.)(prod|production|www)\./,unknown:/.*/};function a(n){if(typeof window>"u"||!window.location)return "unknown";let e=window.location.hostname,t={...v,...n};return t.local.test(e)?"local":t.dev.test(e)?"dev":t.stage.test(e)?"stage":t.production.test(e)?"production":"unknown"}function p(n="time"){let e=new Date;switch(n){case "time":return m(e);case "datetime":return E(e);case "iso":return e.toISOString();case "ms":return e.getTime().toString();default:return m(e)}}function m(n){let e=o(n.getHours()),t=o(n.getMinutes()),s=o(n.getSeconds());return `${e}:${t}:${s}`}function E(n){let e=n.getFullYear(),t=o(n.getMonth()+1),s=o(n.getDate()),i=m(n);return `${e}-${t}-${s} ${i}`}function o(n){return n.toString().padStart(2,"0")}var r=class n{constructor(e={}){let{enabledEnvironments:t=["local","dev","stage"],customHostnamePatterns:s,prefix:i="[develog]",forceEnvironment:l,showTimestamp:c=false,timestampFormat:g="time",enabledNamespaces:d,_namespaceName:h}=e;this.environment=l||a(s),this.enabledEnvironments=new Set(t),this.prefix=i,this.showTimestamp=c,this.timestampFormat=g,this.namespaces=new Map,this.namespaceName=h,this.namespaceFilter=d;let u=this.enabledEnvironments.has(this.environment),f=this.isNamespaceEnabled();this.isEnabled=u&&f;}getEnvironment(){return this.environment}isLoggingEnabled(){return this.isEnabled}namespace(e){if(this.namespaces.has(e))return this.namespaces.get(e);let t=this.namespaceName?`${this.namespaceName}:${e}`:e,s=new n({enabledEnvironments:Array.from(this.enabledEnvironments),prefix:this.prefix,forceEnvironment:this.environment,showTimestamp:this.showTimestamp,timestampFormat:this.timestampFormat,enabledNamespaces:this.namespaceFilter,_namespaceName:t});return this.namespaces.set(e,s),s}isNamespaceEnabled(){if(!this.namespaceFilter||this.namespaceFilter.length===0||!this.namespaceName||this.namespaceFilter.includes("*")||this.namespaceFilter.includes(this.namespaceName))return true;for(let e of this.namespaceFilter)if(e.endsWith(":*")){let t=e.slice(0,-2);if(this.namespaceName===t||this.namespaceName.startsWith(`${t}:`))return true}return false}getLogPrefix(){let e=this.prefix;if(this.namespaceName&&(e=`${e}:${this.namespaceName}`),this.showTimestamp){let t=p(this.timestampFormat);e=`${e} [${t}]`;}return e}log(...e){this.logWithLevel("log",...e);}info(...e){this.logWithLevel("info",...e);}warn(...e){this.logWithLevel("warn",...e);}error(...e){this.logWithLevel("error",...e);}debug(...e){this.logWithLevel("debug",...e);}group(e){this.isEnabled&&(e?console.group(this.formatMessage(e)):console.group());}groupCollapsed(e){this.isEnabled&&(e?console.groupCollapsed(this.formatMessage(e)):console.groupCollapsed());}groupEnd(){this.isEnabled&&console.groupEnd();}table(e){this.isEnabled&&(console.log(this.getLogPrefix()),console.table(e));}time(e){this.isEnabled&&console.time(this.formatMessage(e));}timeEnd(e){this.isEnabled&&console.timeEnd(this.formatMessage(e));}count(e){this.isEnabled&&console.count(e?this.formatMessage(e):this.prefix);}countReset(e){this.isEnabled&&console.countReset(e?this.formatMessage(e):this.prefix);}clear(){this.isEnabled&&console.clear();}logWithLevel(e,...t){if(!this.isEnabled)return;let s=console[e]||console.log,i=this.getLogPrefix();s(i,...t);}formatMessage(e){return `${this.getLogPrefix()} ${e}`}},w=new r;exports.Develog=r;exports.detectEnvironment=a;exports.develog=w;exports.formatTimestamp=p;//# sourceMappingURL=index.cjs.map
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/environment.ts","../src/utils.ts","../src/logger.ts"],"names":["DEFAULT_HOSTNAME_PATTERNS","detectEnvironment","customPatterns","hostname","patterns","formatTimestamp","format","now","formatTime","formatDateTime","date","hours","padZero","minutes","seconds","year","month","day","timeStr","num","Develog","_Develog","options","enabledEnvironments","customHostnamePatterns","prefix","forceEnvironment","showTimestamp","timestampFormat","enabledNamespaces","_namespaceName","envEnabled","namespaceEnabled","name","fullNamespace","namespacedLogger","pattern","timestamp","args","label","data","level","consoleMethod","logPrefix","message","develog"],"mappings":"aAKA,IAAMA,EAAyD,CAC7D,KAAA,CAAO,kDAAA,CACP,GAAA,CAAK,4BACL,KAAA,CAAO,yBAAA,CACP,UAAA,CAAY,+BAAA,CACZ,QAAS,IACX,CAAA,CAOO,SAASC,CAAAA,CACdC,EACa,CAEb,GAAI,OAAO,MAAA,CAAW,KAAe,CAAC,MAAA,CAAO,QAAA,CAC3C,OAAO,UAGT,IAAMC,CAAAA,CAAW,MAAA,CAAO,QAAA,CAAS,SAC3BC,CAAAA,CAAW,CAAE,GAAGJ,CAAAA,CAA2B,GAAGE,CAAe,CAAA,CAGnE,OAAIE,CAAAA,CAAS,KAAA,CAAM,KAAKD,CAAQ,CAAA,CACvB,OAAA,CAILC,CAAAA,CAAS,IAAI,IAAA,CAAKD,CAAQ,CAAA,CACrB,KAAA,CAILC,EAAS,KAAA,CAAM,IAAA,CAAKD,CAAQ,CAAA,CACvB,OAAA,CAILC,EAAS,UAAA,CAAW,IAAA,CAAKD,CAAQ,CAAA,CAC5B,aAIF,SACT,CC5CO,SAASE,CAAAA,CAAgBC,EAA0B,MAAA,CAAgB,CACxE,IAAMC,CAAAA,CAAM,IAAI,IAAA,CAEhB,OAAQD,GACN,KAAK,OACH,OAAOE,CAAAA,CAAWD,CAAG,CAAA,CACvB,KAAK,UAAA,CACH,OAAOE,CAAAA,CAAeF,CAAG,EAC3B,KAAK,KAAA,CACH,OAAOA,CAAAA,CAAI,aAAY,CACzB,KAAK,IAAA,CACH,OAAOA,EAAI,OAAA,EAAQ,CAAE,QAAA,EAAS,CAChC,QACE,OAAOC,CAAAA,CAAWD,CAAG,CACzB,CACF,CAKA,SAASC,CAAAA,CAAWE,CAAAA,CAAoB,CACtC,IAAMC,CAAAA,CAAQC,EAAQF,CAAAA,CAAK,QAAA,EAAU,CAAA,CAC/BG,CAAAA,CAAUD,CAAAA,CAAQF,CAAAA,CAAK,YAAY,CAAA,CACnCI,CAAAA,CAAUF,CAAAA,CAAQF,EAAK,UAAA,EAAY,CAAA,CACzC,OAAO,GAAGC,CAAK,CAAA,CAAA,EAAIE,CAAO,CAAA,CAAA,EAAIC,CAAO,EACvC,CAKA,SAASL,CAAAA,CAAeC,CAAAA,CAAoB,CAC1C,IAAMK,CAAAA,CAAOL,CAAAA,CAAK,WAAA,GACZM,CAAAA,CAAQJ,CAAAA,CAAQF,CAAAA,CAAK,QAAA,GAAa,CAAC,CAAA,CACnCO,EAAML,CAAAA,CAAQF,CAAAA,CAAK,SAAS,CAAA,CAC5BQ,CAAAA,CAAUV,CAAAA,CAAWE,CAAI,CAAA,CAC/B,OAAO,CAAA,EAAGK,CAAI,IAAIC,CAAK,CAAA,CAAA,EAAIC,CAAG,CAAA,CAAA,EAAIC,CAAO,CAAA,CAC3C,CAKA,SAASN,CAAAA,CAAQO,EAAqB,CACpC,OAAOA,CAAAA,CAAI,QAAA,GAAW,QAAA,CAAS,CAAA,CAAG,GAAG,CACvC,CC3CO,IAAMC,CAAAA,CAAN,MAAMC,CAAQ,CAWnB,WAAA,CAAYC,CAAAA,CAAyB,EAAC,CAAG,CACvC,GAAM,CACJ,mBAAA,CAAAC,CAAAA,CAAsB,CAAC,QAAS,KAAA,CAAO,OAAO,CAAA,CAC9C,sBAAA,CAAAC,EACA,MAAA,CAAAC,CAAAA,CAAS,WAAA,CACT,gBAAA,CAAAC,EACA,aAAA,CAAAC,CAAAA,CAAgB,MAChB,eAAA,CAAAC,CAAAA,CAAkB,OAClB,iBAAA,CAAAC,CAAAA,CACA,cAAA,CAAAC,CACF,EAAIR,CAAAA,CAGJ,IAAA,CAAK,WAAA,CAAcI,CAAAA,EAAoBzB,EAAkBuB,CAAsB,CAAA,CAC/E,IAAA,CAAK,mBAAA,CAAsB,IAAI,GAAA,CAAID,CAAmB,EACtD,IAAA,CAAK,MAAA,CAASE,EACd,IAAA,CAAK,aAAA,CAAgBE,CAAAA,CACrB,IAAA,CAAK,gBAAkBC,CAAAA,CACvB,IAAA,CAAK,UAAA,CAAa,IAAI,IACtB,IAAA,CAAK,aAAA,CAAgBE,CAAAA,CACrB,IAAA,CAAK,gBAAkBD,CAAAA,CAGvB,IAAME,EAAa,IAAA,CAAK,mBAAA,CAAoB,IAAI,IAAA,CAAK,WAAW,CAAA,CAG1DC,CAAAA,CAAmB,KAAK,kBAAA,EAAmB,CAEjD,IAAA,CAAK,SAAA,CAAYD,GAAcC,EACjC,CAKA,cAAA,EAA8B,CAC5B,OAAO,IAAA,CAAK,WACd,CAKA,gBAAA,EAA4B,CAC1B,OAAO,IAAA,CAAK,SACd,CAOA,SAAA,CAAUC,EAAuB,CAE/B,GAAI,IAAA,CAAK,UAAA,CAAW,IAAIA,CAAI,CAAA,CAC1B,OAAO,IAAA,CAAK,WAAW,GAAA,CAAIA,CAAI,EAIjC,IAAMC,CAAAA,CAAgB,KAAK,aAAA,CAAgB,CAAA,EAAG,IAAA,CAAK,aAAa,IAAID,CAAI,CAAA,CAAA,CAAKA,CAAAA,CAGvEE,CAAAA,CAAmB,IAAId,CAAAA,CAAQ,CACnC,mBAAA,CAAqB,KAAA,CAAM,KAAK,IAAA,CAAK,mBAAmB,EACxD,MAAA,CAAQ,IAAA,CAAK,OACb,gBAAA,CAAkB,IAAA,CAAK,WAAA,CACvB,aAAA,CAAe,KAAK,aAAA,CACpB,eAAA,CAAiB,IAAA,CAAK,eAAA,CACtB,kBAAmB,IAAA,CAAK,eAAA,CACxB,cAAA,CAAgBa,CAClB,CAAC,CAAA,CAED,OAAA,IAAA,CAAK,UAAA,CAAW,GAAA,CAAID,EAAME,CAAgB,CAAA,CACnCA,CACT,CAKQ,oBAA8B,CAiBpC,GAfI,CAAC,IAAA,CAAK,iBAAmB,IAAA,CAAK,eAAA,CAAgB,MAAA,GAAW,CAAA,EAKzD,CAAC,IAAA,CAAK,aAAA,EAKN,KAAK,eAAA,CAAgB,QAAA,CAAS,GAAG,CAAA,EAKjC,IAAA,CAAK,eAAA,CAAgB,QAAA,CAAS,KAAK,aAAa,CAAA,CAClD,OAAO,KAAA,CAIT,QAAWC,CAAAA,IAAW,IAAA,CAAK,eAAA,CACzB,GAAIA,EAAQ,QAAA,CAAS,IAAI,EAAG,CAC1B,IAAMX,EAASW,CAAAA,CAAQ,KAAA,CAAM,CAAA,CAAG,EAAE,EAClC,GAAI,IAAA,CAAK,aAAA,GAAkBX,CAAAA,EAAU,KAAK,aAAA,CAAc,UAAA,CAAW,CAAA,EAAGA,CAAM,GAAG,CAAA,CAC7E,OAAO,KAEX,CAGF,OAAO,MACT,CAKQ,YAAA,EAAuB,CAC7B,IAAIA,EAAS,IAAA,CAAK,MAAA,CAQlB,GALI,IAAA,CAAK,gBACPA,CAAAA,CAAS,CAAA,EAAGA,CAAM,CAAA,CAAA,EAAI,KAAK,aAAa,CAAA,CAAA,CAAA,CAItC,IAAA,CAAK,aAAA,CAAe,CACtB,IAAMY,CAAAA,CAAYhC,CAAAA,CAAgB,IAAA,CAAK,eAAe,CAAA,CACtDoB,CAAAA,CAAS,CAAA,EAAGA,CAAM,KAAKY,CAAS,CAAA,CAAA,EAClC,CAEA,OAAOZ,CACT,CAKA,GAAA,CAAA,GAAOa,EAAuB,CAC5B,IAAA,CAAK,aAAa,KAAA,CAAO,GAAGA,CAAI,EAClC,CAKA,IAAA,CAAA,GAAQA,CAAAA,CAAuB,CAC7B,IAAA,CAAK,aAAa,MAAA,CAAQ,GAAGA,CAAI,EACnC,CAKA,IAAA,CAAA,GAAQA,CAAAA,CAAuB,CAC7B,IAAA,CAAK,YAAA,CAAa,OAAQ,GAAGA,CAAI,EACnC,CAKA,SAASA,CAAAA,CAAuB,CAC9B,IAAA,CAAK,YAAA,CAAa,QAAS,GAAGA,CAAI,EACpC,CAKA,SAASA,CAAAA,CAAuB,CAC9B,KAAK,YAAA,CAAa,OAAA,CAAS,GAAGA,CAAI,EACpC,CAKA,KAAA,CAAMC,EAAsB,CACrB,IAAA,CAAK,SAAA,GACNA,CAAAA,CACF,QAAQ,KAAA,CAAM,IAAA,CAAK,aAAA,CAAcA,CAAK,CAAC,CAAA,CAEvC,OAAA,CAAQ,KAAA,EAAM,EAElB,CAKA,cAAA,CAAeA,CAAAA,CAAsB,CAC9B,IAAA,CAAK,YACNA,CAAAA,CACF,OAAA,CAAQ,cAAA,CAAe,IAAA,CAAK,cAAcA,CAAK,CAAC,CAAA,CAEhD,OAAA,CAAQ,gBAAe,EAE3B,CAKA,UAAiB,CACV,IAAA,CAAK,WACV,OAAA,CAAQ,QAAA,GACV,CAKA,MAAMC,CAAAA,CAAqB,CACpB,IAAA,CAAK,SAAA,GACV,QAAQ,GAAA,CAAI,IAAA,CAAK,YAAA,EAAc,EAC/B,OAAA,CAAQ,KAAA,CAAMA,CAAI,CAAA,EACpB,CAKA,KAAKD,CAAAA,CAAqB,CACnB,IAAA,CAAK,SAAA,EACV,QAAQ,IAAA,CAAK,IAAA,CAAK,aAAA,CAAcA,CAAK,CAAC,EACxC,CAKA,OAAA,CAAQA,CAAAA,CAAqB,CACtB,IAAA,CAAK,SAAA,EACV,QAAQ,OAAA,CAAQ,IAAA,CAAK,cAAcA,CAAK,CAAC,EAC3C,CAKA,MAAMA,CAAAA,CAAsB,CACrB,IAAA,CAAK,SAAA,EAER,QAAQ,KAAA,CADNA,CAAAA,CACY,IAAA,CAAK,aAAA,CAAcA,CAAK,CAAA,CAExB,IAAA,CAAK,MAFoB,EAI3C,CAKA,WAAWA,CAAAA,CAAsB,CAC1B,IAAA,CAAK,SAAA,EAER,QAAQ,UAAA,CADNA,CAAAA,CACiB,IAAA,CAAK,aAAA,CAAcA,CAAK,CAAA,CAExB,IAAA,CAAK,MAFoB,EAIhD,CAKA,KAAA,EAAc,CACP,KAAK,SAAA,EACV,OAAA,CAAQ,QACV,CAKQ,YAAA,CAAaE,CAAAA,CAAAA,GAAoBH,EAAuB,CAC9D,GAAI,CAAC,IAAA,CAAK,UAAW,OAErB,IAAMI,CAAAA,CAAgB,OAAA,CAAQD,CAAK,CAAA,EAAK,OAAA,CAAQ,IAC1CE,CAAAA,CAAY,IAAA,CAAK,cAAa,CACpCD,CAAAA,CAAcC,CAAAA,CAAW,GAAGL,CAAI,EAClC,CAKQ,aAAA,CAAcM,CAAAA,CAAyB,CAE7C,OAAO,CAAA,EADW,IAAA,CAAK,YAAA,EACJ,CAAA,CAAA,EAAIA,CAAO,EAChC,CACF,CAAA,CAKaC,EAAU,IAAIzB","file":"index.cjs","sourcesContent":["import type { Environment } from './types';\n\n/**\n * 기본 hostname 패턴 정의\n */\nconst DEFAULT_HOSTNAME_PATTERNS: Record<Environment, RegExp> = {\n local: /^(localhost|127\\.0\\.0\\.1|0\\.0\\.0\\.0|::1|\\[::1\\])/,\n dev: /(^|\\.)(dev|development)\\./,\n stage: /(^|\\.)(stage|staging)\\./,\n production: /(^|\\.)(prod|production|www)\\./,\n unknown: /.*/,\n};\n\n/**\n * 현재 브라우저의 hostname 또는 IP를 기반으로 실행 환경을 감지\n * @param customPatterns - 커스텀 hostname 패턴\n * @returns 감지된 환경\n */\nexport function detectEnvironment(\n customPatterns?: Partial<Record<Environment, RegExp>>,\n): Environment {\n // 브라우저 환경이 아닌 경우\n if (typeof window === 'undefined' || !window.location) {\n return 'unknown';\n }\n\n const hostname = window.location.hostname;\n const patterns = { ...DEFAULT_HOSTNAME_PATTERNS, ...customPatterns };\n\n // local 환경 체크 (최우선)\n if (patterns.local.test(hostname)) {\n return 'local';\n }\n\n // dev 환경 체크\n if (patterns.dev.test(hostname)) {\n return 'dev';\n }\n\n // stage 환경 체크\n if (patterns.stage.test(hostname)) {\n return 'stage';\n }\n\n // production 환경 체크\n if (patterns.production.test(hostname)) {\n return 'production';\n }\n\n // 매칭되지 않으면 unknown\n return 'unknown';\n}\n","import type { TimestampFormat } from './types';\n\n/**\n * 현재 시간을 지정된 포맷으로 변환\n * @param format - 타임스탬프 포맷\n * @returns 포맷된 타임스탬프 문자열\n */\nexport function formatTimestamp(format: TimestampFormat = 'time'): string {\n const now = new Date();\n\n switch (format) {\n case 'time':\n return formatTime(now);\n case 'datetime':\n return formatDateTime(now);\n case 'iso':\n return now.toISOString();\n case 'ms':\n return now.getTime().toString();\n default:\n return formatTime(now);\n }\n}\n\n/**\n * HH:MM:SS 포맷\n */\nfunction formatTime(date: Date): string {\n const hours = padZero(date.getHours());\n const minutes = padZero(date.getMinutes());\n const seconds = padZero(date.getSeconds());\n return `${hours}:${minutes}:${seconds}`;\n}\n\n/**\n * YYYY-MM-DD HH:MM:SS 포맷\n */\nfunction formatDateTime(date: Date): string {\n const year = date.getFullYear();\n const month = padZero(date.getMonth() + 1);\n const day = padZero(date.getDate());\n const timeStr = formatTime(date);\n return `${year}-${month}-${day} ${timeStr}`;\n}\n\n/**\n * 숫자를 두 자리로 패딩\n */\nfunction padZero(num: number): string {\n return num.toString().padStart(2, '0');\n}\n","import { detectEnvironment } from './environment';\nimport type { Environment, LoggerOptions, LogLevel, TimestampFormat } from './types';\nimport { formatTimestamp } from './utils';\n\n/**\n * develog - 브라우저 환경 기반 로거\n */\nexport class Develog {\n private readonly environment: Environment;\n private readonly enabledEnvironments: Set<Environment>;\n private readonly prefix: string;\n private readonly isEnabled: boolean;\n private readonly showTimestamp: boolean;\n private readonly timestampFormat: TimestampFormat;\n private readonly namespaces: Map<string, Develog>;\n private readonly namespaceName?: string;\n private readonly namespaceFilter?: string[];\n\n constructor(options: LoggerOptions = {}) {\n const {\n enabledEnvironments = ['local', 'dev', 'stage'],\n customHostnamePatterns,\n prefix = '[develog]',\n forceEnvironment,\n showTimestamp = false,\n timestampFormat = 'time',\n enabledNamespaces,\n _namespaceName,\n } = options;\n\n // 환경 감지\n this.environment = forceEnvironment || detectEnvironment(customHostnamePatterns);\n this.enabledEnvironments = new Set(enabledEnvironments);\n this.prefix = prefix;\n this.showTimestamp = showTimestamp;\n this.timestampFormat = timestampFormat;\n this.namespaces = new Map();\n this.namespaceName = _namespaceName;\n this.namespaceFilter = enabledNamespaces;\n\n // 환경 기반 활성화 체크\n const envEnabled = this.enabledEnvironments.has(this.environment);\n\n // 네임스페이스 필터링 체크\n const namespaceEnabled = this.isNamespaceEnabled();\n\n this.isEnabled = envEnabled && namespaceEnabled;\n }\n\n /**\n * 현재 감지된 환경을 반환\n */\n getEnvironment(): Environment {\n return this.environment;\n }\n\n /**\n * 로깅이 활성화되어 있는지 확인\n */\n isLoggingEnabled(): boolean {\n return this.isEnabled;\n }\n\n /**\n * 네임스페이스별 로거 인스턴스 생성\n * @param name - 네임스페이스 이름\n * @returns 네임스페이스 로거 인스턴스\n */\n namespace(name: string): Develog {\n // 이미 생성된 네임스페이스가 있으면 재사용\n if (this.namespaces.has(name)) {\n return this.namespaces.get(name)!;\n }\n\n // 계층 구조 지원: 부모 네임스페이스가 있으면 연결\n const fullNamespace = this.namespaceName ? `${this.namespaceName}:${name}` : name;\n\n // 새로운 네임스페이스 로거 생성\n const namespacedLogger = new Develog({\n enabledEnvironments: Array.from(this.enabledEnvironments),\n prefix: this.prefix,\n forceEnvironment: this.environment,\n showTimestamp: this.showTimestamp,\n timestampFormat: this.timestampFormat,\n enabledNamespaces: this.namespaceFilter,\n _namespaceName: fullNamespace,\n });\n\n this.namespaces.set(name, namespacedLogger);\n return namespacedLogger;\n }\n\n /**\n * 현재 네임스페이스가 활성화되어 있는지 확인\n */\n private isNamespaceEnabled(): boolean {\n // 네임스페이스 필터가 없으면 모두 활성화\n if (!this.namespaceFilter || this.namespaceFilter.length === 0) {\n return true;\n }\n\n // 네임스페이스가 없는 루트 로거는 항상 활성화\n if (!this.namespaceName) {\n return true;\n }\n\n // '*'는 모든 네임스페이스 활성화\n if (this.namespaceFilter.includes('*')) {\n return true;\n }\n\n // 정확한 매칭 확인\n if (this.namespaceFilter.includes(this.namespaceName)) {\n return true;\n }\n\n // 와일드카드 패턴 매칭\n for (const pattern of this.namespaceFilter) {\n if (pattern.endsWith(':*')) {\n const prefix = pattern.slice(0, -2);\n if (this.namespaceName === prefix || this.namespaceName.startsWith(`${prefix}:`)) {\n return true;\n }\n }\n }\n\n return false;\n }\n\n /**\n * 로그 출력 앞에 붙을 prefix 생성\n */\n private getLogPrefix(): string {\n let prefix = this.prefix;\n\n // 네임스페이스 추가\n if (this.namespaceName) {\n prefix = `${prefix}:${this.namespaceName}`;\n }\n\n // 타임스탬프 추가\n if (this.showTimestamp) {\n const timestamp = formatTimestamp(this.timestampFormat);\n prefix = `${prefix} [${timestamp}]`;\n }\n\n return prefix;\n }\n\n /**\n * 일반 로그 출력\n */\n log(...args: unknown[]): void {\n this.logWithLevel('log', ...args);\n }\n\n /**\n * 정보 로그 출력\n */\n info(...args: unknown[]): void {\n this.logWithLevel('info', ...args);\n }\n\n /**\n * 경고 로그 출력\n */\n warn(...args: unknown[]): void {\n this.logWithLevel('warn', ...args);\n }\n\n /**\n * 에러 로그 출력\n */\n error(...args: unknown[]): void {\n this.logWithLevel('error', ...args);\n }\n\n /**\n * 디버그 로그 출력\n */\n debug(...args: unknown[]): void {\n this.logWithLevel('debug', ...args);\n }\n\n /**\n * 그룹 시작\n */\n group(label?: string): void {\n if (!this.isEnabled) return;\n if (label) {\n console.group(this.formatMessage(label));\n } else {\n console.group();\n }\n }\n\n /**\n * 그룹 시작 (접혀있는 상태)\n */\n groupCollapsed(label?: string): void {\n if (!this.isEnabled) return;\n if (label) {\n console.groupCollapsed(this.formatMessage(label));\n } else {\n console.groupCollapsed();\n }\n }\n\n /**\n * 그룹 종료\n */\n groupEnd(): void {\n if (!this.isEnabled) return;\n console.groupEnd();\n }\n\n /**\n * 테이블 형태로 출력\n */\n table(data: unknown): void {\n if (!this.isEnabled) return;\n console.log(this.getLogPrefix());\n console.table(data);\n }\n\n /**\n * 시간 측정 시작\n */\n time(label: string): void {\n if (!this.isEnabled) return;\n console.time(this.formatMessage(label));\n }\n\n /**\n * 시간 측정 종료 및 출력\n */\n timeEnd(label: string): void {\n if (!this.isEnabled) return;\n console.timeEnd(this.formatMessage(label));\n }\n\n /**\n * 실행 횟수 카운트\n */\n count(label?: string): void {\n if (!this.isEnabled) return;\n if (label) {\n console.count(this.formatMessage(label));\n } else {\n console.count(this.prefix);\n }\n }\n\n /**\n * 카운트 초기화\n */\n countReset(label?: string): void {\n if (!this.isEnabled) return;\n if (label) {\n console.countReset(this.formatMessage(label));\n } else {\n console.countReset(this.prefix);\n }\n }\n\n /**\n * 콘솔 지우기\n */\n clear(): void {\n if (!this.isEnabled) return;\n console.clear();\n }\n\n /**\n * 레벨에 따른 로그 출력\n */\n private logWithLevel(level: LogLevel, ...args: unknown[]): void {\n if (!this.isEnabled) return;\n\n const consoleMethod = console[level] || console.log;\n const logPrefix = this.getLogPrefix();\n consoleMethod(logPrefix, ...args);\n }\n\n /**\n * 메시지에 prefix 추가\n */\n private formatMessage(message: string): string {\n const logPrefix = this.getLogPrefix();\n return `${logPrefix} ${message}`;\n }\n}\n\n/**\n * 기본 인스턴스 생성 및 export\n */\nexport const develog = new Develog();\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 실행 환경을 나타내는 타입
|
|
3
|
+
*/
|
|
4
|
+
type Environment = 'local' | 'dev' | 'stage' | 'production' | 'unknown';
|
|
5
|
+
/**
|
|
6
|
+
* 타임스탬프 포맷 타입
|
|
7
|
+
*/
|
|
8
|
+
type TimestampFormat = 'time' | 'datetime' | 'iso' | 'ms';
|
|
9
|
+
/**
|
|
10
|
+
* Logger 설정 옵션
|
|
11
|
+
*/
|
|
12
|
+
interface LoggerOptions {
|
|
13
|
+
/**
|
|
14
|
+
* 로깅이 활성화될 환경 목록
|
|
15
|
+
* @default ['local', 'dev', 'stage']
|
|
16
|
+
*/
|
|
17
|
+
enabledEnvironments?: Environment[];
|
|
18
|
+
/**
|
|
19
|
+
* 환경 감지에 사용할 커스텀 hostname 패턴
|
|
20
|
+
*/
|
|
21
|
+
customHostnamePatterns?: {
|
|
22
|
+
[key in Environment]?: RegExp;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* 로그 출력 앞에 붙을 prefix
|
|
26
|
+
* @default '[develog]'
|
|
27
|
+
*/
|
|
28
|
+
prefix?: string;
|
|
29
|
+
/**
|
|
30
|
+
* 강제로 환경을 설정 (자동 감지 무시)
|
|
31
|
+
*/
|
|
32
|
+
forceEnvironment?: Environment;
|
|
33
|
+
/**
|
|
34
|
+
* 타임스탬프 표시 여부
|
|
35
|
+
* @default false
|
|
36
|
+
*/
|
|
37
|
+
showTimestamp?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* 타임스탬프 포맷
|
|
40
|
+
* - 'time': HH:MM:SS
|
|
41
|
+
* - 'datetime': YYYY-MM-DD HH:MM:SS
|
|
42
|
+
* - 'iso': ISO 8601 형식
|
|
43
|
+
* - 'ms': Unix timestamp (밀리초)
|
|
44
|
+
* @default 'time'
|
|
45
|
+
*/
|
|
46
|
+
timestampFormat?: TimestampFormat;
|
|
47
|
+
/**
|
|
48
|
+
* 활성화할 네임스페이스 목록
|
|
49
|
+
* - 문자열 배열: 정확한 매칭 ['API', 'DB']
|
|
50
|
+
* - 와일드카드 지원: ['API:*', 'DB']
|
|
51
|
+
* - '*'는 모든 네임스페이스 활성화
|
|
52
|
+
* @default undefined (모든 네임스페이스 활성화)
|
|
53
|
+
*/
|
|
54
|
+
enabledNamespaces?: string[];
|
|
55
|
+
/**
|
|
56
|
+
* 내부 전용: 현재 네임스페이스 이름
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
59
|
+
_namespaceName?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 로그 레벨
|
|
63
|
+
*/
|
|
64
|
+
type LogLevel = 'log' | 'info' | 'warn' | 'error' | 'debug';
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* develog - 브라우저 환경 기반 로거
|
|
68
|
+
*/
|
|
69
|
+
declare class Develog {
|
|
70
|
+
private readonly environment;
|
|
71
|
+
private readonly enabledEnvironments;
|
|
72
|
+
private readonly prefix;
|
|
73
|
+
private readonly isEnabled;
|
|
74
|
+
private readonly showTimestamp;
|
|
75
|
+
private readonly timestampFormat;
|
|
76
|
+
private readonly namespaces;
|
|
77
|
+
private readonly namespaceName?;
|
|
78
|
+
private readonly namespaceFilter?;
|
|
79
|
+
constructor(options?: LoggerOptions);
|
|
80
|
+
/**
|
|
81
|
+
* 현재 감지된 환경을 반환
|
|
82
|
+
*/
|
|
83
|
+
getEnvironment(): Environment;
|
|
84
|
+
/**
|
|
85
|
+
* 로깅이 활성화되어 있는지 확인
|
|
86
|
+
*/
|
|
87
|
+
isLoggingEnabled(): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* 네임스페이스별 로거 인스턴스 생성
|
|
90
|
+
* @param name - 네임스페이스 이름
|
|
91
|
+
* @returns 네임스페이스 로거 인스턴스
|
|
92
|
+
*/
|
|
93
|
+
namespace(name: string): Develog;
|
|
94
|
+
/**
|
|
95
|
+
* 현재 네임스페이스가 활성화되어 있는지 확인
|
|
96
|
+
*/
|
|
97
|
+
private isNamespaceEnabled;
|
|
98
|
+
/**
|
|
99
|
+
* 로그 출력 앞에 붙을 prefix 생성
|
|
100
|
+
*/
|
|
101
|
+
private getLogPrefix;
|
|
102
|
+
/**
|
|
103
|
+
* 일반 로그 출력
|
|
104
|
+
*/
|
|
105
|
+
log(...args: unknown[]): void;
|
|
106
|
+
/**
|
|
107
|
+
* 정보 로그 출력
|
|
108
|
+
*/
|
|
109
|
+
info(...args: unknown[]): void;
|
|
110
|
+
/**
|
|
111
|
+
* 경고 로그 출력
|
|
112
|
+
*/
|
|
113
|
+
warn(...args: unknown[]): void;
|
|
114
|
+
/**
|
|
115
|
+
* 에러 로그 출력
|
|
116
|
+
*/
|
|
117
|
+
error(...args: unknown[]): void;
|
|
118
|
+
/**
|
|
119
|
+
* 디버그 로그 출력
|
|
120
|
+
*/
|
|
121
|
+
debug(...args: unknown[]): void;
|
|
122
|
+
/**
|
|
123
|
+
* 그룹 시작
|
|
124
|
+
*/
|
|
125
|
+
group(label?: string): void;
|
|
126
|
+
/**
|
|
127
|
+
* 그룹 시작 (접혀있는 상태)
|
|
128
|
+
*/
|
|
129
|
+
groupCollapsed(label?: string): void;
|
|
130
|
+
/**
|
|
131
|
+
* 그룹 종료
|
|
132
|
+
*/
|
|
133
|
+
groupEnd(): void;
|
|
134
|
+
/**
|
|
135
|
+
* 테이블 형태로 출력
|
|
136
|
+
*/
|
|
137
|
+
table(data: unknown): void;
|
|
138
|
+
/**
|
|
139
|
+
* 시간 측정 시작
|
|
140
|
+
*/
|
|
141
|
+
time(label: string): void;
|
|
142
|
+
/**
|
|
143
|
+
* 시간 측정 종료 및 출력
|
|
144
|
+
*/
|
|
145
|
+
timeEnd(label: string): void;
|
|
146
|
+
/**
|
|
147
|
+
* 실행 횟수 카운트
|
|
148
|
+
*/
|
|
149
|
+
count(label?: string): void;
|
|
150
|
+
/**
|
|
151
|
+
* 카운트 초기화
|
|
152
|
+
*/
|
|
153
|
+
countReset(label?: string): void;
|
|
154
|
+
/**
|
|
155
|
+
* 콘솔 지우기
|
|
156
|
+
*/
|
|
157
|
+
clear(): void;
|
|
158
|
+
/**
|
|
159
|
+
* 레벨에 따른 로그 출력
|
|
160
|
+
*/
|
|
161
|
+
private logWithLevel;
|
|
162
|
+
/**
|
|
163
|
+
* 메시지에 prefix 추가
|
|
164
|
+
*/
|
|
165
|
+
private formatMessage;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* 기본 인스턴스 생성 및 export
|
|
169
|
+
*/
|
|
170
|
+
declare const develog: Develog;
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* 현재 브라우저의 hostname 또는 IP를 기반으로 실행 환경을 감지
|
|
174
|
+
* @param customPatterns - 커스텀 hostname 패턴
|
|
175
|
+
* @returns 감지된 환경
|
|
176
|
+
*/
|
|
177
|
+
declare function detectEnvironment(customPatterns?: Partial<Record<Environment, RegExp>>): Environment;
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* 현재 시간을 지정된 포맷으로 변환
|
|
181
|
+
* @param format - 타임스탬프 포맷
|
|
182
|
+
* @returns 포맷된 타임스탬프 문자열
|
|
183
|
+
*/
|
|
184
|
+
declare function formatTimestamp(format?: TimestampFormat): string;
|
|
185
|
+
|
|
186
|
+
export { Develog, type Environment, type LogLevel, type LoggerOptions, type TimestampFormat, detectEnvironment, develog, formatTimestamp };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 실행 환경을 나타내는 타입
|
|
3
|
+
*/
|
|
4
|
+
type Environment = 'local' | 'dev' | 'stage' | 'production' | 'unknown';
|
|
5
|
+
/**
|
|
6
|
+
* 타임스탬프 포맷 타입
|
|
7
|
+
*/
|
|
8
|
+
type TimestampFormat = 'time' | 'datetime' | 'iso' | 'ms';
|
|
9
|
+
/**
|
|
10
|
+
* Logger 설정 옵션
|
|
11
|
+
*/
|
|
12
|
+
interface LoggerOptions {
|
|
13
|
+
/**
|
|
14
|
+
* 로깅이 활성화될 환경 목록
|
|
15
|
+
* @default ['local', 'dev', 'stage']
|
|
16
|
+
*/
|
|
17
|
+
enabledEnvironments?: Environment[];
|
|
18
|
+
/**
|
|
19
|
+
* 환경 감지에 사용할 커스텀 hostname 패턴
|
|
20
|
+
*/
|
|
21
|
+
customHostnamePatterns?: {
|
|
22
|
+
[key in Environment]?: RegExp;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* 로그 출력 앞에 붙을 prefix
|
|
26
|
+
* @default '[develog]'
|
|
27
|
+
*/
|
|
28
|
+
prefix?: string;
|
|
29
|
+
/**
|
|
30
|
+
* 강제로 환경을 설정 (자동 감지 무시)
|
|
31
|
+
*/
|
|
32
|
+
forceEnvironment?: Environment;
|
|
33
|
+
/**
|
|
34
|
+
* 타임스탬프 표시 여부
|
|
35
|
+
* @default false
|
|
36
|
+
*/
|
|
37
|
+
showTimestamp?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* 타임스탬프 포맷
|
|
40
|
+
* - 'time': HH:MM:SS
|
|
41
|
+
* - 'datetime': YYYY-MM-DD HH:MM:SS
|
|
42
|
+
* - 'iso': ISO 8601 형식
|
|
43
|
+
* - 'ms': Unix timestamp (밀리초)
|
|
44
|
+
* @default 'time'
|
|
45
|
+
*/
|
|
46
|
+
timestampFormat?: TimestampFormat;
|
|
47
|
+
/**
|
|
48
|
+
* 활성화할 네임스페이스 목록
|
|
49
|
+
* - 문자열 배열: 정확한 매칭 ['API', 'DB']
|
|
50
|
+
* - 와일드카드 지원: ['API:*', 'DB']
|
|
51
|
+
* - '*'는 모든 네임스페이스 활성화
|
|
52
|
+
* @default undefined (모든 네임스페이스 활성화)
|
|
53
|
+
*/
|
|
54
|
+
enabledNamespaces?: string[];
|
|
55
|
+
/**
|
|
56
|
+
* 내부 전용: 현재 네임스페이스 이름
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
59
|
+
_namespaceName?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 로그 레벨
|
|
63
|
+
*/
|
|
64
|
+
type LogLevel = 'log' | 'info' | 'warn' | 'error' | 'debug';
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* develog - 브라우저 환경 기반 로거
|
|
68
|
+
*/
|
|
69
|
+
declare class Develog {
|
|
70
|
+
private readonly environment;
|
|
71
|
+
private readonly enabledEnvironments;
|
|
72
|
+
private readonly prefix;
|
|
73
|
+
private readonly isEnabled;
|
|
74
|
+
private readonly showTimestamp;
|
|
75
|
+
private readonly timestampFormat;
|
|
76
|
+
private readonly namespaces;
|
|
77
|
+
private readonly namespaceName?;
|
|
78
|
+
private readonly namespaceFilter?;
|
|
79
|
+
constructor(options?: LoggerOptions);
|
|
80
|
+
/**
|
|
81
|
+
* 현재 감지된 환경을 반환
|
|
82
|
+
*/
|
|
83
|
+
getEnvironment(): Environment;
|
|
84
|
+
/**
|
|
85
|
+
* 로깅이 활성화되어 있는지 확인
|
|
86
|
+
*/
|
|
87
|
+
isLoggingEnabled(): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* 네임스페이스별 로거 인스턴스 생성
|
|
90
|
+
* @param name - 네임스페이스 이름
|
|
91
|
+
* @returns 네임스페이스 로거 인스턴스
|
|
92
|
+
*/
|
|
93
|
+
namespace(name: string): Develog;
|
|
94
|
+
/**
|
|
95
|
+
* 현재 네임스페이스가 활성화되어 있는지 확인
|
|
96
|
+
*/
|
|
97
|
+
private isNamespaceEnabled;
|
|
98
|
+
/**
|
|
99
|
+
* 로그 출력 앞에 붙을 prefix 생성
|
|
100
|
+
*/
|
|
101
|
+
private getLogPrefix;
|
|
102
|
+
/**
|
|
103
|
+
* 일반 로그 출력
|
|
104
|
+
*/
|
|
105
|
+
log(...args: unknown[]): void;
|
|
106
|
+
/**
|
|
107
|
+
* 정보 로그 출력
|
|
108
|
+
*/
|
|
109
|
+
info(...args: unknown[]): void;
|
|
110
|
+
/**
|
|
111
|
+
* 경고 로그 출력
|
|
112
|
+
*/
|
|
113
|
+
warn(...args: unknown[]): void;
|
|
114
|
+
/**
|
|
115
|
+
* 에러 로그 출력
|
|
116
|
+
*/
|
|
117
|
+
error(...args: unknown[]): void;
|
|
118
|
+
/**
|
|
119
|
+
* 디버그 로그 출력
|
|
120
|
+
*/
|
|
121
|
+
debug(...args: unknown[]): void;
|
|
122
|
+
/**
|
|
123
|
+
* 그룹 시작
|
|
124
|
+
*/
|
|
125
|
+
group(label?: string): void;
|
|
126
|
+
/**
|
|
127
|
+
* 그룹 시작 (접혀있는 상태)
|
|
128
|
+
*/
|
|
129
|
+
groupCollapsed(label?: string): void;
|
|
130
|
+
/**
|
|
131
|
+
* 그룹 종료
|
|
132
|
+
*/
|
|
133
|
+
groupEnd(): void;
|
|
134
|
+
/**
|
|
135
|
+
* 테이블 형태로 출력
|
|
136
|
+
*/
|
|
137
|
+
table(data: unknown): void;
|
|
138
|
+
/**
|
|
139
|
+
* 시간 측정 시작
|
|
140
|
+
*/
|
|
141
|
+
time(label: string): void;
|
|
142
|
+
/**
|
|
143
|
+
* 시간 측정 종료 및 출력
|
|
144
|
+
*/
|
|
145
|
+
timeEnd(label: string): void;
|
|
146
|
+
/**
|
|
147
|
+
* 실행 횟수 카운트
|
|
148
|
+
*/
|
|
149
|
+
count(label?: string): void;
|
|
150
|
+
/**
|
|
151
|
+
* 카운트 초기화
|
|
152
|
+
*/
|
|
153
|
+
countReset(label?: string): void;
|
|
154
|
+
/**
|
|
155
|
+
* 콘솔 지우기
|
|
156
|
+
*/
|
|
157
|
+
clear(): void;
|
|
158
|
+
/**
|
|
159
|
+
* 레벨에 따른 로그 출력
|
|
160
|
+
*/
|
|
161
|
+
private logWithLevel;
|
|
162
|
+
/**
|
|
163
|
+
* 메시지에 prefix 추가
|
|
164
|
+
*/
|
|
165
|
+
private formatMessage;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* 기본 인스턴스 생성 및 export
|
|
169
|
+
*/
|
|
170
|
+
declare const develog: Develog;
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* 현재 브라우저의 hostname 또는 IP를 기반으로 실행 환경을 감지
|
|
174
|
+
* @param customPatterns - 커스텀 hostname 패턴
|
|
175
|
+
* @returns 감지된 환경
|
|
176
|
+
*/
|
|
177
|
+
declare function detectEnvironment(customPatterns?: Partial<Record<Environment, RegExp>>): Environment;
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* 현재 시간을 지정된 포맷으로 변환
|
|
181
|
+
* @param format - 타임스탬프 포맷
|
|
182
|
+
* @returns 포맷된 타임스탬프 문자열
|
|
183
|
+
*/
|
|
184
|
+
declare function formatTimestamp(format?: TimestampFormat): string;
|
|
185
|
+
|
|
186
|
+
export { Develog, type Environment, type LogLevel, type LoggerOptions, type TimestampFormat, detectEnvironment, develog, formatTimestamp };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var v={local:/^(localhost|127\.0\.0\.1|0\.0\.0\.0|::1|\[::1\])/,dev:/(^|\.)(dev|development)\./,stage:/(^|\.)(stage|staging)\./,production:/(^|\.)(prod|production|www)\./,unknown:/.*/};function a(n){if(typeof window>"u"||!window.location)return "unknown";let e=window.location.hostname,t={...v,...n};return t.local.test(e)?"local":t.dev.test(e)?"dev":t.stage.test(e)?"stage":t.production.test(e)?"production":"unknown"}function p(n="time"){let e=new Date;switch(n){case "time":return m(e);case "datetime":return E(e);case "iso":return e.toISOString();case "ms":return e.getTime().toString();default:return m(e)}}function m(n){let e=o(n.getHours()),t=o(n.getMinutes()),s=o(n.getSeconds());return `${e}:${t}:${s}`}function E(n){let e=n.getFullYear(),t=o(n.getMonth()+1),s=o(n.getDate()),i=m(n);return `${e}-${t}-${s} ${i}`}function o(n){return n.toString().padStart(2,"0")}var r=class n{constructor(e={}){let{enabledEnvironments:t=["local","dev","stage"],customHostnamePatterns:s,prefix:i="[develog]",forceEnvironment:l,showTimestamp:c=false,timestampFormat:g="time",enabledNamespaces:d,_namespaceName:h}=e;this.environment=l||a(s),this.enabledEnvironments=new Set(t),this.prefix=i,this.showTimestamp=c,this.timestampFormat=g,this.namespaces=new Map,this.namespaceName=h,this.namespaceFilter=d;let u=this.enabledEnvironments.has(this.environment),f=this.isNamespaceEnabled();this.isEnabled=u&&f;}getEnvironment(){return this.environment}isLoggingEnabled(){return this.isEnabled}namespace(e){if(this.namespaces.has(e))return this.namespaces.get(e);let t=this.namespaceName?`${this.namespaceName}:${e}`:e,s=new n({enabledEnvironments:Array.from(this.enabledEnvironments),prefix:this.prefix,forceEnvironment:this.environment,showTimestamp:this.showTimestamp,timestampFormat:this.timestampFormat,enabledNamespaces:this.namespaceFilter,_namespaceName:t});return this.namespaces.set(e,s),s}isNamespaceEnabled(){if(!this.namespaceFilter||this.namespaceFilter.length===0||!this.namespaceName||this.namespaceFilter.includes("*")||this.namespaceFilter.includes(this.namespaceName))return true;for(let e of this.namespaceFilter)if(e.endsWith(":*")){let t=e.slice(0,-2);if(this.namespaceName===t||this.namespaceName.startsWith(`${t}:`))return true}return false}getLogPrefix(){let e=this.prefix;if(this.namespaceName&&(e=`${e}:${this.namespaceName}`),this.showTimestamp){let t=p(this.timestampFormat);e=`${e} [${t}]`;}return e}log(...e){this.logWithLevel("log",...e);}info(...e){this.logWithLevel("info",...e);}warn(...e){this.logWithLevel("warn",...e);}error(...e){this.logWithLevel("error",...e);}debug(...e){this.logWithLevel("debug",...e);}group(e){this.isEnabled&&(e?console.group(this.formatMessage(e)):console.group());}groupCollapsed(e){this.isEnabled&&(e?console.groupCollapsed(this.formatMessage(e)):console.groupCollapsed());}groupEnd(){this.isEnabled&&console.groupEnd();}table(e){this.isEnabled&&(console.log(this.getLogPrefix()),console.table(e));}time(e){this.isEnabled&&console.time(this.formatMessage(e));}timeEnd(e){this.isEnabled&&console.timeEnd(this.formatMessage(e));}count(e){this.isEnabled&&console.count(e?this.formatMessage(e):this.prefix);}countReset(e){this.isEnabled&&console.countReset(e?this.formatMessage(e):this.prefix);}clear(){this.isEnabled&&console.clear();}logWithLevel(e,...t){if(!this.isEnabled)return;let s=console[e]||console.log,i=this.getLogPrefix();s(i,...t);}formatMessage(e){return `${this.getLogPrefix()} ${e}`}},w=new r;export{r as Develog,a as detectEnvironment,w as develog,p as formatTimestamp};//# sourceMappingURL=index.js.map
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/environment.ts","../src/utils.ts","../src/logger.ts"],"names":["DEFAULT_HOSTNAME_PATTERNS","detectEnvironment","customPatterns","hostname","patterns","formatTimestamp","format","now","formatTime","formatDateTime","date","hours","padZero","minutes","seconds","year","month","day","timeStr","num","Develog","_Develog","options","enabledEnvironments","customHostnamePatterns","prefix","forceEnvironment","showTimestamp","timestampFormat","enabledNamespaces","_namespaceName","envEnabled","namespaceEnabled","name","fullNamespace","namespacedLogger","pattern","timestamp","args","label","data","level","consoleMethod","logPrefix","message","develog"],"mappings":"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","file":"index.js","sourcesContent":["import type { Environment } from './types';\n\n/**\n * 기본 hostname 패턴 정의\n */\nconst DEFAULT_HOSTNAME_PATTERNS: Record<Environment, RegExp> = {\n local: /^(localhost|127\\.0\\.0\\.1|0\\.0\\.0\\.0|::1|\\[::1\\])/,\n dev: /(^|\\.)(dev|development)\\./,\n stage: /(^|\\.)(stage|staging)\\./,\n production: /(^|\\.)(prod|production|www)\\./,\n unknown: /.*/,\n};\n\n/**\n * 현재 브라우저의 hostname 또는 IP를 기반으로 실행 환경을 감지\n * @param customPatterns - 커스텀 hostname 패턴\n * @returns 감지된 환경\n */\nexport function detectEnvironment(\n customPatterns?: Partial<Record<Environment, RegExp>>,\n): Environment {\n // 브라우저 환경이 아닌 경우\n if (typeof window === 'undefined' || !window.location) {\n return 'unknown';\n }\n\n const hostname = window.location.hostname;\n const patterns = { ...DEFAULT_HOSTNAME_PATTERNS, ...customPatterns };\n\n // local 환경 체크 (최우선)\n if (patterns.local.test(hostname)) {\n return 'local';\n }\n\n // dev 환경 체크\n if (patterns.dev.test(hostname)) {\n return 'dev';\n }\n\n // stage 환경 체크\n if (patterns.stage.test(hostname)) {\n return 'stage';\n }\n\n // production 환경 체크\n if (patterns.production.test(hostname)) {\n return 'production';\n }\n\n // 매칭되지 않으면 unknown\n return 'unknown';\n}\n","import type { TimestampFormat } from './types';\n\n/**\n * 현재 시간을 지정된 포맷으로 변환\n * @param format - 타임스탬프 포맷\n * @returns 포맷된 타임스탬프 문자열\n */\nexport function formatTimestamp(format: TimestampFormat = 'time'): string {\n const now = new Date();\n\n switch (format) {\n case 'time':\n return formatTime(now);\n case 'datetime':\n return formatDateTime(now);\n case 'iso':\n return now.toISOString();\n case 'ms':\n return now.getTime().toString();\n default:\n return formatTime(now);\n }\n}\n\n/**\n * HH:MM:SS 포맷\n */\nfunction formatTime(date: Date): string {\n const hours = padZero(date.getHours());\n const minutes = padZero(date.getMinutes());\n const seconds = padZero(date.getSeconds());\n return `${hours}:${minutes}:${seconds}`;\n}\n\n/**\n * YYYY-MM-DD HH:MM:SS 포맷\n */\nfunction formatDateTime(date: Date): string {\n const year = date.getFullYear();\n const month = padZero(date.getMonth() + 1);\n const day = padZero(date.getDate());\n const timeStr = formatTime(date);\n return `${year}-${month}-${day} ${timeStr}`;\n}\n\n/**\n * 숫자를 두 자리로 패딩\n */\nfunction padZero(num: number): string {\n return num.toString().padStart(2, '0');\n}\n","import { detectEnvironment } from './environment';\nimport type { Environment, LoggerOptions, LogLevel, TimestampFormat } from './types';\nimport { formatTimestamp } from './utils';\n\n/**\n * develog - 브라우저 환경 기반 로거\n */\nexport class Develog {\n private readonly environment: Environment;\n private readonly enabledEnvironments: Set<Environment>;\n private readonly prefix: string;\n private readonly isEnabled: boolean;\n private readonly showTimestamp: boolean;\n private readonly timestampFormat: TimestampFormat;\n private readonly namespaces: Map<string, Develog>;\n private readonly namespaceName?: string;\n private readonly namespaceFilter?: string[];\n\n constructor(options: LoggerOptions = {}) {\n const {\n enabledEnvironments = ['local', 'dev', 'stage'],\n customHostnamePatterns,\n prefix = '[develog]',\n forceEnvironment,\n showTimestamp = false,\n timestampFormat = 'time',\n enabledNamespaces,\n _namespaceName,\n } = options;\n\n // 환경 감지\n this.environment = forceEnvironment || detectEnvironment(customHostnamePatterns);\n this.enabledEnvironments = new Set(enabledEnvironments);\n this.prefix = prefix;\n this.showTimestamp = showTimestamp;\n this.timestampFormat = timestampFormat;\n this.namespaces = new Map();\n this.namespaceName = _namespaceName;\n this.namespaceFilter = enabledNamespaces;\n\n // 환경 기반 활성화 체크\n const envEnabled = this.enabledEnvironments.has(this.environment);\n\n // 네임스페이스 필터링 체크\n const namespaceEnabled = this.isNamespaceEnabled();\n\n this.isEnabled = envEnabled && namespaceEnabled;\n }\n\n /**\n * 현재 감지된 환경을 반환\n */\n getEnvironment(): Environment {\n return this.environment;\n }\n\n /**\n * 로깅이 활성화되어 있는지 확인\n */\n isLoggingEnabled(): boolean {\n return this.isEnabled;\n }\n\n /**\n * 네임스페이스별 로거 인스턴스 생성\n * @param name - 네임스페이스 이름\n * @returns 네임스페이스 로거 인스턴스\n */\n namespace(name: string): Develog {\n // 이미 생성된 네임스페이스가 있으면 재사용\n if (this.namespaces.has(name)) {\n return this.namespaces.get(name)!;\n }\n\n // 계층 구조 지원: 부모 네임스페이스가 있으면 연결\n const fullNamespace = this.namespaceName ? `${this.namespaceName}:${name}` : name;\n\n // 새로운 네임스페이스 로거 생성\n const namespacedLogger = new Develog({\n enabledEnvironments: Array.from(this.enabledEnvironments),\n prefix: this.prefix,\n forceEnvironment: this.environment,\n showTimestamp: this.showTimestamp,\n timestampFormat: this.timestampFormat,\n enabledNamespaces: this.namespaceFilter,\n _namespaceName: fullNamespace,\n });\n\n this.namespaces.set(name, namespacedLogger);\n return namespacedLogger;\n }\n\n /**\n * 현재 네임스페이스가 활성화되어 있는지 확인\n */\n private isNamespaceEnabled(): boolean {\n // 네임스페이스 필터가 없으면 모두 활성화\n if (!this.namespaceFilter || this.namespaceFilter.length === 0) {\n return true;\n }\n\n // 네임스페이스가 없는 루트 로거는 항상 활성화\n if (!this.namespaceName) {\n return true;\n }\n\n // '*'는 모든 네임스페이스 활성화\n if (this.namespaceFilter.includes('*')) {\n return true;\n }\n\n // 정확한 매칭 확인\n if (this.namespaceFilter.includes(this.namespaceName)) {\n return true;\n }\n\n // 와일드카드 패턴 매칭\n for (const pattern of this.namespaceFilter) {\n if (pattern.endsWith(':*')) {\n const prefix = pattern.slice(0, -2);\n if (this.namespaceName === prefix || this.namespaceName.startsWith(`${prefix}:`)) {\n return true;\n }\n }\n }\n\n return false;\n }\n\n /**\n * 로그 출력 앞에 붙을 prefix 생성\n */\n private getLogPrefix(): string {\n let prefix = this.prefix;\n\n // 네임스페이스 추가\n if (this.namespaceName) {\n prefix = `${prefix}:${this.namespaceName}`;\n }\n\n // 타임스탬프 추가\n if (this.showTimestamp) {\n const timestamp = formatTimestamp(this.timestampFormat);\n prefix = `${prefix} [${timestamp}]`;\n }\n\n return prefix;\n }\n\n /**\n * 일반 로그 출력\n */\n log(...args: unknown[]): void {\n this.logWithLevel('log', ...args);\n }\n\n /**\n * 정보 로그 출력\n */\n info(...args: unknown[]): void {\n this.logWithLevel('info', ...args);\n }\n\n /**\n * 경고 로그 출력\n */\n warn(...args: unknown[]): void {\n this.logWithLevel('warn', ...args);\n }\n\n /**\n * 에러 로그 출력\n */\n error(...args: unknown[]): void {\n this.logWithLevel('error', ...args);\n }\n\n /**\n * 디버그 로그 출력\n */\n debug(...args: unknown[]): void {\n this.logWithLevel('debug', ...args);\n }\n\n /**\n * 그룹 시작\n */\n group(label?: string): void {\n if (!this.isEnabled) return;\n if (label) {\n console.group(this.formatMessage(label));\n } else {\n console.group();\n }\n }\n\n /**\n * 그룹 시작 (접혀있는 상태)\n */\n groupCollapsed(label?: string): void {\n if (!this.isEnabled) return;\n if (label) {\n console.groupCollapsed(this.formatMessage(label));\n } else {\n console.groupCollapsed();\n }\n }\n\n /**\n * 그룹 종료\n */\n groupEnd(): void {\n if (!this.isEnabled) return;\n console.groupEnd();\n }\n\n /**\n * 테이블 형태로 출력\n */\n table(data: unknown): void {\n if (!this.isEnabled) return;\n console.log(this.getLogPrefix());\n console.table(data);\n }\n\n /**\n * 시간 측정 시작\n */\n time(label: string): void {\n if (!this.isEnabled) return;\n console.time(this.formatMessage(label));\n }\n\n /**\n * 시간 측정 종료 및 출력\n */\n timeEnd(label: string): void {\n if (!this.isEnabled) return;\n console.timeEnd(this.formatMessage(label));\n }\n\n /**\n * 실행 횟수 카운트\n */\n count(label?: string): void {\n if (!this.isEnabled) return;\n if (label) {\n console.count(this.formatMessage(label));\n } else {\n console.count(this.prefix);\n }\n }\n\n /**\n * 카운트 초기화\n */\n countReset(label?: string): void {\n if (!this.isEnabled) return;\n if (label) {\n console.countReset(this.formatMessage(label));\n } else {\n console.countReset(this.prefix);\n }\n }\n\n /**\n * 콘솔 지우기\n */\n clear(): void {\n if (!this.isEnabled) return;\n console.clear();\n }\n\n /**\n * 레벨에 따른 로그 출력\n */\n private logWithLevel(level: LogLevel, ...args: unknown[]): void {\n if (!this.isEnabled) return;\n\n const consoleMethod = console[level] || console.log;\n const logPrefix = this.getLogPrefix();\n consoleMethod(logPrefix, ...args);\n }\n\n /**\n * 메시지에 prefix 추가\n */\n private formatMessage(message: string): string {\n const logPrefix = this.getLogPrefix();\n return `${logPrefix} ${message}`;\n }\n}\n\n/**\n * 기본 인스턴스 생성 및 export\n */\nexport const develog = new Develog();\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "develog",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "A lightweight frontend logger that runs only in local/dev environments.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "junjuny",
|
|
7
|
+
"homepage": "https://github.com/junjuny0227/develog#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/junjuny0227/develog.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/junjuny0227/develog/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"logger",
|
|
17
|
+
"logging",
|
|
18
|
+
"frontend",
|
|
19
|
+
"console",
|
|
20
|
+
"debug",
|
|
21
|
+
"dev",
|
|
22
|
+
"development",
|
|
23
|
+
"local",
|
|
24
|
+
"browser",
|
|
25
|
+
"typescript"
|
|
26
|
+
],
|
|
27
|
+
"type": "module",
|
|
28
|
+
"main": "./dist/index.cjs",
|
|
29
|
+
"module": "./dist/index.js",
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"import": {
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"default": "./dist/index.js"
|
|
36
|
+
},
|
|
37
|
+
"require": {
|
|
38
|
+
"types": "./dist/index.d.cts",
|
|
39
|
+
"default": "./dist/index.cjs"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"files": [
|
|
44
|
+
"dist",
|
|
45
|
+
"README.md",
|
|
46
|
+
"LICENSE.md"
|
|
47
|
+
],
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@eslint/js": "^9.39.2",
|
|
50
|
+
"@types/node": "^25.0.3",
|
|
51
|
+
"@vitest/coverage-v8": "^4.0.16",
|
|
52
|
+
"@vitest/ui": "^4.0.16",
|
|
53
|
+
"eslint": "^9.39.2",
|
|
54
|
+
"eslint-config-prettier": "^10.1.8",
|
|
55
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
56
|
+
"happy-dom": "^20.0.11",
|
|
57
|
+
"prettier": "^3.7.4",
|
|
58
|
+
"tsup": "^8.5.1",
|
|
59
|
+
"typescript": "^5.9.3",
|
|
60
|
+
"typescript-eslint": "^8.50.1",
|
|
61
|
+
"vitest": "^4.0.16"
|
|
62
|
+
},
|
|
63
|
+
"scripts": {
|
|
64
|
+
"build": "tsup",
|
|
65
|
+
"dev": "tsup --watch",
|
|
66
|
+
"test": "vitest run",
|
|
67
|
+
"test:watch": "vitest",
|
|
68
|
+
"test:ui": "vitest --ui",
|
|
69
|
+
"test:coverage": "vitest run --coverage",
|
|
70
|
+
"lint": "eslint .",
|
|
71
|
+
"lint:fix": "eslint . --fix",
|
|
72
|
+
"type-check": "tsc --noEmit",
|
|
73
|
+
"format": "prettier --write .",
|
|
74
|
+
"format:check": "prettier --check ."
|
|
75
|
+
}
|
|
76
|
+
}
|