@podkopaev-tech/nest-infra-modules 0.0.7 → 0.0.9
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/dist/src/modules/cache/cache.service.d.ts +11 -0
- package/dist/src/modules/cache/cache.service.js +133 -0
- package/dist/src/modules/cache/cache.service.js.map +1 -0
- package/dist/src/modules/cache/constant.d.ts +2 -0
- package/dist/src/modules/cache/constant.js +8 -0
- package/dist/src/modules/cache/constant.js.map +1 -0
- package/dist/src/modules/cache/decorators/memoize-async.decorator.d.ts +4 -16
- package/dist/src/modules/cache/decorators/memoize-async.decorator.js +5 -124
- package/dist/src/modules/cache/decorators/memoize-async.decorator.js.map +1 -1
- package/dist/src/modules/cache/types.d.ts +12 -0
- package/dist/src/shared/types/class.types.d.ts +3 -0
- package/dist/src/shared/types/class.types.js +3 -0
- package/dist/src/shared/types/class.types.js.map +1 -0
- package/dist/src/shared/types/index.d.ts +1 -0
- package/dist/src/shared/types/index.js +18 -0
- package/dist/src/shared/types/index.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Cache } from '@nestjs/cache-manager';
|
|
2
|
+
import { IRedisClient } from "../redis";
|
|
3
|
+
import { AsyncMethod } from "../../shared/types";
|
|
4
|
+
import { AsyncMemoizeConfig } from "./types";
|
|
5
|
+
export declare class CacheService {
|
|
6
|
+
private readonly cacheManager;
|
|
7
|
+
private readonly redisClient;
|
|
8
|
+
constructor(cacheManager: Cache, redisClient: IRedisClient);
|
|
9
|
+
private readonly redlock;
|
|
10
|
+
memoizeAsyncify<T = any, D = any, A extends any[] = any[]>(originalMethod: AsyncMethod<D, A>, inputs?: AsyncMemoizeConfig<T, D, A>): AsyncMethod<D, A>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.CacheService = void 0;
|
|
16
|
+
const cache_manager_1 = require("@nestjs/cache-manager");
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const cache_module_1 = require("./cache.module");
|
|
19
|
+
const redlock_1 = require("redlock");
|
|
20
|
+
let CacheService = class CacheService {
|
|
21
|
+
constructor(cacheManager, redisClient) {
|
|
22
|
+
this.cacheManager = cacheManager;
|
|
23
|
+
this.redisClient = redisClient;
|
|
24
|
+
this.redlock = new redlock_1.default([this.redisClient], {
|
|
25
|
+
retryCount: 3,
|
|
26
|
+
retryDelay: 250,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
memoizeAsyncify(originalMethod, inputs) {
|
|
30
|
+
const promCache = new Map();
|
|
31
|
+
const resolvedConfig = {
|
|
32
|
+
expirationTimeMs: 0,
|
|
33
|
+
...(inputs || {}),
|
|
34
|
+
lock: {
|
|
35
|
+
duration: 10000,
|
|
36
|
+
retryCount: 3,
|
|
37
|
+
retryDelay: 250,
|
|
38
|
+
...(inputs?.lock || {}),
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
const cache = this.cacheManager;
|
|
42
|
+
const redlock = this.redlock;
|
|
43
|
+
return async function (...args) {
|
|
44
|
+
const keyResolver = typeof resolvedConfig.keyResolver === 'string'
|
|
45
|
+
? () => resolvedConfig.keyResolver
|
|
46
|
+
: resolvedConfig.keyResolver;
|
|
47
|
+
let key;
|
|
48
|
+
if (keyResolver) {
|
|
49
|
+
key = keyResolver.apply(this, args);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
key = `${this.constructor.name}:${originalMethod.name}:${JSON.stringify(args)}`;
|
|
53
|
+
}
|
|
54
|
+
if (promCache.has(key)) {
|
|
55
|
+
return promCache.get(key);
|
|
56
|
+
}
|
|
57
|
+
const lockKey = `lock:${key}`;
|
|
58
|
+
let finalLock;
|
|
59
|
+
try {
|
|
60
|
+
finalLock = await redlock.acquire([lockKey], resolvedConfig.lock.duration);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
console.error(`Error while acquiring lock for key: ${key}`);
|
|
64
|
+
console.error(error);
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
const prom = new Promise(async (resolve, reject) => {
|
|
68
|
+
let data;
|
|
69
|
+
if (typeof resolvedConfig.expirationTimeMs !== 'number' ||
|
|
70
|
+
resolvedConfig.expirationTimeMs > 0) {
|
|
71
|
+
data = await cache.get(key).catch((e) => {
|
|
72
|
+
console.error(`Error while getting cache for key: ${key}`);
|
|
73
|
+
console.error(e);
|
|
74
|
+
return undefined;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
if (data) {
|
|
78
|
+
let dataValue = typeof data === 'string' && data.startsWith(memoizeTypesPrefix)
|
|
79
|
+
? memoizeTypes.get(data)
|
|
80
|
+
: data;
|
|
81
|
+
if (!!resolvedConfig.cacheWrapperClass && !!dataValue) {
|
|
82
|
+
if (Array.isArray(dataValue)) {
|
|
83
|
+
dataValue = dataValue.map((value) => new resolvedConfig.cacheWrapperClass(value));
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
dataValue = new resolvedConfig.cacheWrapperClass(dataValue);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
resolve(dataValue);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
try {
|
|
93
|
+
data = (await originalMethod.apply(this, args));
|
|
94
|
+
resolve(data);
|
|
95
|
+
const expirationTimeMs = typeof resolvedConfig.expirationTimeMs === 'number'
|
|
96
|
+
? resolvedConfig.expirationTimeMs
|
|
97
|
+
: resolvedConfig.expirationTimeMs.apply(this, [data]);
|
|
98
|
+
if (expirationTimeMs > 0) {
|
|
99
|
+
const dataValue = memoizeTypes.has(data)
|
|
100
|
+
? memoizeTypes.get(data)
|
|
101
|
+
: data;
|
|
102
|
+
if (typeof resolvedConfig.memoizeIf !== 'function' ||
|
|
103
|
+
resolvedConfig.memoizeIf.apply(this, [dataValue])) {
|
|
104
|
+
await cache.set(key, dataValue, expirationTimeMs).catch((e) => {
|
|
105
|
+
console.error(`Error while setting cache for key: ${key}`);
|
|
106
|
+
console.error(e);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
reject(e instanceof Error ? e : new Error(String(e)));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
await finalLock.release().catch((e) => {
|
|
116
|
+
console.error(`Error while release lock for key: ${key}`);
|
|
117
|
+
console.error(e);
|
|
118
|
+
});
|
|
119
|
+
promCache.delete(key);
|
|
120
|
+
});
|
|
121
|
+
promCache.set(key, prom);
|
|
122
|
+
return prom;
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
exports.CacheService = CacheService;
|
|
127
|
+
exports.CacheService = CacheService = __decorate([
|
|
128
|
+
(0, common_1.Injectable)(),
|
|
129
|
+
__param(0, (0, common_1.Inject)(cache_manager_1.CACHE_MANAGER)),
|
|
130
|
+
__param(1, (0, common_1.Inject)((0, common_1.forwardRef)(() => cache_module_1.CacheModule.redisToken))),
|
|
131
|
+
__metadata("design:paramtypes", [Function, Object])
|
|
132
|
+
], CacheService);
|
|
133
|
+
//# sourceMappingURL=cache.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.service.js","sourceRoot":"","sources":["../../../../src/modules/cache/cache.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const memoizeTypesPrefix = '__memoize-types:';
|
|
2
|
+
const memoizeTypes = new Map([
|
|
3
|
+
[memoizeTypesPrefix + 'null', null],
|
|
4
|
+
[null, memoizeTypesPrefix + 'null'],
|
|
5
|
+
[memoizeTypesPrefix + 'undefined', undefined],
|
|
6
|
+
[undefined, memoizeTypesPrefix + 'undefined'],
|
|
7
|
+
]);
|
|
8
|
+
//# sourceMappingURL=constant.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constant.js","sourceRoot":"","sources":["../../../../src/modules/cache/constant.ts"],"names":[],"mappings":"AAAA,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;AAC9C,MAAM,YAAY,GAAG,IAAI,GAAG,CAG1B;IACA,CAAC,kBAAkB,GAAG,MAAM,EAAE,IAAI,CAAC;IACnC,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAAC;IACnC,CAAC,kBAAkB,GAAG,WAAW,EAAE,SAAS,CAAC;IAC7C,CAAC,SAAS,EAAE,kBAAkB,GAAG,WAAW,CAAC;CAC9C,CAAC,CAAC"}
|
|
@@ -1,17 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
type
|
|
4
|
-
type
|
|
5
|
-
interface AsyncMemoizeConfig<T = any, D = any, A extends any[] = any[]> {
|
|
6
|
-
lock?: {
|
|
7
|
-
duration?: number;
|
|
8
|
-
retryCount?: number;
|
|
9
|
-
retryDelay?: number;
|
|
10
|
-
};
|
|
11
|
-
keyResolver?: ((this: T, ...args: A) => string) | string;
|
|
12
|
-
expirationTimeMs?: number | ((this: T, data: D) => number);
|
|
13
|
-
memoizeIf?: (this: T, ...args: A) => boolean;
|
|
14
|
-
cacheWrapperClass?: ClassWithConstructor;
|
|
15
|
-
}
|
|
1
|
+
import { AsyncMemoizeConfig } from '../types';
|
|
2
|
+
import { Method } from '../../../shared/types';
|
|
3
|
+
export type Memoizable<T, D> = (target: T, propertyName: string | symbol | keyof T, descriptor: TypedPropertyDescriptor<Method<D>>) => TypedPropertyDescriptor<Method<D>>;
|
|
4
|
+
export type AsyncMemoizable<T, D> = Memoizable<T, Promise<D>>;
|
|
16
5
|
export declare function MemoizeAsync<T = any, D = any>(inputs?: AsyncMemoizeConfig<T, D, any[]>): AsyncMemoizable<T, D>;
|
|
17
|
-
export {};
|
|
@@ -2,134 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MemoizeAsync = MemoizeAsync;
|
|
4
4
|
const common_1 = require("@nestjs/common");
|
|
5
|
-
const
|
|
6
|
-
const redlock_1 = require("redlock");
|
|
7
|
-
const cache_module_1 = require("../cache.module");
|
|
8
|
-
const memoizeTypesPrefix = '__memoize-types:';
|
|
9
|
-
const memoizeTypes = new Map([
|
|
10
|
-
[memoizeTypesPrefix + 'null', null],
|
|
11
|
-
[null, memoizeTypesPrefix + 'null'],
|
|
12
|
-
[memoizeTypesPrefix + 'undefined', undefined],
|
|
13
|
-
[undefined, memoizeTypesPrefix + 'undefined'],
|
|
14
|
-
]);
|
|
15
|
-
function memoizeAsyncify(originalMethod, inputs) {
|
|
16
|
-
const promCache = new Map();
|
|
17
|
-
const resolvedConfig = {
|
|
18
|
-
expirationTimeMs: 0,
|
|
19
|
-
...(inputs || {}),
|
|
20
|
-
lock: {
|
|
21
|
-
duration: 10000,
|
|
22
|
-
retryCount: 3,
|
|
23
|
-
retryDelay: 250,
|
|
24
|
-
...(inputs?.lock || {}),
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
return async function (...args) {
|
|
28
|
-
const redis = this._redisService;
|
|
29
|
-
const cache = this._cacheManager;
|
|
30
|
-
if (!this._redlock) {
|
|
31
|
-
this._redlock = new redlock_1.default([redis], {
|
|
32
|
-
retryCount: resolvedConfig.lock.retryCount,
|
|
33
|
-
retryDelay: resolvedConfig.lock.retryDelay,
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
const redlock = this._redlock;
|
|
37
|
-
const keyResolver = typeof resolvedConfig.keyResolver === 'string'
|
|
38
|
-
? () => resolvedConfig.keyResolver
|
|
39
|
-
: resolvedConfig.keyResolver;
|
|
40
|
-
let key;
|
|
41
|
-
if (keyResolver) {
|
|
42
|
-
key = keyResolver.apply(this, args);
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
key = `${this.constructor.name}:${originalMethod.name}:${JSON.stringify(args)}`;
|
|
46
|
-
}
|
|
47
|
-
if (promCache.has(key)) {
|
|
48
|
-
return promCache.get(key);
|
|
49
|
-
}
|
|
50
|
-
const lockKey = `lock:${key}`;
|
|
51
|
-
let finalLock;
|
|
52
|
-
try {
|
|
53
|
-
finalLock = await redlock.acquire([lockKey], resolvedConfig.lock.duration);
|
|
54
|
-
}
|
|
55
|
-
catch (error) {
|
|
56
|
-
console.error(`Error while acquiring lock for key: ${key}`);
|
|
57
|
-
console.error(error);
|
|
58
|
-
throw error;
|
|
59
|
-
}
|
|
60
|
-
const prom = new Promise(async (resolve, reject) => {
|
|
61
|
-
let data;
|
|
62
|
-
if (typeof resolvedConfig.expirationTimeMs !== 'number' ||
|
|
63
|
-
resolvedConfig.expirationTimeMs > 0) {
|
|
64
|
-
data = await cache.get(key).catch((e) => {
|
|
65
|
-
console.error(`Error while getting cache for key: ${key}`);
|
|
66
|
-
console.error(e);
|
|
67
|
-
return undefined;
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
if (data) {
|
|
71
|
-
let dataValue = typeof data === 'string' && data.startsWith(memoizeTypesPrefix)
|
|
72
|
-
? memoizeTypes.get(data)
|
|
73
|
-
: data;
|
|
74
|
-
if (!!resolvedConfig.cacheWrapperClass && !!dataValue) {
|
|
75
|
-
if (Array.isArray(dataValue)) {
|
|
76
|
-
dataValue = dataValue.map((value) => new resolvedConfig.cacheWrapperClass(value));
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
dataValue = new resolvedConfig.cacheWrapperClass(dataValue);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
resolve(dataValue);
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
try {
|
|
86
|
-
data = (await originalMethod.apply(this, args));
|
|
87
|
-
resolve(data);
|
|
88
|
-
const expirationTimeMs = typeof resolvedConfig.expirationTimeMs === 'number'
|
|
89
|
-
? resolvedConfig.expirationTimeMs
|
|
90
|
-
: resolvedConfig.expirationTimeMs.apply(this, [data]);
|
|
91
|
-
if (expirationTimeMs > 0) {
|
|
92
|
-
const dataValue = memoizeTypes.has(data)
|
|
93
|
-
? memoizeTypes.get(data)
|
|
94
|
-
: data;
|
|
95
|
-
if (typeof resolvedConfig.memoizeIf !== 'function' ||
|
|
96
|
-
resolvedConfig.memoizeIf.apply(this, [dataValue])) {
|
|
97
|
-
await cache.set(key, dataValue, expirationTimeMs).catch((e) => {
|
|
98
|
-
console.error(`Error while setting cache for key: ${key}`);
|
|
99
|
-
console.error(e);
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
catch (e) {
|
|
105
|
-
reject(e instanceof Error ? e : new Error(String(e)));
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
await finalLock.release().catch((e) => {
|
|
109
|
-
console.error(`Error while release lock for key: ${key}`);
|
|
110
|
-
console.error(e);
|
|
111
|
-
});
|
|
112
|
-
promCache.delete(key);
|
|
113
|
-
});
|
|
114
|
-
promCache.set(key, prom);
|
|
115
|
-
return prom;
|
|
116
|
-
};
|
|
117
|
-
}
|
|
5
|
+
const cache_service_1 = require("../cache.service");
|
|
118
6
|
function MemoizeAsync(inputs) {
|
|
119
|
-
const
|
|
120
|
-
const cacheManagerInjector = (0, common_1.Inject)(cache_manager_1.CACHE_MANAGER);
|
|
7
|
+
const cacheServiceInjector = (0, common_1.Inject)(cache_service_1.CacheService);
|
|
121
8
|
return (_target, _propertyName, descriptor) => {
|
|
122
|
-
if (!
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
if (!('_redisService' in _target)) {
|
|
126
|
-
redisInjector(_target, '_redisService');
|
|
127
|
-
}
|
|
128
|
-
if (!('_cacheManager' in _target)) {
|
|
129
|
-
cacheManagerInjector(_target, '_cacheManager');
|
|
9
|
+
if (!('_cacheService' in _target)) {
|
|
10
|
+
cacheServiceInjector(_target, '_cacheService');
|
|
130
11
|
}
|
|
131
12
|
if (descriptor.value) {
|
|
132
|
-
descriptor.value = memoizeAsyncify(descriptor.value, inputs);
|
|
13
|
+
descriptor.value = _target._cacheService.memoizeAsyncify(descriptor.value, inputs);
|
|
133
14
|
return descriptor;
|
|
134
15
|
}
|
|
135
16
|
throw new Error('@MemoizeAsync is applicable only on a methods.');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memoize-async.decorator.js","sourceRoot":"","sources":["../../../../../src/modules/cache/decorators/memoize-async.decorator.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"memoize-async.decorator.js","sourceRoot":"","sources":["../../../../../src/modules/cache/decorators/memoize-async.decorator.ts"],"names":[],"mappings":";;AAeA,oCAuBC;AArCD,2CAAwC;AACxC,oDAAgD;AAahD,SAAgB,YAAY,CAC1B,MAAwC;IAExC,MAAM,oBAAoB,GAAG,IAAA,eAAM,EAAC,4BAAY,CAAC,CAAC;IAElD,OAAO,CACL,OAAY,EACZ,aAAwC,EACxC,UAAmD,EACV,EAAE;QAE3C,IAAI,CAAC,CAAC,eAAe,IAAI,OAAO,CAAC,EAAE,CAAC;YAClC,oBAAoB,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,UAAU,CAAC,KAAK,GAAG,OAAO,CAAC,aAAa,CAAC,eAAe,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAEnF,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,4 +1,16 @@
|
|
|
1
|
+
import { ClassWithConstructor } from "../../shared/types";
|
|
1
2
|
export type CacheModuleOptions = {
|
|
2
3
|
defaultTtl: number;
|
|
3
4
|
redisToken: string | symbol;
|
|
4
5
|
};
|
|
6
|
+
export interface AsyncMemoizeConfig<T = any, D = any, A extends any[] = any[]> {
|
|
7
|
+
lock?: {
|
|
8
|
+
duration?: number;
|
|
9
|
+
retryCount?: number;
|
|
10
|
+
retryDelay?: number;
|
|
11
|
+
};
|
|
12
|
+
keyResolver?: ((this: T, ...args: A) => string) | string;
|
|
13
|
+
expirationTimeMs?: number | ((this: T, data: D) => number);
|
|
14
|
+
memoizeIf?: (this: T, ...args: A) => boolean;
|
|
15
|
+
cacheWrapperClass?: ClassWithConstructor;
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"class.types.js","sourceRoot":"","sources":["../../../../src/shared/types/class.types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './class.types';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./class.types"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/shared/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B"}
|