@almatar/branding 1.0.0-beta.2 → 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 +11 -5
- package/lib/lib/AlmatarBranding.js +6 -9
- package/lib/lib/BrandIdentifier.js +54 -110
- package/lib/lib/BrandManager.js +132 -192
- package/lib/lib/Models/BrandModel.js +3 -4
- package/lib/lib/Models/EmployeeBrandModel.js +3 -4
- package/lib/lib/Storage.js +78 -159
- package/lib/lib/TenantModel/Mongoose/MultiTenant.js +13 -17
- package/lib/lib/TenantModel/MongooseModel.js +53 -39
- package/lib/lib/TenantModel/NestMongoose/TenantMongooseModule.js +12 -31
- 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 -99
- package/lib/lib/request/TenantRequest.js +36 -98
- package/package.json +5 -1
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EmployeeBrandModel = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
class EmployeeBrandModel {
|
|
5
|
+
constructor(init) {
|
|
6
6
|
Object.assign(this, init);
|
|
7
7
|
}
|
|
8
|
-
|
|
9
|
-
}());
|
|
8
|
+
}
|
|
10
9
|
exports.EmployeeBrandModel = EmployeeBrandModel;
|
package/lib/lib/Storage.js
CHANGED
|
@@ -1,189 +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 (_) 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
|
-
// tslint:disable-next-line no-console
|
|
78
|
-
console.log('[ContextNamespace] Setting employeeBrands in context:', brand);
|
|
79
|
-
ns.set('employeeBrands', brand);
|
|
80
|
-
next();
|
|
81
|
-
}
|
|
82
|
-
else if (typeof brand === 'string') {
|
|
83
|
-
// tslint:disable-next-line no-console
|
|
84
|
-
console.log('[ContextNamespace] Setting brand in context:', brand);
|
|
85
|
-
ns.set('brand', brand);
|
|
86
|
-
next();
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
// Brand is null or undefined - set empty array for employeeBrands
|
|
90
|
-
// tslint:disable-next-line no-console
|
|
91
|
-
console.log('[ContextNamespace] No brand found, setting empty array for employeeBrands');
|
|
92
|
-
ns.set('employeeBrands', []);
|
|
93
|
-
next();
|
|
94
|
-
}
|
|
95
|
-
return [2 /*return*/];
|
|
96
|
-
}
|
|
97
|
-
});
|
|
12
|
+
ns.run(async () => {
|
|
13
|
+
const brandIdentifier = new BrandIdentifier_1.BrandIdentifier('express');
|
|
14
|
+
await brandIdentifier.getBrands();
|
|
15
|
+
next();
|
|
98
16
|
});
|
|
99
|
-
}
|
|
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
|
+
}
|
|
100
41
|
/* Express End */
|
|
101
42
|
/* Hapi Start */
|
|
102
|
-
|
|
103
|
-
var _this = this;
|
|
43
|
+
static bindHNamespace(req, reply) {
|
|
104
44
|
ns.bindEmitter(req.raw.req);
|
|
105
45
|
ns.bindEmitter(req.raw.res);
|
|
106
|
-
ns.run(
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
case 0:
|
|
111
|
-
brandIdentifier = new BrandIdentifier_1.BrandIdentifier('hapi');
|
|
112
|
-
return [4 /*yield*/, brandIdentifier.getBrands()];
|
|
113
|
-
case 1:
|
|
114
|
-
_a.sent();
|
|
115
|
-
reply();
|
|
116
|
-
return [2 /*return*/];
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
}); });
|
|
120
|
-
};
|
|
121
|
-
ContextNamespace.setHBrand = function (req, reply) {
|
|
122
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
123
|
-
var brandIdentifier, brand;
|
|
124
|
-
return __generator(this, function (_a) {
|
|
125
|
-
switch (_a.label) {
|
|
126
|
-
case 0:
|
|
127
|
-
brandIdentifier = new BrandIdentifier_1.BrandIdentifier('hapi');
|
|
128
|
-
return [4 /*yield*/, brandIdentifier.getBrand(req)];
|
|
129
|
-
case 1:
|
|
130
|
-
brand = _a.sent();
|
|
131
|
-
if (Array.isArray(brand)) {
|
|
132
|
-
ns.set('employeeBrands', brand);
|
|
133
|
-
reply();
|
|
134
|
-
}
|
|
135
|
-
else if (typeof brand === 'string') {
|
|
136
|
-
ns.set('brand', brand);
|
|
137
|
-
reply();
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
reply(brand);
|
|
141
|
-
}
|
|
142
|
-
return [2 /*return*/];
|
|
143
|
-
}
|
|
144
|
-
});
|
|
46
|
+
ns.run(async () => {
|
|
47
|
+
const brandIdentifier = new BrandIdentifier_1.BrandIdentifier('hapi');
|
|
48
|
+
await brandIdentifier.getBrands();
|
|
49
|
+
reply();
|
|
145
50
|
});
|
|
146
|
-
}
|
|
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
|
+
}
|
|
147
67
|
/* Hapi End */
|
|
148
|
-
|
|
68
|
+
static setBrand(brand) {
|
|
149
69
|
if (Array.isArray(brand)) {
|
|
150
70
|
return ns.set('employeeBrands', brand);
|
|
151
71
|
}
|
|
152
72
|
else {
|
|
153
73
|
return ns.set('brand', brand);
|
|
154
74
|
}
|
|
155
|
-
}
|
|
156
|
-
|
|
75
|
+
}
|
|
76
|
+
static getBrand() {
|
|
157
77
|
return ns.get('brand');
|
|
158
|
-
}
|
|
159
|
-
|
|
78
|
+
}
|
|
79
|
+
static getEmployeeBrands() {
|
|
160
80
|
return ns.get('employeeBrands');
|
|
161
|
-
}
|
|
162
|
-
|
|
81
|
+
}
|
|
82
|
+
static getNamespace() {
|
|
163
83
|
return ns;
|
|
164
|
-
}
|
|
165
|
-
|
|
84
|
+
}
|
|
85
|
+
static setBrandsList(brandList) {
|
|
166
86
|
return ns.set('brandsList', brandList);
|
|
167
|
-
}
|
|
168
|
-
|
|
87
|
+
}
|
|
88
|
+
static setBrands(brands) {
|
|
169
89
|
return ns.set('brands', brands);
|
|
170
|
-
}
|
|
171
|
-
|
|
90
|
+
}
|
|
91
|
+
static getBrands() {
|
|
172
92
|
return ns.get('brands');
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
|
|
93
|
+
}
|
|
94
|
+
static getDefaultBrand() {
|
|
95
|
+
const brandIdentifier = new BrandIdentifier_1.BrandIdentifier('hapi');
|
|
176
96
|
return brandIdentifier.getDefaultBrand();
|
|
177
|
-
}
|
|
178
|
-
|
|
97
|
+
}
|
|
98
|
+
static isValidBrand(brand) {
|
|
179
99
|
var _a;
|
|
180
100
|
return (_a = ns.get('brands')) === null || _a === void 0 ? void 0 : _a.includes(brand);
|
|
181
|
-
}
|
|
182
|
-
|
|
101
|
+
}
|
|
102
|
+
static isBrandIncludesProduct(brandKey, product) {
|
|
183
103
|
var _a, _b;
|
|
184
|
-
|
|
104
|
+
const brand = (_a = ns.get('brandsList')) === null || _a === void 0 ? void 0 : _a.filter((b) => b.key === brandKey)[0];
|
|
185
105
|
return (_b = brand.products) === null || _b === void 0 ? void 0 : _b.includes(product);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
}());
|
|
106
|
+
}
|
|
107
|
+
}
|
|
189
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;
|
|
@@ -4,40 +4,49 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.MongooseModel = void 0;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
const Storage_1 = __importDefault(require("../Storage"));
|
|
8
|
+
class MongooseModel {
|
|
9
|
+
constructor(mongoose) {
|
|
10
10
|
this.mongoose = mongoose;
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
createModel(name, schema, options, existingModels, skipBrand) {
|
|
13
|
+
let brands = [];
|
|
14
14
|
if (!skipBrand) {
|
|
15
|
-
brands
|
|
16
|
-
|
|
17
|
-
|
|
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] : []);
|
|
18
21
|
schema.add({ brand: String });
|
|
19
22
|
this.addPreReadQueries(schema);
|
|
20
23
|
this.addPreAggregateQueries(schema);
|
|
21
24
|
this.addPreSaveQueries(schema);
|
|
22
25
|
this.addPreInsertManyQueries(schema);
|
|
23
26
|
}
|
|
24
|
-
|
|
27
|
+
const modelName = skipBrand || !Array.isArray(brands) ? name : `${name}-${brands.join('-')}`;
|
|
25
28
|
if (!existingModels[modelName]) {
|
|
26
29
|
existingModels[modelName] = this.mongoose.model(modelName, schema, options);
|
|
27
30
|
}
|
|
28
31
|
return existingModels[modelName];
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
|
35
44
|
// @ts-ignore
|
|
36
45
|
this.where({ brand: { $in: brands } });
|
|
37
46
|
}
|
|
38
47
|
next();
|
|
39
|
-
}
|
|
40
|
-
|
|
48
|
+
}
|
|
49
|
+
addPreReadQueries(schema) {
|
|
41
50
|
schema.pre('count', this.addPreCondition);
|
|
42
51
|
schema.pre('find', this.addPreCondition);
|
|
43
52
|
schema.pre('findOne', this.addPreCondition);
|
|
@@ -50,44 +59,49 @@ var MongooseModel = /** @class */ (function () {
|
|
|
50
59
|
schema.pre('deleteMany', this.addPreCondition);
|
|
51
60
|
schema.pre('deleteOne', this.addPreCondition);
|
|
52
61
|
schema.pre('remove', this.addPreCondition);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
|
59
74
|
// @ts-ignore
|
|
60
75
|
this.pipeline().unshift({ $match: { brand: { $in: brands } } });
|
|
61
76
|
}
|
|
62
77
|
next();
|
|
63
|
-
}
|
|
64
|
-
|
|
78
|
+
}
|
|
79
|
+
addPreAggregateQueries(schema) {
|
|
65
80
|
schema.pre('aggregate', this.addPreAggregate);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
81
|
+
}
|
|
82
|
+
addPreSave(next) {
|
|
83
|
+
const brand = Storage_1.default.getBrand();
|
|
69
84
|
// @ts-ignore
|
|
70
85
|
if (!this.brand && brand) {
|
|
71
86
|
// @ts-ignore
|
|
72
87
|
this.brand = brand;
|
|
73
88
|
}
|
|
74
89
|
next();
|
|
75
|
-
}
|
|
76
|
-
|
|
90
|
+
}
|
|
91
|
+
addPreSaveQueries(schema) {
|
|
77
92
|
schema.pre('save', this.addPreSave);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
dataArray.forEach(
|
|
93
|
+
}
|
|
94
|
+
addPreInsertMany(next, dataArray) {
|
|
95
|
+
const brand = Storage_1.default.getBrand();
|
|
96
|
+
dataArray.forEach((data) => {
|
|
82
97
|
if (!data.tanentId && brand) {
|
|
83
98
|
data.brand = brand;
|
|
84
99
|
}
|
|
85
100
|
});
|
|
86
101
|
next();
|
|
87
|
-
}
|
|
88
|
-
|
|
102
|
+
}
|
|
103
|
+
addPreInsertManyQueries(schema) {
|
|
89
104
|
schema.pre('insertMany', this.addPreInsertMany);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
}());
|
|
105
|
+
}
|
|
106
|
+
}
|
|
93
107
|
exports.MongooseModel = MongooseModel;
|
|
@@ -1,17 +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 (b.hasOwnProperty(p)) d[p] = b[p]; };
|
|
7
|
-
return extendStatics(d, b);
|
|
8
|
-
};
|
|
9
|
-
return function (d, b) {
|
|
10
|
-
extendStatics(d, b);
|
|
11
|
-
function __() { this.constructor = d; }
|
|
12
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
13
|
-
};
|
|
14
|
-
})();
|
|
15
2
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
16
3
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
17
4
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -19,27 +6,21 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
19
6
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
20
7
|
};
|
|
21
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
TenantMongooseModule.forFeature = function (models, connectionName) {
|
|
31
|
-
if (models === void 0) { models = []; }
|
|
32
|
-
connectionName = connectionName ? connectionName + "Connection" : 'MongooseConnectionName';
|
|
33
|
-
var modelProviders = 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);
|
|
34
16
|
return {
|
|
35
17
|
module: mongoose_1.MongooseModule,
|
|
36
18
|
providers: modelProviders,
|
|
37
19
|
exports: modelProviders,
|
|
38
20
|
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}(mongoose_1.MongooseModule));
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
TenantMongooseModule = __decorate([
|
|
24
|
+
common_1.Module({})
|
|
25
|
+
], TenantMongooseModule);
|
|
45
26
|
exports.default = TenantMongooseModule;
|
|
@@ -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: [connectionName
|
|
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;
|