@leyyo/common 1.3.16 → 1.3.18

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.
@@ -1,7 +1,7 @@
1
1
  import { DeployCommon, EnumPool, ErrorCommon, ErrorPool, EventCommon, LifecycleCommon, LiteralPool, LogCommon, RepoCommon } from "../common/index.js";
2
2
  import { DeveloperError, LeyyoError } from "../error/index.js";
3
3
  import { LoggerInstance } from "../class/logger.instance.js";
4
- import { KEY_SECURE_1 } from "../const/index.js";
4
+ import { KEY_LEYYO_SECURE } from "../const/index.js";
5
5
  import { $$set_leyyo_fn } from "../function/leyyo-fn.js";
6
6
  class Leyyo {
7
7
  _developerError;
@@ -21,11 +21,11 @@ class Leyyo {
21
21
  // region binding
22
22
  $$set_leyyo_fn(this);
23
23
  this._developerError = DeveloperError;
24
- this._developerError[KEY_SECURE_1](this);
24
+ this._developerError[KEY_LEYYO_SECURE](this);
25
25
  this._leyyoError = LeyyoError;
26
- this._leyyoError[KEY_SECURE_1](this);
26
+ this._leyyoError[KEY_LEYYO_SECURE](this);
27
27
  this._loggerInstance = LoggerInstance;
28
- this._loggerInstance[KEY_SECURE_1](this);
28
+ this._loggerInstance[KEY_LEYYO_SECURE](this);
29
29
  // endregion binding
30
30
  // region instances
31
31
  this._repoCommon = new RepoCommon(this); // none
@@ -1,12 +1,12 @@
1
1
  import { LeyyoLike } from "../base/index.js";
2
2
  import { LogLevel } from "../enum/index.js";
3
3
  import { Opt } from "../function/index.js";
4
- import { KEY_SECURE_1 } from "../const/index.js";
4
+ import { KEY_LEYYO_SECURE } from "../const/index.js";
5
5
  import { Logger, LoggerSecure } from "../common/index.js";
6
6
  export declare class LoggerInstance implements Logger, LoggerSecure {
7
7
  private _name;
8
8
  constructor(name: string);
9
- static [KEY_SECURE_1](leyyo: LeyyoLike): void;
9
+ static [KEY_LEYYO_SECURE](leyyo: LeyyoLike): void;
10
10
  debug(message: any, params?: any | Opt): void;
11
11
  trace(message: any, params?: any | Opt): void;
12
12
  info(message: any, params?: any | Opt): void;
@@ -1,5 +1,5 @@
1
1
  import { isText } from "../function/index.js";
2
- import { KEY_SECURE_1 } from "../const/index.js";
2
+ import { KEY_LEYYO_SECURE } from "../const/index.js";
3
3
  // region property
4
4
  let _leyyo;
5
5
  // endregion property
@@ -13,7 +13,7 @@ export class LoggerInstance {
13
13
  this._name = name;
14
14
  }
15
15
  // region static
16
- static [KEY_SECURE_1](leyyo) {
16
+ static [KEY_LEYYO_SECURE](leyyo) {
17
17
  if (!_leyyo) {
18
18
  _leyyo = leyyo;
19
19
  }
@@ -2,10 +2,12 @@ import { FQN } from "../internal.js";
2
2
  import { isText, testCase } from "../function/index.js";
3
3
  import { DeveloperError } from "../error/index.js";
4
4
  import { List } from "../class/index.js";
5
+ import { getRootStorage } from "../sys/index.js";
5
6
  /**
6
7
  * Identifier of file
7
8
  * */
8
9
  const where = `${FQN}.Repo`;
10
+ const _NAME = '$$leyyo.repo';
9
11
  // noinspection JSUnusedGlobalSymbols
10
12
  export class RepoCommon {
11
13
  leyyo;
@@ -14,35 +16,35 @@ export class RepoCommon {
14
16
  /**
15
17
  * Internal items which stores arrays
16
18
  * */
17
- _arrayItems = new Map();
19
+ _arrayItems = getRootStorage(_NAME, new Map());
18
20
  /**
19
21
  * Internal array volatile repo which could be cleared after lifecycle run
20
22
  * */
21
- _arrayVolatiles = new Set();
23
+ _arrayVolatiles = getRootStorage(_NAME, new Set());
22
24
  /**
23
25
  * Internal items which stores lists
24
26
  * */
25
- _listItems = new Map();
27
+ _listItems = getRootStorage(_NAME, new Map());
26
28
  /**
27
29
  * Internal list volatiles repo which could be cleared after lifecycle run
28
30
  * */
29
- _listVolatiles = new Set();
31
+ _listVolatiles = getRootStorage(_NAME, new Set());
30
32
  /**
31
33
  * Internal items which stores maps
32
34
  * */
33
- _mapItems = new Map();
35
+ _mapItems = getRootStorage(_NAME, new Map());
34
36
  /**
35
37
  * Internal map volatile repo which could be cleared after lifecycle run
36
38
  * */
37
- _mapVolatiles = new Set();
39
+ _mapVolatiles = getRootStorage(_NAME, new Set());
38
40
  /**
39
41
  * Internal items which stores sets
40
42
  * */
41
- _setItems = new Map();
43
+ _setItems = getRootStorage(_NAME, new Map());
42
44
  /**
43
45
  * Internal set volatiles repo which could be cleared after lifecycle run
44
46
  * */
45
- _setVolatiles = new Set();
47
+ _setVolatiles = getRootStorage(_NAME, new Set());
46
48
  // endregion property
47
49
  constructor(leyyo) {
48
50
  this.leyyo = leyyo;
@@ -1,5 +1,3 @@
1
- export declare const KEY_FQN_NAME: unique symbol;
2
- export declare const KEY_FQN_ON_SET: unique symbol;
3
1
  export declare const VAL_FQN_ANONYMOUS = "#Fqn";
4
2
  /**
5
3
  * Normal empty values
@@ -8,12 +6,14 @@ export declare const EMPTY_VALUES: any[];
8
6
  /**
9
7
  * Empty values with empty string
10
8
  * */
11
- export declare const EMPTY_VALUES_STR: string[];
12
- export declare const VAL_NAME_ANONYMOUS = "~";
13
- export declare const KEY_SECURE_1: unique symbol;
14
- export declare const KEY_ERROR_HTTP_STATUS: unique symbol;
9
+ export declare const EMPTY_VALUES_STR: Array<unknown>;
10
+ export declare const VAL_NAME_ANONYMOUS: string;
15
11
  export declare const VAL_ERROR_UNKNOWN_NAME: string;
16
12
  export declare const VAL_ERROR_UNKNOWN_MESSAGE: string;
13
+ export declare const KEY_FQN_NAME: unique symbol;
14
+ export declare const KEY_FQN_ON_SET: unique symbol;
15
+ export declare const KEY_LEYYO_SECURE: unique symbol;
16
+ export declare const KEY_ERROR_HTTP_STATUS: unique symbol;
17
17
  export declare const KEY_ERROR_DEFAULT_MESSAGE: unique symbol;
18
18
  export declare const KEY_ERROR_I18N: unique symbol;
19
19
  export declare const KEY_ERROR_EMIT: unique symbol;
@@ -31,3 +31,6 @@ export declare const KEY_ENUM_I18N: unique symbol;
31
31
  export declare const KEY_LITERAL_NAME: unique symbol;
32
32
  export declare const KEY_LITERAL_ALT: unique symbol;
33
33
  export declare const KEY_LITERAL_I18N: unique symbol;
34
+ export declare const KEY_DEVELOPER_MESSAGE: unique symbol;
35
+ export declare const KEY_DEVELOPER_CASE: unique symbol;
36
+ export declare const KEY_DEVELOPER_WHERE: unique symbol;
@@ -1,5 +1,3 @@
1
- export const KEY_FQN_NAME = Symbol.for('leyyo:fqn:basic');
2
- export const KEY_FQN_ON_SET = Symbol.for('leyyo:fqn:on-set');
3
1
  export const VAL_FQN_ANONYMOUS = '#Fqn';
4
2
  /**
5
3
  * Normal empty values
@@ -11,10 +9,12 @@ export const EMPTY_VALUES = [null, undefined];
11
9
  * */
12
10
  export const EMPTY_VALUES_STR = [null, undefined, ''];
13
11
  export const VAL_NAME_ANONYMOUS = '~';
14
- export const KEY_SECURE_1 = Symbol.for('leyyo:secure:1');
15
- export const KEY_ERROR_HTTP_STATUS = Symbol.for('leyyo:http:status');
16
12
  export const VAL_ERROR_UNKNOWN_NAME = 'UnknownError';
17
13
  export const VAL_ERROR_UNKNOWN_MESSAGE = 'Unknown error';
14
+ export const KEY_FQN_NAME = Symbol.for('leyyo:fqn:basic');
15
+ export const KEY_FQN_ON_SET = Symbol.for('leyyo:fqn:on-set');
16
+ export const KEY_LEYYO_SECURE = Symbol.for('leyyo:secure');
17
+ export const KEY_ERROR_HTTP_STATUS = Symbol.for('leyyo:error:http-status');
18
18
  export const KEY_ERROR_DEFAULT_MESSAGE = Symbol.for('leyyo:error:message');
19
19
  export const KEY_ERROR_I18N = Symbol.for('leyyo:error:i18n');
20
20
  export const KEY_ERROR_EMIT = Symbol.for('leyyo:error:emit');
@@ -26,9 +26,12 @@ export const KEY_LOADER_NAME = Symbol.for('leyyo:loader:name');
26
26
  export const KEY_LOADER_STAMP = Symbol.for('leyyo:loader:stamp');
27
27
  export const KEY_LOADER_EMPTY = Symbol.for('leyyo:loader:empty');
28
28
  export const KEY_LOG_ALREADY = Symbol.for('leyyo:log:already');
29
- export const KEY_ENUM_NAME = Symbol.for('leyyo::enum:name');
29
+ export const KEY_ENUM_NAME = Symbol.for('leyyo:enum:name');
30
30
  export const KEY_ENUM_ALT = Symbol.for('leyyo:enum:alt');
31
31
  export const KEY_ENUM_I18N = Symbol.for('leyyo:enum:i18n');
32
- export const KEY_LITERAL_NAME = Symbol.for('leyyo::literal:name');
32
+ export const KEY_LITERAL_NAME = Symbol.for('leyyo:literal:name');
33
33
  export const KEY_LITERAL_ALT = Symbol.for('leyyo:literal:alt');
34
34
  export const KEY_LITERAL_I18N = Symbol.for('leyyo:literal:i18n');
35
+ export const KEY_DEVELOPER_MESSAGE = Symbol.for('leyyo:developer:message');
36
+ export const KEY_DEVELOPER_CASE = Symbol.for('leyyo:developer:case');
37
+ export const KEY_DEVELOPER_WHERE = Symbol.for('leyyo:developer:where');
@@ -1,14 +1,11 @@
1
- import { KEY_SECURE_1 } from "../const/index.js";
1
+ import { KEY_DEVELOPER_CASE, KEY_DEVELOPER_MESSAGE, KEY_DEVELOPER_WHERE, KEY_LEYYO_SECURE } from "../const/index.js";
2
2
  import { LeyyoLike } from "../base/index.js";
3
3
  import { DeveloperErrorLike, ErrorStackLine } from "./index.types.js";
4
- declare const LY_DEVELOPER_MESSAGE: unique symbol;
5
- declare const LY_DEVELOPER_CASE: unique symbol;
6
- declare const LY_DEVELOPER_WHERE: unique symbol;
7
4
  /** Developer error */
8
5
  export declare class DeveloperError extends Error implements DeveloperErrorLike {
9
- protected [LY_DEVELOPER_MESSAGE]: string;
10
- protected [LY_DEVELOPER_CASE]: string;
11
- protected [LY_DEVELOPER_WHERE]: string;
6
+ protected [KEY_DEVELOPER_MESSAGE]: string;
7
+ protected [KEY_DEVELOPER_CASE]: string;
8
+ protected [KEY_DEVELOPER_WHERE]: string;
12
9
  /** @inheritDoc */
13
10
  stackTrace?: Array<ErrorStackLine>;
14
11
  /**
@@ -17,8 +14,7 @@ export declare class DeveloperError extends Error implements DeveloperErrorLike
17
14
  * @param {string} where - where
18
15
  * */
19
16
  constructor(message: string, issue?: string, where?: string);
20
- static [KEY_SECURE_1](leyyo: LeyyoLike): void;
17
+ static [KEY_LEYYO_SECURE](leyyo: LeyyoLike): void;
21
18
  /** @inheritDoc */
22
19
  log(err?: Error): void;
23
20
  }
24
- export {};
@@ -1,15 +1,12 @@
1
- import { KEY_SECURE_1 } from "../const/index.js";
1
+ import { KEY_DEVELOPER_CASE, KEY_DEVELOPER_MESSAGE, KEY_DEVELOPER_WHERE, KEY_LEYYO_SECURE } from "../const/index.js";
2
2
  // region properties
3
- const LY_DEVELOPER_MESSAGE = Symbol.for('leyyo/developer.message');
4
- const LY_DEVELOPER_CASE = Symbol.for('leyyo/developer.case');
5
- const LY_DEVELOPER_WHERE = Symbol.for('leyyo/developer.where');
6
3
  let _leyyo;
7
4
  // endregion properties
8
5
  /** Developer error */
9
6
  export class DeveloperError extends Error {
10
- [LY_DEVELOPER_MESSAGE];
11
- [LY_DEVELOPER_CASE];
12
- [LY_DEVELOPER_WHERE];
7
+ [KEY_DEVELOPER_MESSAGE];
8
+ [KEY_DEVELOPER_CASE];
9
+ [KEY_DEVELOPER_WHERE];
13
10
  /** @inheritDoc */
14
11
  stackTrace;
15
12
  /**
@@ -27,16 +24,16 @@ export class DeveloperError extends Error {
27
24
  message += ` [w:${where}]`;
28
25
  }
29
26
  super(message);
30
- this[LY_DEVELOPER_MESSAGE] = pureMessage;
27
+ this[KEY_DEVELOPER_MESSAGE] = pureMessage;
31
28
  if (typeof issue === 'string') {
32
- this[LY_DEVELOPER_CASE] = issue;
29
+ this[KEY_DEVELOPER_CASE] = issue;
33
30
  }
34
31
  if (typeof where === 'string') {
35
- this[LY_DEVELOPER_WHERE] = where;
32
+ this[KEY_DEVELOPER_WHERE] = where;
36
33
  }
37
34
  _leyyo.errorCommon.buildStack(this);
38
35
  }
39
- static [KEY_SECURE_1](leyyo) {
36
+ static [KEY_LEYYO_SECURE](leyyo) {
40
37
  if (!_leyyo) {
41
38
  _leyyo = leyyo;
42
39
  }
@@ -46,6 +43,6 @@ export class DeveloperError extends Error {
46
43
  if (err instanceof Error) {
47
44
  this['causedBy'] = err;
48
45
  }
49
- _leyyo.logCommon.emitLog('fatal', this[LY_DEVELOPER_WHERE], this, _leyyo.errorCommon.toJsonBasic(this, { testCase: this[LY_DEVELOPER_CASE] }));
46
+ _leyyo.logCommon.emitLog('fatal', this[KEY_DEVELOPER_WHERE], this, _leyyo.errorCommon.toJsonBasic(this, { testCase: this[KEY_DEVELOPER_CASE] }));
50
47
  }
51
48
  }
@@ -2,7 +2,7 @@ import { Logger } from "../common/index.js";
2
2
  import { ErrorStackLine, LeyyoErrorLike, LeyyoErrorSecure, LeyyoErrorTag } from "./index.types.js";
3
3
  import { ClassLike, LeyyoLike, Obj, OneOrMore } from "../base/index.js";
4
4
  import { Opt } from "../function/index.js";
5
- import { KEY_ERROR_FLAGS, KEY_SECURE_1 } from "../const/index.js";
5
+ import { KEY_ERROR_FLAGS, KEY_LEYYO_SECURE } from "../const/index.js";
6
6
  type T2 = LeyyoErrorTag;
7
7
  /**
8
8
  * Leyyo base error
@@ -40,7 +40,7 @@ export declare class LeyyoError extends Error implements LeyyoErrorLike, LeyyoEr
40
40
  * @param {Opt} params - error parameters
41
41
  * */
42
42
  constructor(message: string, params: Opt);
43
- static [KEY_SECURE_1](leyyo: LeyyoLike): void;
43
+ static [KEY_LEYYO_SECURE](leyyo: LeyyoLike): void;
44
44
  causes(err: Error): this;
45
45
  where(p1: ClassLike | Obj | string, fqn?: string): this;
46
46
  private _log;
@@ -1,5 +1,5 @@
1
1
  import { getFqn, getSymbol, isFilledObj, isObj, optAdd, optAppend, setSymbol } from "../function/index.js";
2
- import { KEY_ERROR_FLAGS, KEY_ERROR_WHERE, KEY_SECURE_1, VAL_ERROR_UNKNOWN_MESSAGE } from "../const/index.js";
2
+ import { KEY_ERROR_FLAGS, KEY_ERROR_WHERE, KEY_LEYYO_SECURE, VAL_ERROR_UNKNOWN_MESSAGE } from "../const/index.js";
3
3
  let _leyyo;
4
4
  // region property
5
5
  const _errorField = ['name', 'message', 'stack'];
@@ -54,7 +54,7 @@ export class LeyyoError extends Error {
54
54
  _leyyo.errorCommon.buildStack(this);
55
55
  _leyyo.errorCommon.emit(this);
56
56
  }
57
- static [KEY_SECURE_1](leyyo) {
57
+ static [KEY_LEYYO_SECURE](leyyo) {
58
58
  if (!_leyyo) {
59
59
  _leyyo = leyyo;
60
60
  }
@@ -1,44 +1,44 @@
1
- export declare function sysStat(): SysStat;
2
- export interface SysStat {
3
- cpu: SysStatCpu;
4
- memory: SysStatMemory;
5
- time: SysStatTime;
6
- npm: SysStatNpm;
7
- node: SysStatNode;
8
- project: SysStatProject;
9
- os: SysStatOs;
1
+ export declare function getStat(): Statistics;
2
+ export interface Statistics {
3
+ cpu: StatisticsCpu;
4
+ memory: StatisticsMemory;
5
+ time: StatisticsTime;
6
+ npm: StatisticsNpm;
7
+ node: StatisticsNode;
8
+ project: StatisticsProject;
9
+ os: StatisticsOs;
10
10
  }
11
- export interface SysStatCpu {
11
+ export interface StatisticsCpu {
12
12
  user: number;
13
13
  system: number;
14
14
  }
15
- export interface SysStatTime {
15
+ export interface StatisticsTime {
16
16
  uptime: number;
17
17
  startedAt: number;
18
18
  }
19
- export interface SysStatNpm {
19
+ export interface StatisticsNpm {
20
20
  pwd: string;
21
21
  version: string;
22
22
  }
23
- export interface SysStatNode {
23
+ export interface StatisticsNode {
24
24
  type: string;
25
25
  version: string;
26
26
  }
27
- export interface SysStatProject {
27
+ export interface StatisticsProject {
28
28
  name: string;
29
29
  version: string;
30
30
  environment: string;
31
31
  log: string;
32
32
  }
33
- export interface SysStatOs {
33
+ export interface StatisticsOs {
34
34
  version: string;
35
35
  arch: string;
36
36
  platform: string;
37
37
  machineType: string;
38
38
  network: Record<string, unknown>;
39
- cpu: Array<SysStatCpuInfo>;
39
+ cpu: Array<StatisticsCpuInfo>;
40
40
  }
41
- export interface SysStatMemory {
41
+ export interface StatisticsMemory {
42
42
  /**
43
43
  * Resident Set Size, is the amount of space occupied in the main memory device (that is a subset of the total allocated memory) for the
44
44
  * process, including all C++ and JavaScript objects and code.
@@ -60,7 +60,7 @@ export interface SysStatMemory {
60
60
  */
61
61
  arrayBuffers: number;
62
62
  }
63
- export interface SysStatCpuInfo {
63
+ export interface StatisticsCpuInfo {
64
64
  model: string;
65
65
  speed: number;
66
66
  times: {
@@ -1,5 +1,5 @@
1
1
  import os from "node:os";
2
- export function sysStat() {
2
+ export function getStat() {
3
3
  const uptime = Math.round(process.uptime() * 1_000);
4
4
  return {
5
5
  cpu: process.cpuUsage(),
@@ -5,6 +5,7 @@ export * from './delete-prop.js';
5
5
  export * from './empty-fn.js';
6
6
  export * from './extended-type.js';
7
7
  export * from './get-fqn.js';
8
+ export * from './get-stat.js';
8
9
  export * from './set-fqn.js';
9
10
  export * from './remove-fqn.js';
10
11
  export * from './on-fqn-set.js';
@@ -19,6 +20,7 @@ export * from './is-obj.js';
19
20
  export * from './is-text.js';
20
21
  export * from './is-anonymous-name.js';
21
22
  export * from './jitter-interval.js';
23
+ export * from './load-config.js';
22
24
  export * from './stamp-loader.js';
23
25
  export * from './one-or-more.js';
24
26
  export * from './opt-add.js';
@@ -5,6 +5,7 @@ export * from './delete-prop.js';
5
5
  export * from './empty-fn.js';
6
6
  export * from './extended-type.js';
7
7
  export * from './get-fqn.js';
8
+ export * from './get-stat.js';
8
9
  export * from './set-fqn.js';
9
10
  export * from './remove-fqn.js';
10
11
  export * from './on-fqn-set.js';
@@ -19,6 +20,7 @@ export * from './is-obj.js';
19
20
  export * from './is-text.js';
20
21
  export * from './is-anonymous-name.js';
21
22
  export * from './jitter-interval.js';
23
+ export * from './load-config.js';
22
24
  export * from './stamp-loader.js';
23
25
  export * from './one-or-more.js';
24
26
  export * from './opt-add.js';
@@ -33,3 +33,6 @@ export type ExporterValue = Record<string, unknown>;
33
33
  export interface ExporterDepot {
34
34
  add(name: string, value: ExporterValue): void;
35
35
  }
36
+ export interface LeyyoConfig {
37
+ [fqn: string]: Record<string, unknown>;
38
+ }
@@ -1,2 +1 @@
1
1
  export {};
2
- // endregion exporter
@@ -0,0 +1,22 @@
1
+ import { LeyyoConfig } from "./index.types.js";
2
+ export declare const leyyoConfig: LeyyoConfig;
3
+ /**
4
+ * Load config from `.leyyo.yaml` file
5
+ *
6
+ * `OBJECT` postfixes:
7
+ * - !: only override (`don't merge`)
8
+ * - ?: only merge (`don't override`)
9
+ * - <empty>: only set if key is absent
10
+ *
11
+ * `ARRAY` postfixes:
12
+ * - !: only override (`don't merge`)
13
+ * - ?: only merge (`don't override`)
14
+ * - <empty>: only set if key is absent
15
+ *
16
+ * Generics:
17
+ * - `C`- config model
18
+ *
19
+ * @param {string} url
20
+ * @return {LeyyoConfig}
21
+ * */
22
+ export declare function loadConfig(url: string): LeyyoConfig;
@@ -0,0 +1,242 @@
1
+ import * as fs from "node:fs";
2
+ import path from "node:path";
3
+ import { dirname } from "path";
4
+ import { fileURLToPath } from "url";
5
+ import * as yaml from 'js-yaml';
6
+ import { isObj } from "./is-obj.js";
7
+ import { getRootStorage } from "../sys/index.js";
8
+ import { isText } from "./is-text.js";
9
+ import { isEmpty } from "./is-empty.js";
10
+ import { secureJson, secureObject } from "./secure-json.js";
11
+ const _NAME = '$$leyyo.config';
12
+ export const leyyoConfig = getRootStorage(_NAME, {});
13
+ /**
14
+ * Load config from `.leyyo.yaml` file
15
+ *
16
+ * `OBJECT` postfixes:
17
+ * - !: only override (`don't merge`)
18
+ * - ?: only merge (`don't override`)
19
+ * - <empty>: only set if key is absent
20
+ *
21
+ * `ARRAY` postfixes:
22
+ * - !: only override (`don't merge`)
23
+ * - ?: only merge (`don't override`)
24
+ * - <empty>: only set if key is absent
25
+ *
26
+ * Generics:
27
+ * - `C`- config model
28
+ *
29
+ * @param {string} url
30
+ * @return {LeyyoConfig}
31
+ * */
32
+ export function loadConfig(url) {
33
+ try {
34
+ const __dirname = dirname(dirname(fileURLToPath(url)));
35
+ const yamlPath = path.normalize(__dirname + '/.leyyo.yaml');
36
+ if (fs.existsSync(yamlPath)) {
37
+ const input = fs.readFileSync(yamlPath, 'utf8');
38
+ const data = yaml.load(input);
39
+ if (isObj(data)) {
40
+ for (const [k, v] of Object.entries(data)) {
41
+ _object(leyyoConfig, k, v);
42
+ }
43
+ }
44
+ return leyyoConfig;
45
+ }
46
+ }
47
+ catch (e) {
48
+ console.error(`[leyyoConfig] ${e.name} => ${e.message}`);
49
+ return undefined;
50
+ }
51
+ }
52
+ /**
53
+ * Get key behaviour
54
+ * @param {string} keyFull - key
55
+ * @return {Array} - tuple as `[behaviour, key]`
56
+ * */
57
+ function _behaviour(keyFull) {
58
+ if (!isText(keyFull)) {
59
+ return [undefined, undefined];
60
+ }
61
+ if (keyFull.endsWith('!')) {
62
+ keyFull = keyFull.substring(keyFull.length - 1).trim();
63
+ if (!isText(keyFull)) {
64
+ return [undefined, undefined];
65
+ }
66
+ return ['override', keyFull];
67
+ }
68
+ else if (keyFull.endsWith('?')) {
69
+ keyFull = keyFull.substring(keyFull.length - 1).trim();
70
+ if (!isText(keyFull)) {
71
+ return [undefined, undefined];
72
+ }
73
+ return ['merge', keyFull];
74
+ }
75
+ return [undefined, keyFull];
76
+ }
77
+ /**
78
+ * Merge array
79
+ *
80
+ * @param {Array} source
81
+ * @param {string} key
82
+ * @param {Array} value
83
+ * */
84
+ function _array(source, key, value) {
85
+ value.forEach((item, index) => {
86
+ if (isEmpty(item)) {
87
+ console.warn(`[leyyoConfig] value empty at (${key}#${index})`);
88
+ return;
89
+ }
90
+ const clonedSource = source.map(item => JSON.stringify(item));
91
+ switch (typeof item) {
92
+ case "string":
93
+ case "number":
94
+ case "boolean":
95
+ if (!clonedSource.includes(JSON.stringify(item))) {
96
+ source.push(item);
97
+ }
98
+ break;
99
+ case "object":
100
+ if (!clonedSource.includes(secureJson(item))) {
101
+ source.push(secureObject(item));
102
+ }
103
+ break;
104
+ case "undefined":
105
+ case "bigint":
106
+ case "symbol":
107
+ case "function":
108
+ console.warn(`[leyyoConfig] type is not allowed at (${key}#${index})`);
109
+ break;
110
+ }
111
+ });
112
+ }
113
+ /**
114
+ * Merge object
115
+ *
116
+ * @param {object} source
117
+ * @param {string} keyFull - key
118
+ * @param {any} value
119
+ * */
120
+ function _object(source, keyFull, value) {
121
+ if (isEmpty(value)) {
122
+ return;
123
+ }
124
+ const [behaviour, key] = _behaviour(keyFull);
125
+ if (!key) {
126
+ console.warn(`[leyyoConfig] key empty at (${keyFull})`);
127
+ return;
128
+ }
129
+ if (!source) {
130
+ source = {};
131
+ }
132
+ // old is empty
133
+ if (isEmpty(source[key])) {
134
+ switch (typeof value) {
135
+ case "string":
136
+ case "number":
137
+ case "boolean":
138
+ source[key] = value;
139
+ break;
140
+ case "object":
141
+ source[key] = secureObject(value);
142
+ break;
143
+ case "function":
144
+ case "symbol":
145
+ case "bigint":
146
+ case "undefined":
147
+ console.warn(`[leyyoConfig] type is not allowed at (${key})`);
148
+ break;
149
+ }
150
+ return;
151
+ }
152
+ switch (typeof value) {
153
+ case "string":
154
+ case "number":
155
+ case "boolean":
156
+ switch (behaviour) {
157
+ case "override":
158
+ source[key] = value;
159
+ break;
160
+ default: // merge
161
+ if (isEmpty(source[key])) {
162
+ source[key] = value;
163
+ }
164
+ break;
165
+ }
166
+ break;
167
+ case "object":
168
+ // new is an array
169
+ if (Array.isArray(value)) {
170
+ // old is an array (BOTH)
171
+ if (Array.isArray(source[key])) {
172
+ switch (behaviour) {
173
+ case "override":
174
+ source[key] = secureObject(value);
175
+ break;
176
+ case "merge":
177
+ _array(source[key], key, value);
178
+ break;
179
+ default:
180
+ // old exists, ignore
181
+ break;
182
+ }
183
+ }
184
+ // CONFLICT: old is not array
185
+ else {
186
+ switch (behaviour) {
187
+ case "override":
188
+ source[key] = secureObject(value);
189
+ break;
190
+ case "merge":
191
+ // old is different, conflict
192
+ console.warn(`[leyyoConfig] type is conflicted at (${key})`);
193
+ break;
194
+ default:
195
+ // old exists, ignore
196
+ break;
197
+ }
198
+ }
199
+ }
200
+ // new is an object
201
+ else {
202
+ // CONFLICT: old is not object
203
+ if (Array.isArray(source[key])) {
204
+ switch (behaviour) {
205
+ case "override":
206
+ source[key] = value;
207
+ break;
208
+ case "merge":
209
+ // old is different, conflict
210
+ console.warn(`[leyyoConfig] type is conflicted at (${key})`);
211
+ break;
212
+ default:
213
+ // old exists, ignore
214
+ break;
215
+ }
216
+ }
217
+ // old is an object (BOTH)
218
+ else {
219
+ switch (behaviour) {
220
+ case "override":
221
+ source[key] = value;
222
+ break;
223
+ case "merge":
224
+ for (const [k, v] of Object.entries(value)) {
225
+ _object(source[key], k, v);
226
+ }
227
+ break;
228
+ default:
229
+ // old exists, ignore
230
+ break;
231
+ }
232
+ }
233
+ }
234
+ break;
235
+ case "function":
236
+ case "symbol":
237
+ case "bigint":
238
+ case "undefined":
239
+ console.warn(`[leyyoConfig] type is not allowed at (${key})`);
240
+ break;
241
+ }
242
+ }
@@ -1 +1 @@
1
- export declare const NME: string, FQN: string, VER: string, CNF: import("./sys/index.types.js").LeyyoConfig;
1
+ export declare const NME: string, FQN: string, VER: string;
package/dist/internal.js CHANGED
@@ -1,2 +1,2 @@
1
- import { sysAll } from "./sys/index.js";
2
- export const { pck: { name: NME, fqn: FQN, version: VER }, config: CNF } = sysAll(import.meta.url);
1
+ import { packageJson } from "./sys/index.js";
2
+ export const { name: NME, fqn: FQN, version: VER } = packageJson(import.meta.url);
@@ -1,4 +1,2 @@
1
- export * from './index.types.js';
2
- export * from './leyyo-config.js';
3
1
  export * from './package-json.js';
4
- export * from './sys-all.js';
2
+ export * from './leyyo-storage.js';
package/dist/sys/index.js CHANGED
@@ -1,4 +1,2 @@
1
- export * from './index.types.js';
2
- export * from './leyyo-config.js';
3
1
  export * from './package-json.js';
4
- export * from './sys-all.js';
2
+ export * from './leyyo-storage.js';
@@ -0,0 +1,11 @@
1
+ type LeyyoStorage = Map<string, unknown>;
2
+ /**
3
+ * Local storage for leyyo platform
4
+ * */
5
+ export declare const leyyoStorage: LeyyoStorage;
6
+ /**
7
+ * @param {string} name - name of storage
8
+ * @param {any} def - initial value
9
+ * */
10
+ export declare function getRootStorage<T>(name: string, def: T): T;
11
+ export {};
@@ -0,0 +1,59 @@
1
+ const _NAME = '$$leyyo.packages';
2
+ /**
3
+ * Create a standalone storage
4
+ *
5
+ * @return {LeyyoStorage}
6
+ * */
7
+ function _new() {
8
+ return new Map();
9
+ }
10
+ /**
11
+ * Get a global storage
12
+ *
13
+ * @param {any} source - `global` or `globalThis`
14
+ * @return {LeyyoStorage}
15
+ * */
16
+ function _get(source) {
17
+ if (!source) {
18
+ return undefined;
19
+ }
20
+ if (source[_NAME] && source[_NAME] instanceof Map) {
21
+ return source[_NAME];
22
+ }
23
+ source[_NAME] = _new();
24
+ return source[_NAME];
25
+ }
26
+ /**
27
+ * Build storage
28
+ *
29
+ * @return {LeyyoStorage}
30
+ * */
31
+ function _build() {
32
+ try {
33
+ return _get(globalThis) ?? _get(global) ?? _new();
34
+ }
35
+ catch (e) {
36
+ return _new();
37
+ }
38
+ }
39
+ /**
40
+ * Local storage for leyyo platform
41
+ * */
42
+ export const leyyoStorage = _build();
43
+ /**
44
+ * @param {string} name - name of storage
45
+ * @param {any} def - initial value
46
+ * */
47
+ export function getRootStorage(name, def) {
48
+ if (typeof name !== 'string') {
49
+ throw new Error('Invalid storage name', name);
50
+ }
51
+ if (leyyoStorage.has(name)) {
52
+ return leyyoStorage.get(name);
53
+ }
54
+ if (!def || typeof def !== 'object') {
55
+ throw new Error('Invalid storage value', def);
56
+ }
57
+ leyyoStorage.set(name, def);
58
+ return def;
59
+ }
@@ -1,3 +1,8 @@
1
- import { PackageJson } from "./index.types.js";
1
+ export interface PackageJson {
2
+ fqn: string;
3
+ name: string;
4
+ version: string;
5
+ [k: string]: unknown;
6
+ }
2
7
  export declare function packageJson<P extends PackageJson = PackageJson>(url: string): P;
3
8
  export declare function packageJson<P extends PackageJson = PackageJson>(url: string, full: true): P;
@@ -2,8 +2,10 @@ import * as fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { dirname } from "path";
4
4
  import { fileURLToPath } from "url";
5
+ import { getRootStorage } from "./leyyo-storage.js";
6
+ const _NAME = '$$leyyo.packages';
5
7
  const _empty = { fqn: 'leyyo.unknown', name: '@leyyo/unknown', version: '0.0.0' };
6
- const _map = new Map();
8
+ const _map = getRootStorage(_NAME, new Map());
7
9
  export function packageJson(url, full) {
8
10
  try {
9
11
  const __dirname = dirname(dirname(fileURLToPath(url)));
@@ -17,9 +19,17 @@ export function packageJson(url, full) {
17
19
  const name = jsonData.name;
18
20
  const version = jsonData.version;
19
21
  if (_map.has(name)) {
20
- console.error(`Same package[${name}] duplicated, versions: ['${_map.get(name)}', '${version}']`);
22
+ if (Array.isArray(_map.get(name))) {
23
+ console.warn(`Same package[${name}] duplicated, current: ${version}, previous versions: ${JSON.stringify(_map.get(name))}`);
24
+ }
25
+ else {
26
+ _map.set(name, []);
27
+ }
21
28
  }
22
- _map.set(name, version);
29
+ else {
30
+ _map.set(name, []);
31
+ }
32
+ _map.get(name).push(version);
23
33
  const fqn = jsonData?.name.split('/').join('.').split('@').join('');
24
34
  if (full) {
25
35
  return { ...jsonData, fqn };
@@ -33,7 +43,7 @@ export function packageJson(url, full) {
33
43
  }
34
44
  }
35
45
  catch (e) {
36
- console.log(`[packageJson] ${e.name} => ${e.message}`);
46
+ console.error(`[packageJson] ${e.name} => ${e.message}`);
37
47
  return _empty;
38
48
  }
39
49
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leyyo/common",
3
- "version": "1.3.16",
3
+ "version": "1.3.18",
4
4
  "description": "Leyyo common library",
5
5
  "keywords": [
6
6
  "common"
@@ -39,6 +39,7 @@
39
39
  "@types/jest": "^30.0.0",
40
40
  "@types/js-yaml": "^4.0.9",
41
41
  "@types/node": "^24.2.1",
42
+ "@types/node-localstorage": "^1.3.3",
42
43
  "@typescript-eslint/eslint-plugin": "^8.39.1",
43
44
  "@typescript-eslint/parser": "^8.39.1",
44
45
  "eslint": "^9.33.0",
@@ -64,6 +65,7 @@
64
65
  },
65
66
  "dependencies": {
66
67
  "js-yaml": "^4.1.1",
68
+ "node-localstorage": "^3.0.5",
67
69
  "stacktrace-parser": "^0.1.11"
68
70
  }
69
71
  }
@@ -1,13 +0,0 @@
1
- export interface PackageJson {
2
- fqn: string;
3
- name: string;
4
- version: string;
5
- [k: string]: unknown;
6
- }
7
- export interface LeyyoConfig {
8
- [fqn: string]: Record<string, unknown>;
9
- }
10
- export interface LeyyoSysAll<C extends LeyyoConfig = LeyyoConfig, P extends PackageJson = PackageJson> {
11
- config: C;
12
- pck: P;
13
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,2 +0,0 @@
1
- import { LeyyoConfig } from "./index.types.js";
2
- export declare function leyyoConfig<C extends LeyyoConfig = LeyyoConfig>(url: string): C;
@@ -1,19 +0,0 @@
1
- import * as fs from "node:fs";
2
- import path from "node:path";
3
- import { dirname } from "path";
4
- import { fileURLToPath } from "url";
5
- import * as yaml from 'js-yaml';
6
- export function leyyoConfig(url) {
7
- try {
8
- const __dirname = dirname(dirname(fileURLToPath(url)));
9
- const yamlPath = path.normalize(__dirname + '/.leyyo.yaml');
10
- if (fs.existsSync(yamlPath)) {
11
- const input = fs.readFileSync(yamlPath, 'utf8');
12
- return yaml.load(input);
13
- }
14
- }
15
- catch (e) {
16
- console.log(`[leyyoConfig] ${e.name} => ${e.message}`);
17
- return undefined;
18
- }
19
- }
@@ -1,2 +0,0 @@
1
- import { LeyyoConfig, LeyyoSysAll, PackageJson } from "./index.types.js";
2
- export declare function sysAll<C extends LeyyoConfig = LeyyoConfig, P extends PackageJson = PackageJson>(url: string): LeyyoSysAll<C, P>;
@@ -1,8 +0,0 @@
1
- import { leyyoConfig } from "./leyyo-config.js";
2
- import { packageJson } from "./package-json.js";
3
- export function sysAll(url) {
4
- return {
5
- config: leyyoConfig(url),
6
- pck: packageJson(url),
7
- };
8
- }