@schorts/shared-kernel 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/.idx/airules.md +186 -0
- package/.idx/dev.nix +54 -0
- package/.vscode/settings.json +7 -0
- package/CHANGELOG +0 -0
- package/README.md +98 -0
- package/__tests__/auth/auth-provider.test.ts +45 -0
- package/__tests__/auth/require-auth.decorator.test.ts +88 -0
- package/__tests__/criteria/criteria.test.ts +159 -0
- package/__tests__/criteria/direction.test.ts +11 -0
- package/__tests__/criteria/filter-criterion.test.ts +15 -0
- package/__tests__/criteria/operator.test.ts +22 -0
- package/__tests__/criteria/order.test.ts +14 -0
- package/__tests__/domain-events/domain-event-primitives.test.ts +34 -0
- package/__tests__/domain-events/domain-event.test.ts +50 -0
- package/__tests__/entities/entity.test.ts +114 -0
- package/__tests__/formatters/pascal-camel-to-snake.test.ts +19 -0
- package/__tests__/http/fetch-http-provider.test.ts +155 -0
- package/__tests__/http/http-provider.test.ts +55 -0
- package/__tests__/json-api/json-api-connector.test.ts +78 -0
- package/__tests__/json-api/json-api-list.test.ts +24 -0
- package/__tests__/json-api/json-api-single.test.ts +24 -0
- package/__tests__/json-api/url-criteria-builder.test.ts +74 -0
- package/__tests__/messages/message.test.ts +16 -0
- package/__tests__/models/base-model.test.ts +10 -0
- package/__tests__/state-manager/state-manager.test.ts +101 -0
- package/__tests__/utils/url/url-with-params-builder.test.ts +39 -0
- package/__tests__/value-objects/coordinates-value.test.ts +68 -0
- package/__tests__/value-objects/email-value.test.ts +43 -0
- package/__tests__/value-objects/enum-value.test.ts +51 -0
- package/__tests__/value-objects/integer-value.test.ts +115 -0
- package/__tests__/value-objects/phone-value.test.ts +82 -0
- package/__tests__/value-objects/slug-value.test.ts +43 -0
- package/__tests__/value-objects/string-value.test.ts +121 -0
- package/__tests__/value-objects/uuid-value.test.ts +67 -0
- package/__tests__/value-objects/value-object.test.ts +25 -0
- package/jest.config.js +25 -0
- package/package.json +289 -0
- package/src/auth/auth-provider.ts +10 -0
- package/src/auth/exceptions/index.ts +1 -0
- package/src/auth/exceptions/not-authenticated.ts +1 -0
- package/src/auth/index.ts +3 -0
- package/src/auth/require-auth.decorator.ts +41 -0
- package/src/criteria/criteria.ts +51 -0
- package/src/criteria/direction.ts +1 -0
- package/src/criteria/exceptions/index.ts +2 -0
- package/src/criteria/exceptions/limit-not-valid.ts +1 -0
- package/src/criteria/exceptions/offset-not-valid.ts +1 -0
- package/src/criteria/filter-criterion.ts +6 -0
- package/src/criteria/index.ts +7 -0
- package/src/criteria/operator.ts +12 -0
- package/src/criteria/order.ts +4 -0
- package/src/domain-events/domain-event-primitives.ts +7 -0
- package/src/domain-events/domain-event.ts +15 -0
- package/src/domain-events/index.ts +2 -0
- package/src/entities/entity.ts +22 -0
- package/src/entities/index.ts +1 -0
- package/src/formatters/index.ts +1 -0
- package/src/formatters/pascal-camel-to-snake.ts +8 -0
- package/src/http/exceptions/http-exception.ts +8 -0
- package/src/http/exceptions/index.ts +1 -0
- package/src/http/fetch-http-provider.ts +120 -0
- package/src/http/http-provider.ts +7 -0
- package/src/http/index.ts +4 -0
- package/src/json-api/index.ts +4 -0
- package/src/json-api/json-api-connector.ts +56 -0
- package/src/json-api/json-api-list.ts +13 -0
- package/src/json-api/json-api-single.ts +13 -0
- package/src/json-api/url-criteria-builder.ts +49 -0
- package/src/messages/index.ts +1 -0
- package/src/messages/message.ts +3 -0
- package/src/models/base-model.ts +3 -0
- package/src/models/index.ts +1 -0
- package/src/state-manager/index.ts +1 -0
- package/src/state-manager/state-manager.ts +28 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/url/index.ts +1 -0
- package/src/utils/url/url-with-params-builder.ts +19 -0
- package/src/value-objects/coordinates-value.ts +50 -0
- package/src/value-objects/email-value.ts +25 -0
- package/src/value-objects/enum-value.ts +25 -0
- package/src/value-objects/index.ts +10 -0
- package/src/value-objects/integer-value.ts +29 -0
- package/src/value-objects/phone-value.ts +53 -0
- package/src/value-objects/slug-value.ts +25 -0
- package/src/value-objects/string-value.ts +27 -0
- package/src/value-objects/uuid-value.ts +34 -0
- package/src/value-objects/value-object.ts +7 -0
- package/tsconfig.json +46 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { expectTypeOf } from "expect-type";
|
|
2
|
+
|
|
3
|
+
import { ValueObject, UUIDValue } from "../../src/value-objects";
|
|
4
|
+
|
|
5
|
+
class TestUUIDValue extends UUIDValue {
|
|
6
|
+
readonly attributeName = "test";
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
describe("UUIDValue", () => {
|
|
10
|
+
it('should implement "ValueObject" interface', () => {
|
|
11
|
+
expectTypeOf<UUIDValue>().toExtend<ValueObject>();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('should have a "valueType" with "UUID" as value', () => {
|
|
15
|
+
const testUUIDvalue = new TestUUIDValue();
|
|
16
|
+
|
|
17
|
+
expect(testUUIDvalue.valueType).toEqual("UUID");
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should have a "value" property of type string | undefined', () => {
|
|
21
|
+
expectTypeOf<UUIDValue["value"]>().toEqualTypeOf<string | undefined>();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should have a "optional" property of type boolean', () => {
|
|
25
|
+
expectTypeOf<UUIDValue["optional"]>().toBeBoolean();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should define the "equals" method', () => {
|
|
29
|
+
expectTypeOf<UUIDValue["equals"]>().toEqualTypeOf<(valueObject: unknown) => boolean>();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe('when "value" is present', () => {
|
|
33
|
+
describe('when "value" is valid', () => {
|
|
34
|
+
it('should have a getter "isValid" that returns true', () => {
|
|
35
|
+
const testUUIDvalue = new TestUUIDValue("87a00bc1-c586-4d23-bfc7-dd637628777c");
|
|
36
|
+
|
|
37
|
+
expect(testUUIDvalue.isValid).toBeTruthy();
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('when "value" is not valid', () => {
|
|
42
|
+
it('should have a getter "isValid" that returns false', () => {
|
|
43
|
+
const testUUIDvalue = new TestUUIDValue("dummy-uuid-12346-5734");
|
|
44
|
+
|
|
45
|
+
expect(testUUIDvalue.isValid).toBeFalsy();
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('when "value" is not present', () => {
|
|
51
|
+
describe('when "value" is optional', () => {
|
|
52
|
+
it('should have a getter "isValid" that returns true', () => {
|
|
53
|
+
const testUUIDvalue = new TestUUIDValue(undefined, true);
|
|
54
|
+
|
|
55
|
+
expect(testUUIDvalue.isValid).toBeTruthy();
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
describe('when "value" is not optional', () => {
|
|
60
|
+
it('should have a getter "isValid" that runs the validations normally and returns false', () => {
|
|
61
|
+
const testUUIDvalue = new TestUUIDValue(undefined, false);
|
|
62
|
+
|
|
63
|
+
expect(testUUIDvalue.isValid).toBeFalsy();
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { expectTypeOf } from "expect-type";
|
|
2
|
+
|
|
3
|
+
import { ValueObject } from "../../src/value-objects";
|
|
4
|
+
|
|
5
|
+
describe("ValueObject", () => {
|
|
6
|
+
it('should have a "value" property of type unknown', () => {
|
|
7
|
+
expectTypeOf<ValueObject>().toHaveProperty("value");
|
|
8
|
+
expectTypeOf<ValueObject['value']>().toBeUnknown();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('should have a "isValid" property of type boolean', () => {
|
|
12
|
+
expectTypeOf<ValueObject>().toHaveProperty("isValid");
|
|
13
|
+
expectTypeOf<ValueObject['isValid']>().toBeBoolean();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should have a "valueType" property of type string', () => {
|
|
17
|
+
expectTypeOf<ValueObject>().toHaveProperty("valueType");
|
|
18
|
+
expectTypeOf<ValueObject['valueType']>().toBeString();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should have a "attributeName" property of type string', () => {
|
|
22
|
+
expectTypeOf<ValueObject>().toHaveProperty("attributeName");
|
|
23
|
+
expectTypeOf<ValueObject['attributeName']>().toBeString();
|
|
24
|
+
});
|
|
25
|
+
});
|
package/jest.config.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// jest.config.js
|
|
2
|
+
const { defaults: tsjPreset } = require("ts-jest/presets");
|
|
3
|
+
const { transform } = require("typescript");
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
preset: "ts-jest/presets/default-esm",
|
|
7
|
+
testEnvironment: "node",
|
|
8
|
+
extensionsToTreatAsEsm: [".ts"],
|
|
9
|
+
transform: {
|
|
10
|
+
'^.+\\.(ts|tsx)$': ['ts-jest', { useESM: true }],
|
|
11
|
+
},
|
|
12
|
+
moduleFileExtensions: ["ts", "js", "json", "node"],
|
|
13
|
+
testMatch: ["**/__tests__/**/*.ts", "**/?(*.)+(spec|test).ts"],
|
|
14
|
+
collectCoverageFrom: [
|
|
15
|
+
"src/**/*.ts",
|
|
16
|
+
"!src/**/*.d.ts",
|
|
17
|
+
"!src/index.ts",
|
|
18
|
+
],
|
|
19
|
+
coverageDirectory: "coverage",
|
|
20
|
+
coverageReporters: ["text", "lcov", "html"],
|
|
21
|
+
moduleNameMapper: {
|
|
22
|
+
"^@schorts/shared-kernel/(.*)$": "<rootDir>/src/$1",
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@schorts/shared-kernel",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A modular, type-safe foundation for building expressive, maintainable applications. This package provides core abstractions for domain modeling, HTTP integration, authentication, state management, and more — designed to be framework-agnostic and highly extensible.",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
"./auth": {
|
|
9
|
+
"import": "./dist/auth/index.js",
|
|
10
|
+
"types": "./dist/auth/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"./criteria": {
|
|
13
|
+
"import": "./dist/criteria/index.js",
|
|
14
|
+
"types": "./dist/criteria/index.d.ts"
|
|
15
|
+
},
|
|
16
|
+
"./domain-events": {
|
|
17
|
+
"import": "./dist/domain-events/index.js",
|
|
18
|
+
"types": "./dist/domain-events/index.d.ts"
|
|
19
|
+
},
|
|
20
|
+
"./entities": {
|
|
21
|
+
"import": "./dist/entities/index.js",
|
|
22
|
+
"types": "./dist/entities/index.d.ts"
|
|
23
|
+
},
|
|
24
|
+
"./formatters": {
|
|
25
|
+
"import": "./dist/formatters/index.js",
|
|
26
|
+
"types": "./dist/formatters/index.d.ts"
|
|
27
|
+
},
|
|
28
|
+
"./http": {
|
|
29
|
+
"import": "./dist/http/index.js",
|
|
30
|
+
"types": "./dist/http/index.d.ts"
|
|
31
|
+
},
|
|
32
|
+
"./json-api": {
|
|
33
|
+
"import": "./dist/json-api/index.js",
|
|
34
|
+
"types": "./dist/json-api/index.d.ts"
|
|
35
|
+
},
|
|
36
|
+
"./messages": {
|
|
37
|
+
"import": "./dist/messages/index.js",
|
|
38
|
+
"types": "./dist/messages/index.d.ts"
|
|
39
|
+
},
|
|
40
|
+
"./models": {
|
|
41
|
+
"import": "./dist/models/index.js",
|
|
42
|
+
"types": "./dist/models/index.d.ts"
|
|
43
|
+
},
|
|
44
|
+
"./utils": {
|
|
45
|
+
"import": "./dist/utils/index.js",
|
|
46
|
+
"types": "./dist/utils/index.d.ts"
|
|
47
|
+
},
|
|
48
|
+
"./state-manager": {
|
|
49
|
+
"import": "./dist/state-manager/index.js",
|
|
50
|
+
"types": "./dist/state-manager/index.d.ts"
|
|
51
|
+
},
|
|
52
|
+
"./value-objects": {
|
|
53
|
+
"import": "./dist/value-objects/index.js",
|
|
54
|
+
"types": "./dist/value-objects/index.d.ts"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "tsc",
|
|
59
|
+
"test": "jest",
|
|
60
|
+
"test:watch": "jest --watch",
|
|
61
|
+
"test:coverage": "jest --coverage",
|
|
62
|
+
"test:ci": "jest --ci --coverage --watchAll=false"
|
|
63
|
+
},
|
|
64
|
+
"author": "Jorge Castillo (https://github.com/schorts)",
|
|
65
|
+
"license": "LGPL-3.0-or-later",
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@jest/globals": "^30.1.2",
|
|
68
|
+
"@types/jest": "^30.0.0",
|
|
69
|
+
"@types/node": "^24.5.2",
|
|
70
|
+
"expect-type": "^1.2.2",
|
|
71
|
+
"jest": "^30.1.3",
|
|
72
|
+
"jest-html-reporter": "^4.3.0",
|
|
73
|
+
"ts-jest": "^29.4.4",
|
|
74
|
+
"typescript": "^5.9.2"
|
|
75
|
+
},
|
|
76
|
+
"dependencies": {
|
|
77
|
+
"ansi-escapes": "^4.3.2",
|
|
78
|
+
"ansi-regex": "^6.2.2",
|
|
79
|
+
"ansi-styles": "^4.3.0",
|
|
80
|
+
"anymatch": "^3.1.3",
|
|
81
|
+
"argparse": "^1.0.10",
|
|
82
|
+
"babel-jest": "^30.1.2",
|
|
83
|
+
"babel-plugin-istanbul": "^7.0.1",
|
|
84
|
+
"babel-plugin-jest-hoist": "^30.0.1",
|
|
85
|
+
"babel-preset-current-node-syntax": "^1.2.0",
|
|
86
|
+
"babel-preset-jest": "^30.0.1",
|
|
87
|
+
"balanced-match": "^1.0.2",
|
|
88
|
+
"baseline-browser-mapping": "^2.8.6",
|
|
89
|
+
"brace-expansion": "^2.0.2",
|
|
90
|
+
"braces": "^3.0.3",
|
|
91
|
+
"browserslist": "^4.26.2",
|
|
92
|
+
"bs-logger": "^0.2.6",
|
|
93
|
+
"bser": "^2.1.1",
|
|
94
|
+
"buffer-from": "^1.1.2",
|
|
95
|
+
"callsites": "^3.1.0",
|
|
96
|
+
"camelcase": "^5.3.1",
|
|
97
|
+
"caniuse-lite": "^1.0.30001743",
|
|
98
|
+
"chalk": "^4.1.2",
|
|
99
|
+
"char-regex": "^1.0.2",
|
|
100
|
+
"ci-info": "^4.3.0",
|
|
101
|
+
"cjs-module-lexer": "^2.1.0",
|
|
102
|
+
"cliui": "^8.0.1",
|
|
103
|
+
"co": "^4.6.0",
|
|
104
|
+
"collect-v8-coverage": "^1.0.2",
|
|
105
|
+
"color-convert": "^2.0.1",
|
|
106
|
+
"color-name": "^1.1.4",
|
|
107
|
+
"concat-map": "^0.0.1",
|
|
108
|
+
"convert-source-map": "^2.0.0",
|
|
109
|
+
"cross-spawn": "^7.0.6",
|
|
110
|
+
"dateformat": "^3.0.2",
|
|
111
|
+
"debug": "^4.4.3",
|
|
112
|
+
"dedent": "^1.7.0",
|
|
113
|
+
"deepmerge": "^4.3.1",
|
|
114
|
+
"detect-newline": "^3.1.0",
|
|
115
|
+
"eastasianwidth": "^0.2.0",
|
|
116
|
+
"electron-to-chromium": "^1.5.223",
|
|
117
|
+
"emittery": "^0.13.1",
|
|
118
|
+
"emoji-regex": "^9.2.2",
|
|
119
|
+
"error-ex": "^1.3.4",
|
|
120
|
+
"escalade": "^3.2.0",
|
|
121
|
+
"escape-string-regexp": "^2.0.0",
|
|
122
|
+
"esprima": "^4.0.1",
|
|
123
|
+
"execa": "^5.1.1",
|
|
124
|
+
"exit-x": "^0.2.2",
|
|
125
|
+
"expect": "^30.1.2",
|
|
126
|
+
"fast-json-stable-stringify": "^2.1.0",
|
|
127
|
+
"fb-watchman": "^2.0.2",
|
|
128
|
+
"fill-range": "^7.1.1",
|
|
129
|
+
"find-up": "^4.1.0",
|
|
130
|
+
"foreground-child": "^3.3.1",
|
|
131
|
+
"fs.realpath": "^1.0.0",
|
|
132
|
+
"gensync": "^1.0.0-beta.2",
|
|
133
|
+
"get-caller-file": "^2.0.5",
|
|
134
|
+
"get-package-type": "^0.1.0",
|
|
135
|
+
"get-stream": "^6.0.1",
|
|
136
|
+
"glob": "^10.4.5",
|
|
137
|
+
"graceful-fs": "^4.2.11",
|
|
138
|
+
"handlebars": "^4.7.8",
|
|
139
|
+
"has-flag": "^4.0.0",
|
|
140
|
+
"html-escaper": "^2.0.2",
|
|
141
|
+
"human-signals": "^2.1.0",
|
|
142
|
+
"import-local": "^3.2.0",
|
|
143
|
+
"imurmurhash": "^0.1.4",
|
|
144
|
+
"inflight": "^1.0.6",
|
|
145
|
+
"inherits": "^2.0.4",
|
|
146
|
+
"is-arrayish": "^0.2.1",
|
|
147
|
+
"is-fullwidth-code-point": "^3.0.0",
|
|
148
|
+
"is-generator-fn": "^2.1.0",
|
|
149
|
+
"is-number": "^7.0.0",
|
|
150
|
+
"is-stream": "^2.0.1",
|
|
151
|
+
"isexe": "^2.0.0",
|
|
152
|
+
"istanbul-lib-coverage": "^3.2.2",
|
|
153
|
+
"istanbul-lib-instrument": "^6.0.3",
|
|
154
|
+
"istanbul-lib-report": "^3.0.1",
|
|
155
|
+
"istanbul-lib-source-maps": "^5.0.6",
|
|
156
|
+
"istanbul-reports": "^3.2.0",
|
|
157
|
+
"jackspeak": "^3.4.3",
|
|
158
|
+
"jest-changed-files": "^30.0.5",
|
|
159
|
+
"jest-circus": "^30.1.3",
|
|
160
|
+
"jest-cli": "^30.1.3",
|
|
161
|
+
"jest-config": "^30.1.3",
|
|
162
|
+
"jest-diff": "^30.1.2",
|
|
163
|
+
"jest-docblock": "^30.0.1",
|
|
164
|
+
"jest-each": "^30.1.0",
|
|
165
|
+
"jest-environment-node": "^30.1.2",
|
|
166
|
+
"jest-haste-map": "^30.1.0",
|
|
167
|
+
"jest-leak-detector": "^30.1.0",
|
|
168
|
+
"jest-matcher-utils": "^30.1.2",
|
|
169
|
+
"jest-message-util": "^30.1.0",
|
|
170
|
+
"jest-mock": "^30.0.5",
|
|
171
|
+
"jest-pnp-resolver": "^1.2.3",
|
|
172
|
+
"jest-regex-util": "^30.0.1",
|
|
173
|
+
"jest-resolve": "^30.1.3",
|
|
174
|
+
"jest-resolve-dependencies": "^30.1.3",
|
|
175
|
+
"jest-runner": "^30.1.3",
|
|
176
|
+
"jest-runtime": "^30.1.3",
|
|
177
|
+
"jest-snapshot": "^30.1.2",
|
|
178
|
+
"jest-util": "^30.0.5",
|
|
179
|
+
"jest-validate": "^30.1.0",
|
|
180
|
+
"jest-watcher": "^30.1.3",
|
|
181
|
+
"jest-worker": "^30.1.0",
|
|
182
|
+
"js-tokens": "^4.0.0",
|
|
183
|
+
"js-yaml": "^3.14.1",
|
|
184
|
+
"jsesc": "^3.1.0",
|
|
185
|
+
"json-parse-even-better-errors": "^2.3.1",
|
|
186
|
+
"json5": "^2.2.3",
|
|
187
|
+
"leven": "^3.1.0",
|
|
188
|
+
"lines-and-columns": "^1.2.4",
|
|
189
|
+
"locate-path": "^5.0.0",
|
|
190
|
+
"lodash.memoize": "^4.1.2",
|
|
191
|
+
"lru-cache": "^5.1.1",
|
|
192
|
+
"make-dir": "^4.0.0",
|
|
193
|
+
"make-error": "^1.3.6",
|
|
194
|
+
"makeerror": "^1.0.12",
|
|
195
|
+
"merge-stream": "^2.0.0",
|
|
196
|
+
"micromatch": "^4.0.8",
|
|
197
|
+
"mimic-fn": "^2.1.0",
|
|
198
|
+
"minimatch": "^9.0.5",
|
|
199
|
+
"minimist": "^1.2.8",
|
|
200
|
+
"minipass": "^7.1.2",
|
|
201
|
+
"mkdirp": "^1.0.4",
|
|
202
|
+
"ms": "^2.1.3",
|
|
203
|
+
"napi-postinstall": "^0.3.3",
|
|
204
|
+
"natural-compare": "^1.4.0",
|
|
205
|
+
"neo-async": "^2.6.2",
|
|
206
|
+
"node-int64": "^0.4.0",
|
|
207
|
+
"node-releases": "^2.0.21",
|
|
208
|
+
"normalize-path": "^3.0.0",
|
|
209
|
+
"npm-run-path": "^4.0.1",
|
|
210
|
+
"once": "^1.4.0",
|
|
211
|
+
"onetime": "^5.1.2",
|
|
212
|
+
"p-limit": "^3.1.0",
|
|
213
|
+
"p-locate": "^4.1.0",
|
|
214
|
+
"p-try": "^2.2.0",
|
|
215
|
+
"package-json-from-dist": "^1.0.1",
|
|
216
|
+
"parse-json": "^5.2.0",
|
|
217
|
+
"path-exists": "^4.0.0",
|
|
218
|
+
"path-is-absolute": "^1.0.1",
|
|
219
|
+
"path-key": "^3.1.1",
|
|
220
|
+
"path-scurry": "^1.11.1",
|
|
221
|
+
"picocolors": "^1.1.1",
|
|
222
|
+
"picomatch": "^2.3.1",
|
|
223
|
+
"pirates": "^4.0.7",
|
|
224
|
+
"pkg-dir": "^4.2.0",
|
|
225
|
+
"pretty-format": "^30.0.5",
|
|
226
|
+
"pure-rand": "^7.0.1",
|
|
227
|
+
"react-is": "^18.3.1",
|
|
228
|
+
"require-directory": "^2.1.1",
|
|
229
|
+
"resolve-cwd": "^3.0.0",
|
|
230
|
+
"resolve-from": "^5.0.0",
|
|
231
|
+
"semver": "^6.3.1",
|
|
232
|
+
"shebang-command": "^2.0.0",
|
|
233
|
+
"shebang-regex": "^3.0.0",
|
|
234
|
+
"signal-exit": "^4.1.0",
|
|
235
|
+
"slash": "^3.0.0",
|
|
236
|
+
"source-map": "^0.6.1",
|
|
237
|
+
"source-map-support": "^0.5.13",
|
|
238
|
+
"sprintf-js": "^1.0.3",
|
|
239
|
+
"stack-utils": "^2.0.6",
|
|
240
|
+
"string-length": "^4.0.2",
|
|
241
|
+
"string-width": "^5.1.2",
|
|
242
|
+
"string-width-cjs": "^4.2.3",
|
|
243
|
+
"strip-ansi": "^7.1.2",
|
|
244
|
+
"strip-ansi-cjs": "^6.0.1",
|
|
245
|
+
"strip-bom": "^4.0.0",
|
|
246
|
+
"strip-final-newline": "^2.0.0",
|
|
247
|
+
"strip-json-comments": "^3.1.1",
|
|
248
|
+
"supports-color": "^7.2.0",
|
|
249
|
+
"synckit": "^0.11.11",
|
|
250
|
+
"test-exclude": "^6.0.0",
|
|
251
|
+
"tmpl": "^1.0.5",
|
|
252
|
+
"to-regex-range": "^5.0.1",
|
|
253
|
+
"type-detect": "^4.0.8",
|
|
254
|
+
"type-fest": "^0.21.3",
|
|
255
|
+
"uglify-js": "^3.19.3",
|
|
256
|
+
"undici-types": "^7.12.0",
|
|
257
|
+
"unrs-resolver": "^1.11.1",
|
|
258
|
+
"update-browserslist-db": "^1.1.3",
|
|
259
|
+
"v8-to-istanbul": "^9.3.0",
|
|
260
|
+
"walker": "^1.0.8",
|
|
261
|
+
"which": "^2.0.2",
|
|
262
|
+
"wordwrap": "^1.0.0",
|
|
263
|
+
"wrap-ansi": "^8.1.0",
|
|
264
|
+
"wrap-ansi-cjs": "^7.0.0",
|
|
265
|
+
"wrappy": "^1.0.2",
|
|
266
|
+
"write-file-atomic": "^5.0.1",
|
|
267
|
+
"xmlbuilder": "^15.0.0",
|
|
268
|
+
"y18n": "^5.0.8",
|
|
269
|
+
"yallist": "^3.1.1",
|
|
270
|
+
"yargs": "^17.7.2",
|
|
271
|
+
"yargs-parser": "^21.1.1",
|
|
272
|
+
"yocto-queue": "^0.1.0"
|
|
273
|
+
},
|
|
274
|
+
"repository": {
|
|
275
|
+
"type": "git",
|
|
276
|
+
"url": "git+https://github.com/schorts/shared-kernel.git"
|
|
277
|
+
},
|
|
278
|
+
"keywords": [
|
|
279
|
+
"shared-kernel",
|
|
280
|
+
"auth",
|
|
281
|
+
"jsonapi",
|
|
282
|
+
"kernel",
|
|
283
|
+
"value-objects"
|
|
284
|
+
],
|
|
285
|
+
"bugs": {
|
|
286
|
+
"url": "https://github.com/schorts/shared-kernel/issues"
|
|
287
|
+
},
|
|
288
|
+
"homepage": "https://github.com/schorts/shared-kernel#readme"
|
|
289
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Entity } from "../entities";
|
|
2
|
+
import { BaseModel } from "../models";
|
|
3
|
+
|
|
4
|
+
export interface AuthProvider<UserEntity extends Entity<BaseModel>> {
|
|
5
|
+
authenticate(...args: any[]): Promise<void>;
|
|
6
|
+
logout(): Promise<void>;
|
|
7
|
+
isAuthenticated(): Promise<boolean>;
|
|
8
|
+
currentUser(): Promise<UserEntity | null>;
|
|
9
|
+
onAuthChange(callback: (user: UserEntity | null) => void): () => void;
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { NotAuthenticated } from "./not-authenticated";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export class NotAuthenticated extends Error {}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { AuthProvider } from "./auth-provider";
|
|
2
|
+
import { NotAuthenticated } from './exceptions';
|
|
3
|
+
|
|
4
|
+
export function RequireAuth(onFail?: () => any) {
|
|
5
|
+
function wrapper<T extends { authProvider?: AuthProvider<any> }, A extends any[], R>(
|
|
6
|
+
originalMethod: (this: T, ...args: A) => Promise<R>
|
|
7
|
+
): (this: T, ...args: A) => Promise<R> {
|
|
8
|
+
return async function (this: T, ...args: A): Promise<R> {
|
|
9
|
+
if (!this.authProvider) {
|
|
10
|
+
throw new Error("authProvider: AuthProvider is required on this instance");
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const isAuthenticated = await this.authProvider.isAuthenticated();
|
|
14
|
+
|
|
15
|
+
if (!isAuthenticated) {
|
|
16
|
+
if (onFail) {
|
|
17
|
+
return onFail();
|
|
18
|
+
} else {
|
|
19
|
+
throw new NotAuthenticated();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return await originalMethod.apply(this, args);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return function (...args: any[]) {
|
|
28
|
+
if (args.length === 3 && typeof args[2] === 'object') {
|
|
29
|
+
const descriptor = args[2] as PropertyDescriptor;
|
|
30
|
+
descriptor.value = wrapper(descriptor.value);
|
|
31
|
+
return descriptor;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (args.length === 2 && typeof args[1] === 'object' && 'kind' in args[1]) {
|
|
35
|
+
const [originalMethod] = args;
|
|
36
|
+
return wrapper(originalMethod);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
throw new Error("RequireAuth decorator used incorrectly");
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { FilterCriterion } from "./filter-criterion";
|
|
2
|
+
import { Order } from "./order";
|
|
3
|
+
import { Operator } from "./operator";
|
|
4
|
+
import { Direction } from "./direction";
|
|
5
|
+
import { OffsetNotValid, LimitNotValid } from "./exceptions";
|
|
6
|
+
|
|
7
|
+
export class Criteria {
|
|
8
|
+
readonly filters: Record<string, FilterCriterion> = {};
|
|
9
|
+
readonly orders: Array<Order> = [];
|
|
10
|
+
limit?: number;
|
|
11
|
+
offset?: number;
|
|
12
|
+
|
|
13
|
+
where(
|
|
14
|
+
field: string,
|
|
15
|
+
operator: Operator,
|
|
16
|
+
value: any,
|
|
17
|
+
): Criteria {
|
|
18
|
+
this.filters[field] = { value, operator };
|
|
19
|
+
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
orderBy(
|
|
24
|
+
field: string,
|
|
25
|
+
direction: Direction = "ASC",
|
|
26
|
+
): Criteria {
|
|
27
|
+
this.orders.push({ field, direction });
|
|
28
|
+
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
limitResults(limit: number): Criteria {
|
|
33
|
+
if (limit < 1) {
|
|
34
|
+
throw new LimitNotValid();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
this.limit = limit;
|
|
38
|
+
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
offsetResults(offset: number): Criteria {
|
|
43
|
+
if (offset < 1) {
|
|
44
|
+
throw new OffsetNotValid();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
this.offset = offset;
|
|
48
|
+
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Direction = "ASC" | "DESC";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export class LimitNotValid extends Error {}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export class OffsetNotValid extends Error {}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { Operator } from "./operator";
|
|
2
|
+
export type { Order } from "./order";
|
|
3
|
+
export type { FilterCriterion } from "./filter-criterion";
|
|
4
|
+
export type { Direction } from "./direction";
|
|
5
|
+
|
|
6
|
+
export { Criteria } from "./criteria";
|
|
7
|
+
export { OffsetNotValid, LimitNotValid } from "./exceptions";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Message } from "../messages";
|
|
2
|
+
import { DomainEventPrimitives } from "./domain-event-primitives";
|
|
3
|
+
|
|
4
|
+
export abstract class DomainEvent<PayloadSchema = {}> implements Message<DomainEventPrimitives<PayloadSchema>> {
|
|
5
|
+
constructor(
|
|
6
|
+
readonly id: string,
|
|
7
|
+
readonly occurredAt: Date,
|
|
8
|
+
readonly type: string,
|
|
9
|
+
readonly version: number,
|
|
10
|
+
readonly payload: PayloadSchema,
|
|
11
|
+
) {}
|
|
12
|
+
|
|
13
|
+
abstract getEventName(): string;
|
|
14
|
+
abstract toPrimitives(): DomainEventPrimitives<PayloadSchema>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ValueObject } from "../value-objects";
|
|
2
|
+
import { BaseModel } from "../models";
|
|
3
|
+
import { DomainEvent } from "../domain-events";
|
|
4
|
+
|
|
5
|
+
export abstract class Entity<Model extends BaseModel> {
|
|
6
|
+
private domainEvents: Array<DomainEvent> = [];
|
|
7
|
+
|
|
8
|
+
constructor(readonly id: ValueObject) {}
|
|
9
|
+
|
|
10
|
+
pullDomainEvents(): Array<DomainEvent> {
|
|
11
|
+
const domainEvents = [...this.domainEvents];
|
|
12
|
+
this.domainEvents = [];
|
|
13
|
+
|
|
14
|
+
return domainEvents;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
recordDomainEvent(domainEvent: DomainEvent): void {
|
|
18
|
+
this.domainEvents.push(domainEvent);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
abstract toPrimitives(): Model;
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Entity } from "./entity";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PascalCamelToSnake } from "./pascal-camel-to-snake";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { HTTPException } from "./http-exception";
|