1 line
3.5 KiB
Plaintext
1 line
3.5 KiB
Plaintext
{"version":3,"sources":["../../src/common/SyncLocker.ts","../../src/decorators/singleton.ts","../../src/common/ZError.ts"],"sourcesContent":["import { singleton } from 'decorators/singleton'\nimport { ZError } from './ZError'\n\ninterface IRequest {\n method: string\n url: string\n user?: {\n id: string\n }\n}\n\n@singleton\nexport class SyncLocker {\n map: Map<string, boolean> = new Map()\n\n public lock(req: IRequest) {\n const key = `${req.method}:${req.url}:${req.user?.id || ''}`\n if (this.map.has(key)) {\n return false\n }\n this.map.set(key, true)\n return true\n }\n\n public unlock(req: IRequest) {\n const key = `${req.method}:${req.url}:${req.user?.id || ''}`\n this.map.delete(key)\n }\n\n public checkLock(req: IRequest) {\n const key = `${req.method}:${req.url}:${req.user?.id || ''}`\n if (this.map.has(key)) {\n throw new ZError(100, 'request too fast')\n }\n this.lock(req)\n return true\n }\n\n public isLocked(req: IRequest) {\n const key = `${req.method}:${req.url}:${req.user?.id || ''}`\n return this.map.has(key)\n }\n}\n","/**\n * Singletonize a class\n * Usage:\n * @singleton\n * class Test {}\n * new Test() === new Test() // returns `true`\n * It can also be used without a decorator\n * const TestSingleton = singleton(Test)\n * new TestSingleton() === new TestSingleton() // returns `true`\n */\n\nexport const SINGLETON_KEY = Symbol()\n\nexport type Singleton<T extends new (...args: any[]) => any> = T & {\n [SINGLETON_KEY]: T extends new (...args: any[]) => infer I ? I : never\n}\nexport const singleton = <T extends new (...args: any[]) => any>(classTarget: T) =>\n new Proxy(classTarget, {\n construct(target: Singleton<T>, argumentsList, newTarget) {\n // Skip proxy for children\n if (target.prototype !== newTarget.prototype) {\n return Reflect.construct(target, argumentsList, newTarget)\n }\n if (!target[SINGLETON_KEY]) {\n target[SINGLETON_KEY] = Reflect.construct(target, argumentsList, newTarget)\n }\n return target[SINGLETON_KEY]\n },\n })\n","export class ZError implements Error {\n code: string\n statusCode?: number\n message: string\n name: string\n\n constructor(statusCode: number, message: string) {\n this.statusCode = statusCode\n this.message = message\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACWO,IAAM,gBAAgB,OAAO;AAK7B,IAAM,YAAY,CAAwC,gBAC/D,IAAI,MAAM,aAAa;AAAA,EACrB,UAAU,QAAsB,eAAe,WAAW;AAExD,QAAI,OAAO,cAAc,UAAU,WAAW;AAC5C,aAAO,QAAQ,UAAU,QAAQ,eAAe,SAAS;AAAA,IAC3D;AACA,QAAI,CAAC,OAAO,aAAa,GAAG;AAC1B,aAAO,aAAa,IAAI,QAAQ,UAAU,QAAQ,eAAe,SAAS;AAAA,IAC5E;AACA,WAAO,OAAO,aAAa;AAAA,EAC7B;AACF,CAAC;;;AC5BI,IAAM,SAAN,MAA8B;AAAA,EAMnC,YAAY,YAAoB,SAAiB;AAC/C,SAAK,aAAa;AAClB,SAAK,UAAU;AAAA,EACjB;AACF;;;AFEO,IAAM,aAAN,MAAiB;AAAA,EAAjB;AACL,eAA4B,oBAAI,IAAI;AAAA;AAAA,EAE7B,KAAK,KAAe;AACzB,UAAM,MAAM,GAAG,IAAI,MAAM,IAAI,IAAI,GAAG,IAAI,IAAI,MAAM,MAAM,EAAE;AAC1D,QAAI,KAAK,IAAI,IAAI,GAAG,GAAG;AACrB,aAAO;AAAA,IACT;AACA,SAAK,IAAI,IAAI,KAAK,IAAI;AACtB,WAAO;AAAA,EACT;AAAA,EAEO,OAAO,KAAe;AAC3B,UAAM,MAAM,GAAG,IAAI,MAAM,IAAI,IAAI,GAAG,IAAI,IAAI,MAAM,MAAM,EAAE;AAC1D,SAAK,IAAI,OAAO,GAAG;AAAA,EACrB;AAAA,EAEO,UAAU,KAAe;AAC9B,UAAM,MAAM,GAAG,IAAI,MAAM,IAAI,IAAI,GAAG,IAAI,IAAI,MAAM,MAAM,EAAE;AAC1D,QAAI,KAAK,IAAI,IAAI,GAAG,GAAG;AACrB,YAAM,IAAI,OAAO,KAAK,kBAAkB;AAAA,IAC1C;AACA,SAAK,KAAK,GAAG;AACb,WAAO;AAAA,EACT;AAAA,EAEO,SAAS,KAAe;AAC7B,UAAM,MAAM,GAAG,IAAI,MAAM,IAAI,IAAI,GAAG,IAAI,IAAI,MAAM,MAAM,EAAE;AAC1D,WAAO,KAAK,IAAI,IAAI,GAAG;AAAA,EACzB;AACF;AA9Ba,aAAN;AAAA,EADN;AAAA,GACY;","names":[]} |