Browse Source

chore: extends createDebugger parameters with additional segments

e22m4u 8 months ago
parent
commit
5482799adc
5 changed files with 110 additions and 19 deletions
  1. 9 3
      README.md
  2. 15 7
      dist/cjs/index.cjs
  3. 8 2
      src/create-debugger.d.ts
  4. 21 7
      src/create-debugger.js
  5. 57 0
      src/create-debugger.spec.js

+ 9 - 3
README.md

@@ -94,9 +94,15 @@ debug({
 ```js
 ```js
 import {createDebugger} from '@e22m4u/js-debug';
 import {createDebugger} from '@e22m4u/js-debug';
 
 
-const debug = createDebugger('myApp');
-debug('Hello world');
+const debug1 = createDebugger('myApp');
+const debug2 = createDebugger('myApp', 'myService');
+const debug3 = createDebugger('myApp:myService');
+debug1('Hello world');
+debug2('Hello world');
+debug3('Hello world');
 // myApp Hello world
 // myApp Hello world
+// myApp:myService Hello world
+// myApp:myService Hello world
 ```
 ```
 
 
 Использование пространства имен из переменной окружения.
 Использование пространства имен из переменной окружения.
@@ -111,7 +117,7 @@ debug('Hello world');
 // myApp Hello world
 // myApp Hello world
 ```
 ```
 
 
-Расширение пространства имен.
+Расширение сегментов пространства имен.
 
 
 ```js
 ```js
 import {createDebugger} from '@e22m4u/js-debug';
 import {createDebugger} from '@e22m4u/js-debug';

+ 15 - 7
dist/cjs/index.cjs

@@ -183,7 +183,7 @@ function matchPattern(pattern, input) {
   return regexp.test(input);
   return regexp.test(input);
 }
 }
 __name(matchPattern, "matchPattern");
 __name(matchPattern, "matchPattern");
-function createDebugger(namespaceOrOptions = void 0) {
+function createDebugger(namespaceOrOptions = void 0, ...namespaceSegments) {
   if (namespaceOrOptions && typeof namespaceOrOptions !== "string" && !isNonArrayObject(namespaceOrOptions)) {
   if (namespaceOrOptions && typeof namespaceOrOptions !== "string" && !isNonArrayObject(namespaceOrOptions)) {
     throw new import_js_format.Errorf(
     throw new import_js_format.Errorf(
       'The parameter "namespace" of the function createDebugger must be a String or an Object, but %v given.',
       'The parameter "namespace" of the function createDebugger must be a String or an Object, but %v given.',
@@ -191,24 +191,32 @@ function createDebugger(namespaceOrOptions = void 0) {
     );
     );
   }
   }
   const state = isNonArrayObject(namespaceOrOptions) ? namespaceOrOptions : {};
   const state = isNonArrayObject(namespaceOrOptions) ? namespaceOrOptions : {};
-  state.nsArr = Array.isArray(state.nsArr) ? state.nsArr : [];
+  state.nsSegments = Array.isArray(state.nsSegments) ? state.nsSegments : [];
   state.pattern = typeof state.pattern === "string" ? state.pattern : "";
   state.pattern = typeof state.pattern === "string" ? state.pattern : "";
   state.hash = typeof state.hash === "string" ? state.hash : "";
   state.hash = typeof state.hash === "string" ? state.hash : "";
   state.offsetSize = typeof state.offsetSize === "number" ? state.offsetSize : 0;
   state.offsetSize = typeof state.offsetSize === "number" ? state.offsetSize : 0;
   state.offsetStep = typeof state.offsetStep === "string" ? state.offsetStep : "   ";
   state.offsetStep = typeof state.offsetStep === "string" ? state.offsetStep : "   ";
   state.delimiter = state.delimiter && typeof state.delimiter === "string" ? state.delimiter : ":";
   state.delimiter = state.delimiter && typeof state.delimiter === "string" ? state.delimiter : ":";
   if (typeof process !== "undefined" && process.env && process.env["DEBUGGER_NAMESPACE"]) {
   if (typeof process !== "undefined" && process.env && process.env["DEBUGGER_NAMESPACE"]) {
-    state.nsArr.push(process.env.DEBUGGER_NAMESPACE);
+    state.nsSegments.push(process.env.DEBUGGER_NAMESPACE);
   }
   }
   if (typeof namespaceOrOptions === "string")
   if (typeof namespaceOrOptions === "string")
-    state.nsArr.push(namespaceOrOptions);
+    state.nsSegments.push(namespaceOrOptions);
+  namespaceSegments.forEach((segment) => {
+    if (!segment || typeof segment !== "string")
+      throw new import_js_format.Errorf(
+        "Namespace segment must be a non-empty String, but %v given.",
+        segment
+      );
+    state.nsSegments.push(segment);
+  });
   if (typeof process !== "undefined" && process.env && process.env["DEBUG"]) {
   if (typeof process !== "undefined" && process.env && process.env["DEBUG"]) {
     state.pattern = process.env["DEBUG"];
     state.pattern = process.env["DEBUG"];
   } else if (typeof localStorage !== "undefined" && typeof localStorage.getItem("debug") === "string") {
   } else if (typeof localStorage !== "undefined" && typeof localStorage.getItem("debug") === "string") {
     state.pattern = localStorage.getItem("debug");
     state.pattern = localStorage.getItem("debug");
   }
   }
   const isDebuggerEnabled = /* @__PURE__ */ __name(() => {
   const isDebuggerEnabled = /* @__PURE__ */ __name(() => {
-    const nsStr = state.nsArr.join(state.delimiter);
+    const nsStr = state.nsSegments.join(state.delimiter);
     const patterns = state.pattern.split(/[\s,]+/).filter((p) => p.length > 0);
     const patterns = state.pattern.split(/[\s,]+/).filter((p) => p.length > 0);
     if (patterns.length === 0 && state.pattern !== "*") return false;
     if (patterns.length === 0 && state.pattern !== "*") return false;
     for (const singlePattern of patterns) {
     for (const singlePattern of patterns) {
@@ -218,7 +226,7 @@ function createDebugger(namespaceOrOptions = void 0) {
   }, "isDebuggerEnabled");
   }, "isDebuggerEnabled");
   const getPrefix = /* @__PURE__ */ __name(() => {
   const getPrefix = /* @__PURE__ */ __name(() => {
     let tokens = [];
     let tokens = [];
-    [...state.nsArr, state.hash].filter(Boolean).forEach((token) => {
+    [...state.nsSegments, state.hash].filter(Boolean).forEach((token) => {
       const extractedTokens = token.split(state.delimiter).filter(Boolean);
       const extractedTokens = token.split(state.delimiter).filter(Boolean);
       tokens = [...tokens, ...extractedTokens];
       tokens = [...tokens, ...extractedTokens];
     });
     });
@@ -255,7 +263,7 @@ function createDebugger(namespaceOrOptions = void 0) {
           "Debugger namespace must be a non-empty String, but %v given.",
           "Debugger namespace must be a non-empty String, but %v given.",
           ns
           ns
         );
         );
-      stCopy.nsArr.push(ns);
+      stCopy.nsSegments.push(ns);
     });
     });
     return createDebugger(stCopy);
     return createDebugger(stCopy);
   };
   };

+ 8 - 2
src/create-debugger.d.ts

@@ -49,6 +49,12 @@ export interface Debugger {
 /**
 /**
  * Create debugger.
  * Create debugger.
  *
  *
- * @param namespace
+ * @param namespace Сегмент пространства имен.
+ * @param namespaceSegments Дополнительные сегменты пространства имен для
+ *   добавления.
+ * @returns Новый экземпляр Debugger.
  */
  */
-export declare function createDebugger(namespace: string): Debugger;
+export declare function createDebugger(
+  namespace?: string,
+  ...namespaceSegments: string[],
+): Debugger;

+ 21 - 7
src/create-debugger.js

@@ -113,9 +113,13 @@ function matchPattern(pattern, input) {
  * Create debugger.
  * Create debugger.
  *
  *
  * @param {string} namespaceOrOptions
  * @param {string} namespaceOrOptions
+ * @param {string[]} namespaceSegments
  * @returns {Function}
  * @returns {Function}
  */
  */
-export function createDebugger(namespaceOrOptions = undefined) {
+export function createDebugger(
+  namespaceOrOptions = undefined,
+  ...namespaceSegments
+) {
   // если первый аргумент не является строкой
   // если первый аргумент не является строкой
   // и объектом, то выбрасывается ошибка
   // и объектом, то выбрасывается ошибка
   if (
   if (
@@ -132,7 +136,7 @@ export function createDebugger(namespaceOrOptions = undefined) {
   // формирование состояния отладчика
   // формирование состояния отладчика
   // для хранения текущих настроек
   // для хранения текущих настроек
   const state = isNonArrayObject(namespaceOrOptions) ? namespaceOrOptions : {};
   const state = isNonArrayObject(namespaceOrOptions) ? namespaceOrOptions : {};
-  state.nsArr = Array.isArray(state.nsArr) ? state.nsArr : [];
+  state.nsSegments = Array.isArray(state.nsSegments) ? state.nsSegments : [];
   state.pattern = typeof state.pattern === 'string' ? state.pattern : '';
   state.pattern = typeof state.pattern === 'string' ? state.pattern : '';
   state.hash = typeof state.hash === 'string' ? state.hash : '';
   state.hash = typeof state.hash === 'string' ? state.hash : '';
   state.offsetSize =
   state.offsetSize =
@@ -151,12 +155,22 @@ export function createDebugger(namespaceOrOptions = undefined) {
     process.env &&
     process.env &&
     process.env['DEBUGGER_NAMESPACE']
     process.env['DEBUGGER_NAMESPACE']
   ) {
   ) {
-    state.nsArr.push(process.env.DEBUGGER_NAMESPACE);
+    state.nsSegments.push(process.env.DEBUGGER_NAMESPACE);
   }
   }
   // если первый аргумент содержит значение,
   // если первый аргумент содержит значение,
   // то оно используется как пространство имен
   // то оно используется как пространство имен
   if (typeof namespaceOrOptions === 'string')
   if (typeof namespaceOrOptions === 'string')
-    state.nsArr.push(namespaceOrOptions);
+    state.nsSegments.push(namespaceOrOptions);
+  // проверка типа дополнительных сегментов пространства
+  // имен, и добавление их в общий набор сегментов
+  namespaceSegments.forEach(segment => {
+    if (!segment || typeof segment !== 'string')
+      throw new Errorf(
+        'Namespace segment must be a non-empty String, but %v given.',
+        segment,
+      );
+    state.nsSegments.push(segment);
+  });
   // если переменная окружения DEBUG содержит
   // если переменная окружения DEBUG содержит
   // значение, то оно используется как шаблон
   // значение, то оно используется как шаблон
   if (typeof process !== 'undefined' && process.env && process.env['DEBUG']) {
   if (typeof process !== 'undefined' && process.env && process.env['DEBUG']) {
@@ -174,7 +188,7 @@ export function createDebugger(namespaceOrOptions = undefined) {
   // формирование функции для проверки
   // формирование функции для проверки
   // активности текущего отладчика
   // активности текущего отладчика
   const isDebuggerEnabled = () => {
   const isDebuggerEnabled = () => {
-    const nsStr = state.nsArr.join(state.delimiter);
+    const nsStr = state.nsSegments.join(state.delimiter);
     const patterns = state.pattern.split(/[\s,]+/).filter(p => p.length > 0);
     const patterns = state.pattern.split(/[\s,]+/).filter(p => p.length > 0);
     if (patterns.length === 0 && state.pattern !== '*') return false;
     if (patterns.length === 0 && state.pattern !== '*') return false;
     for (const singlePattern of patterns) {
     for (const singlePattern of patterns) {
@@ -186,7 +200,7 @@ export function createDebugger(namespaceOrOptions = undefined) {
   // для сообщений отладки
   // для сообщений отладки
   const getPrefix = () => {
   const getPrefix = () => {
     let tokens = [];
     let tokens = [];
-    [...state.nsArr, state.hash].filter(Boolean).forEach(token => {
+    [...state.nsSegments, state.hash].filter(Boolean).forEach(token => {
       const extractedTokens = token.split(state.delimiter).filter(Boolean);
       const extractedTokens = token.split(state.delimiter).filter(Boolean);
       tokens = [...tokens, ...extractedTokens];
       tokens = [...tokens, ...extractedTokens];
     });
     });
@@ -226,7 +240,7 @@ export function createDebugger(namespaceOrOptions = undefined) {
           'Debugger namespace must be a non-empty String, but %v given.',
           'Debugger namespace must be a non-empty String, but %v given.',
           ns,
           ns,
         );
         );
-      stCopy.nsArr.push(ns);
+      stCopy.nsSegments.push(ns);
     });
     });
     return createDebugger(stCopy);
     return createDebugger(stCopy);
   };
   };

+ 57 - 0
src/create-debugger.spec.js

@@ -174,6 +174,26 @@ describe('createDebugger', function () {
       );
       );
     });
     });
 
 
+    it('should use multiple namespace segments provided in createDebugger', function () {
+      process.env.DEBUG = 'app:service:module';
+      const debug = createDebugger('app', 'service', 'module');
+      debug('multi segment message');
+      expect(consoleLogSpy.calledOnce).to.be.true;
+      expect(stripAnsi(consoleLogSpy.firstCall.args[0])).to.equal(
+        'app:service:module multi segment message',
+      );
+    });
+
+    it('should handle subsequent segments even if the first arg is the only namespace part', function () {
+      process.env.DEBUG = 'service:module';
+      const debug = createDebugger('service', 'module');
+      debug('segments only message');
+      expect(consoleLogSpy.calledOnce).to.be.true;
+      expect(stripAnsi(consoleLogSpy.firstCall.args[0])).to.equal(
+        'service:module segments only message',
+      );
+    });
+
     it('should use namespace from DEBUGGER_NAMESPACE env variable', function () {
     it('should use namespace from DEBUGGER_NAMESPACE env variable', function () {
       process.env.DEBUGGER_NAMESPACE = 'base';
       process.env.DEBUGGER_NAMESPACE = 'base';
       // должен быть включен для вывода
       // должен быть включен для вывода
@@ -196,6 +216,17 @@ describe('createDebugger', function () {
       );
       );
     });
     });
 
 
+    it('should combine DEBUGGER_NAMESPACE and multiple createDebugger segments', function () {
+      process.env.DEBUGGER_NAMESPACE = 'base';
+      process.env.DEBUG = 'base:app:svc';
+      const debug = createDebugger('app', 'svc');
+      debug('env plus multi segment message');
+      expect(consoleLogSpy.calledOnce).to.be.true;
+      expect(stripAnsi(consoleLogSpy.firstCall.args[0])).to.equal(
+        'base:app:svc env plus multi segment message',
+      );
+    });
+
     it('should extend namespace with withNs()', function () {
     it('should extend namespace with withNs()', function () {
       process.env.DEBUG = 'app:service';
       process.env.DEBUG = 'app:service';
       const debugApp = createDebugger('app');
       const debugApp = createDebugger('app');
@@ -206,6 +237,17 @@ describe('createDebugger', function () {
       );
       );
     });
     });
 
 
+    it('should extend namespace with withNs() after creating with multiple segments', function () {
+      process.env.DEBUG = 'app:svc:mod';
+      const debugBase = createDebugger('app', 'svc');
+      const debugMod = debugBase.withNs('mod');
+      debugMod('multi create then withNs');
+      expect(consoleLogSpy.calledOnce).to.be.true;
+      expect(stripAnsi(consoleLogSpy.firstCall.args[0])).to.equal(
+        'app:svc:mod multi create then withNs',
+      );
+    });
+
     it('should extend namespace with multiple args in withNs()', function () {
     it('should extend namespace with multiple args in withNs()', function () {
       process.env.DEBUG = 'app:service:module';
       process.env.DEBUG = 'app:service:module';
       const debugApp = createDebugger('app');
       const debugApp = createDebugger('app');
@@ -225,6 +267,21 @@ describe('createDebugger', function () {
       );
       );
     });
     });
 
 
+    it('should throw error if createDebugger is called with invalid subsequent segment type', function () {
+      expect(() => createDebugger('app', 'valid', 123)).to.throw(
+        /Namespace segment must be a non-empty String/,
+      );
+      expect(() => createDebugger('app', 'valid', null)).to.throw(
+        /Namespace segment must be a non-empty String/,
+      );
+      expect(() => createDebugger('app', 'valid', '')).to.throw(
+        /Namespace segment must be a non-empty String/,
+      );
+      expect(() => createDebugger('app', '')).to.throw(
+        /Namespace segment must be a non-empty String/,
+      ); // Также проверяем пустой второй сегмент
+    });
+
     it('should throw error if withNs is called with non-string', function () {
     it('should throw error if withNs is called with non-string', function () {
       const debug = createDebugger('app');
       const debug = createDebugger('app');
       expect(() => debug.withNs(123)).to.throw(/must be a non-empty String/);
       expect(() => debug.withNs(123)).to.throw(/must be a non-empty String/);