@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.
- package/dist/concepts/projection-metadata.d.ts +4 -4
- package/dist/concepts/projection-metadata.js +6 -6
- package/dist/concepts/reducer-metadata.d.ts +5 -0
- package/dist/concepts/reducer-metadata.js +5 -0
- package/dist/concepts/register.js +6 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.js +78 -65
- package/dist/envelope.d.ts +9 -0
- package/dist/errors/command-handler-global-error.js +2 -0
- package/dist/errors/event-global-error.js +1 -0
- package/dist/errors/event-handler-global-error.js +3 -0
- package/dist/errors/global-error-container.js +1 -0
- package/dist/errors/projection-global-error.js +4 -0
- package/dist/errors/query-handler-global-error.js +1 -0
- package/dist/errors/reducer-global-error.js +4 -0
- package/dist/errors/schedule-command-global-error.js +2 -0
- package/dist/errors/snapshot-persist-handler-global-error.js +1 -0
- package/dist/errors.js +6 -3
- package/dist/event-store-adapter.d.ts +71 -16
- package/dist/graphql-websocket-messages.js +11 -7
- package/dist/http-service.js +2 -2
- package/dist/index.d.ts +17 -20
- package/dist/index.js +30 -20
- package/dist/instances.d.ts +20 -0
- package/dist/instances.js +10 -0
- package/dist/logger.js +5 -6
- package/dist/metadata-types.d.ts +20 -0
- package/dist/retrier.js +3 -3
- package/dist/searcher.js +10 -3
- package/dist/timestamp-generator.d.ts +38 -0
- package/dist/timestamp-generator.js +84 -0
- package/package.json +2 -2
- package/dist/field-decorator.d.ts +0 -63
- package/dist/field-decorator.js +0 -122
- package/dist/internal-info.d.ts +0 -2
- package/dist/internal-info.js +0 -6
- package/dist/promises.d.ts +0 -25
- package/dist/promises.js +0 -42
- package/dist/run-command.d.ts +0 -5
- 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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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("./
|
|
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("./
|
|
14
|
+
tslib_1.__exportStar(require("./logger"), exports);
|
|
19
15
|
tslib_1.__exportStar(require("./searcher"), exports);
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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("./
|
|
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);
|
package/dist/instances.d.ts
CHANGED
|
@@ -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
|
-
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
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);
|
package/dist/metadata-types.d.ts
CHANGED
|
@@ -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
|
|
18
|
+
logger?.debug(`[retryIfError] Try number ${tryNumber}`);
|
|
19
19
|
const result = await logicToRetry(tryNumber);
|
|
20
|
-
logger
|
|
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
|
|
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.
|
|
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.
|
|
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 {};
|
package/dist/field-decorator.js
DELETED
|
@@ -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
|
-
}
|
package/dist/internal-info.d.ts
DELETED
package/dist/internal-info.js
DELETED
|
@@ -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;
|
package/dist/promises.d.ts
DELETED
|
@@ -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;
|
package/dist/run-command.d.ts
DELETED
|
@@ -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>;
|