@almatar/branding 0.1.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/lib/index.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import ContextNamespace from './lib/Storage';
2
+ import MultiTenant from './lib/TenantModel/Mongoose/MultiTenant';
3
+ import MultiTenantMongooseModule from './lib/TenantModel/NestMongoose/TenantMongooseModule';
4
+ import TenantRequest from './lib/request/TenantRequest';
5
+ import AlmatarBranding from "./lib/AlmatarBranding";
6
+ declare const _default: {
7
+ ContextNamespace: typeof ContextNamespace;
8
+ MultiTenant: typeof MultiTenant;
9
+ MultiTenantMongooseModule: typeof MultiTenantMongooseModule;
10
+ TenantRequest: typeof TenantRequest;
11
+ AlmatarBranding: typeof AlmatarBranding;
12
+ };
13
+ export = _default;
package/lib/index.js ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ var Storage_1 = require("./lib/Storage");
3
+ var MultiTenant_1 = require("./lib/TenantModel/Mongoose/MultiTenant");
4
+ var TenantMongooseModule_1 = require("./lib/TenantModel/NestMongoose/TenantMongooseModule");
5
+ var TenantRequest_1 = require("./lib/request/TenantRequest");
6
+ var AlmatarBranding_1 = require("./lib/AlmatarBranding");
7
+ module.exports = {
8
+ ContextNamespace: Storage_1.default,
9
+ MultiTenant: MultiTenant_1.default,
10
+ MultiTenantMongooseModule: TenantMongooseModule_1.default,
11
+ TenantRequest: TenantRequest_1.default,
12
+ AlmatarBranding: AlmatarBranding_1.default
13
+ };
@@ -0,0 +1,4 @@
1
+ export default class AlmatarBranding {
2
+ static employeeAuthService: string;
3
+ static setup(configs: any): void;
4
+ }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var AlmatarBranding = /** @class */ (function () {
4
+ function AlmatarBranding() {
5
+ }
6
+ AlmatarBranding.setup = function (configs) {
7
+ this.employeeAuthService = configs.employeeAuthService;
8
+ };
9
+ AlmatarBranding.employeeAuthService = '';
10
+ return AlmatarBranding;
11
+ }());
12
+ exports.default = AlmatarBranding;
@@ -0,0 +1,6 @@
1
+ export declare class BrandIdentifier {
2
+ private readonly type;
3
+ constructor(type: string);
4
+ getBrand(req: any): Promise<string | string[] | null | Error>;
5
+ private error;
6
+ }
@@ -0,0 +1,85 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ var Boom = require("@hapi/boom");
40
+ var BrandManager_1 = require("./BrandManager");
41
+ var BrandIdentifier = /** @class */ (function () {
42
+ function BrandIdentifier(type) {
43
+ this.type = type;
44
+ }
45
+ BrandIdentifier.prototype.getBrand = function (req) {
46
+ return __awaiter(this, void 0, void 0, function () {
47
+ var brandManager, brand;
48
+ return __generator(this, function (_a) {
49
+ switch (_a.label) {
50
+ case 0:
51
+ brandManager = new BrandManager_1.BrandManager(this.type);
52
+ if (!req.headers['x-brand']) return [3 /*break*/, 1];
53
+ return [2 /*return*/, brandManager.getB2CBrand(req)];
54
+ case 1:
55
+ if (!(req.headers.authorization || req.headers['x-employee-brands'])) return [3 /*break*/, 3];
56
+ return [4 /*yield*/, brandManager.getConsoleBrands(req)];
57
+ case 2:
58
+ brand = _a.sent();
59
+ if (brand) {
60
+ if (brand.length) {
61
+ return [2 /*return*/, brand];
62
+ }
63
+ return [2 /*return*/, 'almatar'];
64
+ }
65
+ return [2 /*return*/, this.error('Unauthorized!')];
66
+ case 3: return [2 /*return*/, 'almatar'];
67
+ }
68
+ });
69
+ });
70
+ };
71
+ BrandIdentifier.prototype.error = function (message) {
72
+ switch (this.type) {
73
+ case 'hapi':
74
+ return Boom.unauthorized(message);
75
+ break;
76
+ case 'express':
77
+ return new Error(message);
78
+ break;
79
+ default:
80
+ return new Error(message);
81
+ }
82
+ };
83
+ return BrandIdentifier;
84
+ }());
85
+ exports.BrandIdentifier = BrandIdentifier;
@@ -0,0 +1,7 @@
1
+ export declare class BrandManager {
2
+ private readonly type;
3
+ constructor(type: string);
4
+ getB2CBrand(req: any): string;
5
+ getConsoleBrands(req: any): Promise<string[] | null>;
6
+ loadBrands(req: any): Promise<string[] | null>;
7
+ }
@@ -0,0 +1,107 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ var AlmatarBranding_1 = require("./AlmatarBranding");
40
+ var Storage_1 = require("./Storage");
41
+ var PromiseRequest_1 = require("./request/PromiseRequest");
42
+ var BrandManager = /** @class */ (function () {
43
+ function BrandManager(type) {
44
+ this.type = type;
45
+ }
46
+ BrandManager.prototype.getB2CBrand = function (req) {
47
+ return req.headers['x-brand'];
48
+ };
49
+ BrandManager.prototype.getConsoleBrands = function (req) {
50
+ return __awaiter(this, void 0, void 0, function () {
51
+ var reqBody, brands;
52
+ return __generator(this, function (_a) {
53
+ switch (_a.label) {
54
+ case 0:
55
+ if (req.headers['x-employee-brands']) {
56
+ return [2 /*return*/, req.headers['x-employee-brands'].split(',')];
57
+ }
58
+ reqBody = (req.payload) ? req.payload : req.body;
59
+ return [4 /*yield*/, this.loadBrands(req)];
60
+ case 1:
61
+ brands = _a.sent();
62
+ if (reqBody && reqBody.brand) {
63
+ Storage_1.default.setBrand(reqBody.brand);
64
+ }
65
+ return [2 /*return*/, brands];
66
+ }
67
+ });
68
+ });
69
+ };
70
+ BrandManager.prototype.loadBrands = function (req) {
71
+ return __awaiter(this, void 0, void 0, function () {
72
+ var reqBody, options, employeeBrands, brands, err_1;
73
+ return __generator(this, function (_a) {
74
+ switch (_a.label) {
75
+ case 0:
76
+ _a.trys.push([0, 2, , 3]);
77
+ reqBody = (req.payload) ? req.payload : req.body;
78
+ options = {
79
+ url: AlmatarBranding_1.default.employeeAuthService + '/v1/user/brands',
80
+ headers: {
81
+ authorization: req.headers.authorization
82
+ }
83
+ };
84
+ return [4 /*yield*/, PromiseRequest_1.PromiseRequest.request(options)];
85
+ case 1:
86
+ employeeBrands = _a.sent();
87
+ if (employeeBrands.status === 200) {
88
+ brands = employeeBrands.data.map(function (brand) { return brand.slug; });
89
+ if (reqBody && reqBody.brand) {
90
+ return [2 /*return*/, (brands.indexOf(reqBody.brand) > -1) ? brands : null];
91
+ }
92
+ return [2 /*return*/, brands];
93
+ }
94
+ return [2 /*return*/, null];
95
+ case 2:
96
+ err_1 = _a.sent();
97
+ // tslint:disable-next-line no-console
98
+ console.log(err_1);
99
+ return [2 /*return*/, null];
100
+ case 3: return [2 /*return*/];
101
+ }
102
+ });
103
+ });
104
+ };
105
+ return BrandManager;
106
+ }());
107
+ exports.BrandManager = BrandManager;
@@ -0,0 +1,6 @@
1
+ export declare class EmployeeBrandModel {
2
+ id: number;
3
+ slug: string;
4
+ name: string;
5
+ constructor(init?: Partial<EmployeeBrandModel>);
6
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var EmployeeBrandModel = /** @class */ (function () {
4
+ function EmployeeBrandModel(init) {
5
+ Object.assign(this, init);
6
+ }
7
+ return EmployeeBrandModel;
8
+ }());
9
+ exports.EmployeeBrandModel = EmployeeBrandModel;
@@ -0,0 +1,10 @@
1
+ export default class ContextNamespace {
2
+ static bindENamespace(req: any, res: any, next: any): void;
3
+ static setEBrand(req: any, res: any, next: any): Promise<void>;
4
+ static bindHNamespace(req: any, reply: any): void;
5
+ static setHBrand(req: any, reply: any): Promise<void>;
6
+ static setBrand(brnad: string | string[]): any;
7
+ static getBrand(): any;
8
+ static getEmployeeBrands(): any;
9
+ static getNamespace(): any;
10
+ }
@@ -0,0 +1,135 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ var BrandIdentifier_1 = require("./BrandIdentifier");
40
+ var createNamespace = require('cls-hooked').createNamespace;
41
+ var namespaceName = 'request';
42
+ var ns = createNamespace(namespaceName);
43
+ var ContextNamespace = /** @class */ (function () {
44
+ function ContextNamespace() {
45
+ }
46
+ /* Express Start */
47
+ ContextNamespace.bindENamespace = function (req, res, next) {
48
+ ns.bindEmitter(req);
49
+ ns.bindEmitter(res);
50
+ ns.run(function () {
51
+ next();
52
+ });
53
+ };
54
+ ContextNamespace.setEBrand = function (req, res, next) {
55
+ return __awaiter(this, void 0, void 0, function () {
56
+ var brandIdentifier, brand;
57
+ return __generator(this, function (_a) {
58
+ switch (_a.label) {
59
+ case 0:
60
+ brandIdentifier = new BrandIdentifier_1.BrandIdentifier('express');
61
+ return [4 /*yield*/, brandIdentifier.getBrand(req)];
62
+ case 1:
63
+ brand = _a.sent();
64
+ if (Array.isArray(brand)) {
65
+ ns.set('employeeBrands', brand);
66
+ next();
67
+ }
68
+ else if (typeof brand === 'string') {
69
+ ns.set('brand', brand);
70
+ next();
71
+ }
72
+ else {
73
+ next(brand);
74
+ }
75
+ return [2 /*return*/];
76
+ }
77
+ });
78
+ });
79
+ };
80
+ /* Express End */
81
+ /* Hapi Start */
82
+ ContextNamespace.bindHNamespace = function (req, reply) {
83
+ ns.bindEmitter(req.raw.req);
84
+ ns.bindEmitter(req.raw.res);
85
+ ns.run(function () {
86
+ reply();
87
+ });
88
+ };
89
+ ContextNamespace.setHBrand = function (req, reply) {
90
+ return __awaiter(this, void 0, void 0, function () {
91
+ var brandIdentifier, brand;
92
+ return __generator(this, function (_a) {
93
+ switch (_a.label) {
94
+ case 0:
95
+ brandIdentifier = new BrandIdentifier_1.BrandIdentifier('hapi');
96
+ return [4 /*yield*/, brandIdentifier.getBrand(req)];
97
+ case 1:
98
+ brand = _a.sent();
99
+ if (Array.isArray(brand)) {
100
+ ns.set('employeeBrands', brand);
101
+ reply();
102
+ }
103
+ else if (typeof brand === 'string') {
104
+ ns.set('brand', brand);
105
+ reply();
106
+ }
107
+ else {
108
+ reply(brand);
109
+ }
110
+ return [2 /*return*/];
111
+ }
112
+ });
113
+ });
114
+ };
115
+ /* Hapi End */
116
+ ContextNamespace.setBrand = function (brnad) {
117
+ if (Array.isArray(brnad)) {
118
+ return ns.set('employeeBrands', brnad);
119
+ }
120
+ else {
121
+ return ns.set('brand', brnad);
122
+ }
123
+ };
124
+ ContextNamespace.getBrand = function () {
125
+ return ns.get('brand');
126
+ };
127
+ ContextNamespace.getEmployeeBrands = function () {
128
+ return ns.get('employeeBrands');
129
+ };
130
+ ContextNamespace.getNamespace = function () {
131
+ return ns;
132
+ };
133
+ return ContextNamespace;
134
+ }());
135
+ exports.default = ContextNamespace;
@@ -0,0 +1,8 @@
1
+ declare class MultiTenant {
2
+ private mongoose;
3
+ private models;
4
+ constructor(mongoose: any);
5
+ tenantModel(name: string, schema: any, options?: any): (props?: {}) => any;
6
+ tenantlessModel(name: string, schema: any, options?: any): () => any;
7
+ }
8
+ export default MultiTenant;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var MongooseModel_1 = require("../MongooseModel");
4
+ var MultiTenant = /** @class */ (function () {
5
+ function MultiTenant(mongoose) {
6
+ this.mongoose = mongoose;
7
+ this.models = {};
8
+ }
9
+ MultiTenant.prototype.tenantModel = function (name, schema, options) {
10
+ var _this = this;
11
+ return function (props) {
12
+ if (props === void 0) { props = {}; }
13
+ var skipBrand = props.skipBrand;
14
+ var mongooseModel = new MongooseModel_1.MongooseModel(_this.mongoose);
15
+ return mongooseModel.createModel(name, schema, options, _this.models, skipBrand);
16
+ };
17
+ };
18
+ MultiTenant.prototype.tenantlessModel = function (name, schema, options) {
19
+ var _this = this;
20
+ return function () { return _this.mongoose.model(name, schema, options); };
21
+ };
22
+ return MultiTenant;
23
+ }());
24
+ exports.default = MultiTenant;
@@ -0,0 +1,13 @@
1
+ export declare class MongooseModel {
2
+ private mongoose;
3
+ constructor(mongoose: any);
4
+ createModel(name: string, schema: any, options?: any, existingModels?: any, skipBrand?: boolean): any;
5
+ private addPreCondition;
6
+ private addPreReadQueries;
7
+ private addPreAggregate;
8
+ private addPreAggregateQueries;
9
+ private addPreSave;
10
+ private addPreSaveQueries;
11
+ private addPreInsertMany;
12
+ private addPreInsertManyQueries;
13
+ }
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var Storage_1 = require("../Storage");
4
+ var MongooseModel = /** @class */ (function () {
5
+ function MongooseModel(mongoose) {
6
+ this.mongoose = mongoose;
7
+ }
8
+ MongooseModel.prototype.createModel = function (name, schema, options, existingModels, skipBrand) {
9
+ var brands = [];
10
+ if (!skipBrand) {
11
+ brands = (Storage_1.default.getEmployeeBrands()) ? Storage_1.default.getEmployeeBrands() : [Storage_1.default.getBrand()];
12
+ schema.add({ brand: String });
13
+ this.addPreReadQueries(schema);
14
+ this.addPreAggregateQueries(schema);
15
+ this.addPreSaveQueries(schema);
16
+ this.addPreInsertManyQueries(schema);
17
+ }
18
+ var modelName = (skipBrand || !Array.isArray(brands)) ? name : name + "-" + brands.join("-");
19
+ if (!existingModels[modelName]) {
20
+ existingModels[modelName] = this.mongoose.model(modelName, schema, options);
21
+ }
22
+ return existingModels[modelName];
23
+ };
24
+ MongooseModel.prototype.addPreCondition = function (next) {
25
+ var brands = (Storage_1.default.getEmployeeBrands()) ? Storage_1.default.getEmployeeBrands() : [Storage_1.default.getBrand()];
26
+ if (Array.isArray(brands)) {
27
+ // @ts-ignore
28
+ this.where({ brand: { $in: brands } });
29
+ }
30
+ next();
31
+ };
32
+ MongooseModel.prototype.addPreReadQueries = function (schema) {
33
+ schema.pre('count', this.addPreCondition);
34
+ schema.pre('find', this.addPreCondition);
35
+ schema.pre('findOne', this.addPreCondition);
36
+ schema.pre('update', this.addPreCondition);
37
+ schema.pre('findOneAndUpdate', this.addPreCondition);
38
+ schema.pre('updateOne', this.addPreCondition);
39
+ schema.pre('updateMany', this.addPreCondition);
40
+ schema.pre('findOneAndDelete', this.addPreCondition);
41
+ schema.pre('findOneAndRemove', this.addPreCondition);
42
+ schema.pre('deleteMany', this.addPreCondition);
43
+ schema.pre('deleteOne', this.addPreCondition);
44
+ schema.pre('remove', this.addPreCondition);
45
+ };
46
+ MongooseModel.prototype.addPreAggregate = function (next) {
47
+ var brands = (Storage_1.default.getEmployeeBrands()) ? Storage_1.default.getEmployeeBrands() : [Storage_1.default.getBrand()];
48
+ if (Array.isArray(brands)) {
49
+ // @ts-ignore
50
+ this.pipeline().unshift({ $match: { brand: { $in: brands } } });
51
+ }
52
+ next();
53
+ };
54
+ MongooseModel.prototype.addPreAggregateQueries = function (schema) {
55
+ schema.pre('aggregate', this.addPreAggregate);
56
+ };
57
+ MongooseModel.prototype.addPreSave = function (next) {
58
+ var brand = Storage_1.default.getBrand();
59
+ // @ts-ignore
60
+ if (!this.brand && brand) {
61
+ // @ts-ignore
62
+ this.brand = brand;
63
+ }
64
+ next();
65
+ };
66
+ MongooseModel.prototype.addPreSaveQueries = function (schema) {
67
+ schema.pre('save', this.addPreSave);
68
+ };
69
+ MongooseModel.prototype.addPreInsertMany = function (next, dataArray) {
70
+ var brand = Storage_1.default.getBrand();
71
+ dataArray.forEach(function (data) {
72
+ if (!data.tanentId && brand) {
73
+ data.brand = brand;
74
+ }
75
+ });
76
+ next();
77
+ };
78
+ MongooseModel.prototype.addPreInsertManyQueries = function (schema) {
79
+ schema.pre('insertMany', this.addPreInsertMany);
80
+ };
81
+ return MongooseModel;
82
+ }());
83
+ exports.MongooseModel = MongooseModel;
@@ -0,0 +1,9 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ import { MongooseModule } from '@nestjs/mongoose';
3
+ export default class TenantMongooseModule extends MongooseModule {
4
+ static forFeature(models?: {
5
+ name: string;
6
+ schema: any;
7
+ collection?: string;
8
+ }[], connectionName?: string): DynamicModule;
9
+ }
@@ -0,0 +1,44 @@
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
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
16
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
17
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
18
+ 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;
19
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ var common_1 = require("@nestjs/common");
23
+ var mongoose_1 = require("@nestjs/mongoose");
24
+ var mongoose_providers_1 = require("./mongoose.providers");
25
+ var TenantMongooseModule = /** @class */ (function (_super) {
26
+ __extends(TenantMongooseModule, _super);
27
+ function TenantMongooseModule() {
28
+ return _super !== null && _super.apply(this, arguments) || this;
29
+ }
30
+ TenantMongooseModule.forFeature = function (models, connectionName) {
31
+ if (models === void 0) { models = []; }
32
+ var modelProviders = mongoose_providers_1.createMongooseProviders(connectionName, models);
33
+ return {
34
+ module: mongoose_1.MongooseModule,
35
+ providers: modelProviders,
36
+ exports: modelProviders,
37
+ };
38
+ };
39
+ TenantMongooseModule = __decorate([
40
+ common_1.Module({})
41
+ ], TenantMongooseModule);
42
+ return TenantMongooseModule;
43
+ }(mongoose_1.MongooseModule));
44
+ exports.default = TenantMongooseModule;
@@ -0,0 +1,10 @@
1
+ import { Connection, Schema } from 'mongoose';
2
+ export declare function createMongooseProviders(connectionName?: string, models?: {
3
+ name: string;
4
+ schema: Schema;
5
+ collection?: string;
6
+ }[]): {
7
+ provide: string;
8
+ useFactory: (connection: Connection) => any;
9
+ inject: string[];
10
+ }[];
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var mongoose_utils_1 = require("../../../../node_modules/@nestjs/mongoose/dist/common/mongoose.utils");
4
+ var MongooseModel_1 = require("../MongooseModel");
5
+ function createMongooseProviders(connectionName, models) {
6
+ if (models === void 0) { models = []; }
7
+ var providers = (models || []).map(function (model) { return ({
8
+ provide: mongoose_utils_1.getModelToken(model.name),
9
+ useFactory: function (connection) {
10
+ var mongooseModel = new MongooseModel_1.MongooseModel(connection);
11
+ return mongooseModel.createModel(model.name, model.schema, model.collection, {});
12
+ },
13
+ inject: [mongoose_utils_1.getConnectionToken(connectionName)],
14
+ }); });
15
+ return providers;
16
+ }
17
+ exports.createMongooseProviders = createMongooseProviders;
@@ -0,0 +1,3 @@
1
+ export declare class PromiseRequest {
2
+ static request(options: any): Promise<any>;
3
+ }
@@ -0,0 +1,61 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ var request = require("request");
40
+ var PromiseRequest = /** @class */ (function () {
41
+ function PromiseRequest() {
42
+ }
43
+ PromiseRequest.request = function (options) {
44
+ return __awaiter(this, void 0, void 0, function () {
45
+ return __generator(this, function (_a) {
46
+ return [2 /*return*/, new Promise(function (resolve, reject) {
47
+ request(options, function (err, response, body) {
48
+ if (err) {
49
+ reject(err);
50
+ }
51
+ ;
52
+ body = (body) ? JSON.parse(body) : null;
53
+ resolve(body);
54
+ });
55
+ })];
56
+ });
57
+ });
58
+ };
59
+ return PromiseRequest;
60
+ }());
61
+ exports.PromiseRequest = PromiseRequest;
@@ -0,0 +1,4 @@
1
+ declare class TenantRequest {
2
+ static request(options: any, callback: any): void;
3
+ }
4
+ export default TenantRequest;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var Storage_1 = require("../Storage");
4
+ var request = require("request");
5
+ var TenantRequest = /** @class */ (function () {
6
+ function TenantRequest() {
7
+ }
8
+ TenantRequest.request = function (options, callback) {
9
+ var brand = Storage_1.default.getBrand();
10
+ var employeeBrands = Storage_1.default.getEmployeeBrands();
11
+ if (!options.headers) {
12
+ options.headers = {};
13
+ }
14
+ options.headers['x-brand'] = brand;
15
+ options.headers['x-employee-brands'] = (employeeBrands) ? employeeBrands.join(',') : null;
16
+ request(options, callback);
17
+ };
18
+ return TenantRequest;
19
+ }());
20
+ exports.default = TenantRequest;
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@almatar/branding",
3
+ "version": "0.1.0",
4
+ "description": "",
5
+ "main": "lib/index.js",
6
+ "types": "lib/index.d.ts",
7
+ "files": [
8
+ "lib/**/*"
9
+ ],
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"",
13
+ "lint": "tslint -p tsconfig.json",
14
+ "test": "jest --config jestconfig.json",
15
+ "prepare": "npm run build",
16
+ "prepublishOnly": "npm test && npm run lint",
17
+ "preversion": "npm run lint",
18
+ "version": "npm run format && git add -A && git commit -m \"Setup Package\"",
19
+ "postversion": "git push && git push --tags"
20
+ },
21
+ "pre-commit": [
22
+ "lint"
23
+ ],
24
+ "dependencies": {
25
+ "@hapi/boom": "^8.0.1",
26
+ "@nestjs/common": "^6.8.2",
27
+ "@nestjs/core": "^6.8.2",
28
+ "@nestjs/mongoose": "^6.1.2",
29
+ "@types/mongoose": "^5.5.19",
30
+ "@types/request": "^2.48.3",
31
+ "cls-hooked": "^4.2.2",
32
+ "mongoose": "^5.7.3",
33
+ "reflect-metadata": "^0.1.13",
34
+ "request": "^2.88.0",
35
+ "rxjs": "^6.5.3"
36
+ },
37
+ "author": "",
38
+ "license": "ISC",
39
+ "devDependencies": {
40
+ "@babel/core": "^7.5.5",
41
+ "@babel/preset-env": "^7.5.5",
42
+ "@babel/register": "^7.5.5",
43
+ "@types/jest": "^24.0.18",
44
+ "@types/node": "^12.7.5",
45
+ "jest": "^24.9.0",
46
+ "pre-commit": "^1.2.2",
47
+ "npm-watch": "^0.6.0",
48
+ "prettier": "^1.18.2",
49
+ "ts-jest": "^24.1.0",
50
+ "tslint": "^5.20.0",
51
+ "tslint-config-prettier": "^1.18.0",
52
+ "typescript": "^3.6.3"
53
+ }
54
+ }
package/readme.md ADDED
@@ -0,0 +1,146 @@
1
+ # Almatar Branding
2
+
3
+ this package make microservice able to handle different brands
4
+
5
+ ## How It Works
6
+
7
+ ## Nest.js
8
+
9
+ ### save brand on any request
10
+
11
+ save brand on any request using the package middleware in main.ts file
12
+ ```
13
+ import { ContextNamespace } from 'almatar-branding';
14
+
15
+ app.use(ContextNamespace.bindENamespace);
16
+ app.use(ContextNamespace.setEBrand);
17
+ ```
18
+
19
+ ### build mongoose model
20
+
21
+ `import { MultiTenantMongooseModule } from 'almatar-branding';` instead of `import {MongooseModule} from '@nestjs/mongoose';`
22
+
23
+ ```
24
+ import { MultiTenantMongooseModule } from 'almatar-branding';
25
+
26
+ @Module({
27
+ imports: [
28
+ MultiTenantMongooseModule.forFeature([{name: 'Test', schema: TestSchema}]),
29
+ ],
30
+ controllers: [TestController],
31
+ providers: [
32
+ TestService,
33
+ ],
34
+ })
35
+ ```
36
+
37
+ and add `.exec()` at the end of any query make search on database
38
+
39
+ `count, find, findOne, aggregate, update, findOneAndUpdate, updateOne, updateMany, findOneAndDelete, findOneAndRemove, deleteMany, deleteOne, remove`
40
+
41
+ example: `await this.Test.find({ id: '123' }).exec()`
42
+
43
+
44
+ ## Hapi.js
45
+
46
+ ### save brand on each request
47
+
48
+ save brand on each request by using the package middleware in pre functions on each route
49
+
50
+ ```
51
+ import { ContextNamespace } from 'almatar-branding';
52
+
53
+ // configs
54
+
55
+ auth: false,
56
+ // "tags" enable swagger to document API
57
+ tags: ['api'],
58
+ description: 'Get all coupon data',
59
+ notes: 'Returns a list of all coupons',
60
+ pre: [
61
+ { method: ContextNamespace.bindHNamespace },
62
+ { method: ContextNamespace.setHBrand }
63
+ ],
64
+ handler: (request, reply) => {
65
+ // some code
66
+ }
67
+ ```
68
+
69
+ ### build mongoose model
70
+
71
+ ```
72
+ import { MultiTenant } from 'almatar-branding';
73
+ const mongoose = require('mongoose');
74
+
75
+ const TestSchema = new mongoose.Schema(
76
+ {
77
+ id: { type: Number, required: true }
78
+ }
79
+ )
80
+
81
+ const multiTenant = new MultiTenant(mongoose);
82
+
83
+ module.exports = multiTenant.tenantModel('Test', TestSchema);
84
+
85
+ ```
86
+
87
+ ### use mongoose model
88
+
89
+ ```
90
+ const Test = require('../models/coupon.model');
91
+
92
+ Test().count({}, callback);
93
+ ```
94
+
95
+ ### skip brand for specific query
96
+
97
+ add { skipBrand: true } if you need to get the data regardless of the brand
98
+
99
+ ```
100
+ const Test = require('../models/coupon.model');
101
+
102
+ Test({ skipBrand: true }).count({}, callback);
103
+ ```
104
+
105
+ ### to keep the context in multiple callbacks
106
+
107
+ ```
108
+ import { ContextNamespace } from 'almatar-branding';
109
+
110
+ const ns = ContextNamespace.getNamespace();
111
+ async.waterfall(
112
+ [
113
+ ns.bind(function(cb) {
114
+ cb(err, data)
115
+ }),
116
+ ns.bind(function(couponsCount, cb1) {
117
+ cb1(err, data)
118
+ })
119
+ ],
120
+ callback
121
+ );
122
+ ```
123
+
124
+ ### Send request With brand header
125
+
126
+ ```
127
+ import { MultiTenantRequest } from 'almatar-branding';
128
+
129
+ const reqOptions = {
130
+ url: `${BASEURL}/test`
131
+ };
132
+ MultiTenantRequest.request(reqOptions, (error, response, body) => {
133
+ console.log(body);
134
+ });
135
+ ```
136
+
137
+ ### Setup Branding Package
138
+
139
+ ```
140
+ import { AlmatarBranding } from 'almatar-branding';
141
+
142
+ AlmatarBranding.setup({
143
+ employeeAuthService: config.EMPLOYEE_AUTH_SERVICE
144
+ });
145
+
146
+ ```