@magek/common 0.0.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/app.d.ts +17 -0
- package/dist/app.js +2 -0
- package/dist/concepts/authorizers.d.ts +7 -0
- package/dist/concepts/authorizers.js +2 -0
- package/dist/concepts/command.d.ts +14 -0
- package/dist/concepts/command.js +2 -0
- package/dist/concepts/data-migration.d.ts +19 -0
- package/dist/concepts/data-migration.js +8 -0
- package/dist/concepts/entity.d.ts +12 -0
- package/dist/concepts/entity.js +2 -0
- package/dist/concepts/event-handler.d.ts +6 -0
- package/dist/concepts/event-handler.js +2 -0
- package/dist/concepts/event-stream-configuration.d.ts +14 -0
- package/dist/concepts/event-stream-configuration.js +2 -0
- package/dist/concepts/event.d.ts +12 -0
- package/dist/concepts/event.js +2 -0
- package/dist/concepts/filter-hooks.d.ts +15 -0
- package/dist/concepts/filter-hooks.js +2 -0
- package/dist/concepts/global-error-handler-metadata.d.ts +24 -0
- package/dist/concepts/global-error-handler-metadata.js +2 -0
- package/dist/concepts/index.d.ts +21 -0
- package/dist/concepts/index.js +24 -0
- package/dist/concepts/migration.d.ts +8 -0
- package/dist/concepts/migration.js +2 -0
- package/dist/concepts/notification.d.ts +12 -0
- package/dist/concepts/notification.js +2 -0
- package/dist/concepts/projection-metadata.d.ts +15 -0
- package/dist/concepts/projection-metadata.js +8 -0
- package/dist/concepts/query.d.ts +21 -0
- package/dist/concepts/query.js +2 -0
- package/dist/concepts/read-model.d.ts +33 -0
- package/dist/concepts/read-model.js +8 -0
- package/dist/concepts/reducer-metadata.d.ts +5 -0
- package/dist/concepts/reducer-metadata.js +2 -0
- package/dist/concepts/register.d.ts +91 -0
- package/dist/concepts/register.js +84 -0
- package/dist/concepts/role.d.ts +27 -0
- package/dist/concepts/role.js +2 -0
- package/dist/concepts/scheduled-command.d.ts +10 -0
- package/dist/concepts/scheduled-command.js +2 -0
- package/dist/concepts/sequence-metadata.d.ts +5 -0
- package/dist/concepts/sequence-metadata.js +2 -0
- package/dist/concepts/token-verifier.d.ts +25 -0
- package/dist/concepts/token-verifier.js +2 -0
- package/dist/concepts/uuid.d.ts +18 -0
- package/dist/concepts/uuid.js +28 -0
- package/dist/config.d.ts +122 -0
- package/dist/config.js +180 -0
- package/dist/data-migration-parameters.d.ts +3 -0
- package/dist/data-migration-parameters.js +2 -0
- package/dist/envelope.d.ts +188 -0
- package/dist/envelope.js +2 -0
- package/dist/errors/command-handler-global-error.d.ts +8 -0
- package/dist/errors/command-handler-global-error.js +12 -0
- package/dist/errors/event-global-error.d.ts +6 -0
- package/dist/errors/event-global-error.js +11 -0
- package/dist/errors/event-handler-global-error.d.ts +9 -0
- package/dist/errors/event-handler-global-error.js +13 -0
- package/dist/errors/global-error-container.d.ts +4 -0
- package/dist/errors/global-error-container.js +9 -0
- package/dist/errors/index.d.ts +9 -0
- package/dist/errors/index.js +12 -0
- package/dist/errors/projection-global-error.d.ts +10 -0
- package/dist/errors/projection-global-error.js +14 -0
- package/dist/errors/query-handler-global-error.d.ts +6 -0
- package/dist/errors/query-handler-global-error.js +11 -0
- package/dist/errors/reducer-global-error.d.ts +10 -0
- package/dist/errors/reducer-global-error.js +14 -0
- package/dist/errors/schedule-command-global-error.d.ts +8 -0
- package/dist/errors/schedule-command-global-error.js +12 -0
- package/dist/errors/snapshot-persist-handler-global-error.d.ts +16 -0
- package/dist/errors/snapshot-persist-handler-global-error.js +21 -0
- package/dist/errors.d.ts +30 -0
- package/dist/errors.js +60 -0
- package/dist/event-store-adapter.d.ts +123 -0
- package/dist/event-store-adapter.js +2 -0
- package/dist/field-decorator.d.ts +63 -0
- package/dist/field-decorator.js +122 -0
- package/dist/graphql-websocket-messages.d.ts +65 -0
- package/dist/graphql-websocket-messages.js +55 -0
- package/dist/groups.d.ts +4 -0
- package/dist/groups.js +9 -0
- package/dist/http-service.d.ts +10 -0
- package/dist/http-service.js +50 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +33 -0
- package/dist/instances.d.ts +47 -0
- package/dist/instances.js +136 -0
- package/dist/instrumentation/trace-types.d.ts +52 -0
- package/dist/instrumentation/trace-types.js +34 -0
- package/dist/internal-info.d.ts +2 -0
- package/dist/internal-info.js +6 -0
- package/dist/logger.d.ts +14 -0
- package/dist/logger.js +33 -0
- package/dist/metadata-types.d.ts +28 -0
- package/dist/metadata-types.js +12 -0
- package/dist/promises.d.ts +25 -0
- package/dist/promises.js +42 -0
- package/dist/provider/azure-configuration.d.ts +12 -0
- package/dist/provider/azure-configuration.js +4 -0
- package/dist/provider.d.ts +83 -0
- package/dist/provider.js +2 -0
- package/dist/read-model-store-adapter.d.ts +84 -0
- package/dist/read-model-store-adapter.js +2 -0
- package/dist/retrier.d.ts +12 -0
- package/dist/retrier.js +36 -0
- package/dist/rocket-loader.d.ts +7 -0
- package/dist/rocket-loader.js +21 -0
- package/dist/rockets.d.ts +10 -0
- package/dist/rockets.js +4 -0
- package/dist/run-command.d.ts +5 -0
- package/dist/run-command.js +48 -0
- package/dist/schedule.d.ts +8 -0
- package/dist/schedule.js +2 -0
- package/dist/searcher.d.ts +98 -0
- package/dist/searcher.js +79 -0
- package/dist/sensor/health-indicator-configuration.d.ts +60 -0
- package/dist/sensor/health-indicator-configuration.js +31 -0
- package/dist/session-store-adapter.d.ts +103 -0
- package/dist/session-store-adapter.js +2 -0
- package/dist/stream-types.d.ts +1 -0
- package/dist/stream-types.js +2 -0
- package/dist/super-kind.d.ts +2 -0
- package/dist/super-kind.js +5 -0
- package/dist/typelevel.d.ts +28 -0
- package/dist/typelevel.js +9 -0
- package/dist/user-app.d.ts +18 -0
- package/dist/user-app.js +2 -0
- package/package.json +66 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { MagekConfig } from './config';
|
|
2
|
+
import { GraphQLRequestEnvelope, GraphQLRequestEnvelopeError, HealthEnvelope, ScheduledCommandEnvelope } from './envelope';
|
|
3
|
+
export interface ProviderLibrary {
|
|
4
|
+
graphQL: ProviderGraphQLLibrary;
|
|
5
|
+
api: ProviderAPIHandling;
|
|
6
|
+
messaging: ProviderMessagingLibrary;
|
|
7
|
+
scheduled: ScheduledCommandsLibrary;
|
|
8
|
+
sensor: ProviderSensorLibrary;
|
|
9
|
+
}
|
|
10
|
+
export interface ProviderMessagingLibrary {
|
|
11
|
+
/**
|
|
12
|
+
* Sends a message to a specific connection.
|
|
13
|
+
*
|
|
14
|
+
* @param config - The Magek configuration object.
|
|
15
|
+
* @param connectionID - The ID of the connection.
|
|
16
|
+
* @param data - The data to be sent to the connection.
|
|
17
|
+
* @returns A promise that resolves when the message has been sent successfully.
|
|
18
|
+
*/
|
|
19
|
+
sendMessage(config: MagekConfig, connectionID: string, data: unknown): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
export interface ProviderSensorLibrary {
|
|
22
|
+
databaseEventsHealthDetails(config: MagekConfig): Promise<unknown>;
|
|
23
|
+
databaseReadModelsHealthDetails(config: MagekConfig): Promise<unknown>;
|
|
24
|
+
isDatabaseEventUp(config: MagekConfig): Promise<boolean>;
|
|
25
|
+
areDatabaseReadModelsUp(config: MagekConfig): Promise<boolean>;
|
|
26
|
+
databaseUrls(config: MagekConfig): Promise<Array<string>>;
|
|
27
|
+
isGraphQLFunctionUp(config: MagekConfig): Promise<boolean>;
|
|
28
|
+
graphQLFunctionUrl(config: MagekConfig): Promise<string>;
|
|
29
|
+
rawRequestToHealthEnvelope(rawRequest: unknown): HealthEnvelope;
|
|
30
|
+
}
|
|
31
|
+
export interface ProviderGraphQLLibrary {
|
|
32
|
+
/**
|
|
33
|
+
* Converts a raw GraphQL request to a `GraphQLRequestEnvelope` or a `GraphQLRequestEnvelopeError`.
|
|
34
|
+
*
|
|
35
|
+
* @param config - The Magek configuration object.
|
|
36
|
+
* @param rawGraphQLRequest - The raw GraphQL request to be converted.
|
|
37
|
+
* @returns A promise that resolves to either a `GraphQLRequestEnvelope` or a `GraphQLRequestEnvelopeError` object.
|
|
38
|
+
*/
|
|
39
|
+
rawToEnvelope(config: MagekConfig, rawGraphQLRequest: unknown): Promise<GraphQLRequestEnvelope | GraphQLRequestEnvelopeError>;
|
|
40
|
+
/**
|
|
41
|
+
* Handles the result of a GraphQL request.
|
|
42
|
+
*
|
|
43
|
+
* @param result - The result of the GraphQL request (optional).
|
|
44
|
+
* @param headers - The headers associated with the GraphQL request result (optional).
|
|
45
|
+
* @returns A promise that resolves to any value.
|
|
46
|
+
*/
|
|
47
|
+
handleResult(result?: unknown, headers?: Record<string, string>): Promise<unknown>;
|
|
48
|
+
}
|
|
49
|
+
export interface ProviderAPIHandling {
|
|
50
|
+
/**
|
|
51
|
+
* Handles a successful API request by returning the response body.
|
|
52
|
+
*
|
|
53
|
+
* @param body - The response body of the API request.
|
|
54
|
+
* @param headers - The headers of the API request.
|
|
55
|
+
* @returns A promise that resolves with the response body.
|
|
56
|
+
*/
|
|
57
|
+
requestSucceeded(body?: unknown, headers?: Record<string, number | string | ReadonlyArray<string>>): Promise<unknown>;
|
|
58
|
+
/**
|
|
59
|
+
* Handles a failed API request by returning an error.
|
|
60
|
+
*
|
|
61
|
+
* @param error - The error that occurred during the API request.
|
|
62
|
+
* @returns A promise that resolves with the error.
|
|
63
|
+
*/
|
|
64
|
+
requestFailed(error: Error): Promise<unknown>;
|
|
65
|
+
/**
|
|
66
|
+
* Handles a health check response with appropriate status code.
|
|
67
|
+
*
|
|
68
|
+
* @param body - The health check results
|
|
69
|
+
* @param isHealthy - Whether all the components are UP
|
|
70
|
+
* @returns A promise that resolves with the response
|
|
71
|
+
*/
|
|
72
|
+
healthRequestResult(body: unknown, isHealthy: boolean): Promise<unknown>;
|
|
73
|
+
}
|
|
74
|
+
export interface ScheduledCommandsLibrary {
|
|
75
|
+
/**
|
|
76
|
+
* Converts a raw message into a `ScheduledCommandEnvelope`.
|
|
77
|
+
*
|
|
78
|
+
* @param config - The configuration for the application.
|
|
79
|
+
* @param rawMessage - The raw message to convert.
|
|
80
|
+
* @returns A promise that resolves with the `ScheduledCommandEnvelope` representation of the raw message.
|
|
81
|
+
*/
|
|
82
|
+
rawToEnvelope(config: MagekConfig, rawMessage: unknown): Promise<ScheduledCommandEnvelope>;
|
|
83
|
+
}
|
package/dist/provider.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { SequenceKey, UUID } from './concepts';
|
|
2
|
+
import { MagekConfig } from './config';
|
|
3
|
+
import { ReadModelInterface } from './concepts';
|
|
4
|
+
import { FilterFor, ProjectionFor, SortFor } from './searcher';
|
|
5
|
+
import { ReadModelListResult } from './envelope';
|
|
6
|
+
import { ReadOnlyNonEmptyArray } from './typelevel';
|
|
7
|
+
export interface ReadModelStoreEnvelope<T = ReadModelInterface> {
|
|
8
|
+
typeName: string;
|
|
9
|
+
value: T;
|
|
10
|
+
id: UUID;
|
|
11
|
+
version: number;
|
|
12
|
+
createdAt: string;
|
|
13
|
+
updatedAt: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ReadModelStoreAdapter {
|
|
16
|
+
/**
|
|
17
|
+
* Fetches a read model by its ID
|
|
18
|
+
*
|
|
19
|
+
* @param config - The Magek configuration object
|
|
20
|
+
* @param readModelName - The name of the read model type
|
|
21
|
+
* @param readModelID - The ID of the read model to fetch
|
|
22
|
+
* @param sequenceKey - The sequence key for sequenced read models (optional)
|
|
23
|
+
* @returns A promise that resolves to an array of read models, or undefined if not found
|
|
24
|
+
*/
|
|
25
|
+
fetch<TReadModel extends ReadModelInterface>(config: MagekConfig, readModelName: string, readModelID: UUID, sequenceKey?: SequenceKey): Promise<ReadOnlyNonEmptyArray<TReadModel> | undefined>;
|
|
26
|
+
/**
|
|
27
|
+
* Searches for read models based on specific parameters
|
|
28
|
+
* This method signature matches the original provider library interface
|
|
29
|
+
*
|
|
30
|
+
* @param config - The Magek configuration object
|
|
31
|
+
* @param readModelName - The name of the read model type
|
|
32
|
+
* @param filters - The filters to be applied during the search
|
|
33
|
+
* @param sortBy - An object that specifies how the results should be sorted (optional)
|
|
34
|
+
* @param limit - The maximum number of results to return (optional)
|
|
35
|
+
* @param afterCursor - A cursor that specifies the position after which results should be returned (optional)
|
|
36
|
+
* @param paginatedVersion - A boolean value that indicates whether the results should be paginated (optional)
|
|
37
|
+
* @param select - An object that specifies fields to be returned, including calculated field dependencies (optional)
|
|
38
|
+
* @returns A promise that resolves to an array of read models or a ReadModelListResult
|
|
39
|
+
*/
|
|
40
|
+
search<TReadModel extends ReadModelInterface>(config: MagekConfig, readModelName: string, filters: FilterFor<unknown>, sortBy?: SortFor<unknown>, limit?: number, afterCursor?: unknown, paginatedVersion?: boolean, select?: ProjectionFor<TReadModel>): Promise<Array<TReadModel> | ReadModelListResult<TReadModel>>;
|
|
41
|
+
/**
|
|
42
|
+
* Stores or updates a read model
|
|
43
|
+
*
|
|
44
|
+
* @param config - The Magek configuration object
|
|
45
|
+
* @param readModelName - The name of the read model type
|
|
46
|
+
* @param readModel - The read model envelope to store
|
|
47
|
+
* @returns A promise that resolves to the stored read model envelope
|
|
48
|
+
*/
|
|
49
|
+
store<TReadModel extends ReadModelInterface>(config: MagekConfig, readModelName: string, readModel: ReadModelStoreEnvelope<TReadModel>): Promise<ReadModelStoreEnvelope<TReadModel>>;
|
|
50
|
+
/**
|
|
51
|
+
* Deletes a read model by its ID
|
|
52
|
+
*
|
|
53
|
+
* @param config - The Magek configuration object
|
|
54
|
+
* @param readModelName - The name of the read model type
|
|
55
|
+
* @param readModelID - The ID of the read model to delete
|
|
56
|
+
* @returns A promise that resolves when the read model has been deleted
|
|
57
|
+
*/
|
|
58
|
+
delete(config: MagekConfig, readModelName: string, readModelID: UUID): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Converts raw read model data into ReadModelStoreEnvelope objects
|
|
61
|
+
*
|
|
62
|
+
* @param config - The Magek configuration object
|
|
63
|
+
* @param rawReadModels - The raw read model data to be converted
|
|
64
|
+
* @returns A promise that resolves to an array of ReadModelStoreEnvelope objects
|
|
65
|
+
*/
|
|
66
|
+
rawToEnvelopes<TReadModel extends ReadModelInterface>(config: MagekConfig, rawReadModels: unknown): Promise<Array<ReadModelStoreEnvelope<TReadModel>>>;
|
|
67
|
+
/**
|
|
68
|
+
* Health check methods for the read model store
|
|
69
|
+
*/
|
|
70
|
+
healthCheck?: {
|
|
71
|
+
/**
|
|
72
|
+
* Check if the read model store is up and running
|
|
73
|
+
*/
|
|
74
|
+
isUp(config: MagekConfig): Promise<boolean>;
|
|
75
|
+
/**
|
|
76
|
+
* Get detailed health information about the read model store
|
|
77
|
+
*/
|
|
78
|
+
details(config: MagekConfig): Promise<unknown>;
|
|
79
|
+
/**
|
|
80
|
+
* Get the URLs/endpoints of the read model store
|
|
81
|
+
*/
|
|
82
|
+
urls(config: MagekConfig): Promise<Array<string>>;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Class } from './typelevel';
|
|
2
|
+
import { Logger } from './logger';
|
|
3
|
+
/**
|
|
4
|
+
* Retries an async function if it fails with an error that matches the given class.
|
|
5
|
+
*
|
|
6
|
+
* @param logicToRetry Async function to retry
|
|
7
|
+
* @param errorClassThatRetries Error class. If the async function fails with an error that matches this class, it will be retried.
|
|
8
|
+
* @param logger Logger to use for logging. If not provided, no logging will be performed.
|
|
9
|
+
* @param maxRetries Maximum number of retries. If not provided, the default is 1000.
|
|
10
|
+
* @returns The result of the first successful retry.
|
|
11
|
+
*/
|
|
12
|
+
export declare function retryIfError<TReturn>(logicToRetry: (tryNumber?: number) => Promise<TReturn>, errorClassThatRetries: Class<Error>, logger?: Logger, maxRetries?: number): Promise<TReturn>;
|
package/dist/retrier.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.retryIfError = retryIfError;
|
|
4
|
+
/**
|
|
5
|
+
* Retries an async function if it fails with an error that matches the given class.
|
|
6
|
+
*
|
|
7
|
+
* @param logicToRetry Async function to retry
|
|
8
|
+
* @param errorClassThatRetries Error class. If the async function fails with an error that matches this class, it will be retried.
|
|
9
|
+
* @param logger Logger to use for logging. If not provided, no logging will be performed.
|
|
10
|
+
* @param maxRetries Maximum number of retries. If not provided, the default is 1000.
|
|
11
|
+
* @returns The result of the first successful retry.
|
|
12
|
+
*/
|
|
13
|
+
async function retryIfError(logicToRetry, errorClassThatRetries, logger, maxRetries = 1000) {
|
|
14
|
+
let tryNumber;
|
|
15
|
+
let errorAfterMaxTries;
|
|
16
|
+
for (tryNumber = 1; tryNumber <= maxRetries; tryNumber++) {
|
|
17
|
+
try {
|
|
18
|
+
logger === null || logger === void 0 ? void 0 : logger.debug(`[retryIfError] Try number ${tryNumber}`);
|
|
19
|
+
const result = await logicToRetry(tryNumber);
|
|
20
|
+
logger === null || logger === void 0 ? void 0 : logger.debug(`[retryIfError] Succeeded after ${tryNumber} retries`);
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
const error = e;
|
|
25
|
+
checkRetryError(error, errorClassThatRetries, logger);
|
|
26
|
+
errorAfterMaxTries = error;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
throw new Error(`[retryIfError] Reached the maximum number of retries (${maxRetries}), but still getting the following error: ${errorAfterMaxTries}`);
|
|
30
|
+
}
|
|
31
|
+
function checkRetryError(e, errorClassThatRetries, logger) {
|
|
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');
|
|
34
|
+
throw e;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RocketLoader = void 0;
|
|
4
|
+
class RocketLoader {
|
|
5
|
+
// Separate function to make it easier to mock in tests
|
|
6
|
+
static requireRocket(rocketPackageName) {
|
|
7
|
+
return require(rocketPackageName).default;
|
|
8
|
+
}
|
|
9
|
+
static loadRocket(rocketDescriptor) {
|
|
10
|
+
const rocketBuilder = RocketLoader.requireRocket(rocketDescriptor.packageName);
|
|
11
|
+
if (!rocketBuilder)
|
|
12
|
+
throw new Error(`Could not load the rocket infrastructure package ${rocketDescriptor.packageName}. Make sure you installed it in your project devDependencies.`);
|
|
13
|
+
if (typeof rocketBuilder !== 'function')
|
|
14
|
+
throw new Error(`Could not initialize rocket infrastructure package ${rocketDescriptor.packageName}. It doesn't seem to implement a rocket builder method as default export.`);
|
|
15
|
+
const rocket = rocketBuilder(rocketDescriptor.parameters);
|
|
16
|
+
if (!(rocket === null || rocket === void 0 ? void 0 : rocket.mountStack))
|
|
17
|
+
throw new Error(`The package ${rocketDescriptor.packageName} doesn't seem to be a rocket.`);
|
|
18
|
+
return rocket;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.RocketLoader = RocketLoader;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { MagekConfig } from './config';
|
|
2
|
+
export declare const rocketFunctionIDEnvVar = "ROCKET_FUNCTION_ID";
|
|
3
|
+
export type RocketFunction = (config: MagekConfig, request: unknown) => Promise<unknown>;
|
|
4
|
+
export interface RocketDescriptor {
|
|
5
|
+
packageName: string;
|
|
6
|
+
parameters: unknown;
|
|
7
|
+
}
|
|
8
|
+
export interface RocketEnvelope {
|
|
9
|
+
rocketId: string | undefined;
|
|
10
|
+
}
|
package/dist/rockets.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
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>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runCommandAsync = runCommandAsync;
|
|
4
|
+
exports.runCommand = runCommand;
|
|
5
|
+
const child_process_1 = require("child_process");
|
|
6
|
+
/** Spawn a CLI command and optionally printing the logs and error messages */
|
|
7
|
+
function runCommandAsync(path, command, ignoreLogs = false) {
|
|
8
|
+
// Split the command into an array of arguments
|
|
9
|
+
const args = command.split(' ');
|
|
10
|
+
// Use the first argument as the command name
|
|
11
|
+
const subprocess = (0, child_process_1.spawn)(args[0], args.slice(1), {
|
|
12
|
+
cwd: path,
|
|
13
|
+
stdio: 'pipe',
|
|
14
|
+
});
|
|
15
|
+
if (!ignoreLogs) {
|
|
16
|
+
subprocess.stdout.on('data', (data) => {
|
|
17
|
+
console.log(data.toString());
|
|
18
|
+
});
|
|
19
|
+
subprocess.stderr.on('data', (data) => {
|
|
20
|
+
console.error(data.toString());
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
return subprocess;
|
|
24
|
+
}
|
|
25
|
+
/** Synchronously run a CLI command and return the stdout, optionally printing the logs and error messages */
|
|
26
|
+
function runCommand(path, command, ignoreLogs = false) {
|
|
27
|
+
return new Promise((resolve, reject) => {
|
|
28
|
+
const subprocess = runCommandAsync(path, command, ignoreLogs);
|
|
29
|
+
let stdout = '';
|
|
30
|
+
let stderr = '';
|
|
31
|
+
if (subprocess) {
|
|
32
|
+
subprocess.stdout.on('data', (data) => {
|
|
33
|
+
stdout += data.toString();
|
|
34
|
+
});
|
|
35
|
+
subprocess.stderr.on('data', (data) => {
|
|
36
|
+
stderr += data.toString();
|
|
37
|
+
});
|
|
38
|
+
subprocess.on('close', (code) => {
|
|
39
|
+
if (code === 0) {
|
|
40
|
+
resolve(stdout);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
reject(stderr);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
package/dist/schedule.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { SequenceKey, UUID } from './concepts';
|
|
2
|
+
import { ReadModelListResult } from './envelope';
|
|
3
|
+
import { AnyClass, Class, ReadOnlyNonEmptyArray } from './typelevel';
|
|
4
|
+
export type SearcherFunction<TObject, TResult> = (objectClass: AnyClass, filters: FilterFor<TObject>, sortBy: SortFor<TObject>, limit?: number, afterCursor?: any, paginatedVersion?: boolean, select?: ProjectionFor<TObject>) => Promise<TResult>;
|
|
5
|
+
export type FinderByKeyFunction<TObject> = (objectClass: AnyClass, id: UUID, sequenceKey?: SequenceKey) => Promise<TObject | ReadOnlyNonEmptyArray<TObject>>;
|
|
6
|
+
export type SequenceFinderByKeyFunction<TObject> = (className: string, id: UUID, sequenceKey?: SequenceKey) => Promise<TObject>;
|
|
7
|
+
/**
|
|
8
|
+
* This class represents a search intended to be run by any search provider. They way you use it
|
|
9
|
+
* is by setting filters on the properties of the object you want to search and then run it.
|
|
10
|
+
* Check the documentation on the individual methods to know more about how to do so.
|
|
11
|
+
*/
|
|
12
|
+
export declare class Searcher<TObject, TSingleResult extends SingleResultType<TObject> = TObject, TContainer extends ContainerType = Array<any>> {
|
|
13
|
+
private readonly objectClass;
|
|
14
|
+
private readonly searcherFunction;
|
|
15
|
+
private readonly finderByKeyFunction;
|
|
16
|
+
private _limit?;
|
|
17
|
+
private _afterCursor?;
|
|
18
|
+
private filters;
|
|
19
|
+
private _sortByList;
|
|
20
|
+
private _paginatedVersion;
|
|
21
|
+
private _selectFor?;
|
|
22
|
+
/**
|
|
23
|
+
* @param objectClass The class of the object you want to run the search for.
|
|
24
|
+
* @param searcherFunction The function that will receive all the filters and run the actual search
|
|
25
|
+
* @param finderByKeyFunction Function that performs a find by Key operation (Either simple or compound keys)
|
|
26
|
+
*/
|
|
27
|
+
constructor(objectClass: Class<TObject>, searcherFunction: SearcherFunction<TObject, ApplyContainerToType<TContainer, TSingleResult>>, finderByKeyFunction: FinderByKeyFunction<TObject>);
|
|
28
|
+
/**
|
|
29
|
+
* Adds a filter for the search. For example: If you want to search for people whose age is greater than 30
|
|
30
|
+
* and their height is between 1.80m and 2.00m, you would do:
|
|
31
|
+
* ```
|
|
32
|
+
* searcher.filter({
|
|
33
|
+
* age: { gt: 30 },
|
|
34
|
+
* height: { gte: 1.8, lte: 2 }
|
|
35
|
+
* }).search()
|
|
36
|
+
* ```
|
|
37
|
+
* @param filters An object with the property filters
|
|
38
|
+
*/
|
|
39
|
+
filter(filters: FilterFor<TObject>): this;
|
|
40
|
+
sortBy(sortBy?: SortFor<TObject>): this;
|
|
41
|
+
select(select?: ProjectionFor<TObject>): SearchAfterSelect<TObject, TContainer>;
|
|
42
|
+
limit(limit?: number): this;
|
|
43
|
+
afterCursor(afterCursor?: unknown): this;
|
|
44
|
+
paginatedVersion<TPaginated extends boolean>(paginatedVersion?: TPaginated): SearcherAfterPaginatedVersion<TObject, TSingleResult, TPaginated>;
|
|
45
|
+
findById(id: UUID, sequenceKey?: SequenceKey): Promise<TObject | ReadOnlyNonEmptyArray<TObject>>;
|
|
46
|
+
searchOne(): Promise<TSingleResult | undefined>;
|
|
47
|
+
/**
|
|
48
|
+
* Do the actual search by sending all the configured filters to the provided search function
|
|
49
|
+
*/
|
|
50
|
+
search(): Promise<ApplyContainerToType<TContainer, TSingleResult>>;
|
|
51
|
+
}
|
|
52
|
+
type SingleResultType<TObject> = TObject | Partial<TObject>;
|
|
53
|
+
type ContainerType = Array<any> | ReadModelListResult<any>;
|
|
54
|
+
type ApplyContainerToType<Container extends ContainerType, Type> = Container extends Array<any> ? Array<Type> : ReadModelListResult<Type>;
|
|
55
|
+
type SearchAfterSelect<TObject, TContainer extends ContainerType> = Searcher<TObject, Partial<TObject>, TContainer>;
|
|
56
|
+
type SearcherAfterPaginatedVersion<TObject, TSingleResult extends SingleResultType<TObject>, Paginated extends boolean> = Searcher<TObject, TSingleResult, Paginated extends true ? ReadModelListResult<any> : Array<any>>;
|
|
57
|
+
type Tail<T extends any[]> = T extends [any, ...infer Rest] ? Rest : never;
|
|
58
|
+
type Paths<T, TLevels extends any[] = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]> = TLevels extends [] ? '' : T extends object ? {
|
|
59
|
+
[K in keyof T]: `${Exclude<K, symbol>}${'' | `.${Paths<T[K], Tail<TLevels>>}`}`;
|
|
60
|
+
}[keyof T] : never;
|
|
61
|
+
export type ProjectionFor<TType> = Array<Paths<TType>>;
|
|
62
|
+
export type SortFor<TType> = {
|
|
63
|
+
[TProp in keyof TType]?: SortFor<TType[TProp]> | 'ASC' | 'DESC';
|
|
64
|
+
};
|
|
65
|
+
export type FilterFor<TType> = {
|
|
66
|
+
[TProp in keyof TType]?: Operation<TType[TProp]>;
|
|
67
|
+
} & FilterCombinators<TType> & IsDefinedOperator;
|
|
68
|
+
interface FilterCombinators<TType> {
|
|
69
|
+
and?: Array<FilterFor<TType>>;
|
|
70
|
+
or?: Array<FilterFor<TType>>;
|
|
71
|
+
not?: FilterFor<TType>;
|
|
72
|
+
}
|
|
73
|
+
export type Operation<TType> = TType extends Array<infer TElementType> ? ArrayOperators<TElementType> : TType extends string | UUID ? StringOperators<TType> : TType extends number ? ScalarOperators<TType> : TType extends boolean ? BooleanOperators<TType> : TType extends Record<string, any> ? FilterFor<TType> : never;
|
|
74
|
+
interface IsDefinedOperator {
|
|
75
|
+
isDefined?: boolean;
|
|
76
|
+
}
|
|
77
|
+
interface BooleanOperators<TType> extends IsDefinedOperator {
|
|
78
|
+
eq?: TType | null;
|
|
79
|
+
ne?: TType | null;
|
|
80
|
+
}
|
|
81
|
+
interface ScalarOperators<TType> extends BooleanOperators<TType> {
|
|
82
|
+
gt?: TType;
|
|
83
|
+
gte?: TType;
|
|
84
|
+
lt?: TType;
|
|
85
|
+
lte?: TType;
|
|
86
|
+
in?: Array<TType>;
|
|
87
|
+
}
|
|
88
|
+
interface StringOperators<TType> extends ScalarOperators<TType> {
|
|
89
|
+
beginsWith?: TType;
|
|
90
|
+
contains?: TType;
|
|
91
|
+
regex?: TType;
|
|
92
|
+
iRegex?: TType;
|
|
93
|
+
}
|
|
94
|
+
interface ArrayOperators<TElementType> {
|
|
95
|
+
includes?: TElementType;
|
|
96
|
+
isDefined?: boolean;
|
|
97
|
+
}
|
|
98
|
+
export {};
|
package/dist/searcher.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Searcher = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* This class represents a search intended to be run by any search provider. They way you use it
|
|
6
|
+
* is by setting filters on the properties of the object you want to search and then run it.
|
|
7
|
+
* Check the documentation on the individual methods to know more about how to do so.
|
|
8
|
+
*/
|
|
9
|
+
class Searcher {
|
|
10
|
+
/**
|
|
11
|
+
* @param objectClass The class of the object you want to run the search for.
|
|
12
|
+
* @param searcherFunction The function that will receive all the filters and run the actual search
|
|
13
|
+
* @param finderByKeyFunction Function that performs a find by Key operation (Either simple or compound keys)
|
|
14
|
+
*/
|
|
15
|
+
constructor(objectClass, searcherFunction, finderByKeyFunction) {
|
|
16
|
+
this.objectClass = objectClass;
|
|
17
|
+
this.searcherFunction = searcherFunction;
|
|
18
|
+
this.finderByKeyFunction = finderByKeyFunction;
|
|
19
|
+
this.filters = {};
|
|
20
|
+
this._sortByList = {};
|
|
21
|
+
this._paginatedVersion = false;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Adds a filter for the search. For example: If you want to search for people whose age is greater than 30
|
|
25
|
+
* and their height is between 1.80m and 2.00m, you would do:
|
|
26
|
+
* ```
|
|
27
|
+
* searcher.filter({
|
|
28
|
+
* age: { gt: 30 },
|
|
29
|
+
* height: { gte: 1.8, lte: 2 }
|
|
30
|
+
* }).search()
|
|
31
|
+
* ```
|
|
32
|
+
* @param filters An object with the property filters
|
|
33
|
+
*/
|
|
34
|
+
filter(filters) {
|
|
35
|
+
this.filters = filters;
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
sortBy(sortBy) {
|
|
39
|
+
if (sortBy)
|
|
40
|
+
this._sortByList = sortBy;
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
select(select) {
|
|
44
|
+
if (select)
|
|
45
|
+
this._selectFor = select;
|
|
46
|
+
return this;
|
|
47
|
+
}
|
|
48
|
+
limit(limit) {
|
|
49
|
+
if (limit)
|
|
50
|
+
this._limit = limit;
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
afterCursor(afterCursor) {
|
|
54
|
+
if (afterCursor)
|
|
55
|
+
this._afterCursor = afterCursor;
|
|
56
|
+
return this;
|
|
57
|
+
}
|
|
58
|
+
paginatedVersion(paginatedVersion) {
|
|
59
|
+
if (paginatedVersion)
|
|
60
|
+
this._paginatedVersion = paginatedVersion;
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
63
|
+
async findById(id, sequenceKey) {
|
|
64
|
+
return this.finderByKeyFunction(this.objectClass, id, sequenceKey);
|
|
65
|
+
}
|
|
66
|
+
async searchOne() {
|
|
67
|
+
const searchResult = await this.searcherFunction(this.objectClass, this.filters, this._sortByList, 1, // Forces limit 1
|
|
68
|
+
this._afterCursor, false, // It doesn't make sense to paginate a single result, as pagination metadata would be discarded
|
|
69
|
+
this._selectFor);
|
|
70
|
+
return searchResult[0];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Do the actual search by sending all the configured filters to the provided search function
|
|
74
|
+
*/
|
|
75
|
+
async search() {
|
|
76
|
+
return this.searcherFunction(this.objectClass, this.filters, this._sortByList, this._limit, this._afterCursor, this._paginatedVersion, this._selectFor);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.Searcher = Searcher;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { HealthRoleAccess } from '../concepts';
|
|
2
|
+
import { MagekConfig } from '../config';
|
|
3
|
+
import { Class } from '../typelevel';
|
|
4
|
+
export declare enum HealthStatus {
|
|
5
|
+
UP = "UP",// The component or subsystem is working as expected
|
|
6
|
+
PARTIALLY_UP = "PARTIALLY_UP",// The component is partially working or has reduced functionality
|
|
7
|
+
DOWN = "DOWN",// The component is not working
|
|
8
|
+
OUT_OF_SERVICE = "OUT_OF_SERVICE",// The component is out of service temporarily
|
|
9
|
+
UNKNOWN = "UNKNOWN"
|
|
10
|
+
}
|
|
11
|
+
export interface HealthIndicatorResult {
|
|
12
|
+
status: HealthStatus;
|
|
13
|
+
details?: {
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface HealthIndicatorsResult extends HealthIndicatorResult {
|
|
18
|
+
name: string;
|
|
19
|
+
id: string;
|
|
20
|
+
components?: Array<HealthIndicatorsResult>;
|
|
21
|
+
}
|
|
22
|
+
export declare enum HEALTH_INDICATORS_IDS {
|
|
23
|
+
ROOT = "magek",
|
|
24
|
+
FUNCTION = "magek/function",
|
|
25
|
+
DATABASE = "magek/database",
|
|
26
|
+
DATABASE_EVENTS = "magek/database/events",
|
|
27
|
+
DATABASE_READ_MODELS = "magek/database/readmodels"
|
|
28
|
+
}
|
|
29
|
+
export declare const DEFAULT_HEALTH_CONFIGURATION: SensorMagekHealthConfigurationDetails;
|
|
30
|
+
export declare const DEFAULT_SENSOR_HEALTH_CONFIGURATIONS: Record<HEALTH_INDICATORS_IDS, SensorMagekHealthConfigurationDetails>;
|
|
31
|
+
export type SensorMagekHealthConfigurationDetails = HealthIndicatorConfigurationBase;
|
|
32
|
+
export interface SensorMagekHealthConfiguration {
|
|
33
|
+
globalAuthorizer: HealthRoleAccess;
|
|
34
|
+
magek: {
|
|
35
|
+
[HEALTH_INDICATORS_IDS.ROOT]: SensorMagekHealthConfigurationDetails;
|
|
36
|
+
[HEALTH_INDICATORS_IDS.FUNCTION]: SensorMagekHealthConfigurationDetails;
|
|
37
|
+
[HEALTH_INDICATORS_IDS.DATABASE]: SensorMagekHealthConfigurationDetails;
|
|
38
|
+
[HEALTH_INDICATORS_IDS.DATABASE_EVENTS]: SensorMagekHealthConfigurationDetails;
|
|
39
|
+
[HEALTH_INDICATORS_IDS.DATABASE_READ_MODELS]: SensorMagekHealthConfigurationDetails;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export interface SensorConfiguration {
|
|
43
|
+
health: SensorMagekHealthConfiguration;
|
|
44
|
+
}
|
|
45
|
+
export interface HealthIndicatorInterface {
|
|
46
|
+
health: (config: MagekConfig, healthIndicatorMetadata: HealthIndicatorMetadata) => Promise<HealthIndicatorResult>;
|
|
47
|
+
}
|
|
48
|
+
export interface HealthIndicatorConfigurationBase {
|
|
49
|
+
enabled: boolean;
|
|
50
|
+
details: boolean;
|
|
51
|
+
showChildren?: boolean;
|
|
52
|
+
}
|
|
53
|
+
export interface HealthIndicatorConfiguration extends HealthIndicatorConfigurationBase {
|
|
54
|
+
id: string;
|
|
55
|
+
name: string;
|
|
56
|
+
}
|
|
57
|
+
export interface HealthIndicatorMetadata {
|
|
58
|
+
readonly class: Class<HealthIndicatorInterface>;
|
|
59
|
+
readonly healthIndicatorConfiguration: HealthIndicatorConfiguration;
|
|
60
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_SENSOR_HEALTH_CONFIGURATIONS = exports.DEFAULT_HEALTH_CONFIGURATION = exports.HEALTH_INDICATORS_IDS = exports.HealthStatus = void 0;
|
|
4
|
+
var HealthStatus;
|
|
5
|
+
(function (HealthStatus) {
|
|
6
|
+
HealthStatus["UP"] = "UP";
|
|
7
|
+
HealthStatus["PARTIALLY_UP"] = "PARTIALLY_UP";
|
|
8
|
+
HealthStatus["DOWN"] = "DOWN";
|
|
9
|
+
HealthStatus["OUT_OF_SERVICE"] = "OUT_OF_SERVICE";
|
|
10
|
+
HealthStatus["UNKNOWN"] = "UNKNOWN";
|
|
11
|
+
})(HealthStatus || (exports.HealthStatus = HealthStatus = {}));
|
|
12
|
+
var HEALTH_INDICATORS_IDS;
|
|
13
|
+
(function (HEALTH_INDICATORS_IDS) {
|
|
14
|
+
HEALTH_INDICATORS_IDS["ROOT"] = "magek";
|
|
15
|
+
HEALTH_INDICATORS_IDS["FUNCTION"] = "magek/function";
|
|
16
|
+
HEALTH_INDICATORS_IDS["DATABASE"] = "magek/database";
|
|
17
|
+
HEALTH_INDICATORS_IDS["DATABASE_EVENTS"] = "magek/database/events";
|
|
18
|
+
HEALTH_INDICATORS_IDS["DATABASE_READ_MODELS"] = "magek/database/readmodels";
|
|
19
|
+
})(HEALTH_INDICATORS_IDS || (exports.HEALTH_INDICATORS_IDS = HEALTH_INDICATORS_IDS = {}));
|
|
20
|
+
exports.DEFAULT_HEALTH_CONFIGURATION = {
|
|
21
|
+
enabled: false,
|
|
22
|
+
details: true,
|
|
23
|
+
showChildren: true,
|
|
24
|
+
};
|
|
25
|
+
exports.DEFAULT_SENSOR_HEALTH_CONFIGURATIONS = {
|
|
26
|
+
[HEALTH_INDICATORS_IDS.ROOT]: { ...exports.DEFAULT_HEALTH_CONFIGURATION },
|
|
27
|
+
[HEALTH_INDICATORS_IDS.FUNCTION]: { ...exports.DEFAULT_HEALTH_CONFIGURATION },
|
|
28
|
+
[HEALTH_INDICATORS_IDS.DATABASE]: { ...exports.DEFAULT_HEALTH_CONFIGURATION },
|
|
29
|
+
[HEALTH_INDICATORS_IDS.DATABASE_EVENTS]: { ...exports.DEFAULT_HEALTH_CONFIGURATION },
|
|
30
|
+
[HEALTH_INDICATORS_IDS.DATABASE_READ_MODELS]: { ...exports.DEFAULT_HEALTH_CONFIGURATION },
|
|
31
|
+
};
|