@bluelibs/runner 1.1.0 → 1.2.0
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/README.md +191 -13
- package/dist/DependencyProcessor.d.ts +2 -2
- package/dist/DependencyProcessor.js +3 -3
- package/dist/DependencyProcessor.js.map +1 -1
- package/dist/Store.d.ts +24 -1
- package/dist/Store.js +108 -34
- package/dist/Store.js.map +1 -1
- package/dist/TaskRunner.d.ts +3 -0
- package/dist/TaskRunner.js +3 -0
- package/dist/TaskRunner.js.map +1 -1
- package/dist/define.js +1 -0
- package/dist/define.js.map +1 -1
- package/dist/defs.d.ts +6 -4
- package/dist/globalEvents.d.ts +2 -0
- package/dist/globalEvents.js +3 -0
- package/dist/globalEvents.js.map +1 -1
- package/dist/globalResources.d.ts +5 -3
- package/dist/globalResources.js +4 -0
- package/dist/globalResources.js.map +1 -1
- package/dist/index.d.ts +8 -6
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/models/DependencyProcessor.d.ts +49 -0
- package/dist/models/DependencyProcessor.js +178 -0
- package/dist/models/DependencyProcessor.js.map +1 -0
- package/dist/models/EventManager.d.ts +17 -0
- package/dist/models/EventManager.js +73 -0
- package/dist/models/EventManager.js.map +1 -0
- package/dist/models/Logger.d.ts +33 -0
- package/dist/models/Logger.js +76 -0
- package/dist/models/Logger.js.map +1 -0
- package/dist/models/ResourceInitializer.d.ts +13 -0
- package/dist/models/ResourceInitializer.js +54 -0
- package/dist/models/ResourceInitializer.js.map +1 -0
- package/dist/models/Store.d.ts +90 -0
- package/dist/models/Store.js +302 -0
- package/dist/models/Store.js.map +1 -0
- package/dist/models/TaskRunner.d.ts +25 -0
- package/dist/models/TaskRunner.js +96 -0
- package/dist/models/TaskRunner.js.map +1 -0
- package/dist/models/index.d.ts +5 -0
- package/dist/models/index.js +22 -0
- package/dist/models/index.js.map +1 -0
- package/dist/run.d.ts +3 -3
- package/dist/run.js +12 -6
- package/dist/run.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/index.ts +8 -4
- package/src/__tests__/{EventManager.test.ts → models/EventManager.test.ts} +3 -3
- package/src/__tests__/models/Logger.test.ts +140 -0
- package/src/__tests__/{ResourceInitializer.test.ts → models/ResourceInitializer.test.ts} +4 -4
- package/src/__tests__/{Store.test.ts → models/Store.test.ts} +4 -4
- package/src/__tests__/{TaskRunner.test.ts → models/TaskRunner.test.ts} +5 -5
- package/src/__tests__/run.overrides.test.ts +392 -0
- package/src/define.ts +3 -0
- package/src/defs.ts +7 -4
- package/src/globalEvents.ts +4 -0
- package/src/globalResources.ts +8 -3
- package/src/index.ts +3 -3
- package/src/{DependencyProcessor.ts → models/DependencyProcessor.ts} +6 -6
- package/src/{EventManager.ts → models/EventManager.ts} +2 -2
- package/src/models/Logger.ts +100 -0
- package/src/{ResourceInitializer.ts → models/ResourceInitializer.ts} +2 -2
- package/src/{Store.ts → models/Store.ts} +145 -47
- package/src/{TaskRunner.ts → models/TaskRunner.ts} +6 -3
- package/src/models/index.ts +5 -0
- package/src/run.ts +13 -7
package/dist/run.js
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.run = run;
|
|
4
|
-
const TaskRunner_1 = require("./TaskRunner");
|
|
5
|
-
const DependencyProcessor_1 = require("./DependencyProcessor");
|
|
6
|
-
const EventManager_1 = require("./EventManager");
|
|
4
|
+
const TaskRunner_1 = require("./models/TaskRunner");
|
|
5
|
+
const DependencyProcessor_1 = require("./models/DependencyProcessor");
|
|
6
|
+
const EventManager_1 = require("./models/EventManager");
|
|
7
7
|
const globalEvents_1 = require("./globalEvents");
|
|
8
|
-
const Store_1 = require("./Store");
|
|
8
|
+
const Store_1 = require("./models/Store");
|
|
9
9
|
const findCircularDependencies_1 = require("./tools/findCircularDependencies");
|
|
10
10
|
const errors_1 = require("./errors");
|
|
11
11
|
const globalResources_1 = require("./globalResources");
|
|
12
|
+
const Logger_1 = require("./models/Logger");
|
|
12
13
|
async function run(resource, config) {
|
|
13
14
|
const eventManager = new EventManager_1.EventManager();
|
|
14
15
|
const store = new Store_1.Store(eventManager);
|
|
15
16
|
const taskRunner = new TaskRunner_1.TaskRunner(store, eventManager);
|
|
16
17
|
const processor = new DependencyProcessor_1.DependencyProcessor(store, eventManager, taskRunner);
|
|
18
|
+
const logger = new Logger_1.Logger(eventManager);
|
|
17
19
|
// In the registration phase we register deeply all the resources, tasks, middleware and events
|
|
18
20
|
store.initializeStore(resource, config);
|
|
21
|
+
store.storeGenericItem(globalResources_1.globalResources.logger.with(logger));
|
|
19
22
|
store.storeGenericItem(globalResources_1.globalResources.taskRunner.with(taskRunner));
|
|
20
23
|
// We verify that there isn't any circular dependencies before we begin computing the dependencies
|
|
21
24
|
const dependentNodes = store.getDependentNodes();
|
|
@@ -23,11 +26,14 @@ async function run(resource, config) {
|
|
|
23
26
|
if (circularDependencies.cycles.length > 0) {
|
|
24
27
|
throw errors_1.Errors.circularDependencies(circularDependencies.cycles);
|
|
25
28
|
}
|
|
26
|
-
await
|
|
29
|
+
await store.processOverrides();
|
|
30
|
+
// a form of hooking, we store the events for all tasks
|
|
31
|
+
await store.storeEventsForAllTasks();
|
|
32
|
+
await processor.attachHooks();
|
|
33
|
+
await processor.computeAllDependencies();
|
|
27
34
|
// Now we can safely compute dependencies without being afraid of an infinite loop.
|
|
28
35
|
// The hooking part is done here.
|
|
29
36
|
await eventManager.emit(globalEvents_1.globalEvents.beforeInit);
|
|
30
|
-
await processor.computeAllDependencies();
|
|
31
37
|
// leftovers that were registered but not depended upon, except root
|
|
32
38
|
await processor.initializeUninitializedResources();
|
|
33
39
|
// Now we can initialise the root resource
|
package/dist/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":";;AA4DA,kBA6CC;AAzGD,oDAAiD;AAUjD,sEAAmE;AACnE,wDAAqD;AACrD,iDAA8C;AAC9C,0CAAuC;AACvC,+EAA4E;AAC5E,qCAAkC;AAClC,uDAAoD;AACpD,4CAAyC;AA2ClC,KAAK,UAAU,GAAG,CACvB,QAAyB,EACzB,MAAU;IAEV,MAAM,YAAY,GAAG,IAAI,2BAAY,EAAE,CAAC;IACxC,MAAM,KAAK,GAAG,IAAI,aAAK,CAAC,YAAY,CAAC,CAAC;IACtC,MAAM,UAAU,GAAG,IAAI,uBAAU,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,IAAI,yCAAmB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;IAC3E,MAAM,MAAM,GAAG,IAAI,eAAM,CAAC,YAAY,CAAC,CAAC;IAExC,+FAA+F;IAC/F,KAAK,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACxC,KAAK,CAAC,gBAAgB,CAAC,iCAAe,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5D,KAAK,CAAC,gBAAgB,CAAC,iCAAe,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAEpE,kGAAkG;IAClG,MAAM,cAAc,GAAG,KAAK,CAAC,iBAAiB,EAAE,CAAC;IACjD,MAAM,oBAAoB,GAAG,IAAA,mDAAwB,EAAC,cAAc,CAAC,CAAC;IACtE,IAAI,oBAAoB,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3C,MAAM,eAAM,CAAC,oBAAoB,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,KAAK,CAAC,gBAAgB,EAAE,CAAC;IAE/B,uDAAuD;IACvD,MAAM,KAAK,CAAC,sBAAsB,EAAE,CAAC;IACrC,MAAM,SAAS,CAAC,WAAW,EAAE,CAAC;IAC9B,MAAM,SAAS,CAAC,sBAAsB,EAAE,CAAC;IAEzC,mFAAmF;IACnF,iCAAiC;IACjC,MAAM,YAAY,CAAC,IAAI,CAAC,2BAAY,CAAC,UAAU,CAAC,CAAC;IAEjD,oEAAoE;IACpE,MAAM,SAAS,CAAC,gCAAgC,EAAE,CAAC;IAEnD,0CAA0C;IAC1C,MAAM,SAAS,CAAC,cAAc,EAAE,CAAC;IAEjC,MAAM,YAAY,CAAC,IAAI,CAAC,2BAAY,CAAC,SAAS,CAAC,CAAC;IAEhD,0CAA0C;IAC1C,KAAK,CAAC,IAAI,EAAE,CAAC;IAEb,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;AAC1B,CAAC"}
|
package/package.json
CHANGED
package/src/__tests__/index.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import "./EventManager.test";
|
|
1
|
+
import "./models/EventManager.test";
|
|
2
|
+
import "./models/ResourceInitializer.test";
|
|
3
|
+
import "./models/TaskRunner.test";
|
|
4
|
+
import "./models/Store.test";
|
|
5
|
+
import "./models/Logger.test";
|
|
6
|
+
|
|
2
7
|
import "./tools/findCircularDependencies.test";
|
|
3
|
-
|
|
8
|
+
|
|
4
9
|
import "./run.test";
|
|
5
10
|
import "./run.hooks.test";
|
|
6
|
-
import "./
|
|
11
|
+
import "./run.overrides.test";
|
|
7
12
|
import "./globalEvents.test";
|
|
8
|
-
import "./Store.test";
|
|
9
13
|
import "./errors.test";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { IEvent, IEventDefinition } from "
|
|
2
|
-
import { Errors } from "
|
|
3
|
-
import { EventManager } from "
|
|
1
|
+
import { IEvent, IEventDefinition } from "../../defs";
|
|
2
|
+
import { Errors } from "../../errors";
|
|
3
|
+
import { EventManager } from "../../models/EventManager";
|
|
4
4
|
|
|
5
5
|
describe("EventManager", () => {
|
|
6
6
|
let eventManager: EventManager;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { Logger, ILog, LogLevels } from "../../models/Logger";
|
|
2
|
+
import { EventManager } from "../../models/EventManager";
|
|
3
|
+
import { globalEvents } from "../../globalEvents";
|
|
4
|
+
import { mock } from "node:test";
|
|
5
|
+
|
|
6
|
+
describe("Logger", () => {
|
|
7
|
+
let logger: Logger;
|
|
8
|
+
let mockEventManager: jest.Mocked<EventManager>;
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
mockEventManager = new EventManager() as jest.Mocked<EventManager>;
|
|
12
|
+
logger = new Logger(mockEventManager);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
describe("log method", () => {
|
|
16
|
+
it("should emit a log event with correct data", async () => {
|
|
17
|
+
const testData = "Test log message";
|
|
18
|
+
const testLevel = "info";
|
|
19
|
+
mockEventManager.emit = jest.fn();
|
|
20
|
+
|
|
21
|
+
await logger.log(testLevel, testData);
|
|
22
|
+
|
|
23
|
+
expect(mockEventManager.emit).toHaveBeenCalledWith(
|
|
24
|
+
globalEvents.log,
|
|
25
|
+
expect.objectContaining({
|
|
26
|
+
level: testLevel,
|
|
27
|
+
data: testData,
|
|
28
|
+
timestamp: expect.any(Date),
|
|
29
|
+
})
|
|
30
|
+
);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("should handle different log levels", async () => {
|
|
34
|
+
const levels: Array<LogLevels> = [
|
|
35
|
+
"trace",
|
|
36
|
+
"debug",
|
|
37
|
+
"info",
|
|
38
|
+
"warn",
|
|
39
|
+
"error",
|
|
40
|
+
"critical",
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
mockEventManager.emit = jest.fn();
|
|
44
|
+
|
|
45
|
+
for (const level of levels) {
|
|
46
|
+
await logger.log(level, `Test ${level} message`);
|
|
47
|
+
|
|
48
|
+
expect(mockEventManager.emit).toHaveBeenCalledWith(
|
|
49
|
+
globalEvents.log,
|
|
50
|
+
expect.objectContaining({
|
|
51
|
+
level,
|
|
52
|
+
data: `Test ${level} message`,
|
|
53
|
+
timestamp: expect.any(Date),
|
|
54
|
+
})
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
describe("print method", () => {
|
|
61
|
+
let consoleLogSpy: jest.SpyInstance;
|
|
62
|
+
|
|
63
|
+
beforeEach(() => {
|
|
64
|
+
consoleLogSpy = jest.spyOn(console, "log").mockImplementation();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
afterEach(() => {
|
|
68
|
+
consoleLogSpy.mockRestore();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("should print log messages correctly", async () => {
|
|
72
|
+
const testLog: ILog = {
|
|
73
|
+
level: "info",
|
|
74
|
+
context: "test",
|
|
75
|
+
data: "Test log message",
|
|
76
|
+
timestamp: new Date("2023-01-01T00:00:00Z"),
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
await logger.print(testLog);
|
|
80
|
+
|
|
81
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
82
|
+
expect.stringContaining("[INFO] (test) - Test log message")
|
|
83
|
+
);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("should handle Error objects in log data", async () => {
|
|
87
|
+
const testError = new Error("Test error");
|
|
88
|
+
const testLog: ILog = {
|
|
89
|
+
level: "error",
|
|
90
|
+
data: testError,
|
|
91
|
+
timestamp: new Date("2023-01-01T00:00:00Z"),
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
await logger.print(testLog);
|
|
95
|
+
|
|
96
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
97
|
+
expect.stringContaining("Error: Error - Test error")
|
|
98
|
+
);
|
|
99
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
100
|
+
expect.stringContaining("Stack Trace:")
|
|
101
|
+
);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("should pretty-print JSON objects in log data", async () => {
|
|
105
|
+
const testObject = { key: "value", nested: { foo: "bar" } };
|
|
106
|
+
const testLog: ILog = {
|
|
107
|
+
level: "debug",
|
|
108
|
+
data: testObject,
|
|
109
|
+
timestamp: new Date("2023-01-01T00:00:00Z"),
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
await logger.print(testLog);
|
|
113
|
+
|
|
114
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
115
|
+
expect.stringContaining(JSON.stringify(testObject, null, 2))
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
describe("log level methods", () => {
|
|
121
|
+
const testLevels: Array<LogLevels> = [
|
|
122
|
+
"trace",
|
|
123
|
+
"debug",
|
|
124
|
+
"info",
|
|
125
|
+
"warn",
|
|
126
|
+
"error",
|
|
127
|
+
"critical",
|
|
128
|
+
];
|
|
129
|
+
|
|
130
|
+
for (const level of testLevels) {
|
|
131
|
+
it(`should call log method with ${level} level`, async () => {
|
|
132
|
+
const logSpy = jest.spyOn(logger, "log").mockImplementation();
|
|
133
|
+
|
|
134
|
+
await logger[level]("Test log message");
|
|
135
|
+
|
|
136
|
+
expect(logSpy).toHaveBeenCalledWith(level, "Test log message");
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ResourceInitializer } from "
|
|
2
|
-
import { Store } from "
|
|
3
|
-
import { EventManager } from "
|
|
4
|
-
import { defineResource } from "
|
|
1
|
+
import { ResourceInitializer } from "../../models/ResourceInitializer";
|
|
2
|
+
import { Store } from "../../models/Store";
|
|
3
|
+
import { EventManager } from "../../models/EventManager";
|
|
4
|
+
import { defineResource } from "../../define";
|
|
5
5
|
|
|
6
6
|
describe("ResourceInitializer", () => {
|
|
7
7
|
let store: Store;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { Store } from "
|
|
2
|
-
import { EventManager } from "
|
|
1
|
+
import { Store } from "../../models/Store";
|
|
2
|
+
import { EventManager } from "../../models/EventManager";
|
|
3
3
|
import {
|
|
4
4
|
defineResource,
|
|
5
5
|
defineTask,
|
|
6
6
|
defineMiddleware,
|
|
7
7
|
defineEvent,
|
|
8
|
-
} from "
|
|
9
|
-
import { globalResources } from "
|
|
8
|
+
} from "../../define";
|
|
9
|
+
import { globalResources } from "../../globalResources";
|
|
10
10
|
|
|
11
11
|
describe("Store", () => {
|
|
12
12
|
let eventManager: EventManager;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { TaskRunner } from "
|
|
2
|
-
import { Store } from "
|
|
3
|
-
import { EventManager } from "
|
|
4
|
-
import { defineTask, defineResource, defineMiddleware } from "
|
|
5
|
-
import { ITask } from "
|
|
1
|
+
import { TaskRunner } from "../../models/TaskRunner";
|
|
2
|
+
import { Store } from "../../models/Store";
|
|
3
|
+
import { EventManager } from "../../models/EventManager";
|
|
4
|
+
import { defineTask, defineResource, defineMiddleware } from "../../define";
|
|
5
|
+
import { ITask } from "../../defs";
|
|
6
6
|
|
|
7
7
|
describe("TaskRunner", () => {
|
|
8
8
|
let store: Store;
|
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
import { definitions } from "..";
|
|
2
|
+
import {
|
|
3
|
+
defineTask,
|
|
4
|
+
defineResource,
|
|
5
|
+
defineEvent,
|
|
6
|
+
defineMiddleware,
|
|
7
|
+
} from "../define";
|
|
8
|
+
import { Errors } from "../errors";
|
|
9
|
+
import { run } from "../run";
|
|
10
|
+
|
|
11
|
+
describe("run.overrides", () => {
|
|
12
|
+
// Tasks
|
|
13
|
+
it("Should work with a simple override", async () => {
|
|
14
|
+
const task = defineTask({
|
|
15
|
+
id: "task",
|
|
16
|
+
run: async () => "Task executed",
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const override = defineTask({
|
|
20
|
+
id: "task",
|
|
21
|
+
run: async () => "Task overridden",
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const app = defineResource({
|
|
25
|
+
id: "app",
|
|
26
|
+
register: [task],
|
|
27
|
+
dependencies: {
|
|
28
|
+
task,
|
|
29
|
+
},
|
|
30
|
+
overrides: [override],
|
|
31
|
+
async init(_, deps) {
|
|
32
|
+
return await deps.task();
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const result = await run(app);
|
|
37
|
+
expect(result).toBe("Task overridden");
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("Should work with a deep override", async () => {
|
|
41
|
+
const task = defineTask({
|
|
42
|
+
id: "task",
|
|
43
|
+
run: async () => "Task executed",
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const override = defineTask({
|
|
47
|
+
id: "task",
|
|
48
|
+
run: async () => "Task overridden",
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const middle = defineResource({
|
|
52
|
+
id: "app",
|
|
53
|
+
register: [task],
|
|
54
|
+
overrides: [override],
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const root = defineResource({
|
|
58
|
+
id: "root",
|
|
59
|
+
register: [middle],
|
|
60
|
+
dependencies: { task },
|
|
61
|
+
async init(_, deps) {
|
|
62
|
+
return await deps.task();
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const result = await run(root);
|
|
67
|
+
expect(result).toBe("Task overridden");
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("Should work with a deep override with config", async () => {
|
|
71
|
+
const task = defineTask({
|
|
72
|
+
id: "task",
|
|
73
|
+
run: async () => "Task executed",
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const override = defineTask({
|
|
77
|
+
id: "task",
|
|
78
|
+
run: async () => "Task overridden",
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const middle = defineResource<{ test: string }>({
|
|
82
|
+
id: "app",
|
|
83
|
+
register: [task],
|
|
84
|
+
overrides: [override],
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const root = defineResource({
|
|
88
|
+
id: "root",
|
|
89
|
+
register: [middle.with({ test: "ok" })],
|
|
90
|
+
dependencies: { task },
|
|
91
|
+
async init(_, deps) {
|
|
92
|
+
return await deps.task();
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const result = await run(root);
|
|
97
|
+
expect(result).toBe("Task overridden");
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it("Should work with a override that has an override", async () => {
|
|
101
|
+
const task = defineTask({
|
|
102
|
+
id: "task",
|
|
103
|
+
run: async () => "Task executed",
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const override = defineTask({
|
|
107
|
+
id: "task",
|
|
108
|
+
run: async () => "Task overridden",
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const resource = defineResource({
|
|
112
|
+
id: "resource",
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const resourceOverride = {
|
|
116
|
+
...resource,
|
|
117
|
+
overrides: [override],
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const middle = defineResource({
|
|
121
|
+
id: "app",
|
|
122
|
+
register: [task],
|
|
123
|
+
overrides: [resourceOverride],
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const root = defineResource({
|
|
127
|
+
id: "root",
|
|
128
|
+
register: [middle, resource],
|
|
129
|
+
dependencies: { task },
|
|
130
|
+
async init(_, deps) {
|
|
131
|
+
return await deps.task();
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const result = await run(root);
|
|
136
|
+
expect(result).toBe("Task overridden");
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it("Should work with a override that has an override with config", async () => {
|
|
140
|
+
const task = defineTask({
|
|
141
|
+
id: "task",
|
|
142
|
+
run: async () => "Task executed",
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const override = defineTask({
|
|
146
|
+
id: "task",
|
|
147
|
+
run: async () => "Task overridden",
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const resource = defineResource({
|
|
151
|
+
id: "resource",
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const resourceOverride: definitions.IResource<any> = {
|
|
155
|
+
...resource,
|
|
156
|
+
overrides: [override],
|
|
157
|
+
async init(config: { test: string }) {
|
|
158
|
+
return "Resource init";
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const middle = defineResource({
|
|
163
|
+
id: "app",
|
|
164
|
+
register: [task],
|
|
165
|
+
overrides: [resourceOverride.with({ test: "ok" })],
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const root = defineResource({
|
|
169
|
+
id: "root",
|
|
170
|
+
register: [middle, resource],
|
|
171
|
+
dependencies: { task },
|
|
172
|
+
async init(_, deps) {
|
|
173
|
+
return await deps.task();
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
const result = await run(root);
|
|
178
|
+
expect(result).toBe("Task overridden");
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it("should work overriding a middleware", async () => {
|
|
182
|
+
const middleware = defineMiddleware({
|
|
183
|
+
id: "middleware",
|
|
184
|
+
run: async ({ next }) => {
|
|
185
|
+
return `Middleware: ${await next()}`;
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const override = defineMiddleware({
|
|
190
|
+
id: "middleware",
|
|
191
|
+
run: async ({ next }) => {
|
|
192
|
+
return `Override: ${await next()}`;
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
const task = defineTask({
|
|
197
|
+
id: "task",
|
|
198
|
+
middleware: [middleware],
|
|
199
|
+
run: async () => "Task executed",
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
const resource = defineResource({
|
|
203
|
+
id: "resource",
|
|
204
|
+
register: [middleware, task],
|
|
205
|
+
dependencies: { task },
|
|
206
|
+
overrides: [override],
|
|
207
|
+
async init(_, deps) {
|
|
208
|
+
return deps.task();
|
|
209
|
+
},
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
const result = await run(resource);
|
|
213
|
+
expect(result).toBe("Override: Task executed");
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
it("should throw, when you try to override something unregistered", async () => {
|
|
217
|
+
const task = defineTask({
|
|
218
|
+
id: "task",
|
|
219
|
+
run: async () => "Task executed",
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
const override = defineTask({
|
|
223
|
+
id: "task2",
|
|
224
|
+
run: async () => "Task overridden",
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
const app = defineResource({
|
|
228
|
+
id: "app",
|
|
229
|
+
dependencies: {
|
|
230
|
+
task,
|
|
231
|
+
},
|
|
232
|
+
overrides: [override],
|
|
233
|
+
async init(_, deps) {
|
|
234
|
+
return await deps.task();
|
|
235
|
+
},
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
await expect(run(app)).rejects.toThrowError(
|
|
239
|
+
Errors.dependencyNotFound("task2").message
|
|
240
|
+
);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it("should throw, when you try to override something unregistered but with resources with config", async () => {
|
|
244
|
+
const r1 = defineResource({
|
|
245
|
+
id: "override",
|
|
246
|
+
init: async () => "Task executed",
|
|
247
|
+
});
|
|
248
|
+
const r2 = defineResource({
|
|
249
|
+
id: "override2",
|
|
250
|
+
init: async () => "Task executed",
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
const app = defineResource({
|
|
254
|
+
id: "app",
|
|
255
|
+
dependencies: {
|
|
256
|
+
r1,
|
|
257
|
+
},
|
|
258
|
+
overrides: [r2.with()],
|
|
259
|
+
async init(_, r1) {
|
|
260
|
+
return r1;
|
|
261
|
+
},
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
await expect(run(app)).rejects.toThrowError(
|
|
265
|
+
Errors.dependencyNotFound("override2").message
|
|
266
|
+
);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it("should have an override priority, the deeper you are, the less priority you have in the override", async () => {
|
|
270
|
+
const task = defineTask({
|
|
271
|
+
id: "task",
|
|
272
|
+
run: async () => "Task executed",
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
const override = defineTask({
|
|
276
|
+
id: "task2",
|
|
277
|
+
run: async () => "Task overridden",
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
const override2 = defineTask({
|
|
281
|
+
id: "task",
|
|
282
|
+
run: async () => "Task super-overridden",
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
const middle = defineResource({
|
|
286
|
+
id: "app",
|
|
287
|
+
register: [task],
|
|
288
|
+
overrides: [override],
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
const app = defineResource({
|
|
292
|
+
id: "app",
|
|
293
|
+
dependencies: {
|
|
294
|
+
task,
|
|
295
|
+
},
|
|
296
|
+
register: [middle],
|
|
297
|
+
overrides: [override2],
|
|
298
|
+
async init(_, deps) {
|
|
299
|
+
return await deps.task();
|
|
300
|
+
},
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
const result = await run(app);
|
|
304
|
+
expect(result).toBe("Task super-overridden");
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it("should override if I have a previously registered normal resource with a resource with config", async () => {
|
|
308
|
+
const r1 = defineResource({
|
|
309
|
+
id: "override",
|
|
310
|
+
init: async () => "Task executed",
|
|
311
|
+
});
|
|
312
|
+
const r2 = defineResource({
|
|
313
|
+
id: "override",
|
|
314
|
+
init: async () => "Task overriden.",
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
const app = defineResource({
|
|
318
|
+
id: "app",
|
|
319
|
+
dependencies: {
|
|
320
|
+
r1,
|
|
321
|
+
},
|
|
322
|
+
register: [r1],
|
|
323
|
+
overrides: [r2.with()],
|
|
324
|
+
async init(_, deps) {
|
|
325
|
+
return deps.r1;
|
|
326
|
+
},
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
await expect(run(app)).resolves.toBe("Task overriden.");
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
it("should override if I have a previously registered normal resource with a resource with config", async () => {
|
|
333
|
+
const r1 = defineResource({
|
|
334
|
+
id: "override",
|
|
335
|
+
init: async () => "Task executed",
|
|
336
|
+
});
|
|
337
|
+
const r2 = defineResource({
|
|
338
|
+
id: "override",
|
|
339
|
+
init: async () => "Task overriden.",
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
const app = defineResource({
|
|
343
|
+
id: "app",
|
|
344
|
+
dependencies: {
|
|
345
|
+
r1,
|
|
346
|
+
},
|
|
347
|
+
register: [r1.with()],
|
|
348
|
+
overrides: [r2.with()],
|
|
349
|
+
async init(_, deps) {
|
|
350
|
+
return deps.r1;
|
|
351
|
+
},
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
await expect(run(app)).resolves.toBe("Task overriden.");
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
it("should override something deeply registered, with a with config", async () => {
|
|
358
|
+
const r1 = defineResource({
|
|
359
|
+
id: "override",
|
|
360
|
+
init: async () => "Task executed",
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
const middle = defineResource({
|
|
364
|
+
id: "app.m1",
|
|
365
|
+
register: [r1],
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
const middle2 = defineResource({
|
|
369
|
+
id: "app.m2",
|
|
370
|
+
register: [middle],
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
const r2 = defineResource({
|
|
374
|
+
id: "override",
|
|
375
|
+
init: async () => "Task overriden.",
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
const app = defineResource({
|
|
379
|
+
id: "app",
|
|
380
|
+
dependencies: {
|
|
381
|
+
r1,
|
|
382
|
+
},
|
|
383
|
+
register: [middle2],
|
|
384
|
+
overrides: [r2.with()],
|
|
385
|
+
async init(_, deps) {
|
|
386
|
+
return deps.r1;
|
|
387
|
+
},
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
await expect(run(app)).resolves.toBe("Task overriden.");
|
|
391
|
+
});
|
|
392
|
+
});
|
package/src/define.ts
CHANGED
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
DependencyMapType,
|
|
11
11
|
DependencyValuesType,
|
|
12
12
|
IMiddleware,
|
|
13
|
+
IHookDefinition,
|
|
14
|
+
IEvent,
|
|
13
15
|
} from "./defs";
|
|
14
16
|
import { Errors } from "./errors";
|
|
15
17
|
|
|
@@ -57,6 +59,7 @@ export function defineResource<
|
|
|
57
59
|
hooks: constConfig.hooks || [],
|
|
58
60
|
dispose: constConfig.dispose,
|
|
59
61
|
register: constConfig.register || [],
|
|
62
|
+
overrides: constConfig.overrides || [],
|
|
60
63
|
init: constConfig.init,
|
|
61
64
|
with: function (config: TConfig) {
|
|
62
65
|
return {
|