@magek/common 0.0.6 → 0.0.8

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.
Files changed (40) hide show
  1. package/dist/concepts/projection-metadata.d.ts +4 -4
  2. package/dist/concepts/projection-metadata.js +6 -6
  3. package/dist/concepts/reducer-metadata.d.ts +5 -0
  4. package/dist/concepts/reducer-metadata.js +5 -0
  5. package/dist/concepts/register.js +6 -1
  6. package/dist/config.d.ts +4 -0
  7. package/dist/config.js +78 -65
  8. package/dist/envelope.d.ts +9 -0
  9. package/dist/errors/command-handler-global-error.js +2 -0
  10. package/dist/errors/event-global-error.js +1 -0
  11. package/dist/errors/event-handler-global-error.js +3 -0
  12. package/dist/errors/global-error-container.js +1 -0
  13. package/dist/errors/projection-global-error.js +4 -0
  14. package/dist/errors/query-handler-global-error.js +1 -0
  15. package/dist/errors/reducer-global-error.js +4 -0
  16. package/dist/errors/schedule-command-global-error.js +2 -0
  17. package/dist/errors/snapshot-persist-handler-global-error.js +1 -0
  18. package/dist/errors.js +6 -3
  19. package/dist/event-store-adapter.d.ts +71 -16
  20. package/dist/graphql-websocket-messages.js +11 -7
  21. package/dist/http-service.js +2 -2
  22. package/dist/index.d.ts +17 -20
  23. package/dist/index.js +30 -20
  24. package/dist/instances.d.ts +20 -0
  25. package/dist/instances.js +10 -0
  26. package/dist/logger.js +5 -6
  27. package/dist/metadata-types.d.ts +20 -0
  28. package/dist/retrier.js +3 -3
  29. package/dist/searcher.js +10 -3
  30. package/dist/timestamp-generator.d.ts +38 -0
  31. package/dist/timestamp-generator.js +84 -0
  32. package/package.json +2 -2
  33. package/dist/field-decorator.d.ts +0 -63
  34. package/dist/field-decorator.js +0 -122
  35. package/dist/internal-info.d.ts +0 -2
  36. package/dist/internal-info.js +0 -6
  37. package/dist/promises.d.ts +0 -25
  38. package/dist/promises.js +0 -42
  39. package/dist/run-command.d.ts +0 -5
  40. package/dist/run-command.js +0 -48
package/dist/index.js CHANGED
@@ -1,33 +1,43 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
- tslib_1.__exportStar(require("./groups"), exports);
5
- tslib_1.__exportStar(require("./promises"), exports);
6
- tslib_1.__exportStar(require("./retrier"), exports);
7
- tslib_1.__exportStar(require("./instances"), exports);
8
- tslib_1.__exportStar(require("./run-command"), exports);
9
- tslib_1.__exportStar(require("./logger"), exports);
10
- tslib_1.__exportStar(require("./http-service"), exports);
4
+ // =============================================================================
5
+ // PUBLIC API - Core Framework Types
6
+ // These are the primary exports for framework users building Magek applications
7
+ // =============================================================================
11
8
  tslib_1.__exportStar(require("./app"), exports);
12
- tslib_1.__exportStar(require("./envelope"), exports);
13
9
  tslib_1.__exportStar(require("./config"), exports);
14
10
  tslib_1.__exportStar(require("./concepts"), exports);
15
- tslib_1.__exportStar(require("./typelevel"), exports);
11
+ tslib_1.__exportStar(require("./envelope"), exports);
16
12
  tslib_1.__exportStar(require("./errors"), exports);
17
13
  tslib_1.__exportStar(require("./errors/index"), exports);
18
- tslib_1.__exportStar(require("./user-app"), exports);
14
+ tslib_1.__exportStar(require("./logger"), exports);
19
15
  tslib_1.__exportStar(require("./searcher"), exports);
20
- tslib_1.__exportStar(require("./graphql-websocket-messages"), exports);
21
- tslib_1.__exportStar(require("./schedule"), exports);
22
- tslib_1.__exportStar(require("./data-migration-parameters"), exports);
23
- tslib_1.__exportStar(require("./super-kind"), exports);
24
- tslib_1.__exportStar(require("./instrumentation/trace-types"), exports);
25
- tslib_1.__exportStar(require("./sensor/health-indicator-configuration"), exports);
26
- tslib_1.__exportStar(require("./internal-info"), exports);
27
- tslib_1.__exportStar(require("./stream-types"), exports);
28
- tslib_1.__exportStar(require("./runtime"), exports);
16
+ // =============================================================================
17
+ // ADAPTER DEVELOPMENT
18
+ // Types and utilities for building custom adapters (event stores, read models, etc.)
19
+ // =============================================================================
29
20
  tslib_1.__exportStar(require("./event-store-adapter"), exports);
30
21
  tslib_1.__exportStar(require("./read-model-store-adapter"), exports);
31
22
  tslib_1.__exportStar(require("./session-store-adapter"), exports);
32
- tslib_1.__exportStar(require("./field-decorator"), exports);
23
+ tslib_1.__exportStar(require("./retrier"), exports);
24
+ tslib_1.__exportStar(require("./timestamp-generator"), exports);
25
+ tslib_1.__exportStar(require("./instances"), exports);
26
+ tslib_1.__exportStar(require("./groups"), exports);
27
+ tslib_1.__exportStar(require("./stream-types"), exports);
28
+ // =============================================================================
29
+ // FRAMEWORK INTERNALS
30
+ // Used by @magek/core, @magek/server, and other framework packages
31
+ // These may change between versions - use with caution in user code
32
+ // =============================================================================
33
+ tslib_1.__exportStar(require("./typelevel"), exports);
34
+ tslib_1.__exportStar(require("./runtime"), exports);
35
+ tslib_1.__exportStar(require("./user-app"), exports);
33
36
  tslib_1.__exportStar(require("./metadata-types"), exports);
37
+ tslib_1.__exportStar(require("./super-kind"), exports);
38
+ tslib_1.__exportStar(require("./schedule"), exports);
39
+ tslib_1.__exportStar(require("./data-migration-parameters"), exports);
40
+ tslib_1.__exportStar(require("./graphql-websocket-messages"), exports);
41
+ tslib_1.__exportStar(require("./http-service"), exports);
42
+ tslib_1.__exportStar(require("./instrumentation/trace-types"), exports);
43
+ tslib_1.__exportStar(require("./sensor/health-indicator-configuration"), exports);
@@ -37,6 +37,26 @@ export declare function createInstance<T>(instanceClass: Class<T>, rawObject: Re
37
37
  * @see {@link createInstance}
38
38
  */
39
39
  export declare function createInstances<T>(instanceClass: Class<T>, rawObjects: Array<Record<string, any>>): T[];
40
+ /**
41
+ * Applies partial changes to an entity, optionally using defaults when creating a new instance.
42
+ * Designed for plain objects (entity state); use `createInstance` for class instances.
43
+ *
44
+ * @remarks
45
+ * This function always returns a shallow copy, ensuring immutability.
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * // Update existing entity
50
+ * const updated = evolve(current, { balance: current.balance + event.amount })
51
+ * // Create new entity with defaults
52
+ * const created = evolve(undefined, { id: event.entityId, name: event.name }, { status: 'active' })
53
+ * // Create new entity without defaults (changes must be complete)
54
+ * const created = evolve(undefined, { id: event.entityId, name: event.name, status: 'active' })
55
+ * ```
56
+ */
57
+ export declare function evolve<T extends object>(current: T, changes: Partial<T>): T;
58
+ export declare function evolve<C extends object, D extends object>(current: undefined, changes: C, defaults: D): C & D;
59
+ export declare function evolve<T extends object>(current: undefined, changes: T): T;
40
60
  /**
41
61
  * Creates an instance of the read model class with the calculated properties included
42
62
  * @param instanceClass The read model class
package/dist/instances.js CHANGED
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createInstance = createInstance;
4
4
  exports.createInstances = createInstances;
5
+ exports.evolve = evolve;
5
6
  exports.createInstanceWithCalculatedProperties = createInstanceWithCalculatedProperties;
6
7
  /**
7
8
  * Creates an instance of the given class from the given raw object.
@@ -44,6 +45,15 @@ function createInstance(instanceClass, rawObject) {
44
45
  function createInstances(instanceClass, rawObjects) {
45
46
  return rawObjects.map((rawObject) => createInstance(instanceClass, rawObject));
46
47
  }
48
+ function evolve(current, changes, defaults) {
49
+ if (current !== undefined) {
50
+ return { ...current, ...changes };
51
+ }
52
+ if (defaults !== undefined) {
53
+ return { ...defaults, ...changes };
54
+ }
55
+ return { ...changes };
56
+ }
47
57
  /**
48
58
  * Creates an instance of the read model class with the calculated properties included
49
59
  * @param instanceClass The read model class
package/dist/logger.js CHANGED
@@ -11,12 +11,11 @@ var Level;
11
11
  })(Level || (exports.Level = Level = {}));
12
12
  const defaultLogPrefix = 'Magek';
13
13
  function getLogger(config, location, overridenLogPrefix) {
14
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
15
- const debug = (_b = (_a = config.logger) === null || _a === void 0 ? void 0 : _a.debug) !== null && _b !== void 0 ? _b : console.debug;
16
- const info = (_d = (_c = config.logger) === null || _c === void 0 ? void 0 : _c.info) !== null && _d !== void 0 ? _d : console.info;
17
- const warn = (_f = (_e = config.logger) === null || _e === void 0 ? void 0 : _e.warn) !== null && _f !== void 0 ? _f : console.warn;
18
- const error = (_h = (_g = config.logger) === null || _g === void 0 ? void 0 : _g.error) !== null && _h !== void 0 ? _h : console.error;
19
- const logPrefix = (_j = overridenLogPrefix !== null && overridenLogPrefix !== void 0 ? overridenLogPrefix : config === null || config === void 0 ? void 0 : config.logPrefix) !== null && _j !== void 0 ? _j : defaultLogPrefix;
14
+ const debug = config.logger?.debug ?? console.debug;
15
+ const info = config.logger?.info ?? console.info;
16
+ const warn = config.logger?.warn ?? console.warn;
17
+ const error = config.logger?.error ?? console.error;
18
+ const logPrefix = overridenLogPrefix ?? config?.logPrefix ?? defaultLogPrefix;
20
19
  const locationStr = location ? `|${location}: ` : ': ';
21
20
  const prefix = `[${logPrefix}]${locationStr}`;
22
21
  const prefixedDebugFunction = debug.bind(null, prefix);
@@ -2,6 +2,26 @@ import 'reflect-metadata';
2
2
  export type ClassType = {
3
3
  new (...args: unknown[]): unknown;
4
4
  };
5
+ /**
6
+ * Type function for specifying field types
7
+ * The parameter is optional and not used - it's just for TypeGraphQL-style ergonomics
8
+ */
9
+ export type TypeFunction = (type?: unknown) => unknown;
10
+ /**
11
+ * Options for the @field() decorator
12
+ */
13
+ export interface FieldOptions {
14
+ nullable?: boolean;
15
+ readonly?: boolean;
16
+ }
17
+ /**
18
+ * Metadata stored for each field
19
+ */
20
+ export interface FieldMetadata {
21
+ name: string;
22
+ typeFunction?: TypeFunction;
23
+ options: FieldOptions;
24
+ }
5
25
  export type TypeGroup = 'String' | 'Number' | 'Boolean' | 'Enum' | 'Union' | 'Intersection' | 'Function' | 'Class' | 'Interface' | 'Type' | 'Array' | 'Object' | 'ReadonlyArray' | 'Other';
6
26
  export interface TypeMetadata {
7
27
  name: string;
package/dist/retrier.js CHANGED
@@ -15,9 +15,9 @@ async function retryIfError(logicToRetry, errorClassThatRetries, logger, maxRetr
15
15
  let errorAfterMaxTries;
16
16
  for (tryNumber = 1; tryNumber <= maxRetries; tryNumber++) {
17
17
  try {
18
- logger === null || logger === void 0 ? void 0 : logger.debug(`[retryIfError] Try number ${tryNumber}`);
18
+ logger?.debug(`[retryIfError] Try number ${tryNumber}`);
19
19
  const result = await logicToRetry(tryNumber);
20
- logger === null || logger === void 0 ? void 0 : logger.debug(`[retryIfError] Succeeded after ${tryNumber} retries`);
20
+ logger?.debug(`[retryIfError] Succeeded after ${tryNumber} retries`);
21
21
  return result;
22
22
  }
23
23
  catch (e) {
@@ -30,7 +30,7 @@ async function retryIfError(logicToRetry, errorClassThatRetries, logger, maxRetr
30
30
  }
31
31
  function checkRetryError(e, errorClassThatRetries, logger) {
32
32
  if (!(e instanceof errorClassThatRetries)) {
33
- logger === null || logger === void 0 ? void 0 : logger.debug('[checkRetryError] Logic failed with an error that must not be retried. Rethrowing');
33
+ logger?.debug('[checkRetryError] Logic failed with an error that must not be retried. Rethrowing');
34
34
  throw e;
35
35
  }
36
36
  }
package/dist/searcher.js CHANGED
@@ -7,6 +7,16 @@ exports.Searcher = void 0;
7
7
  * Check the documentation on the individual methods to know more about how to do so.
8
8
  */
9
9
  class Searcher {
10
+ objectClass;
11
+ searcherFunction;
12
+ finderByKeyFunction;
13
+ // private offset?: number
14
+ _limit;
15
+ _afterCursor;
16
+ filters = {};
17
+ _sortByList = {};
18
+ _paginatedVersion = false;
19
+ _selectFor;
10
20
  /**
11
21
  * @param objectClass The class of the object you want to run the search for.
12
22
  * @param searcherFunction The function that will receive all the filters and run the actual search
@@ -16,9 +26,6 @@ class Searcher {
16
26
  this.objectClass = objectClass;
17
27
  this.searcherFunction = searcherFunction;
18
28
  this.finderByKeyFunction = finderByKeyFunction;
19
- this.filters = {};
20
- this._sortByList = {};
21
- this._paginatedVersion = false;
22
29
  }
23
30
  /**
24
31
  * Adds a filter for the search. For example: If you want to search for people whose age is greater than 30
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Generates unique, monotonically increasing ISO 8601 timestamps with sub-millisecond precision.
3
+ *
4
+ * Format: 2024-01-28T12:34:56.12345678Z where:
5
+ * - Digits 1-3 (123): actual milliseconds from Date.now()
6
+ * - Digits 4-7 (4567): monotonic counter (0000-9999)
7
+ * - Digit 8 (8): random seed for distributed uniqueness (0-9)
8
+ *
9
+ * This provides:
10
+ * - 10,000 unique orderable timestamps per millisecond per instance
11
+ * - 100,000 total combinations across distributed instances (10,000 counter values × 10 seeds)
12
+ * - Standard ISO 8601 format parseable by any Date library
13
+ * - Deterministic ordering via string comparison
14
+ * - Random component for distributed uniqueness
15
+ */
16
+ export declare class TimestampGenerator {
17
+ private lastMs;
18
+ private counter;
19
+ private readonly randomSeed;
20
+ constructor();
21
+ /**
22
+ * Generates the next unique timestamp with microsecond precision.
23
+ *
24
+ * @returns ISO 8601 timestamp string with 8 fractional digits
25
+ */
26
+ next(): string;
27
+ }
28
+ /**
29
+ * Returns the singleton TimestampGenerator instance.
30
+ * Creates it if it doesn't exist yet.
31
+ *
32
+ * @returns The global TimestampGenerator instance
33
+ */
34
+ export declare function getTimestampGenerator(): TimestampGenerator;
35
+ /**
36
+ * Resets the singleton instance. Primarily for testing purposes.
37
+ */
38
+ export declare function resetTimestampGenerator(): void;
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TimestampGenerator = void 0;
4
+ exports.getTimestampGenerator = getTimestampGenerator;
5
+ exports.resetTimestampGenerator = resetTimestampGenerator;
6
+ /**
7
+ * Generates unique, monotonically increasing ISO 8601 timestamps with sub-millisecond precision.
8
+ *
9
+ * Format: 2024-01-28T12:34:56.12345678Z where:
10
+ * - Digits 1-3 (123): actual milliseconds from Date.now()
11
+ * - Digits 4-7 (4567): monotonic counter (0000-9999)
12
+ * - Digit 8 (8): random seed for distributed uniqueness (0-9)
13
+ *
14
+ * This provides:
15
+ * - 10,000 unique orderable timestamps per millisecond per instance
16
+ * - 100,000 total combinations across distributed instances (10,000 counter values × 10 seeds)
17
+ * - Standard ISO 8601 format parseable by any Date library
18
+ * - Deterministic ordering via string comparison
19
+ * - Random component for distributed uniqueness
20
+ */
21
+ class TimestampGenerator {
22
+ lastMs = 0;
23
+ counter = 0;
24
+ randomSeed;
25
+ constructor() {
26
+ // Generate random seed 0-9 for distributed uniqueness
27
+ this.randomSeed = Math.floor(Math.random() * 10);
28
+ }
29
+ /**
30
+ * Generates the next unique timestamp with microsecond precision.
31
+ *
32
+ * @returns ISO 8601 timestamp string with 8 fractional digits
33
+ */
34
+ next() {
35
+ const nowMs = Date.now();
36
+ // Reset counter only if we've moved forward to a new millisecond
37
+ // When nowMs <= lastMs (clock skew), continue using lastMs and incrementing counter
38
+ if (nowMs > this.lastMs) {
39
+ this.lastMs = nowMs;
40
+ this.counter = 0;
41
+ }
42
+ // If counter exceeds 9999, advance lastMs to maintain monotonicity
43
+ if (this.counter > 9999) {
44
+ this.lastMs++;
45
+ this.counter = 0;
46
+ }
47
+ // Format: milliseconds (3 digits) + counter (4 digits) + seed (1 digit)
48
+ const microPart = String(this.counter).padStart(4, '0') + String(this.randomSeed);
49
+ this.counter++;
50
+ // Build ISO 8601 timestamp with microsecond precision
51
+ // Use lastMs (which may be clamped due to clock skew) instead of nowMs
52
+ const date = new Date(this.lastMs);
53
+ const isoString = date.toISOString();
54
+ // Replace milliseconds with our extended precision
55
+ // ISO format: 2024-01-28T12:34:56.123Z
56
+ // ^^^
57
+ // We extend to: 2024-01-28T12:34:56.12345678Z
58
+ const withMicros = isoString.slice(0, -1) + microPart + 'Z';
59
+ return withMicros;
60
+ }
61
+ }
62
+ exports.TimestampGenerator = TimestampGenerator;
63
+ /**
64
+ * Global singleton instance of TimestampGenerator.
65
+ */
66
+ let timestampGeneratorInstance;
67
+ /**
68
+ * Returns the singleton TimestampGenerator instance.
69
+ * Creates it if it doesn't exist yet.
70
+ *
71
+ * @returns The global TimestampGenerator instance
72
+ */
73
+ function getTimestampGenerator() {
74
+ if (!timestampGeneratorInstance) {
75
+ timestampGeneratorInstance = new TimestampGenerator();
76
+ }
77
+ return timestampGeneratorInstance;
78
+ }
79
+ /**
80
+ * Resets the singleton instance. Primarily for testing purposes.
81
+ */
82
+ function resetTimestampGenerator() {
83
+ timestampGeneratorInstance = undefined;
84
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magek/common",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "Contains Magek common helpers used by the core and provider packages",
5
5
  "keywords": [
6
6
  "framework-common-helpers"
@@ -33,7 +33,7 @@
33
33
  "uuid": "^13.0.0"
34
34
  },
35
35
  "devDependencies": {
36
- "@magek/eslint-config": "^0.0.6",
36
+ "@magek/eslint-config": "^0.0.8",
37
37
  "@types/chai": "5.2.3",
38
38
  "@types/chai-as-promised": "8.0.2",
39
39
  "@types/mocha": "10.0.10",
@@ -1,63 +0,0 @@
1
- import 'reflect-metadata';
2
- /**
3
- * Type function for specifying field types
4
- * The parameter is optional and not used - it's just for TypeGraphQL-style ergonomics
5
- */
6
- export type TypeFunction = (type?: unknown) => unknown;
7
- /**
8
- * Options for the @Field() decorator
9
- */
10
- export interface FieldOptions {
11
- nullable?: boolean;
12
- readonly?: boolean;
13
- }
14
- /**
15
- * Metadata stored for each field
16
- */
17
- export interface FieldMetadata {
18
- name: string;
19
- typeFunction?: TypeFunction;
20
- options: FieldOptions;
21
- designType?: unknown;
22
- }
23
- /**
24
- * Stage 3 decorator context for class fields (TypeScript 5.0+)
25
- */
26
- interface Stage3FieldContext {
27
- kind: 'field';
28
- name: string | symbol;
29
- static: boolean;
30
- private: boolean;
31
- metadata: Record<string | symbol, unknown>;
32
- access?: {
33
- get: () => unknown;
34
- set: (value: unknown) => void;
35
- };
36
- addInitializer?: (initializer: () => void) => void;
37
- }
38
- /**
39
- * Decorator return type that supports both legacy and Stage 3 formats.
40
- * This is a function that can be called with either signature.
41
- */
42
- type UniversalFieldDecorator = {
43
- (target: object, propertyKey: string | symbol): void;
44
- (value: undefined, context: Stage3FieldContext): void;
45
- };
46
- /**
47
- * @Field() decorator for explicit type declaration
48
- *
49
- * Supports both legacy decorators (experimentalDecorators) and
50
- * Stage 3 TC39 decorators.
51
- *
52
- * Usage:
53
- * @Field() - Simple type (inferred from design:type in legacy mode)
54
- * @Field(type => String) - Explicit type
55
- * @Field(type => [String]) - Array type
56
- * @Field({ nullable: true }) - With options
57
- * @Field(type => String, { nullable: true }) - Type with options
58
- */
59
- export declare function Field(): UniversalFieldDecorator;
60
- export declare function Field(options: FieldOptions): UniversalFieldDecorator;
61
- export declare function Field(typeFunction: TypeFunction): UniversalFieldDecorator;
62
- export declare function Field(typeFunction: TypeFunction, options: FieldOptions): UniversalFieldDecorator;
63
- export {};
@@ -1,122 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Field = Field;
4
- require("reflect-metadata");
5
- // Symbol for storing fields metadata (for Stage 3 decorators)
6
- const FIELDS_KEY = Symbol.for('magek:fields');
7
- /**
8
- * Type guard to detect Stage 3 decorator context
9
- */
10
- function isStage3Context(arg) {
11
- return (arg !== null &&
12
- typeof arg === 'object' &&
13
- 'kind' in arg &&
14
- arg.kind === 'field' &&
15
- 'name' in arg &&
16
- 'metadata' in arg);
17
- }
18
- /**
19
- * Store field metadata on a constructor (works for both legacy and Stage 3)
20
- */
21
- function storeFieldMetadata(constructor, fieldMetadata) {
22
- // Get existing fields
23
- let existingFields = [];
24
- // Try Reflect.getMetadata first
25
- try {
26
- if (typeof Reflect !== 'undefined' && typeof Reflect.getMetadata === 'function') {
27
- existingFields = Reflect.getMetadata('magek:fields', constructor) || [];
28
- }
29
- }
30
- catch {
31
- // Ignore
32
- }
33
- // Also check fallback property
34
- const ctorWithFields = constructor;
35
- if (existingFields.length === 0 && ctorWithFields.__magek_fields__) {
36
- existingFields = ctorWithFields.__magek_fields__;
37
- }
38
- // Add this field (avoid duplicates by name)
39
- const filteredFields = existingFields.filter((f) => f.name !== fieldMetadata.name);
40
- filteredFields.push(fieldMetadata);
41
- // Store using both mechanisms for reliability
42
- try {
43
- if (typeof Reflect !== 'undefined' && typeof Reflect.defineMetadata === 'function') {
44
- Reflect.defineMetadata('magek:fields', filteredFields, constructor);
45
- }
46
- }
47
- catch {
48
- // Ignore
49
- }
50
- // Also store as a fallback property
51
- ctorWithFields.__magek_fields__ = filteredFields;
52
- }
53
- /**
54
- * Handle legacy decorator format (experimentalDecorators)
55
- */
56
- function handleLegacyDecorator(target, propertyKey, typeFunction, fieldOptions) {
57
- // Get design type from TypeScript decorator metadata
58
- let designType;
59
- try {
60
- if (typeof Reflect !== 'undefined' && typeof Reflect.getMetadata === 'function') {
61
- designType = Reflect.getMetadata('design:type', target, propertyKey);
62
- }
63
- }
64
- catch {
65
- // Ignore - Reflect.getMetadata may fail if called before initialization
66
- }
67
- const fieldMetadata = {
68
- name: propertyKey.toString(),
69
- typeFunction,
70
- options: fieldOptions,
71
- designType,
72
- };
73
- const constructor = target.constructor;
74
- if (constructor) {
75
- storeFieldMetadata(constructor, fieldMetadata);
76
- }
77
- }
78
- /**
79
- * Handle Stage 3 decorator format (TC39 decorators)
80
- */
81
- function handleStage3Decorator(context, typeFunction, fieldOptions) {
82
- const fieldMetadata = {
83
- name: context.name.toString(),
84
- typeFunction,
85
- options: fieldOptions,
86
- designType: undefined, // Stage 3 doesn't have design:type
87
- };
88
- // Store in context.metadata for later retrieval by class decorators
89
- // Class decorators (like @Command, @Entity, etc.) will transfer this to the class constructor
90
- if (!context.metadata[FIELDS_KEY]) {
91
- context.metadata[FIELDS_KEY] = [];
92
- }
93
- const fields = context.metadata[FIELDS_KEY];
94
- const filteredFields = fields.filter((f) => f.name !== fieldMetadata.name);
95
- filteredFields.push(fieldMetadata);
96
- context.metadata[FIELDS_KEY] = filteredFields;
97
- }
98
- function Field(typeFunctionOrOptions, options) {
99
- // Parse arguments
100
- let typeFunction;
101
- let fieldOptions = {};
102
- if (typeof typeFunctionOrOptions === 'function') {
103
- typeFunction = typeFunctionOrOptions;
104
- fieldOptions = options || {};
105
- }
106
- else if (typeFunctionOrOptions) {
107
- fieldOptions = typeFunctionOrOptions;
108
- }
109
- // Return decorator that handles both formats
110
- return function fieldDecorator(targetOrValue, propertyKeyOrContext) {
111
- // Detect Stage 3 vs Legacy based on the second argument
112
- if (isStage3Context(propertyKeyOrContext)) {
113
- // Stage 3 decorator
114
- handleStage3Decorator(propertyKeyOrContext, typeFunction, fieldOptions);
115
- }
116
- else if (targetOrValue) {
117
- // Legacy decorator
118
- handleLegacyDecorator(targetOrValue, propertyKeyOrContext, typeFunction, fieldOptions);
119
- }
120
- // If targetOrValue is undefined and not Stage 3, silently skip
121
- };
122
- }
@@ -1,2 +0,0 @@
1
- export declare const MAGEK_LOCAL_PORT = "INTERNAL_LOCAL_PORT";
2
- export declare const localPort: () => string;
@@ -1,6 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.localPort = exports.MAGEK_LOCAL_PORT = void 0;
4
- exports.MAGEK_LOCAL_PORT = 'INTERNAL_LOCAL_PORT';
5
- const localPort = () => process.env[exports.MAGEK_LOCAL_PORT] || '3000';
6
- exports.localPort = localPort;
@@ -1,25 +0,0 @@
1
- export declare class Promises {
2
- /**
3
- * Waits until all the passed promise-like values are settled, no matter if they were fulfilled or rejected.
4
- * If some rejected were found, an array with all the rejected promises is thrown.
5
- * If all were fulfilled, an array of PromiseFulfilledResult is returned
6
- * @param values Array of promise-like values to be wait for
7
- * @throws an array of PromiseRejectedResult with all the rejected promises, if any
8
- *
9
- * Comparison with other similar Promise methods:
10
- * - `Promise.all`: This has an "all-or-nothing" behavior. As long as one of the promises is rejected, the result is
11
- * rejected. More importantly, **it does not wait for al the promises to finish**, which could lead to undesired behaviors
12
- * - `Promise.allSettled`: This method waits for all the promises to finish and then returns an array of results. Some
13
- * of them will be fulfilled and some rejected. More importantly, **it never throws an error**, which could lead to
14
- * unexpected consequences. For example if you do "await Promise.allSettle(...)" expecting it to throw if some of them
15
- * failed, you won't get that.
16
- *
17
- * In brief, `Promises.allSettledAndFulfilled` behaves exactly the same way as `Promise.allSettle` but it throws with
18
- * an array of the failed promises, only if there are any.
19
- */
20
- static allSettledAndFulfilled<TValue>(values: Iterable<TValue>): ReturnType<PromiseConstructor['allSettled']>;
21
- }
22
- export declare class PromisesError extends Error {
23
- readonly failedReasons: Array<unknown>;
24
- constructor(rejectedResults: Array<PromiseRejectedResult>);
25
- }
package/dist/promises.js DELETED
@@ -1,42 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PromisesError = exports.Promises = void 0;
4
- class Promises {
5
- /**
6
- * Waits until all the passed promise-like values are settled, no matter if they were fulfilled or rejected.
7
- * If some rejected were found, an array with all the rejected promises is thrown.
8
- * If all were fulfilled, an array of PromiseFulfilledResult is returned
9
- * @param values Array of promise-like values to be wait for
10
- * @throws an array of PromiseRejectedResult with all the rejected promises, if any
11
- *
12
- * Comparison with other similar Promise methods:
13
- * - `Promise.all`: This has an "all-or-nothing" behavior. As long as one of the promises is rejected, the result is
14
- * rejected. More importantly, **it does not wait for al the promises to finish**, which could lead to undesired behaviors
15
- * - `Promise.allSettled`: This method waits for all the promises to finish and then returns an array of results. Some
16
- * of them will be fulfilled and some rejected. More importantly, **it never throws an error**, which could lead to
17
- * unexpected consequences. For example if you do "await Promise.allSettle(...)" expecting it to throw if some of them
18
- * failed, you won't get that.
19
- *
20
- * In brief, `Promises.allSettledAndFulfilled` behaves exactly the same way as `Promise.allSettle` but it throws with
21
- * an array of the failed promises, only if there are any.
22
- */
23
- static async allSettledAndFulfilled(values) {
24
- const results = await Promise.allSettled(values); // Promise.allSettled never throws
25
- // Get all the failed promises
26
- const failed = results.filter((result) => result.status === 'rejected');
27
- // Throw if we found any failed ones
28
- if (failed.length > 0) {
29
- throw new PromisesError(failed);
30
- }
31
- return results;
32
- }
33
- }
34
- exports.Promises = Promises;
35
- class PromisesError extends Error {
36
- constructor(rejectedResults) {
37
- const reasons = rejectedResults.map((res) => res.reason);
38
- super(reasons.join('. '));
39
- this.failedReasons = reasons;
40
- }
41
- }
42
- exports.PromisesError = PromisesError;
@@ -1,5 +0,0 @@
1
- import { ChildProcessWithoutNullStreams } from 'child_process';
2
- /** Spawn a CLI command and optionally printing the logs and error messages */
3
- export declare function runCommandAsync(path: string, command: string, ignoreLogs?: boolean): ChildProcessWithoutNullStreams;
4
- /** Synchronously run a CLI command and return the stdout, optionally printing the logs and error messages */
5
- export declare function runCommand(path: string, command: string, ignoreLogs?: boolean): Promise<string>;