xtaskjs 1.0.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/.github/workflows/publish.yml +44 -0
- package/app.ts +7 -0
- package/babel.config.js +4 -0
- package/dist/packages/common/index.js +17 -0
- package/dist/packages/common/src/decorators/core/server/applicationrunner.js +11 -0
- package/dist/packages/common/src/decorators/core/server/commandlinerunner.js +11 -0
- package/dist/packages/common/src/decorators/core/server/constants.js +5 -0
- package/dist/packages/common/src/decorators/core/server/index.js +20 -0
- package/dist/packages/common/src/decorators/core/server/onevent.js +11 -0
- package/dist/packages/common/src/index.js +24 -0
- package/dist/packages/common/src/logger/index.js +17 -0
- package/dist/packages/common/src/logger/logger.js +40 -0
- package/dist/packages/common/src/types/eventhandlermeta.js +2 -0
- package/dist/packages/common/src/types/index.js +19 -0
- package/dist/packages/common/src/types/lifecycle-events.js +2 -0
- package/dist/packages/common/src/types/runnermeta.js +2 -0
- package/dist/packages/common/test/logger/logger.test.js +12 -0
- package/dist/packages/core/index.js +17 -0
- package/dist/packages/core/src/bootstrap.js +13 -0
- package/dist/packages/core/src/di/autowired.js +41 -0
- package/dist/packages/core/src/di/component.js +19 -0
- package/dist/packages/core/src/di/container.js +225 -0
- package/dist/packages/core/src/di/index.js +27 -0
- package/dist/packages/core/src/di/lifecycle.js +27 -0
- package/dist/packages/core/src/di/managedinstance.js +2 -0
- package/dist/packages/core/src/di/qualifier.js +26 -0
- package/dist/packages/core/src/di/stereotypes.js +10 -0
- package/dist/packages/core/src/index.js +21 -0
- package/dist/packages/core/src/kernel/index.js +18 -0
- package/dist/packages/core/src/kernel/kernel.js +26 -0
- package/dist/packages/core/src/kernel/kernellisteners.js +72 -0
- package/dist/packages/core/src/server/application-lifecycle.js +103 -0
- package/dist/packages/core/src/server/index.js +19 -0
- package/dist/packages/core/src/server/registereventhandlers.js +15 -0
- package/dist/packages/core/test/di/autowired.test.js +92 -0
- package/dist/packages/core/test/di/container.test.js +43 -0
- package/dist/packages/core/test/di/qualifier.test.js +71 -0
- package/dist/packages/core/test/logger/logger.test.js +12 -0
- package/dist/packages/core/test/server/applicationlifecycle.test.js +28 -0
- package/jest.config.js +9 -0
- package/package.json +36 -0
- package/packages/common/README.md +21 -0
- package/packages/common/babel.config.js +3 -0
- package/packages/common/index.ts +1 -0
- package/packages/common/jest.config.js +11 -0
- package/packages/common/package.json +50 -0
- package/packages/common/src/decorators/core/server/applicationrunner.ts +10 -0
- package/packages/common/src/decorators/core/server/commandlinerunner.ts +10 -0
- package/packages/common/src/decorators/core/server/constants.ts +2 -0
- package/packages/common/src/decorators/core/server/index.ts +4 -0
- package/packages/common/src/decorators/core/server/onevent.ts +10 -0
- package/packages/common/src/index.ts +5 -0
- package/packages/common/src/logger/index.ts +1 -0
- package/packages/common/src/logger/logger.ts +26 -0
- package/packages/common/src/types/eventhandlermeta.ts +7 -0
- package/packages/common/src/types/index.ts +3 -0
- package/packages/common/src/types/lifecycle-events.ts +10 -0
- package/packages/common/src/types/runnermeta.ts +5 -0
- package/packages/common/test/logger/logger.test.ts +11 -0
- package/packages/common/tsconfig.json +13 -0
- package/packages/core/README.md +21 -0
- package/packages/core/babel.config.js +3 -0
- package/packages/core/index.ts +1 -0
- package/packages/core/jest.config.js +15 -0
- package/packages/core/package.json +51 -0
- package/packages/core/src/bootstrap.ts +11 -0
- package/packages/core/src/di/autowired.ts +56 -0
- package/packages/core/src/di/component.ts +34 -0
- package/packages/core/src/di/container.ts +216 -0
- package/packages/core/src/di/index.ts +8 -0
- package/packages/core/src/di/lifecycle.ts +25 -0
- package/packages/core/src/di/managedinstance.ts +4 -0
- package/packages/core/src/di/qualifier.ts +25 -0
- package/packages/core/src/di/stereotypes.ts +10 -0
- package/packages/core/src/index.ts +5 -0
- package/packages/core/src/kernel/index.ts +2 -0
- package/packages/core/src/kernel/kernel.ts +31 -0
- package/packages/core/src/kernel/kernellisteners.ts +36 -0
- package/packages/core/src/server/application-lifecycle.ts +85 -0
- package/packages/core/src/server/index.ts +3 -0
- package/packages/core/src/server/registereventhandlers.ts +18 -0
- package/packages/core/test/di/autowired.test.ts +83 -0
- package/packages/core/test/di/container.test.ts +49 -0
- package/packages/core/test/di/qualifier.test.ts +60 -0
- package/packages/core/test/logger/logger.test.ts +11 -0
- package/packages/core/test/server/applicationlifecycle.test.ts +13 -0
- package/packages/core/tsconfig.json +19 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: Publish Packages
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
release:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
env:
|
|
12
|
+
BROWSER: none
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout repository
|
|
15
|
+
uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Use Node.js
|
|
18
|
+
uses: actions/setup-node@v4
|
|
19
|
+
with:
|
|
20
|
+
node-version: 20
|
|
21
|
+
registry-url: 'https://registry.npmjs.org/'
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: npm install
|
|
25
|
+
|
|
26
|
+
- name: Build all packages
|
|
27
|
+
run: npm run build
|
|
28
|
+
|
|
29
|
+
- name: Set up git user
|
|
30
|
+
run: |
|
|
31
|
+
git config --global user.name 'github-actions[bot]'
|
|
32
|
+
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
|
33
|
+
|
|
34
|
+
- name: Bump versions and publish packages
|
|
35
|
+
run: |
|
|
36
|
+
npx lerna version --conventional-commits --yes
|
|
37
|
+
npx lerna publish from-package --yes
|
|
38
|
+
env:
|
|
39
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
40
|
+
|
|
41
|
+
- name: Push changes
|
|
42
|
+
run: git push --follow-tags origin main
|
|
43
|
+
env:
|
|
44
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
package/app.ts
ADDED
package/babel.config.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./src"), exports);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApplicationRunner = ApplicationRunner;
|
|
4
|
+
const constants_1 = require("./constants");
|
|
5
|
+
function ApplicationRunner(priority = 0) {
|
|
6
|
+
return (target, propertyKey) => {
|
|
7
|
+
const runners = Reflect.getMetadata(constants_1.RUNNERS_KEY, target.constructor) || [];
|
|
8
|
+
runners.push({ type: "ApplicationRunner", method: propertyKey, priority });
|
|
9
|
+
Reflect.defineMetadata(constants_1.RUNNERS_KEY, runners, target.constructor);
|
|
10
|
+
};
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CommandLineRunner = CommandLineRunner;
|
|
4
|
+
const constants_1 = require("./constants");
|
|
5
|
+
function CommandLineRunner(priority = 0) {
|
|
6
|
+
return (target, propertyKey) => {
|
|
7
|
+
const runners = Reflect.getMetadata(constants_1.RUNNERS_KEY, target.constructor) || [];
|
|
8
|
+
runners.push({ type: "CommandLineRunner", method: propertyKey, priority });
|
|
9
|
+
Reflect.defineMetadata(constants_1.RUNNERS_KEY, runners, target.constructor);
|
|
10
|
+
};
|
|
11
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./onevent"), exports);
|
|
18
|
+
__exportStar(require("./applicationrunner"), exports);
|
|
19
|
+
__exportStar(require("./commandlinerunner"), exports);
|
|
20
|
+
__exportStar(require("./constants"), exports);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OnEvent = OnEvent;
|
|
4
|
+
const constants_1 = require("./constants");
|
|
5
|
+
function OnEvent(phase, priority = 0) {
|
|
6
|
+
return (target, propertyKey) => {
|
|
7
|
+
const handlers = Reflect.getMetadata(constants_1.HANDLERS_KEY, target.constructor) || [];
|
|
8
|
+
handlers.push({ phase, method: propertyKey, priority });
|
|
9
|
+
Reflect.defineMetadata(constants_1.HANDLERS_KEY, handlers, target.constructor);
|
|
10
|
+
};
|
|
11
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.RUNNERS_KEY = exports.HANDLERS_KEY = void 0;
|
|
18
|
+
require("reflect-metadata");
|
|
19
|
+
__exportStar(require("./logger"), exports);
|
|
20
|
+
__exportStar(require("./decorators/core/server"), exports);
|
|
21
|
+
__exportStar(require("./types"), exports);
|
|
22
|
+
var constants_1 = require("./decorators/core/server/constants");
|
|
23
|
+
Object.defineProperty(exports, "HANDLERS_KEY", { enumerable: true, get: function () { return constants_1.HANDLERS_KEY; } });
|
|
24
|
+
Object.defineProperty(exports, "RUNNERS_KEY", { enumerable: true, get: function () { return constants_1.RUNNERS_KEY; } });
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./logger"), exports);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.Logger = void 0;
|
|
13
|
+
const stereotypes_1 = require("../../../core/src/di/stereotypes");
|
|
14
|
+
const lifecycle_1 = require("../../../core/src/di/lifecycle");
|
|
15
|
+
let Logger = class Logger {
|
|
16
|
+
constructor() { }
|
|
17
|
+
init() {
|
|
18
|
+
console.log("Logger Initialized");
|
|
19
|
+
}
|
|
20
|
+
info(message) {
|
|
21
|
+
console.log(`INFO: ${message}`);
|
|
22
|
+
}
|
|
23
|
+
warn(message) {
|
|
24
|
+
console.warn(`WARN: ${message}`);
|
|
25
|
+
}
|
|
26
|
+
error(message) {
|
|
27
|
+
console.error(`ERROR: ${message}`);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
exports.Logger = Logger;
|
|
31
|
+
__decorate([
|
|
32
|
+
(0, lifecycle_1.PostConstruct)(),
|
|
33
|
+
__metadata("design:type", Function),
|
|
34
|
+
__metadata("design:paramtypes", []),
|
|
35
|
+
__metadata("design:returntype", void 0)
|
|
36
|
+
], Logger.prototype, "init", null);
|
|
37
|
+
exports.Logger = Logger = __decorate([
|
|
38
|
+
(0, stereotypes_1.Service)({ scope: "singleton" }),
|
|
39
|
+
__metadata("design:paramtypes", [])
|
|
40
|
+
], Logger);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./lifecycle-events"), exports);
|
|
18
|
+
__exportStar(require("./runnermeta"), exports);
|
|
19
|
+
__exportStar(require("./eventhandlermeta"), exports);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const logger_1 = require("../../src/logger/logger");
|
|
4
|
+
describe("Logger", () => {
|
|
5
|
+
it("Should print logs", () => {
|
|
6
|
+
const logger = new logger_1.Logger();
|
|
7
|
+
const spy = jest.spyOn(console, "log").mockImplementation();
|
|
8
|
+
logger.info("hello");
|
|
9
|
+
expect(spy).toHaveBeenCalledWith(expect.stringContaining("hello"));
|
|
10
|
+
spy.mockRestore();
|
|
11
|
+
});
|
|
12
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./src"), exports);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Bootstrap = Bootstrap;
|
|
4
|
+
require("reflect-metadata");
|
|
5
|
+
const core_1 = require("@xtaskjs/core");
|
|
6
|
+
async function Bootstrap() {
|
|
7
|
+
const lifecycle = new core_1.ApplicationLifeCycle();
|
|
8
|
+
const kernel = new core_1.Kernel();
|
|
9
|
+
const listeners = new core_1.KernelListeners();
|
|
10
|
+
(0, core_1.registerEventHandlers)(listeners, lifecycle);
|
|
11
|
+
await lifecycle.boot(() => kernel.boot());
|
|
12
|
+
return kernel;
|
|
13
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AutoWired = AutoWired;
|
|
4
|
+
exports.getAutoWiredProperties = getAutoWiredProperties;
|
|
5
|
+
require("reflect-metadata");
|
|
6
|
+
const AUTOWIRED_KEY = Symbol("xtaskjs:autowired");
|
|
7
|
+
const AUTOWIRED_PROPS_KEY = Symbol("xtaskjs:autowired:props");
|
|
8
|
+
function AutoWired(options = {}) {
|
|
9
|
+
return function (target, propertyKey) {
|
|
10
|
+
const type = Reflect.getMetadata("design:type", target, propertyKey);
|
|
11
|
+
const metaData = {
|
|
12
|
+
type,
|
|
13
|
+
required: options.required !== false,
|
|
14
|
+
qualifier: options.qualifier,
|
|
15
|
+
};
|
|
16
|
+
// Store metadata for the property
|
|
17
|
+
Reflect.defineMetadata(AUTOWIRED_KEY, metaData, target, propertyKey);
|
|
18
|
+
// Store list of autowired properties on the class prototype
|
|
19
|
+
const existingProps = Reflect.getMetadata(AUTOWIRED_PROPS_KEY, target.constructor) || [];
|
|
20
|
+
if (!existingProps.includes(propertyKey)) {
|
|
21
|
+
existingProps.push(propertyKey);
|
|
22
|
+
Reflect.defineMetadata(AUTOWIRED_PROPS_KEY, existingProps, target.constructor);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function getAutoWiredProperties(target) {
|
|
27
|
+
const properties = new Map();
|
|
28
|
+
let currentClass = target.contructor;
|
|
29
|
+
while (currentClass && currentClass !== Object) {
|
|
30
|
+
const autowiredProps = Reflect.getMetadata(AUTOWIRED_PROPS_KEY, currentClass) || [];
|
|
31
|
+
const prototype = currentClass.prototype;
|
|
32
|
+
autowiredProps.forEach((prop) => {
|
|
33
|
+
const metaData = Reflect.getMetadata(AUTOWIRED_KEY, prototype, prop);
|
|
34
|
+
if (metaData && !properties.has(prop)) {
|
|
35
|
+
properties.set(prop, metaData);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
currentClass = Object.getPrototypeOf(currentClass);
|
|
39
|
+
}
|
|
40
|
+
return properties;
|
|
41
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Repository = exports.Service = void 0;
|
|
4
|
+
exports.Component = Component;
|
|
5
|
+
exports.getComponentMetadata = getComponentMetadata;
|
|
6
|
+
require("reflect-metadata");
|
|
7
|
+
const COMPONENT_KEY = Symbol("xtaskjs:component");
|
|
8
|
+
function Component(options = {}) {
|
|
9
|
+
return function (target) {
|
|
10
|
+
Reflect.defineMetadata(COMPONENT_KEY, options, target);
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function getComponentMetadata(target) {
|
|
14
|
+
return Reflect.getMetadata(COMPONENT_KEY, target);
|
|
15
|
+
}
|
|
16
|
+
const Service = (meta = {}) => Component(meta);
|
|
17
|
+
exports.Service = Service;
|
|
18
|
+
const Repository = (meta = {}) => Component(meta);
|
|
19
|
+
exports.Repository = Repository;
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.Container = void 0;
|
|
37
|
+
require("reflect-metadata");
|
|
38
|
+
const component_1 = require("./component");
|
|
39
|
+
const lifecycle_1 = require("./lifecycle");
|
|
40
|
+
const fs_1 = require("fs");
|
|
41
|
+
const path_1 = require("path");
|
|
42
|
+
const ts_morph_1 = require("ts-morph");
|
|
43
|
+
const autowired_1 = require("./autowired");
|
|
44
|
+
const qualifier_1 = require("./qualifier");
|
|
45
|
+
const server_1 = require("../server");
|
|
46
|
+
const common_1 = require("@xtaskjs/common");
|
|
47
|
+
class Container {
|
|
48
|
+
providers = new Map();
|
|
49
|
+
singletons = new Map();
|
|
50
|
+
nameToType = new Map();
|
|
51
|
+
typeToNames = new Map();
|
|
52
|
+
primaryBeans = new Map();
|
|
53
|
+
resolving = new Set();
|
|
54
|
+
managedInstances = [];
|
|
55
|
+
// SCAN FOLDER BASE DIR FOR @Service() AND @Component()
|
|
56
|
+
async autoload(baseDir = "packages") {
|
|
57
|
+
const files = await this.scanDir((0, path_1.join)(process.cwd(), baseDir));
|
|
58
|
+
for (const file of files) {
|
|
59
|
+
const name = file.toString();
|
|
60
|
+
if (name.includes("test"))
|
|
61
|
+
continue; //skip test files
|
|
62
|
+
if (name.endsWith("d.ts"))
|
|
63
|
+
continue; // skip TypeScript declarations Files.
|
|
64
|
+
if (name.includes("js"))
|
|
65
|
+
continue; //skip configuration files
|
|
66
|
+
if (name.includes("json"))
|
|
67
|
+
continue; //skip configuration files
|
|
68
|
+
if (name.includes("index.ts"))
|
|
69
|
+
continue; //skip export files
|
|
70
|
+
const module = await Promise.resolve(`${file}`).then(s => __importStar(require(s)));
|
|
71
|
+
const project = new ts_morph_1.Project();
|
|
72
|
+
const sourceFile = project.addSourceFileAtPath(file);
|
|
73
|
+
const classes = sourceFile.getClasses();
|
|
74
|
+
for (const cls of classes) {
|
|
75
|
+
if (cls.getDecorator("Service") || cls.getDecorator("Component") || cls.getDecorator("Controller") || cls.getDecorator("Repository")) {
|
|
76
|
+
const className = cls.getName();
|
|
77
|
+
if (className && module[className]) {
|
|
78
|
+
const classConstructor = module[className];
|
|
79
|
+
const metaData = (0, component_1.getComponentMetadata)(classConstructor) || { scope: "singleton" };
|
|
80
|
+
const beanName = metaData.name || className;
|
|
81
|
+
this.registerWithName(classConstructor, metaData, beanName);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
registerWithName(target, meta, name) {
|
|
88
|
+
if (name) {
|
|
89
|
+
this.nameToType.set(name, target);
|
|
90
|
+
const existingNames = this.typeToNames.get(target) || [];
|
|
91
|
+
existingNames.push(name);
|
|
92
|
+
this.typeToNames.set(target, existingNames);
|
|
93
|
+
}
|
|
94
|
+
if (meta.primary) {
|
|
95
|
+
this.primaryBeans.set(target, target);
|
|
96
|
+
}
|
|
97
|
+
this.register(target, meta);
|
|
98
|
+
}
|
|
99
|
+
// Register aa class with the container
|
|
100
|
+
register(target, meta) {
|
|
101
|
+
const paramTypes = Reflect.getMetadata("design:paramtypes", target) || [];
|
|
102
|
+
console.log(`Registering component: ${target.name} with dependencies:`, paramTypes.map(t => t?.name || 'unknown'));
|
|
103
|
+
const provider = () => {
|
|
104
|
+
if (this.resolving.has(target)) {
|
|
105
|
+
const resolvingNames = Array.from(this.resolving).map(t => t.name || 'unknown').join(" -> ");
|
|
106
|
+
throw new Error(`Circular dependency detected: ${resolvingNames} -> ${target.name}`);
|
|
107
|
+
}
|
|
108
|
+
this.resolving.add(target);
|
|
109
|
+
try {
|
|
110
|
+
const qualifiers = (0, qualifier_1.getConstructorQualifiers)(target);
|
|
111
|
+
const dependencies = paramTypes.map((dep, index) => {
|
|
112
|
+
const qualifier = qualifiers?.[index];
|
|
113
|
+
return this.getWithQualifier(dep, qualifier);
|
|
114
|
+
});
|
|
115
|
+
const instance = new target(...dependencies);
|
|
116
|
+
this.injectAutoWiredFields(instance);
|
|
117
|
+
//PostConstruct
|
|
118
|
+
const postMethod = (0, lifecycle_1.getPostConstructMethod)(instance);
|
|
119
|
+
if (postMethod && typeof instance[postMethod] === "function") {
|
|
120
|
+
instance[postMethod]();
|
|
121
|
+
}
|
|
122
|
+
//PreDestroy
|
|
123
|
+
const preMethod = (0, lifecycle_1.getPreDestroyMethod)(instance);
|
|
124
|
+
if (preMethod && typeof instance[preMethod] === "function") {
|
|
125
|
+
this.managedInstances.push({
|
|
126
|
+
instance,
|
|
127
|
+
preDestroy: () => instance[preMethod](),
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
return instance;
|
|
131
|
+
}
|
|
132
|
+
finally {
|
|
133
|
+
this.resolving.delete(target);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
if (meta.scope === "transient") {
|
|
137
|
+
this.providers.set(target, provider);
|
|
138
|
+
}
|
|
139
|
+
else { //singleton by default
|
|
140
|
+
this.providers.set(target, () => {
|
|
141
|
+
if (!this.singletons.has(target)) {
|
|
142
|
+
const instance = provider();
|
|
143
|
+
this.singletons.set(target, instance);
|
|
144
|
+
}
|
|
145
|
+
return this.singletons.get(target);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
getByName(name) {
|
|
150
|
+
const type = this.nameToType.get(name);
|
|
151
|
+
if (!type) {
|
|
152
|
+
throw new Error(`No component found with name: ${name}`);
|
|
153
|
+
}
|
|
154
|
+
return this.get(type);
|
|
155
|
+
}
|
|
156
|
+
getWithQualifier(type, qualifier) {
|
|
157
|
+
if (qualifier) {
|
|
158
|
+
return this.getByName(qualifier);
|
|
159
|
+
}
|
|
160
|
+
return this.get(type);
|
|
161
|
+
}
|
|
162
|
+
injectAutoWiredFields(instance) {
|
|
163
|
+
const autoWiredProperties = (0, autowired_1.getAutoWiredProperties)(instance);
|
|
164
|
+
autoWiredProperties.forEach((metaData, propertyKey) => {
|
|
165
|
+
try {
|
|
166
|
+
let value;
|
|
167
|
+
if (metaData.qualifier) {
|
|
168
|
+
value = this.getByName(metaData.qualifier);
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
value = this.get(metaData.type);
|
|
172
|
+
}
|
|
173
|
+
instance[propertyKey] = value;
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
if (metaData.required) {
|
|
177
|
+
throw new Error(`Failed to inject required dependency for property "${String(propertyKey)}": ${error.message}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
// Get instance of class
|
|
183
|
+
get(target) {
|
|
184
|
+
const provider = this.providers.get(target);
|
|
185
|
+
if (!provider) {
|
|
186
|
+
throw new Error(`No provider found for ${target.name}`);
|
|
187
|
+
}
|
|
188
|
+
return provider();
|
|
189
|
+
}
|
|
190
|
+
// Execute all @PreDestroy in reverse order
|
|
191
|
+
destroy() {
|
|
192
|
+
this.managedInstances.reverse().forEach((m) => m.preDestroy?.());
|
|
193
|
+
this.managedInstances = [];
|
|
194
|
+
this.singletons.clear();
|
|
195
|
+
this.providers.clear();
|
|
196
|
+
}
|
|
197
|
+
// Scan folder recursively for .ts or .js files
|
|
198
|
+
async scanDir(dir) {
|
|
199
|
+
let results = [];
|
|
200
|
+
for (const file of (0, fs_1.readdirSync)(dir)) {
|
|
201
|
+
const full = (0, path_1.join)(dir, file);
|
|
202
|
+
const stat = (0, fs_1.statSync)(full);
|
|
203
|
+
if (stat && stat.isDirectory()) {
|
|
204
|
+
const res = await this.scanDir(full);
|
|
205
|
+
results = results.concat(res);
|
|
206
|
+
}
|
|
207
|
+
else if (/\.(ts|js)$/.test(file)) {
|
|
208
|
+
results.push(full);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return results;
|
|
212
|
+
}
|
|
213
|
+
registerLifeCycleListeners(app) {
|
|
214
|
+
for (const [type] of this.providers.entries()) {
|
|
215
|
+
// Check if class has lifecycle decorators
|
|
216
|
+
const handlers = Reflect.getMetadata(common_1.HANDLERS_KEY, type) || [];
|
|
217
|
+
const runners = Reflect.getMetadata(common_1.RUNNERS_KEY, type) || [];
|
|
218
|
+
if (handlers.length > 0 || runners.length > 0) {
|
|
219
|
+
const instance = this.get(type);
|
|
220
|
+
(0, server_1.registerEventHandlers)(instance, app);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
exports.Container = Container;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.getComponentMetadata = exports.Container = exports.Component = void 0;
|
|
18
|
+
var component_1 = require("./component");
|
|
19
|
+
Object.defineProperty(exports, "Component", { enumerable: true, get: function () { return component_1.Component; } });
|
|
20
|
+
var container_1 = require("./container");
|
|
21
|
+
Object.defineProperty(exports, "Container", { enumerable: true, get: function () { return container_1.Container; } });
|
|
22
|
+
__exportStar(require("./lifecycle"), exports);
|
|
23
|
+
var component_2 = require("./component");
|
|
24
|
+
Object.defineProperty(exports, "getComponentMetadata", { enumerable: true, get: function () { return component_2.getComponentMetadata; } });
|
|
25
|
+
__exportStar(require("./stereotypes"), exports);
|
|
26
|
+
__exportStar(require("./autowired"), exports);
|
|
27
|
+
__exportStar(require("./qualifier"), exports);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PRE_DESTROY_KEY = exports.POST_CONSTRUCT_KEY = void 0;
|
|
4
|
+
exports.PostConstruct = PostConstruct;
|
|
5
|
+
exports.PreDestroy = PreDestroy;
|
|
6
|
+
exports.getPostConstructMethod = getPostConstructMethod;
|
|
7
|
+
exports.getPreDestroyMethod = getPreDestroyMethod;
|
|
8
|
+
require("reflect-metadata");
|
|
9
|
+
exports.POST_CONSTRUCT_KEY = Symbol("post_construct");
|
|
10
|
+
exports.PRE_DESTROY_KEY = Symbol("pre_destroy");
|
|
11
|
+
function PostConstruct() {
|
|
12
|
+
return function (target, propertyKey) {
|
|
13
|
+
Reflect.defineMetadata(exports.POST_CONSTRUCT_KEY, propertyKey, target);
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
;
|
|
17
|
+
function PreDestroy() {
|
|
18
|
+
return function (target, propertyKey) {
|
|
19
|
+
Reflect.defineMetadata(exports.PRE_DESTROY_KEY, propertyKey, target);
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function getPostConstructMethod(target) {
|
|
23
|
+
return Reflect.getMetadata(exports.POST_CONSTRUCT_KEY, target);
|
|
24
|
+
}
|
|
25
|
+
function getPreDestroyMethod(target) {
|
|
26
|
+
return Reflect.getMetadata(exports.PRE_DESTROY_KEY, target);
|
|
27
|
+
}
|