@almatar/branding 0.2.0 → 1.0.0-beta.3
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/lib/index.d.ts +6 -0
- package/lib/index.js +14 -5
- package/lib/lib/AlmatarBranding.js +6 -9
- package/lib/lib/BrandIdentifier.d.ts +2 -2
- package/lib/lib/BrandIdentifier.js +72 -88
- package/lib/lib/BrandManager.d.ts +5 -0
- package/lib/lib/BrandManager.js +178 -127
- package/lib/lib/Models/BrandModel.js +3 -4
- package/lib/lib/Models/EmployeeBrandModel.js +3 -4
- package/lib/lib/Storage.js +78 -151
- package/lib/lib/TenantModel/Mongoose/MultiTenant.js +13 -17
- package/lib/lib/TenantModel/MongooseModel.js +56 -39
- package/lib/lib/TenantModel/NestMongoose/TenantMongooseModule.js +12 -33
- package/lib/lib/TenantModel/NestMongoose/mongoose.providers.d.ts +0 -24
- package/lib/lib/TenantModel/NestMongoose/mongoose.providers.js +8 -9
- package/lib/lib/TenantModel/TypeORM/TenantEntitySubscriber.d.ts +27 -0
- package/lib/lib/TenantModel/TypeORM/TenantEntitySubscriber.js +68 -0
- package/lib/lib/TenantModel/TypeORM/TenantHttpInterceptor.d.ts +26 -0
- package/lib/lib/TenantModel/TypeORM/TenantHttpInterceptor.js +92 -0
- package/lib/lib/TenantModel/TypeORM/TenantRepository.d.ts +58 -0
- package/lib/lib/TenantModel/TypeORM/TenantRepository.js +281 -0
- package/lib/lib/request/PromiseRequest.js +37 -56
- package/lib/lib/request/TenantRequest.d.ts +4 -1
- package/lib/lib/request/TenantRequest.js +38 -68
- package/package.json +31 -25
package/lib/lib/Storage.js
CHANGED
|
@@ -1,181 +1,108 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
function ContextNamespace() {
|
|
45
|
-
}
|
|
3
|
+
const BrandIdentifier_1 = require("./BrandIdentifier");
|
|
4
|
+
const createNamespace = require('cls-hooked').createNamespace;
|
|
5
|
+
const namespaceName = 'request';
|
|
6
|
+
const ns = createNamespace(namespaceName);
|
|
7
|
+
class ContextNamespace {
|
|
46
8
|
/* Express Start */
|
|
47
|
-
|
|
48
|
-
var _this = this;
|
|
9
|
+
static bindENamespace(req, res, next) {
|
|
49
10
|
ns.bindEmitter(req);
|
|
50
11
|
ns.bindEmitter(res);
|
|
51
|
-
ns.run(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
case 0:
|
|
56
|
-
brandIdentifier = new BrandIdentifier_1.BrandIdentifier('express');
|
|
57
|
-
return [4 /*yield*/, brandIdentifier.getBrands()];
|
|
58
|
-
case 1:
|
|
59
|
-
_a.sent();
|
|
60
|
-
next();
|
|
61
|
-
return [2 /*return*/];
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
}); });
|
|
65
|
-
};
|
|
66
|
-
ContextNamespace.setEBrand = function (req, res, next) {
|
|
67
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
68
|
-
var brandIdentifier, brand;
|
|
69
|
-
return __generator(this, function (_a) {
|
|
70
|
-
switch (_a.label) {
|
|
71
|
-
case 0:
|
|
72
|
-
brandIdentifier = new BrandIdentifier_1.BrandIdentifier('express');
|
|
73
|
-
return [4 /*yield*/, brandIdentifier.getBrand(req)];
|
|
74
|
-
case 1:
|
|
75
|
-
brand = _a.sent();
|
|
76
|
-
if (Array.isArray(brand)) {
|
|
77
|
-
ns.set('employeeBrands', brand);
|
|
78
|
-
next();
|
|
79
|
-
}
|
|
80
|
-
else if (typeof brand === 'string') {
|
|
81
|
-
ns.set('brand', brand);
|
|
82
|
-
next();
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
next(brand);
|
|
86
|
-
}
|
|
87
|
-
return [2 /*return*/];
|
|
88
|
-
}
|
|
89
|
-
});
|
|
12
|
+
ns.run(async () => {
|
|
13
|
+
const brandIdentifier = new BrandIdentifier_1.BrandIdentifier('express');
|
|
14
|
+
await brandIdentifier.getBrands();
|
|
15
|
+
next();
|
|
90
16
|
});
|
|
91
|
-
}
|
|
17
|
+
}
|
|
18
|
+
static async setEBrand(req, res, next) {
|
|
19
|
+
const brandIdentifier = new BrandIdentifier_1.BrandIdentifier('express');
|
|
20
|
+
const brand = await brandIdentifier.getBrand(req);
|
|
21
|
+
if (Array.isArray(brand)) {
|
|
22
|
+
// tslint:disable-next-line no-console
|
|
23
|
+
console.log('[ContextNamespace] Setting employeeBrands in context:', brand);
|
|
24
|
+
ns.set('employeeBrands', brand);
|
|
25
|
+
next();
|
|
26
|
+
}
|
|
27
|
+
else if (typeof brand === 'string') {
|
|
28
|
+
// tslint:disable-next-line no-console
|
|
29
|
+
console.log('[ContextNamespace] Setting brand in context:', brand);
|
|
30
|
+
ns.set('brand', brand);
|
|
31
|
+
next();
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
// Brand is null or undefined - set empty array for employeeBrands
|
|
35
|
+
// tslint:disable-next-line no-console
|
|
36
|
+
console.log('[ContextNamespace] No brand found, setting empty array for employeeBrands');
|
|
37
|
+
ns.set('employeeBrands', []);
|
|
38
|
+
next();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
92
41
|
/* Express End */
|
|
93
42
|
/* Hapi Start */
|
|
94
|
-
|
|
95
|
-
var _this = this;
|
|
43
|
+
static bindHNamespace(req, reply) {
|
|
96
44
|
ns.bindEmitter(req.raw.req);
|
|
97
45
|
ns.bindEmitter(req.raw.res);
|
|
98
|
-
ns.run(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
case 0:
|
|
103
|
-
brandIdentifier = new BrandIdentifier_1.BrandIdentifier('hapi');
|
|
104
|
-
return [4 /*yield*/, brandIdentifier.getBrands()];
|
|
105
|
-
case 1:
|
|
106
|
-
_a.sent();
|
|
107
|
-
reply();
|
|
108
|
-
return [2 /*return*/];
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
}); });
|
|
112
|
-
};
|
|
113
|
-
ContextNamespace.setHBrand = function (req, reply) {
|
|
114
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
115
|
-
var brandIdentifier, brand;
|
|
116
|
-
return __generator(this, function (_a) {
|
|
117
|
-
switch (_a.label) {
|
|
118
|
-
case 0:
|
|
119
|
-
brandIdentifier = new BrandIdentifier_1.BrandIdentifier('hapi');
|
|
120
|
-
return [4 /*yield*/, brandIdentifier.getBrand(req)];
|
|
121
|
-
case 1:
|
|
122
|
-
brand = _a.sent();
|
|
123
|
-
if (Array.isArray(brand)) {
|
|
124
|
-
ns.set('employeeBrands', brand);
|
|
125
|
-
reply();
|
|
126
|
-
}
|
|
127
|
-
else if (typeof brand === 'string') {
|
|
128
|
-
ns.set('brand', brand);
|
|
129
|
-
reply();
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
reply(brand);
|
|
133
|
-
}
|
|
134
|
-
return [2 /*return*/];
|
|
135
|
-
}
|
|
136
|
-
});
|
|
46
|
+
ns.run(async () => {
|
|
47
|
+
const brandIdentifier = new BrandIdentifier_1.BrandIdentifier('hapi');
|
|
48
|
+
await brandIdentifier.getBrands();
|
|
49
|
+
reply();
|
|
137
50
|
});
|
|
138
|
-
}
|
|
51
|
+
}
|
|
52
|
+
static async setHBrand(req, reply) {
|
|
53
|
+
const brandIdentifier = new BrandIdentifier_1.BrandIdentifier('hapi');
|
|
54
|
+
const brand = await brandIdentifier.getBrand(req);
|
|
55
|
+
if (Array.isArray(brand)) {
|
|
56
|
+
ns.set('employeeBrands', brand);
|
|
57
|
+
reply();
|
|
58
|
+
}
|
|
59
|
+
else if (typeof brand === 'string') {
|
|
60
|
+
ns.set('brand', brand);
|
|
61
|
+
reply();
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
reply(brand);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
139
67
|
/* Hapi End */
|
|
140
|
-
|
|
68
|
+
static setBrand(brand) {
|
|
141
69
|
if (Array.isArray(brand)) {
|
|
142
70
|
return ns.set('employeeBrands', brand);
|
|
143
71
|
}
|
|
144
72
|
else {
|
|
145
73
|
return ns.set('brand', brand);
|
|
146
74
|
}
|
|
147
|
-
}
|
|
148
|
-
|
|
75
|
+
}
|
|
76
|
+
static getBrand() {
|
|
149
77
|
return ns.get('brand');
|
|
150
|
-
}
|
|
151
|
-
|
|
78
|
+
}
|
|
79
|
+
static getEmployeeBrands() {
|
|
152
80
|
return ns.get('employeeBrands');
|
|
153
|
-
}
|
|
154
|
-
|
|
81
|
+
}
|
|
82
|
+
static getNamespace() {
|
|
155
83
|
return ns;
|
|
156
|
-
}
|
|
157
|
-
|
|
84
|
+
}
|
|
85
|
+
static setBrandsList(brandList) {
|
|
158
86
|
return ns.set('brandsList', brandList);
|
|
159
|
-
}
|
|
160
|
-
|
|
87
|
+
}
|
|
88
|
+
static setBrands(brands) {
|
|
161
89
|
return ns.set('brands', brands);
|
|
162
|
-
}
|
|
163
|
-
|
|
90
|
+
}
|
|
91
|
+
static getBrands() {
|
|
164
92
|
return ns.get('brands');
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
|
|
93
|
+
}
|
|
94
|
+
static getDefaultBrand() {
|
|
95
|
+
const brandIdentifier = new BrandIdentifier_1.BrandIdentifier('hapi');
|
|
168
96
|
return brandIdentifier.getDefaultBrand();
|
|
169
|
-
}
|
|
170
|
-
|
|
97
|
+
}
|
|
98
|
+
static isValidBrand(brand) {
|
|
171
99
|
var _a;
|
|
172
100
|
return (_a = ns.get('brands')) === null || _a === void 0 ? void 0 : _a.includes(brand);
|
|
173
|
-
}
|
|
174
|
-
|
|
101
|
+
}
|
|
102
|
+
static isBrandIncludesProduct(brandKey, product) {
|
|
175
103
|
var _a, _b;
|
|
176
|
-
|
|
104
|
+
const brand = (_a = ns.get('brandsList')) === null || _a === void 0 ? void 0 : _a.filter((b) => b.key === brandKey)[0];
|
|
177
105
|
return (_b = brand.products) === null || _b === void 0 ? void 0 : _b.includes(product);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
}());
|
|
106
|
+
}
|
|
107
|
+
}
|
|
181
108
|
exports.default = ContextNamespace;
|
|
@@ -1,24 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
const MongooseModel_1 = require("../MongooseModel");
|
|
4
|
+
class MultiTenant {
|
|
5
|
+
constructor(mongoose) {
|
|
6
6
|
this.mongoose = mongoose;
|
|
7
7
|
this.models = {};
|
|
8
8
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
var mongooseModel = new MongooseModel_1.MongooseModel(_this.mongoose);
|
|
15
|
-
return mongooseModel.createModel(name, schema, options, _this.models, skipBrand);
|
|
9
|
+
tenantModel(name, schema, options) {
|
|
10
|
+
return (props = {}) => {
|
|
11
|
+
const { skipBrand } = props;
|
|
12
|
+
const mongooseModel = new MongooseModel_1.MongooseModel(this.mongoose);
|
|
13
|
+
return mongooseModel.createModel(name, schema, options, this.models, skipBrand);
|
|
16
14
|
};
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return MultiTenant;
|
|
23
|
-
}());
|
|
15
|
+
}
|
|
16
|
+
tenantlessModel(name, schema, options) {
|
|
17
|
+
return () => this.mongoose.model(name, schema, options);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
24
20
|
exports.default = MultiTenant;
|
|
@@ -1,40 +1,52 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.MongooseModel = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
const Storage_1 = __importDefault(require("../Storage"));
|
|
8
|
+
class MongooseModel {
|
|
9
|
+
constructor(mongoose) {
|
|
7
10
|
this.mongoose = mongoose;
|
|
8
11
|
}
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
createModel(name, schema, options, existingModels, skipBrand) {
|
|
13
|
+
let brands = [];
|
|
11
14
|
if (!skipBrand) {
|
|
12
|
-
brands
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
// Check both x-employee-brands and x-brand from context
|
|
16
|
+
const employeeBrands = Storage_1.default.getEmployeeBrands();
|
|
17
|
+
const brand = Storage_1.default.getBrand();
|
|
18
|
+
brands = employeeBrands && employeeBrands.length > 0
|
|
19
|
+
? employeeBrands
|
|
20
|
+
: (brand ? [brand] : []);
|
|
15
21
|
schema.add({ brand: String });
|
|
16
22
|
this.addPreReadQueries(schema);
|
|
17
23
|
this.addPreAggregateQueries(schema);
|
|
18
24
|
this.addPreSaveQueries(schema);
|
|
19
25
|
this.addPreInsertManyQueries(schema);
|
|
20
26
|
}
|
|
21
|
-
|
|
27
|
+
const modelName = skipBrand || !Array.isArray(brands) ? name : `${name}-${brands.join('-')}`;
|
|
22
28
|
if (!existingModels[modelName]) {
|
|
23
29
|
existingModels[modelName] = this.mongoose.model(modelName, schema, options);
|
|
24
30
|
}
|
|
25
31
|
return existingModels[modelName];
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
}
|
|
33
|
+
addPreCondition(next) {
|
|
34
|
+
// Check both x-employee-brands and x-brand from context
|
|
35
|
+
// x-employee-brands can contain multiple brands (comma-separated), so use $in
|
|
36
|
+
const employeeBrands = Storage_1.default.getEmployeeBrands();
|
|
37
|
+
const brand = Storage_1.default.getBrand();
|
|
38
|
+
const brands = employeeBrands && employeeBrands.length > 0
|
|
39
|
+
? employeeBrands
|
|
40
|
+
: (brand ? [brand] : []);
|
|
41
|
+
if (Array.isArray(brands) && brands.length > 0) {
|
|
42
|
+
// Use $in to check if entity's brand (string or array element) is in the user's brands array
|
|
43
|
+
// This handles both: brand as string and brand as array element
|
|
32
44
|
// @ts-ignore
|
|
33
45
|
this.where({ brand: { $in: brands } });
|
|
34
46
|
}
|
|
35
47
|
next();
|
|
36
|
-
}
|
|
37
|
-
|
|
48
|
+
}
|
|
49
|
+
addPreReadQueries(schema) {
|
|
38
50
|
schema.pre('count', this.addPreCondition);
|
|
39
51
|
schema.pre('find', this.addPreCondition);
|
|
40
52
|
schema.pre('findOne', this.addPreCondition);
|
|
@@ -47,44 +59,49 @@ var MongooseModel = /** @class */ (function () {
|
|
|
47
59
|
schema.pre('deleteMany', this.addPreCondition);
|
|
48
60
|
schema.pre('deleteOne', this.addPreCondition);
|
|
49
61
|
schema.pre('remove', this.addPreCondition);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
62
|
+
}
|
|
63
|
+
addPreAggregate(next) {
|
|
64
|
+
// Check both x-employee-brands and x-brand from context
|
|
65
|
+
// x-employee-brands can contain multiple brands (comma-separated), so use $in
|
|
66
|
+
const employeeBrands = Storage_1.default.getEmployeeBrands();
|
|
67
|
+
const brand = Storage_1.default.getBrand();
|
|
68
|
+
const brands = employeeBrands && employeeBrands.length > 0
|
|
69
|
+
? employeeBrands
|
|
70
|
+
: (brand ? [brand] : []);
|
|
71
|
+
if (Array.isArray(brands) && brands.length > 0) {
|
|
72
|
+
// Use $in to check if entity's brand (string or array element) is in the user's brands array
|
|
73
|
+
// This handles both: brand as string and brand as array element
|
|
56
74
|
// @ts-ignore
|
|
57
75
|
this.pipeline().unshift({ $match: { brand: { $in: brands } } });
|
|
58
76
|
}
|
|
59
77
|
next();
|
|
60
|
-
}
|
|
61
|
-
|
|
78
|
+
}
|
|
79
|
+
addPreAggregateQueries(schema) {
|
|
62
80
|
schema.pre('aggregate', this.addPreAggregate);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
|
|
81
|
+
}
|
|
82
|
+
addPreSave(next) {
|
|
83
|
+
const brand = Storage_1.default.getBrand();
|
|
66
84
|
// @ts-ignore
|
|
67
85
|
if (!this.brand && brand) {
|
|
68
86
|
// @ts-ignore
|
|
69
87
|
this.brand = brand;
|
|
70
88
|
}
|
|
71
89
|
next();
|
|
72
|
-
}
|
|
73
|
-
|
|
90
|
+
}
|
|
91
|
+
addPreSaveQueries(schema) {
|
|
74
92
|
schema.pre('save', this.addPreSave);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
dataArray.forEach(
|
|
93
|
+
}
|
|
94
|
+
addPreInsertMany(next, dataArray) {
|
|
95
|
+
const brand = Storage_1.default.getBrand();
|
|
96
|
+
dataArray.forEach((data) => {
|
|
79
97
|
if (!data.tanentId && brand) {
|
|
80
98
|
data.brand = brand;
|
|
81
99
|
}
|
|
82
100
|
});
|
|
83
101
|
next();
|
|
84
|
-
}
|
|
85
|
-
|
|
102
|
+
}
|
|
103
|
+
addPreInsertManyQueries(schema) {
|
|
86
104
|
schema.pre('insertMany', this.addPreInsertMany);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
}());
|
|
105
|
+
}
|
|
106
|
+
}
|
|
90
107
|
exports.MongooseModel = MongooseModel;
|
|
@@ -1,19 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __extends = (this && this.__extends) || (function () {
|
|
3
|
-
var extendStatics = function (d, b) {
|
|
4
|
-
extendStatics = Object.setPrototypeOf ||
|
|
5
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
-
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
-
return extendStatics(d, b);
|
|
8
|
-
};
|
|
9
|
-
return function (d, b) {
|
|
10
|
-
if (typeof b !== "function" && b !== null)
|
|
11
|
-
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
-
extendStatics(d, b);
|
|
13
|
-
function __() { this.constructor = d; }
|
|
14
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
-
};
|
|
16
|
-
})();
|
|
17
2
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
18
3
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
19
4
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -21,27 +6,21 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
21
6
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
22
7
|
};
|
|
23
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
TenantMongooseModule.forFeature = function (models, connectionName) {
|
|
33
|
-
if (models === void 0) { models = []; }
|
|
34
|
-
connectionName = connectionName ? "".concat(connectionName, "Connection") : 'MongooseConnectionName';
|
|
35
|
-
var modelProviders = (0, mongoose_providers_1.createMongooseProviders)(connectionName, models);
|
|
9
|
+
const common_1 = require("@nestjs/common");
|
|
10
|
+
const mongoose_1 = require("@nestjs/mongoose");
|
|
11
|
+
const mongoose_providers_1 = require("./mongoose.providers");
|
|
12
|
+
let TenantMongooseModule = class TenantMongooseModule extends mongoose_1.MongooseModule {
|
|
13
|
+
static forFeature(models = [], connectionName) {
|
|
14
|
+
connectionName = connectionName ? `${connectionName}Connection` : 'MongooseConnectionName';
|
|
15
|
+
const modelProviders = mongoose_providers_1.createMongooseProviders(connectionName, models);
|
|
36
16
|
return {
|
|
37
17
|
module: mongoose_1.MongooseModule,
|
|
38
18
|
providers: modelProviders,
|
|
39
19
|
exports: modelProviders,
|
|
40
20
|
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}(mongoose_1.MongooseModule));
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
TenantMongooseModule = __decorate([
|
|
24
|
+
common_1.Module({})
|
|
25
|
+
], TenantMongooseModule);
|
|
47
26
|
exports.default = TenantMongooseModule;
|
|
@@ -1,27 +1,3 @@
|
|
|
1
|
-
/// <reference types="mongoose/types/aggregate" />
|
|
2
|
-
/// <reference types="mongoose/types/callback" />
|
|
3
|
-
/// <reference types="mongoose/types/collection" />
|
|
4
|
-
/// <reference types="mongoose/types/connection" />
|
|
5
|
-
/// <reference types="mongoose/types/cursor" />
|
|
6
|
-
/// <reference types="mongoose/types/document" />
|
|
7
|
-
/// <reference types="mongoose/types/error" />
|
|
8
|
-
/// <reference types="mongoose/types/expressions" />
|
|
9
|
-
/// <reference types="mongoose/types/helpers" />
|
|
10
|
-
/// <reference types="mongoose/types/middlewares" />
|
|
11
|
-
/// <reference types="mongoose/types/indexes" />
|
|
12
|
-
/// <reference types="mongoose/types/models" />
|
|
13
|
-
/// <reference types="mongoose/types/mongooseoptions" />
|
|
14
|
-
/// <reference types="mongoose/types/pipelinestage" />
|
|
15
|
-
/// <reference types="mongoose/types/populate" />
|
|
16
|
-
/// <reference types="mongoose/types/query" />
|
|
17
|
-
/// <reference types="mongoose/types/schemaoptions" />
|
|
18
|
-
/// <reference types="mongoose/types/schematypes" />
|
|
19
|
-
/// <reference types="mongoose/types/session" />
|
|
20
|
-
/// <reference types="mongoose/types/types" />
|
|
21
|
-
/// <reference types="mongoose/types/utility" />
|
|
22
|
-
/// <reference types="mongoose/types/validation" />
|
|
23
|
-
/// <reference types="mongoose/types/virtuals" />
|
|
24
|
-
/// <reference types="mongoose/types/inferschematype" />
|
|
25
1
|
import { Connection, Schema } from 'mongoose';
|
|
26
2
|
export declare function createMongooseProviders(connectionName?: string, models?: {
|
|
27
3
|
name: string;
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createMongooseProviders = void 0;
|
|
4
|
-
|
|
5
|
-
function createMongooseProviders(connectionName, models) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
var mongooseModel = new MongooseModel_1.MongooseModel(connection);
|
|
4
|
+
const MongooseModel_1 = require("../MongooseModel");
|
|
5
|
+
function createMongooseProviders(connectionName, models = []) {
|
|
6
|
+
const providers = (models || []).map(model => ({
|
|
7
|
+
provide: `${model.name}Model`,
|
|
8
|
+
useFactory: (connection) => {
|
|
9
|
+
const mongooseModel = new MongooseModel_1.MongooseModel(connection);
|
|
11
10
|
return mongooseModel.createModel(model.name, model.schema, model.collection, {});
|
|
12
11
|
},
|
|
13
|
-
inject: [
|
|
14
|
-
})
|
|
12
|
+
inject: [`${connectionName}Connection`],
|
|
13
|
+
}));
|
|
15
14
|
return providers;
|
|
16
15
|
}
|
|
17
16
|
exports.createMongooseProviders = createMongooseProviders;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { EntitySubscriberInterface, InsertEvent, LoadEvent } from 'typeorm';
|
|
2
|
+
/**
|
|
3
|
+
* TypeORM EntitySubscriber that automatically handles brand in all entities
|
|
4
|
+
* Similar to TenantModel in PHP/MongoDB - automatically adds brand on insert
|
|
5
|
+
*
|
|
6
|
+
* Register this subscriber in your DataSource options:
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { TenantEntitySubscriber } from '@almatar/branding';
|
|
9
|
+
*
|
|
10
|
+
* export const dataSourceOptions: DataSourceOptions = {
|
|
11
|
+
* // ... other options
|
|
12
|
+
* subscribers: [TenantEntitySubscriber],
|
|
13
|
+
* };
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export declare class TenantEntitySubscriber implements EntitySubscriberInterface {
|
|
17
|
+
/**
|
|
18
|
+
* Called before an entity is inserted
|
|
19
|
+
* Automatically adds brand from context if not provided
|
|
20
|
+
*/
|
|
21
|
+
beforeInsert(event: InsertEvent<any>): void | Promise<any>;
|
|
22
|
+
/**
|
|
23
|
+
* Called after an entity is loaded from the database
|
|
24
|
+
* Validates that loaded entities match brand context (for debugging)
|
|
25
|
+
*/
|
|
26
|
+
afterLoad(entity: any, event: LoadEvent<any>): void | Promise<any>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
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 __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.TenantEntitySubscriber = void 0;
|
|
13
|
+
const typeorm_1 = require("typeorm");
|
|
14
|
+
const Storage_1 = __importDefault(require("../../Storage"));
|
|
15
|
+
/**
|
|
16
|
+
* TypeORM EntitySubscriber that automatically handles brand in all entities
|
|
17
|
+
* Similar to TenantModel in PHP/MongoDB - automatically adds brand on insert
|
|
18
|
+
*
|
|
19
|
+
* Register this subscriber in your DataSource options:
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { TenantEntitySubscriber } from '@almatar/branding';
|
|
22
|
+
*
|
|
23
|
+
* export const dataSourceOptions: DataSourceOptions = {
|
|
24
|
+
* // ... other options
|
|
25
|
+
* subscribers: [TenantEntitySubscriber],
|
|
26
|
+
* };
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
let TenantEntitySubscriber = class TenantEntitySubscriber {
|
|
30
|
+
/**
|
|
31
|
+
* Called before an entity is inserted
|
|
32
|
+
* Automatically adds brand from context if not provided
|
|
33
|
+
*/
|
|
34
|
+
beforeInsert(event) {
|
|
35
|
+
const employeeBrands = Storage_1.default.getEmployeeBrands();
|
|
36
|
+
const brand = Storage_1.default.getBrand();
|
|
37
|
+
const contextBrands = employeeBrands || (brand ? [brand] : null);
|
|
38
|
+
// Only apply if entity has brand column and brand is not already set
|
|
39
|
+
if (event.metadata.columns.find((col) => col.propertyName === 'brand')) {
|
|
40
|
+
if (contextBrands && contextBrands.length > 0 && !event.entity.brand) {
|
|
41
|
+
event.entity.brand = contextBrands;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Called after an entity is loaded from the database
|
|
47
|
+
* Validates that loaded entities match brand context (for debugging)
|
|
48
|
+
*/
|
|
49
|
+
afterLoad(entity, event) {
|
|
50
|
+
const employeeBrands = Storage_1.default.getEmployeeBrands();
|
|
51
|
+
const brand = Storage_1.default.getBrand();
|
|
52
|
+
const contextBrands = employeeBrands || (brand ? [brand] : null);
|
|
53
|
+
if (contextBrands && contextBrands.length > 0 && entity.brand) {
|
|
54
|
+
const entityBrands = Array.isArray(entity.brand) ? entity.brand : [entity.brand];
|
|
55
|
+
const hasMatchingBrand = contextBrands.some((b) => entityBrands.includes(b));
|
|
56
|
+
if (!hasMatchingBrand) {
|
|
57
|
+
// Entity doesn't match brand - this shouldn't happen if TenantRepository is used
|
|
58
|
+
// Log for debugging (optional - can be removed)
|
|
59
|
+
// tslint:disable-next-line no-console
|
|
60
|
+
console.warn(`[TenantEntitySubscriber] Entity ${event.metadata.name} (id: ${entity.id}) doesn't match brand context`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
TenantEntitySubscriber = __decorate([
|
|
66
|
+
typeorm_1.EventSubscriber()
|
|
67
|
+
], TenantEntitySubscriber);
|
|
68
|
+
exports.TenantEntitySubscriber = TenantEntitySubscriber;
|