@h3ravel/shared 0.27.7 → 0.28.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,94 +1,299 @@
1
+ import chalk from "chalk";
1
2
  import { access } from "fs/promises";
2
3
  import escalade from "escalade/sync";
4
+ import { existsSync } from "fs";
3
5
  import path from "path";
4
- import chalk from "chalk";
5
6
  import autocomplete from "inquirer-autocomplete-standalone";
6
7
  import { confirm, input, password, select } from "@inquirer/prompts";
7
8
  import crypto from "crypto";
8
9
  import preferredPM from "preferred-pm";
9
10
 
10
- //#region src/Utils/EnvParser.ts
11
- var EnvParser = class {
12
- static parse(initial) {
13
- const parsed = { ...initial };
14
- for (const key in parsed) {
15
- const value = parsed[key];
16
- parsed[key] = this.parseValue(value);
11
+ //#region src/Container.ts
12
+ const INTERNAL_METHODS = Symbol("internal_methods");
13
+ /**
14
+ * Decorator to mark class properties as internal
15
+ *
16
+ * @param target
17
+ * @param propertyKey
18
+ */
19
+ const internal = (target, propertyKey) => {
20
+ if (!target[INTERNAL_METHODS]) target[INTERNAL_METHODS] = /* @__PURE__ */ new Set();
21
+ target[INTERNAL_METHODS].add(propertyKey);
22
+ };
23
+ /**
24
+ * Checks if a property is decorated with the @internal decorator
25
+ *
26
+ * @param instance
27
+ * @param prop
28
+ * @returns
29
+ */
30
+ const isInternal = (instance, prop) => {
31
+ return Object.getPrototypeOf(instance)[INTERNAL_METHODS]?.has(prop) ?? false;
32
+ };
33
+
34
+ //#endregion
35
+ //#region src/Mixins/MixinSystem.ts
36
+ /**
37
+ * Helper to mix multiple classes into one, this allows extending multiple classes by any single class
38
+ *
39
+ * @param bases
40
+ * @returns
41
+ */
42
+ const mix = (...bases) => {
43
+ class Base {
44
+ constructor(...args) {
45
+ let instance = this;
46
+ for (const constructor of bases) {
47
+ const result = Reflect.construct(constructor, args, new.target);
48
+ if (result && (typeof result === "object" || typeof result === "function")) {
49
+ if (result !== instance) {
50
+ Object.assign(result, instance);
51
+ instance = result;
52
+ }
53
+ }
54
+ }
55
+ return instance;
17
56
  }
18
- return parsed;
19
57
  }
20
- static parseValue(value) {
21
- /**
22
- * Null/undefined stay untouched
23
- */
24
- if (value === null || value === void 0) return value;
25
- /**
26
- * Convert string "true"/"false" to boolean
27
- */
28
- if (value === "true") return true;
29
- if (value === "false") return false;
30
- /**
31
- * Convert string numbers to number
32
- */
33
- if (!isNaN(value) && value.trim() !== "") return Number(value);
34
- /**
35
- * Convert string "null" and "undefined"
36
- */
37
- if (value === "null") return null;
38
- if (value === "undefined") return void 0;
39
- /**
40
- * Otherwise return as-is (string)
41
- */
42
- return value;
58
+ for (let i = 0; i < bases.length; i++) {
59
+ const currentBase = bases[i];
60
+ const nextBase = bases[i + 1];
61
+ Object.getOwnPropertyNames(currentBase.prototype).forEach((prop) => {
62
+ if (prop !== "constructor") Object.defineProperty(Base.prototype, prop, Object.getOwnPropertyDescriptor(currentBase.prototype, prop));
63
+ });
64
+ Object.getOwnPropertyNames(currentBase).forEach((prop) => {
65
+ if (![
66
+ "prototype",
67
+ "name",
68
+ "length"
69
+ ].includes(prop)) Object.defineProperty(Base, prop, Object.getOwnPropertyDescriptor(currentBase, prop));
70
+ });
71
+ if (nextBase) {
72
+ Object.setPrototypeOf(currentBase.prototype, nextBase.prototype);
73
+ Object.setPrototypeOf(currentBase, nextBase);
74
+ }
43
75
  }
76
+ Object.setPrototypeOf(Base.prototype, bases[0].prototype);
77
+ Object.setPrototypeOf(Base, bases[0]);
78
+ return Base;
44
79
  };
45
80
 
46
81
  //#endregion
47
- //#region src/Utils/FileSystem.ts
48
- var FileSystem = class {
49
- static findModulePkg(moduleId, cwd) {
50
- const parts = moduleId.replace(/\\/g, "/").split("/");
51
- let packageName = "";
52
- if (parts.length > 0 && parts[0][0] === "@") packageName += parts.shift() + "/";
53
- packageName += parts.shift();
54
- const packageJson = path.join(cwd ?? process.cwd(), "node_modules", packageName);
55
- const resolved = this.resolveFileUp("package", ["json"], packageJson);
56
- if (!resolved) return;
57
- return path.join(path.dirname(resolved), parts.join("/"));
58
- }
59
- /**
60
- * Check if file exists
61
- *
62
- * @param path
63
- * @returns
64
- */
65
- static async fileExists(path$1) {
66
- try {
67
- await access(path$1);
68
- return true;
69
- } catch {
70
- return false;
82
+ //#region src/Mixins/TraitSystem.ts
83
+ const crcTable = [];
84
+ for (let n = 0; n < 256; n++) {
85
+ let c = n;
86
+ for (let k = 0; k < 8; k++) c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
87
+ crcTable[n] = c;
88
+ }
89
+ const crc32 = (str) => {
90
+ let crc = -1;
91
+ for (let i = 0; i < str.length; i++) crc = crc >>> 8 ^ crcTable[(crc ^ str.charCodeAt(i)) & 255];
92
+ return (crc ^ -1) >>> 0;
93
+ };
94
+ const isCons = (fn) => typeof fn === "function" && !!fn.prototype && !!fn.prototype.constructor;
95
+ const isTypeFactory = (fn) => typeof fn === "function" && !fn.prototype && fn.length === 0;
96
+ function trait(...args) {
97
+ const factory = args.length === 2 ? args[1] : args[0];
98
+ const superTraits = args.length === 2 ? args[0] : void 0;
99
+ return {
100
+ id: crc32(factory.toString()),
101
+ symbol: Symbol("trait"),
102
+ factory,
103
+ superTraits
104
+ };
105
+ }
106
+ const extendProperties = (cons, field, value) => Object.defineProperty(cons, field, {
107
+ value,
108
+ enumerable: false,
109
+ writable: false
110
+ });
111
+ const rawTrait = (x) => isTypeFactory(x) ? x() : x;
112
+ const deriveTrait = (trait$, baseClz, derived) => {
113
+ const trait$1 = rawTrait(trait$);
114
+ let clz = baseClz;
115
+ if (!derived.has(trait$1.id)) {
116
+ derived.set(trait$1.id, true);
117
+ if (trait$1.superTraits !== void 0) for (const superTrait of reverseTraitList(trait$1.superTraits)) clz = deriveTrait(superTrait, clz, derived);
118
+ clz = trait$1.factory(clz);
119
+ extendProperties(clz, "id", crc32(trait$1.factory.toString()));
120
+ extendProperties(clz, trait$1.symbol, true);
121
+ }
122
+ return clz;
123
+ };
124
+ const reverseTraitList = (traits) => traits.slice().reverse();
125
+ function use(...traits) {
126
+ if (traits.length === 0) throw new Error("invalid number of parameters (expected one or more traits)");
127
+ let clz;
128
+ let lot;
129
+ const last = traits[traits.length - 1];
130
+ if (isCons(last) && !isTypeFactory(last)) {
131
+ clz = last;
132
+ lot = traits.slice(0, -1);
133
+ } else {
134
+ clz = class ROOT {};
135
+ lot = traits;
136
+ }
137
+ const derived = /* @__PURE__ */ new Map();
138
+ for (const trait$1 of reverseTraitList(lot)) clz = deriveTrait(trait$1, clz, derived);
139
+ return clz;
140
+ }
141
+ function uses(instance, trait$1) {
142
+ if (typeof instance !== "object" || instance === null) return false;
143
+ let obj = instance;
144
+ if (isCons(trait$1) && !isTypeFactory(trait$1)) return instance instanceof trait$1;
145
+ const idTrait = (isTypeFactory(trait$1) ? trait$1() : trait$1)["id"];
146
+ while (obj) {
147
+ if (Object.hasOwn(obj, "constructor")) {
148
+ if ((obj.constructor["id"] ?? 0) === idTrait) return true;
71
149
  }
150
+ obj = Object.getPrototypeOf(obj);
72
151
  }
73
- /**
74
- * Recursively find files starting from given cwd
75
- *
76
- * @param name
77
- * @param extensions
78
- * @param cwd
79
- *
80
- * @returns
81
- */
82
- static resolveFileUp(name, extensions, cwd) {
83
- cwd ??= process.cwd();
84
- return escalade(cwd, (dir, filesNames) => {
85
- if (typeof extensions === "function") return extensions(dir, filesNames);
86
- const candidates = new Set(extensions.map((ext) => `${name}.${ext}`));
87
- for (const filename of filesNames) if (candidates.has(filename)) return filename;
88
- return false;
89
- }) ?? void 0;
152
+ return false;
153
+ }
154
+
155
+ //#endregion
156
+ //#region src/Mixins/UseFinalizable.ts
157
+ /**
158
+ * the central class instance registry
159
+ */
160
+ const registry = new FinalizationRegistry((fn) => {
161
+ if (typeof fn === "function" && !fn.finalized) {
162
+ fn.finalized = true;
163
+ fn();
164
+ }
165
+ });
166
+ /**
167
+ * the API trait "Finalizable<T>"
168
+ */
169
+ const Finalizable = trait((base) => class Finalizable$1 extends base {
170
+ constructor(...args) {
171
+ super(...args);
172
+ const fn1 = this.$finalize;
173
+ if (typeof fn1 !== "function") throw new Error("trait Finalizable requires a $finalize method to be defined");
174
+ const fn2 = () => {
175
+ fn1(this);
176
+ };
177
+ fn2.finalized = false;
178
+ registry.register(this, fn2, this);
179
+ }
180
+ });
181
+
182
+ //#endregion
183
+ //#region src/Mixins/UseMagic.ts
184
+ /**
185
+ * Wraps an object in a Proxy to emulate PHP magic methods.
186
+ *
187
+ * Supported:
188
+ * - __call(method, args)
189
+ * - __get(property)
190
+ * - __set(property, value)
191
+ * - __isset(property)
192
+ * - __unset(property)
193
+ *
194
+ * Called automatically by Magic's constructor.
195
+ *
196
+ * Return in any class constructor to use
197
+ *
198
+ * @param target
199
+ * @returns
200
+ */
201
+ function makeMagic(target) {
202
+ return new Proxy(target, {
203
+ get(obj, prop, receiver) {
204
+ if (typeof prop === "string") {
205
+ if (prop in obj) return Reflect.get(obj, prop, receiver);
206
+ if (obj.__call) return (...args) => obj.__call(prop, args);
207
+ if (obj.__get) return obj.__get(prop);
208
+ }
209
+ },
210
+ set(obj, prop, value) {
211
+ if (typeof prop === "string" && obj.__set) {
212
+ obj.__set(prop, value);
213
+ return true;
214
+ }
215
+ return Reflect.set(obj, prop, value);
216
+ },
217
+ has(obj, prop) {
218
+ if (typeof prop === "string" && obj.__isset) return obj.__isset(prop);
219
+ return Reflect.has(obj, prop);
220
+ },
221
+ deleteProperty(obj, prop) {
222
+ if (typeof prop === "string" && obj.__unset) {
223
+ obj.__unset(prop);
224
+ return true;
225
+ }
226
+ return Reflect.deleteProperty(obj, prop);
227
+ }
228
+ });
229
+ }
230
+ /**
231
+ * Wraps a class constructor in a Proxy to emulate static PHP magic methods.
232
+ *
233
+ * Supported:
234
+ * - __callStatic(method, args)
235
+ * - static __get(property)
236
+ * - static __set(property, value)
237
+ * - static __isset(property)
238
+ * - static __unset(property)
239
+ *
240
+ * @param cls
241
+ * @returns
242
+ */
243
+ function makeStaticMagic(cls) {
244
+ return new Proxy(cls, {
245
+ get(target, prop) {
246
+ if (typeof prop === "string") {
247
+ if (prop in target) return target[prop];
248
+ if (target.__callStatic) return (...args) => target.__callStatic(prop, args);
249
+ if (target.__get) return target.__get(prop);
250
+ }
251
+ },
252
+ set(target, prop, value) {
253
+ if (typeof prop === "string" && target.__set) {
254
+ target.__set(prop, value);
255
+ return true;
256
+ }
257
+ return Reflect.set(target, prop, value);
258
+ },
259
+ has(target, prop) {
260
+ if (typeof prop === "string" && target.__isset) return target.__isset(prop);
261
+ return Reflect.has(target, prop);
262
+ },
263
+ deleteProperty(target, prop) {
264
+ if (typeof prop === "string" && target.__unset) {
265
+ target.__unset(prop);
266
+ return true;
267
+ }
268
+ return Reflect.deleteProperty(target, prop);
269
+ }
270
+ });
271
+ }
272
+ /**
273
+ * Base class that enables PHP-style magic methods automatically.
274
+ *
275
+ * Any subclass may implement:
276
+ * - __call
277
+ * - __get
278
+ * - __set
279
+ * - __isset
280
+ * - __unset
281
+ *
282
+ * The constructor returns a Proxy transparently.
283
+ */
284
+ var Magic = class {
285
+ constructor() {
286
+ return makeMagic(this);
90
287
  }
91
288
  };
289
+ const UseMagic = trait((Base) => {
290
+ return class Magic$1 extends Base {
291
+ constructor(...args) {
292
+ super(...args);
293
+ return makeMagic(this);
294
+ }
295
+ };
296
+ });
92
297
 
93
298
  //#endregion
94
299
  //#region src/Utils/Logger.ts
@@ -166,6 +371,17 @@ var Logger = class Logger {
166
371
  * @returns
167
372
  */
168
373
  static textFormat(txt, color, preserveCol = false) {
374
+ if (txt instanceof Error) {
375
+ const err = txt;
376
+ const code = err.code ?? err.statusCode ? ` (${err.code ?? err.statusCode})` : "";
377
+ const output = [];
378
+ if (err.message) output.push(this.textFormat(`${err.constructor.name}${code}: ${err.message}`, chalk.bgRed, preserveCol));
379
+ if (err.stack) output.push(" " + chalk.white(err.stack.replace(`${err.name}: ${err.message}`, "").trim()));
380
+ return output.join("\n");
381
+ }
382
+ if (Array.isArray(txt)) return txt.map((e) => this.textFormat(e, color, preserveCol)).join("\n");
383
+ if (typeof txt === "object") return this.textFormat(Object.values(txt), color, preserveCol);
384
+ if (typeof txt !== "string") return color(txt);
169
385
  const str = String(txt);
170
386
  if (preserveCol) return str;
171
387
  const [first, ...rest] = str.split(":");
@@ -262,9 +478,129 @@ var Logger = class Logger {
262
478
  if (typeof config === "string") {
263
479
  const conf = [[config, joiner]];
264
480
  return this.parse(conf, "", log, sc);
265
- } else if (config) return this.parse(config, String(joiner), log, sc);
481
+ } else if (Array.isArray(config)) return this.parse(config, String(joiner), log, sc);
482
+ else if (log && !this.shouldSuppressOutput("line")) return console.log(this.textFormat(config, Logger.chalker(["blue"])));
266
483
  return this;
267
484
  });
485
+ /**
486
+ * A simple console like output logger
487
+ *
488
+ * @returns
489
+ */
490
+ static console() {
491
+ return Console;
492
+ }
493
+ };
494
+
495
+ //#endregion
496
+ //#region src/Utils/Console.ts
497
+ var Console = class {
498
+ static log = (...args) => Logger.log(args.map((e) => [e, "white"]));
499
+ static debug = (...args) => Logger.debug(args, false, true);
500
+ static warn = (...args) => args.map((e) => Logger.warn(e, false, true));
501
+ static info = (...args) => args.map((e) => Logger.info(e, false, true));
502
+ static error = (...args) => args.map((e) => Logger.error(e, false), true);
503
+ };
504
+
505
+ //#endregion
506
+ //#region src/Utils/EnvParser.ts
507
+ var EnvParser = class {
508
+ static parse(initial) {
509
+ const parsed = { ...initial };
510
+ for (const key in parsed) {
511
+ const value = parsed[key];
512
+ parsed[key] = this.parseValue(value);
513
+ }
514
+ return parsed;
515
+ }
516
+ static parseValue(value) {
517
+ /**
518
+ * Null/undefined stay untouched
519
+ */
520
+ if (value === null || value === void 0) return value;
521
+ /**
522
+ * Convert string "true"/"false" to boolean
523
+ */
524
+ if (value === "true") return true;
525
+ if (value === "false") return false;
526
+ /**
527
+ * Convert string numbers to number
528
+ */
529
+ if (!isNaN(value) && value.trim() !== "") return Number(value);
530
+ /**
531
+ * Convert string "null" and "undefined"
532
+ */
533
+ if (value === "null") return null;
534
+ if (value === "undefined") return void 0;
535
+ /**
536
+ * Otherwise return as-is (string)
537
+ */
538
+ return value;
539
+ }
540
+ };
541
+
542
+ //#endregion
543
+ //#region src/Utils/FileSystem.ts
544
+ var FileSystem = class {
545
+ static findModulePkg(moduleId, cwd) {
546
+ const parts = moduleId.replace(/\\/g, "/").split("/");
547
+ let packageName = "";
548
+ if (parts.length > 0 && parts[0][0] === "@") packageName += parts.shift() + "/";
549
+ packageName += parts.shift();
550
+ const packageJson = path.join(cwd ?? process.cwd(), "node_modules", packageName);
551
+ const resolved = this.resolveFileUp("package", ["json"], packageJson);
552
+ if (!resolved) return;
553
+ return path.join(path.dirname(resolved), parts.join("/"));
554
+ }
555
+ /**
556
+ * Check if file exists
557
+ *
558
+ * @param path
559
+ * @returns
560
+ */
561
+ static async fileExists(path$1) {
562
+ try {
563
+ await access(path$1);
564
+ return true;
565
+ } catch {
566
+ return false;
567
+ }
568
+ }
569
+ /**
570
+ * Recursively find files starting from given cwd
571
+ *
572
+ * @param name
573
+ * @param extensions
574
+ * @param cwd
575
+ *
576
+ * @returns
577
+ */
578
+ static resolveFileUp(name, extensions, cwd) {
579
+ cwd ??= process.cwd();
580
+ return escalade(cwd, (dir, filesNames) => {
581
+ if (typeof extensions === "function") return extensions(dir, filesNames);
582
+ const candidates = new Set(extensions.map((ext) => `${name}.${ext}`));
583
+ for (const filename of filesNames) if (candidates.has(filename)) return filename;
584
+ return false;
585
+ }) ?? void 0;
586
+ }
587
+ /**
588
+ * Recursively find files starting from given cwd
589
+ *
590
+ * @param name
591
+ * @param extensions
592
+ * @param cwd
593
+ *
594
+ * @returns
595
+ */
596
+ static resolveModulePath(moduleId, pathName, cwd) {
597
+ pathName = Array.isArray(pathName) ? pathName : [pathName];
598
+ const module = this.findModulePkg(moduleId, cwd) ?? "";
599
+ for (const name of pathName) {
600
+ const file = path.join(module, name);
601
+ if (existsSync(file)) return file;
602
+ }
603
+ }
268
604
  };
269
605
 
270
606
  //#endregion
@@ -278,7 +614,8 @@ var PathLoader = class {
278
614
  config: "/src/config",
279
615
  public: "/public",
280
616
  storage: "/storage",
281
- database: "/src/database"
617
+ database: "/src/database",
618
+ commands: "/src/App/Console/Commands/"
282
619
  };
283
620
  /**
284
621
  * Dynamically retrieves a path property from the class.
@@ -307,6 +644,11 @@ var PathLoader = class {
307
644
  if (base && name !== "base") this.paths[name] = path.join(base, path$1);
308
645
  this.paths[name] = path$1;
309
646
  }
647
+ distPath(path$1, skipExt = false) {
648
+ path$1 = path$1.replace("/src/", `/${process.env.DIST_DIR ?? "src"}/`.replace(/([^:]\/)\/+/g, "$1"));
649
+ if (!skipExt) path$1 = path$1.replace(/\.(ts|tsx|mts|cts)$/, ".js");
650
+ return path.normalize(path$1);
651
+ }
310
652
  };
311
653
 
312
654
  //#endregion
@@ -426,7 +768,7 @@ const mainTsconfig = {
426
768
  },
427
769
  target: "es2022",
428
770
  module: "es2022",
429
- moduleResolution: "Node",
771
+ moduleResolution: "bundler",
430
772
  esModuleInterop: true,
431
773
  strict: true,
432
774
  allowJs: true,
@@ -496,5 +838,5 @@ var TaskManager = class {
496
838
  };
497
839
 
498
840
  //#endregion
499
- export { EnvParser, FileSystem, Logger, PathLoader, Prompts, Resolver, TaskManager, baseTsconfig, mainTsconfig, packageJsonScript };
841
+ export { Console, EnvParser, FileSystem, Finalizable, INTERNAL_METHODS, Logger, Magic, PathLoader, Prompts, Resolver, TaskManager, UseMagic, baseTsconfig, crc32, internal, isInternal, mainTsconfig, makeMagic, makeStaticMagic, mix, packageJsonScript, trait, use, uses };
500
842
  //# sourceMappingURL=index.js.map