@lang-tag/cli 0.14.0 → 0.15.0

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.
@@ -0,0 +1,17 @@
1
+ import { TranslationsCollector } from './type.ts';
2
+ import { LangTagCLIProcessedTag } from '../../config.ts';
3
+ interface Options {
4
+ appendNamespaceToPath: boolean;
5
+ }
6
+ export declare class DictionaryCollector extends TranslationsCollector {
7
+ private readonly options;
8
+ private clean;
9
+ constructor(options?: Options);
10
+ aggregateCollection(namespace: string): string;
11
+ transformTag(tag: LangTagCLIProcessedTag): LangTagCLIProcessedTag;
12
+ preWrite(clean: boolean): Promise<void>;
13
+ resolveCollectionFilePath(baseLanguageCode: string): Promise<any>;
14
+ onMissingCollection(baseLanguageCode: string): Promise<void>;
15
+ postWrite(changedCollections: string[]): Promise<void>;
16
+ }
17
+ export {};
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Translation collectors for organizing translation tags into output files.
3
+ *
4
+ * These collectors define how translation tags are grouped and written to files
5
+ * during the collection process. Each collector implements a different strategy
6
+ * for organizing translations (e.g., single dictionary vs. namespace-based files).
7
+ */
8
+ export { DictionaryCollector } from './dictionary-collector.ts';
9
+ export { NamespaceCollector } from './namespace-collector.ts';
10
+ export { type TranslationsCollector } from './type.ts';
@@ -0,0 +1,12 @@
1
+ import { TranslationsCollector } from './type.ts';
2
+ import { LangTagCLIProcessedTag } from '../../config.ts';
3
+ export declare class NamespaceCollector extends TranslationsCollector {
4
+ private clean;
5
+ private languageDirectory;
6
+ aggregateCollection(namespace: string): string;
7
+ transformTag(tag: LangTagCLIProcessedTag): LangTagCLIProcessedTag;
8
+ preWrite(clean: boolean): Promise<void>;
9
+ resolveCollectionFilePath(collectionName: string): Promise<any>;
10
+ onMissingCollection(collectionName: string): Promise<void>;
11
+ postWrite(changedCollections: string[]): Promise<void>;
12
+ }
@@ -0,0 +1,12 @@
1
+ import { LangTagCLIConfig, LangTagCLIProcessedTag } from '../../config.ts';
2
+ import { LangTagCLILogger } from '../../logger.ts';
3
+ export declare abstract class TranslationsCollector {
4
+ config: LangTagCLIConfig;
5
+ logger: LangTagCLILogger;
6
+ abstract aggregateCollection(namespace: string): string;
7
+ abstract transformTag(tag: LangTagCLIProcessedTag): LangTagCLIProcessedTag;
8
+ abstract preWrite(clean?: boolean): Promise<void>;
9
+ abstract resolveCollectionFilePath(collectionName: string): Promise<string>;
10
+ abstract onMissingCollection(collectionName: string): Promise<void>;
11
+ abstract postWrite(changedCollections: string[]): Promise<void>;
12
+ }
@@ -6,3 +6,4 @@
6
6
  */
7
7
  export { pathBasedConfigGenerator, type PathBasedConfigGeneratorOptions } from './path-based-config-generator.ts';
8
8
  export { configKeeper, type ConfigKeeperOptions, type ConfigKeeperMode } from './config-keeper.ts';
9
+ export { prependNamespaceToPath, type PrependNamespaceToPathOptions } from './prepend-namespace-to-path.ts';
@@ -0,0 +1,28 @@
1
+ import { LangTagCLIConfigGenerationEvent } from '../../config.ts';
2
+ /**
3
+ * Options for the prependNamespaceToPath algorithm.
4
+ */
5
+ export interface PrependNamespaceToPathOptions {
6
+ }
7
+ /**
8
+ * Algorithm that prepends the namespace to the path in translation tag configurations.
9
+ *
10
+ * This is useful when you want to flatten the namespace structure by moving the namespace
11
+ * into the path, effectively removing the namespace separation.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * // Before: { namespace: 'common', path: 'hello.world' }
16
+ * // After: { path: 'common.hello.world' }
17
+ *
18
+ * // Before: { namespace: 'common' }
19
+ * // After: { path: 'common' }
20
+ *
21
+ * // Before: {}
22
+ * // After: { path: 'common' }
23
+ * ```
24
+ *
25
+ * @param options Configuration options for the algorithm
26
+ * @returns A function compatible with LangTagCLIConfigGenerationEvent
27
+ */
28
+ export declare function prependNamespaceToPath(options?: PrependNamespaceToPathOptions): (event: LangTagCLIConfigGenerationEvent) => Promise<void>;
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const namespaceCollector = require("../namespace-collector-DRnZvkDR.cjs");
3
4
  const path = require("pathe");
5
+ const process = require("node:process");
4
6
  const caseLib = require("case");
5
7
  function _interopNamespaceDefault(e) {
6
8
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -19,7 +21,74 @@ function _interopNamespaceDefault(e) {
19
21
  return Object.freeze(n);
20
22
  }
21
23
  const caseLib__namespace = /* @__PURE__ */ _interopNamespaceDefault(caseLib);
22
- const TRIGGER_NAME$1 = "path-based-config-generator";
24
+ class DictionaryCollector extends namespaceCollector.TranslationsCollector {
25
+ constructor(options = {
26
+ appendNamespaceToPath: false
27
+ }) {
28
+ super();
29
+ this.options = options;
30
+ }
31
+ clean;
32
+ aggregateCollection(namespace) {
33
+ return this.config.baseLanguageCode;
34
+ }
35
+ transformTag(tag) {
36
+ const originalPath = tag.parameterConfig.path;
37
+ let path2 = originalPath;
38
+ if (this.options.appendNamespaceToPath) {
39
+ path2 = tag.parameterConfig.namespace;
40
+ if (originalPath) {
41
+ path2 += ".";
42
+ path2 += originalPath;
43
+ }
44
+ return {
45
+ ...tag,
46
+ parameterConfig: {
47
+ ...tag.parameterConfig,
48
+ namespace: void 0,
49
+ path: path2
50
+ }
51
+ };
52
+ }
53
+ return tag;
54
+ }
55
+ async preWrite(clean) {
56
+ this.clean = clean;
57
+ const baseDictionaryFile = path.join(this.config.localesDirectory, `${this.config.baseLanguageCode}.json`);
58
+ if (clean) {
59
+ this.logger.info("Removing {file}", { file: baseDictionaryFile });
60
+ await namespaceCollector.$LT_RemoveFile(baseDictionaryFile);
61
+ }
62
+ await namespaceCollector.$LT_EnsureDirectoryExists(this.config.localesDirectory);
63
+ }
64
+ async resolveCollectionFilePath(baseLanguageCode) {
65
+ return path.resolve(
66
+ process.cwd(),
67
+ this.config.localesDirectory,
68
+ baseLanguageCode + ".json"
69
+ );
70
+ }
71
+ async onMissingCollection(baseLanguageCode) {
72
+ if (!this.clean) {
73
+ this.logger.warn(`Original dictionary file "{namespace}.json" not found. A new one will be created.`, { namespace: baseLanguageCode });
74
+ }
75
+ }
76
+ async postWrite(changedCollections) {
77
+ if (!changedCollections?.length) {
78
+ this.logger.info("No changes were made based on the current configuration and files");
79
+ return;
80
+ }
81
+ if (changedCollections.length > 1) {
82
+ throw new Error("Should not write more than 1 collection! Only 1 base language dictionary expected!");
83
+ }
84
+ const dict = path.resolve(
85
+ this.config.localesDirectory,
86
+ this.config.baseLanguageCode + ".json"
87
+ );
88
+ this.logger.success("Updated dictionary {dict}", { dict });
89
+ }
90
+ }
91
+ const TRIGGER_NAME$2 = "path-based-config-generator";
23
92
  function pathBasedConfigGenerator(options = {}) {
24
93
  const {
25
94
  includeFileName = false,
@@ -109,7 +178,7 @@ function pathBasedConfigGenerator(options = {}) {
109
178
  (key) => key !== "namespace" && key !== "path"
110
179
  );
111
180
  if (!hasOtherProperties) {
112
- event.save(null, TRIGGER_NAME$1);
181
+ event.save(null, TRIGGER_NAME$2);
113
182
  return;
114
183
  } else {
115
184
  delete newConfig.namespace;
@@ -127,7 +196,7 @@ function pathBasedConfigGenerator(options = {}) {
127
196
  }
128
197
  }
129
198
  if (Object.keys(newConfig).length > 0) {
130
- event.save(newConfig, TRIGGER_NAME$1);
199
+ event.save(newConfig, TRIGGER_NAME$2);
131
200
  }
132
201
  };
133
202
  }
@@ -313,7 +382,7 @@ function extractRootDirectoriesFromIncludes(includes) {
313
382
  }
314
383
  return Array.from(directories);
315
384
  }
316
- const TRIGGER_NAME = "config-keeper";
385
+ const TRIGGER_NAME$1 = "config-keeper";
317
386
  function configKeeper(options = {}) {
318
387
  const propertyName = options.propertyName ?? "keep";
319
388
  const keepPropertyAtEnd = options.keepPropertyAtEnd ?? true;
@@ -370,8 +439,33 @@ function configKeeper(options = {}) {
370
439
  delete finalConfig[propertyName];
371
440
  }
372
441
  finalConfig[propertyName] = keepMode;
373
- event.save(finalConfig, TRIGGER_NAME);
442
+ event.save(finalConfig, TRIGGER_NAME$1);
443
+ };
444
+ }
445
+ const TRIGGER_NAME = "prepend-namespace-to-path";
446
+ function prependNamespaceToPath(options = {}) {
447
+ return async (event) => {
448
+ const currentConfig = event.savedConfig;
449
+ const { namespace, path: path2 } = currentConfig || {};
450
+ const actualNamespace = namespace || event.langTagConfig.collect?.defaultNamespace;
451
+ if (!actualNamespace) {
452
+ return;
453
+ }
454
+ let newPath;
455
+ if (path2) {
456
+ newPath = `${actualNamespace}.${path2}`;
457
+ } else {
458
+ newPath = actualNamespace;
459
+ }
460
+ event.save({
461
+ ...currentConfig || {},
462
+ path: newPath,
463
+ namespace: void 0
464
+ }, TRIGGER_NAME);
374
465
  };
375
466
  }
467
+ exports.NamespaceCollector = namespaceCollector.NamespaceCollector;
468
+ exports.DictionaryCollector = DictionaryCollector;
376
469
  exports.configKeeper = configKeeper;
377
470
  exports.pathBasedConfigGenerator = pathBasedConfigGenerator;
471
+ exports.prependNamespaceToPath = prependNamespaceToPath;
@@ -1,7 +1,10 @@
1
1
  /**
2
- * Predefined algorithms for lang-tag-cli configuration.
2
+ * Algorithm modules for lang-tag-cli.
3
3
  *
4
- * These algorithms can be used in your lang-tag-cli config file
5
- * to customize how tags are processed during collection and regeneration.
4
+ * This module provides access to all available algorithms organized by category:
5
+ * - Collectors: Define how translation tags are organized into output files
6
+ * - Config Generation: Customize tag configuration generation
7
+ * - Import: Handle importing translation libraries (future)
6
8
  */
9
+ export * from './collector/index.ts';
7
10
  export * from './config-generation/index.ts';
@@ -1,6 +1,76 @@
1
- import { sep } from "pathe";
1
+ import { T as TranslationsCollector, e as $LT_RemoveFile, c as $LT_EnsureDirectoryExists } from "../namespace-collector-DCruv_PK.js";
2
+ import { N } from "../namespace-collector-DCruv_PK.js";
3
+ import path, { resolve, sep } from "pathe";
4
+ import process__default from "node:process";
2
5
  import * as caseLib from "case";
3
- const TRIGGER_NAME$1 = "path-based-config-generator";
6
+ class DictionaryCollector extends TranslationsCollector {
7
+ constructor(options = {
8
+ appendNamespaceToPath: false
9
+ }) {
10
+ super();
11
+ this.options = options;
12
+ }
13
+ clean;
14
+ aggregateCollection(namespace) {
15
+ return this.config.baseLanguageCode;
16
+ }
17
+ transformTag(tag) {
18
+ const originalPath = tag.parameterConfig.path;
19
+ let path2 = originalPath;
20
+ if (this.options.appendNamespaceToPath) {
21
+ path2 = tag.parameterConfig.namespace;
22
+ if (originalPath) {
23
+ path2 += ".";
24
+ path2 += originalPath;
25
+ }
26
+ return {
27
+ ...tag,
28
+ parameterConfig: {
29
+ ...tag.parameterConfig,
30
+ namespace: void 0,
31
+ path: path2
32
+ }
33
+ };
34
+ }
35
+ return tag;
36
+ }
37
+ async preWrite(clean) {
38
+ this.clean = clean;
39
+ const baseDictionaryFile = path.join(this.config.localesDirectory, `${this.config.baseLanguageCode}.json`);
40
+ if (clean) {
41
+ this.logger.info("Removing {file}", { file: baseDictionaryFile });
42
+ await $LT_RemoveFile(baseDictionaryFile);
43
+ }
44
+ await $LT_EnsureDirectoryExists(this.config.localesDirectory);
45
+ }
46
+ async resolveCollectionFilePath(baseLanguageCode) {
47
+ return resolve(
48
+ process__default.cwd(),
49
+ this.config.localesDirectory,
50
+ baseLanguageCode + ".json"
51
+ );
52
+ }
53
+ async onMissingCollection(baseLanguageCode) {
54
+ if (!this.clean) {
55
+ this.logger.warn(`Original dictionary file "{namespace}.json" not found. A new one will be created.`, { namespace: baseLanguageCode });
56
+ }
57
+ }
58
+ async postWrite(changedCollections) {
59
+ if (!changedCollections?.length) {
60
+ this.logger.info("No changes were made based on the current configuration and files");
61
+ return;
62
+ }
63
+ if (changedCollections.length > 1) {
64
+ throw new Error("Should not write more than 1 collection! Only 1 base language dictionary expected!");
65
+ }
66
+ const dict = resolve(
67
+ this.config.localesDirectory,
68
+ this.config.baseLanguageCode + ".json"
69
+ );
70
+ this.logger.success("Updated dictionary {dict}", { dict });
71
+ }
72
+ }
73
+ const TRIGGER_NAME$2 = "path-based-config-generator";
4
74
  function pathBasedConfigGenerator(options = {}) {
5
75
  const {
6
76
  includeFileName = false,
@@ -56,13 +126,13 @@ function pathBasedConfigGenerator(options = {}) {
56
126
  }
57
127
  pathSegments = pathSegments.filter((seg) => !ignoreDirectories.includes(seg));
58
128
  let namespace;
59
- let path;
129
+ let path2;
60
130
  if (pathSegments.length >= 1) {
61
131
  namespace = pathSegments[0];
62
132
  if (pathSegments.length > 1) {
63
- path = pathSegments.slice(1).join(".");
133
+ path2 = pathSegments.slice(1).join(".");
64
134
  } else {
65
- path = "";
135
+ path2 = "";
66
136
  }
67
137
  } else {
68
138
  namespace = actualFallbackNamespace;
@@ -75,22 +145,22 @@ function pathBasedConfigGenerator(options = {}) {
75
145
  namespace = applyCaseTransform(namespace, namespaceCase);
76
146
  }
77
147
  }
78
- if (path && pathCase) {
79
- const pathParts = path.split(".");
148
+ if (path2 && pathCase) {
149
+ const pathParts = path2.split(".");
80
150
  const transformedParts = pathParts.map((part) => applyCaseTransform(part, pathCase));
81
- path = transformedParts.join(".");
151
+ path2 = transformedParts.join(".");
82
152
  }
83
153
  const newConfig = event.config ? { ...event.config } : {};
84
154
  if (clearOnDefaultNamespace && namespace === actualFallbackNamespace) {
85
- if (path) {
86
- newConfig.path = path;
155
+ if (path2) {
156
+ newConfig.path = path2;
87
157
  delete newConfig.namespace;
88
158
  } else {
89
159
  const hasOtherProperties = event.config && Object.keys(event.config).some(
90
160
  (key) => key !== "namespace" && key !== "path"
91
161
  );
92
162
  if (!hasOtherProperties) {
93
- event.save(null, TRIGGER_NAME$1);
163
+ event.save(null, TRIGGER_NAME$2);
94
164
  return;
95
165
  } else {
96
166
  delete newConfig.namespace;
@@ -101,14 +171,14 @@ function pathBasedConfigGenerator(options = {}) {
101
171
  if (namespace) {
102
172
  newConfig.namespace = namespace;
103
173
  }
104
- if (path) {
105
- newConfig.path = path;
174
+ if (path2) {
175
+ newConfig.path = path2;
106
176
  } else {
107
177
  delete newConfig.path;
108
178
  }
109
179
  }
110
180
  if (Object.keys(newConfig).length > 0) {
111
- event.save(newConfig, TRIGGER_NAME$1);
181
+ event.save(newConfig, TRIGGER_NAME$2);
112
182
  }
113
183
  };
114
184
  }
@@ -294,7 +364,7 @@ function extractRootDirectoriesFromIncludes(includes) {
294
364
  }
295
365
  return Array.from(directories);
296
366
  }
297
- const TRIGGER_NAME = "config-keeper";
367
+ const TRIGGER_NAME$1 = "config-keeper";
298
368
  function configKeeper(options = {}) {
299
369
  const propertyName = options.propertyName ?? "keep";
300
370
  const keepPropertyAtEnd = options.keepPropertyAtEnd ?? true;
@@ -351,10 +421,35 @@ function configKeeper(options = {}) {
351
421
  delete finalConfig[propertyName];
352
422
  }
353
423
  finalConfig[propertyName] = keepMode;
354
- event.save(finalConfig, TRIGGER_NAME);
424
+ event.save(finalConfig, TRIGGER_NAME$1);
425
+ };
426
+ }
427
+ const TRIGGER_NAME = "prepend-namespace-to-path";
428
+ function prependNamespaceToPath(options = {}) {
429
+ return async (event) => {
430
+ const currentConfig = event.savedConfig;
431
+ const { namespace, path: path2 } = currentConfig || {};
432
+ const actualNamespace = namespace || event.langTagConfig.collect?.defaultNamespace;
433
+ if (!actualNamespace) {
434
+ return;
435
+ }
436
+ let newPath;
437
+ if (path2) {
438
+ newPath = `${actualNamespace}.${path2}`;
439
+ } else {
440
+ newPath = actualNamespace;
441
+ }
442
+ event.save({
443
+ ...currentConfig || {},
444
+ path: newPath,
445
+ namespace: void 0
446
+ }, TRIGGER_NAME);
355
447
  };
356
448
  }
357
449
  export {
450
+ DictionaryCollector,
451
+ N as NamespaceCollector,
358
452
  configKeeper,
359
- pathBasedConfigGenerator
453
+ pathBasedConfigGenerator,
454
+ prependNamespaceToPath
360
455
  };
package/config.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { LangTagTranslationsConfig } from 'lang-tag';
2
2
  import { LangTagCLILogger } from './logger.ts';
3
+ import { TranslationsCollector } from './algorithms/collector/type.ts';
3
4
  export interface LangTagCLIConfig {
4
5
  /**
5
6
  * Tag name used to mark translations in code.
@@ -17,11 +18,37 @@ export interface LangTagCLIConfig {
17
18
  */
18
19
  excludes: string[];
19
20
  /**
20
- * Output directory for generated translation namespace files (e.g., common.json, errors.json).
21
- * @default 'locales/en'
21
+ * Root directory for translation files.
22
+ * The actual file structure depends on the collector implementation used.
23
+ * @default 'locales'
24
+ * @example With baseLanguageCode='en' and localesDirectory='locales':
25
+ * - NamespaceCollector (default): locales/en/common.json, locales/en/errors.json
26
+ * - DictionaryCollector: locales/en.json (all translations in one file)
22
27
  */
23
- outputDir: string;
28
+ localesDirectory: string;
29
+ /**
30
+ * The language in which translation values/messages are written in the codebase.
31
+ * This determines the source language for your translations.
32
+ * @default 'en'
33
+ * @example 'en' - Translation values are in English: lang({ helloWorld: 'Hello World' })
34
+ * @example 'pl' - Translation values are in Polish: lang({ helloWorld: 'Witaj Świecie' })
35
+ */
36
+ baseLanguageCode: string;
37
+ /**
38
+ * Indicates whether this configuration is for a translation library.
39
+ * If true, generates an exports file (`.lang-tag.exports.json`) instead of locale files.
40
+ * @default false
41
+ */
42
+ isLibrary: boolean;
24
43
  collect?: {
44
+ /**
45
+ * Translation collector that defines how translation tags are organized into output files.
46
+ * If not specified, NamespaceCollector is used by default.
47
+ * @default NamespaceCollector
48
+ * @example DictionaryCollector - All translations in single file per language
49
+ * @example NamespaceCollector - Separate files per namespace within language directory
50
+ */
51
+ collector?: TranslationsCollector;
25
52
  /**
26
53
  * @default 'common'
27
54
  */
@@ -50,50 +77,6 @@ export interface LangTagCLIConfig {
50
77
  */
51
78
  onCollectFinish?: (event: LangTagCLICollectFinishEvent) => void;
52
79
  };
53
- import: {
54
- /**
55
- * Output directory for generated files containing imported library tags.
56
- * @default 'src/lang-libraries'
57
- */
58
- dir: string;
59
- /**
60
- * The import statement used in generated library files to import the project's `lang` tag function.
61
- * @default 'import { lang } from "@/my-lang-tag-path"'
62
- */
63
- tagImportPath: string;
64
- /**
65
- * A function to customize the generated file name and export name for imported library tags.
66
- * Allows controlling how imported tags are organized and named within the generated files.
67
- */
68
- onImport: (params: LangTagCLIOnImportParams, actions: LangTagCLIOnImportActions) => void;
69
- /**
70
- * A function called after all lang-tags were imported
71
- */
72
- onImportFinish?: () => void;
73
- };
74
- /**
75
- * Determines the position of the translation argument in the `lang()` function.
76
- * If `1`, translations are in the first argument (`lang(translations, options)`).
77
- * If `2`, translations are in the second argument (`lang(options, translations)`).
78
- * @default 1
79
- */
80
- translationArgPosition: 1 | 2;
81
- /**
82
- * Primary language used for the library's translations.
83
- * Affects default language settings when used in library mode.
84
- * @default 'en'
85
- */
86
- language: string;
87
- /**
88
- * Indicates whether this configuration is for a translation library.
89
- * If true, generates an exports file (`.lang-tag.exports.json`) instead of locale files.
90
- * @default false
91
- */
92
- isLibrary: boolean;
93
- /**
94
- * Whether to flatten the translation keys. (Currently unused)
95
- * @default false
96
- */
97
80
  /**
98
81
  * A function called for each found lang tag before processing.
99
82
  * Allows dynamic modification of the tag's configuration (namespace, path, etc.)
@@ -123,6 +106,34 @@ export interface LangTagCLIConfig {
123
106
  * ```
124
107
  */
125
108
  onConfigGeneration: (event: LangTagCLIConfigGenerationEvent) => Promise<void>;
109
+ import: {
110
+ /**
111
+ * Output directory for generated files containing imported library tags.
112
+ * @default 'src/lang-libraries'
113
+ */
114
+ dir: string;
115
+ /**
116
+ * The import statement used in generated library files to import the project's `lang` tag function.
117
+ * @default 'import { lang } from "@/my-lang-tag-path"'
118
+ */
119
+ tagImportPath: string;
120
+ /**
121
+ * A function to customize the generated file name and export name for imported library tags.
122
+ * Allows controlling how imported tags are organized and named within the generated files.
123
+ */
124
+ onImport: (params: LangTagCLIOnImportParams, actions: LangTagCLIOnImportActions) => void;
125
+ /**
126
+ * A function called after all lang-tags were imported
127
+ */
128
+ onImportFinish?: () => void;
129
+ };
130
+ /**
131
+ * Determines the position of the translation argument in the `lang()` function.
132
+ * If `1`, translations are in the first argument (`lang(translations, options)`).
133
+ * If `2`, translations are in the second argument (`lang(options, translations)`).
134
+ * @default 1
135
+ */
136
+ translationArgPosition: 1 | 2;
126
137
  debug?: boolean;
127
138
  }
128
139
  /**