plutin 1.2.2 → 1.3.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.
Files changed (31) hide show
  1. package/dist/core/decorators/controller-http-decorator.cjs +4 -2
  2. package/dist/core/decorators/controller-http-decorator.cjs.map +1 -1
  3. package/dist/core/decorators/controller-http-decorator.js +4 -2
  4. package/dist/core/decorators/controller-http-decorator.js.map +1 -1
  5. package/dist/core/decorators/dependency-container.cjs +4 -2
  6. package/dist/core/decorators/dependency-container.cjs.map +1 -1
  7. package/dist/core/decorators/dependency-container.js +4 -2
  8. package/dist/core/decorators/dependency-container.js.map +1 -1
  9. package/dist/core/entities/replace.cjs +19 -0
  10. package/dist/core/entities/replace.cjs.map +1 -0
  11. package/dist/core/entities/replace.d.cts +5 -0
  12. package/dist/core/entities/replace.d.ts +5 -0
  13. package/dist/core/entities/replace.js +1 -0
  14. package/dist/core/entities/replace.js.map +1 -0
  15. package/dist/core/http/base-controller.cjs +4 -2
  16. package/dist/core/http/base-controller.cjs.map +1 -1
  17. package/dist/core/http/base-controller.js +4 -2
  18. package/dist/core/http/base-controller.js.map +1 -1
  19. package/dist/index.cjs +4 -2
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +1 -0
  22. package/dist/index.d.ts +1 -0
  23. package/dist/index.js +4 -2
  24. package/dist/index.js.map +1 -1
  25. package/dist/infra/adapters/notifications/discord.cjs.map +1 -1
  26. package/dist/infra/adapters/notifications/discord.js.map +1 -1
  27. package/dist/infra/adapters/notifications/notification-factory.cjs.map +1 -1
  28. package/dist/infra/adapters/notifications/notification-factory.js.map +1 -1
  29. package/dist/infra/adapters/notifications/sentry.cjs.map +1 -1
  30. package/dist/infra/adapters/notifications/sentry.js.map +1 -1
  31. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/core/decorators/dependency-container.ts","../../../../src/infra/adapters/notifications/discord.ts","../../../../src/infra/adapters/notifications/in-memory.ts","../../../../src/infra/adapters/notifications/sentry.ts","../../../../src/infra/adapters/notifications/notification-factory.ts"],"sourcesContent":["import 'reflect-metadata'\n\ntype Class<T = any> = new (...args: any[]) => T\n\ntype Registration =\n | { type: 'class'; myClass: Class; singleton: boolean }\n | { type: 'value'; value: any }\n\nexport class DependencyContainer {\n static registry = new Map<string, Registration>()\n static singletons = new Map<string, any>()\n\n static register<T>(\n token: string,\n myClass: Class<T>,\n options: { singleton: boolean }\n ) {\n this.registry.set(token, {\n type: 'class',\n myClass,\n singleton: options.singleton,\n })\n }\n\n static registerValue<T>(token: string, value: T) {\n this.registry.set(token, { type: 'value', value })\n }\n\n static resolve<T>(target: Class<T>): T {\n const paramTypes = Reflect.getMetadata('design:paramtypes', target) || []\n\n const injectMetadata: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', target) || {}\n\n const params = paramTypes.map((_: any, index: number) => {\n const token = injectMetadata[index]\n\n if (!token) {\n throw new Error(\n `Missing @Inject token for parameter index ${index} in ${target.name}`\n )\n }\n\n return this.resolveToken(token)\n })\n\n return new target(...params)\n }\n\n static resolveToken(token: string): any {\n const registration = this.registry.get(token)\n\n if (!registration) {\n throw new Error(\n `\"${token}\" not registered. Please register it in the container.`\n )\n }\n\n if (registration.type === 'value') {\n return registration.value\n }\n\n const { myClass, singleton } = registration\n\n if (singleton) {\n if (!this.singletons.has(token)) {\n const instance = this.resolve(myClass)\n this.singletons.set(token, instance)\n }\n return this.singletons.get(token)\n }\n\n return this.resolve(myClass)\n }\n}\n\nexport function Inject(token: string): ParameterDecorator {\n return (\n target: object,\n _propertyKey: string | symbol | undefined,\n parameterIndex: number\n ): void => {\n const constructor =\n typeof target === 'function' ? target : target.constructor\n\n const existingInjectedParams: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', constructor) || {}\n\n existingInjectedParams[parameterIndex] = token\n\n Reflect.defineMetadata('inject:params', existingInjectedParams, constructor)\n }\n}\n","import { Inject } from 'core/decorators/dependency-container'\nimport { MessageBuilder, Webhook } from 'discord-webhook-node'\n\nimport type { ContextError } from '../../../core/http/base-controller'\nimport type { IErrorNotifier } from '../../../core/http/error-notifier'\n\ntype DiscordOptions = {\n url: string\n env: string\n}\n\nexport class DiscordNotifier implements IErrorNotifier {\n private webhook: Webhook\n\n constructor(\n @Inject('DiscordConfig') private readonly options: DiscordOptions\n ) {\n this.webhook = new Webhook(this.options.url)\n }\n\n async notify(error: Error, context: ContextError): Promise<void> {\n const embed = new MessageBuilder()\n .setTitle('🚨 Error')\n .addField('Message', `\\`\\`\\`${error.message.slice(0, 300)}\\`\\`\\``)\n .addField(\n 'Route:',\n `\\`[${context?.request?.method}] ${context?.request?.url}\\``,\n true\n )\n .addField(\n 'Params:',\n '```json\\n' +\n JSON.stringify(context?.request?.params, null, 2) +\n '\\n```',\n true\n )\n .addField(\n 'Query:',\n '```json\\n' +\n JSON.stringify(context?.request?.query, null, 2) +\n '\\n```',\n true\n )\n .addField(\n 'Headers:',\n '```json\\n' +\n JSON.stringify(context?.request?.headers, null, 2) +\n '\\n```',\n true\n )\n .addField(\n 'Body:',\n '```json\\n' + JSON.stringify(context?.request?.body, null, 2) + '\\n```'\n )\n .addField(\n 'Stack Trace:',\n '```' + (error.stack || 'No stack provided').slice(0, 900) + '```'\n )\n .setFooter(`Env: ${this.options.env || 'development'}`)\n .setTimestamp()\n\n await this.webhook.send(embed)\n }\n}\n","import type { ContextError } from '../../../core/http/base-controller'\nimport type { IErrorNotifier } from '../../../core/http/error-notifier'\n\nexport class NotificationErrorInMemory implements IErrorNotifier {\n public errors: any[] = []\n\n async notify(error: Error, context?: ContextError): Promise<void> {\n console.log('NOTIFICATION ERROR: ', error)\n\n this.errors.push({\n error: error.message,\n context,\n })\n }\n}\n","import * as Sentry from '@sentry/node'\nimport type { ContextError } from 'core/http/base-controller'\n\nimport { Inject } from '../../../core/decorators/dependency-container'\nimport { IErrorNotifier } from '../../../core/http/error-notifier'\n\ntype SentryOptions = {\n dsn: string\n environment: string\n}\n\nexport class SentryNotifier implements IErrorNotifier {\n constructor(@Inject('SentryConfig') private readonly options: SentryOptions) {\n Sentry.init({\n dsn: this.options.dsn,\n environment: this.options.environment,\n attachStacktrace: true,\n tracesSampleRate: this.options.environment === 'production' ? 0.1 : 1.0,\n maxBreadcrumbs: 100,\n debug: this.options.environment !== 'production',\n })\n }\n\n async notify(error: Error, context: ContextError): Promise<void> {\n Sentry.withScope((scope) => {\n scope.setLevel('error')\n\n if (context?.env) scope.setTag('env', context.env)\n\n if (context?.user) {\n scope.setUser({\n id: context.user.id,\n username: context.user.name,\n email: context.user.email,\n })\n }\n\n if (context?.request) {\n const { body, query, params, headers, method, url, requestId } =\n context.request\n\n scope.setContext('http', {\n method,\n requestId,\n url,\n headers,\n query,\n body,\n params,\n })\n }\n\n Sentry.captureException(error)\n })\n }\n}\n","import type { z } from 'zod'\n\nimport type { baseEnvSchema } from '../../env'\n\nimport { DiscordNotifier } from './discord'\nimport { NotificationErrorInMemory } from './in-memory'\nimport { SentryNotifier } from './sentry'\n\ntype OptionsNotifications = 'console' | 'discord' | 'sentry'\ntype EnvironmentEnum = z.infer<typeof baseEnvSchema>['ENVIRONMENT']\n\ntype Props = {\n local?: OptionsNotifications\n test?: OptionsNotifications\n development?: OptionsNotifications\n staging?: OptionsNotifications\n production?: OptionsNotifications\n}\n\nexport class NotificationFactory {\n static define(env: EnvironmentEnum, definitions?: Props): any {\n const defaultDefinition = {\n test: this.defineProvider(definitions?.local ?? 'console'),\n development: this.defineProvider(definitions?.local ?? 'console'),\n staging: this.defineProvider(definitions?.local ?? 'discord'),\n production: this.defineProvider(definitions?.local ?? 'sentry'),\n }\n\n return defaultDefinition[env]\n }\n\n private static defineProvider(provider: OptionsNotifications) {\n switch (provider) {\n case 'console':\n return NotificationErrorInMemory\n case 'discord':\n return DiscordNotifier\n case 'sentry':\n return SentryNotifier\n default:\n return NotificationErrorInMemory\n }\n }\n}\n"],"mappings":";;;;AAAA,OAAO;AA4EA,SAASA,OAAOC,OAAa;AAClC,SAAO,CACLC,QACAC,cACAC,mBAAAA;AAEA,UAAMC,cACJ,OAAOH,WAAW,aAAaA,SAASA,OAAOG;AAEjD,UAAMC,yBACJC,QAAQC,eAAe,iBAAiBH,WAAAA,KAAgB,CAAC;AAE3DC,2BAAuBF,cAAAA,IAAkBH;AAEzCM,YAAQE,eAAe,iBAAiBH,wBAAwBD,WAAAA;EAClE;AACF;AAhBgBL;;;AC3EhB,SAASU,gBAAgBC,eAAe;;;;;;;;;;;;;;;;;;;;;;;AAUjC,IAAMC,kBAAN,MAAMA;SAAAA;;;;EACHC;EAERC,YAC4CC,SAC1C;SAD0CA,UAAAA;AAE1C,SAAKF,UAAU,IAAIG,QAAQ,KAAKD,QAAQE,GAAG;EAC7C;EAEA,MAAMC,OAAOC,OAAcC,SAAsC;AAC/D,UAAMC,QAAQ,IAAIC,eAAAA,EACfC,SAAS,iBAAA,EACTC,SAAS,WAAW,SAASL,MAAMM,QAAQC,MAAM,GAAG,GAAA,CAAA,QAAY,EAChEF,SACC,UACA,MAAMJ,SAASO,SAASC,MAAAA,KAAWR,SAASO,SAASV,GAAAA,MACrD,IAAA,EAEDO,SACC,WACA,cACEK,KAAKC,UAAUV,SAASO,SAASI,QAAQ,MAAM,CAAA,IAC/C,SACF,IAAA,EAEDP,SACC,UACA,cACEK,KAAKC,UAAUV,SAASO,SAASK,OAAO,MAAM,CAAA,IAC9C,SACF,IAAA,EAEDR,SACC,YACA,cACEK,KAAKC,UAAUV,SAASO,SAASM,SAAS,MAAM,CAAA,IAChD,SACF,IAAA,EAEDT,SACC,SACA,cAAcK,KAAKC,UAAUV,SAASO,SAASO,MAAM,MAAM,CAAA,IAAK,OAAA,EAEjEV,SACC,gBACA,SAASL,MAAMgB,SAAS,qBAAqBT,MAAM,GAAG,GAAA,IAAO,KAAA,EAE9DU,UAAU,QAAQ,KAAKrB,QAAQsB,OAAO,aAAA,EAAe,EACrDC,aAAY;AAEf,UAAM,KAAKzB,QAAQ0B,KAAKlB,KAAAA;EAC1B;AACF;;;;;;;;;;AC5DO,IAAMmB,4BAAN,MAAMA;EAAb,OAAaA;;;EACJC,SAAgB,CAAA;EAEvB,MAAMC,OAAOC,OAAcC,SAAuC;AAChEC,YAAQC,IAAI,wBAAwBH,KAAAA;AAEpC,SAAKF,OAAOM,KAAK;MACfJ,OAAOA,MAAMK;MACbJ;IACF,CAAA;EACF;AACF;;;ACdA,YAAYK,YAAY;;;;;;;;;;;;;;;;;;;;;;;AAWjB,IAAMC,iBAAN,MAAMA;SAAAA;;;;EACXC,YAAqDC,SAAwB;SAAxBA,UAAAA;AACnDC,IAAOC,YAAK;MACVC,KAAK,KAAKH,QAAQG;MAClBC,aAAa,KAAKJ,QAAQI;MAC1BC,kBAAkB;MAClBC,kBAAkB,KAAKN,QAAQI,gBAAgB,eAAe,MAAM;MACpEG,gBAAgB;MAChBC,OAAO,KAAKR,QAAQI,gBAAgB;IACtC,CAAA;EACF;EAEA,MAAMK,OAAOC,OAAcC,SAAsC;AAC/DV,IAAOW,iBAAU,CAACC,UAAAA;AAChBA,YAAMC,SAAS,OAAA;AAEf,UAAIH,SAASI;AAAKF,cAAMG,OAAO,OAAOL,QAAQI,GAAG;AAEjD,UAAIJ,SAASM,MAAM;AACjBJ,cAAMK,QAAQ;UACZC,IAAIR,QAAQM,KAAKE;UACjBC,UAAUT,QAAQM,KAAKI;UACvBC,OAAOX,QAAQM,KAAKK;QACtB,CAAA;MACF;AAEA,UAAIX,SAASY,SAAS;AACpB,cAAM,EAAEC,MAAMC,OAAOC,QAAQC,SAASC,QAAQC,KAAKC,UAAS,IAC1DnB,QAAQY;AAEVV,cAAMkB,WAAW,QAAQ;UACvBH;UACAE;UACAD;UACAF;UACAF;UACAD;UACAE;QACF,CAAA;MACF;AAEAzB,MAAO+B,wBAAiBtB,KAAAA;IAC1B,CAAA;EACF;AACF;;;;;;;;;;ACpCO,IAAMuB,sBAAN,MAAMA;EAfb,OAeaA;;;EACX,OAAOC,OAAOC,KAAsBC,aAA0B;AAC5D,UAAMC,oBAAoB;MACxBC,MAAM,KAAKC,eAAeH,aAAaI,SAAS,SAAA;MAChDC,aAAa,KAAKF,eAAeH,aAAaI,SAAS,SAAA;MACvDE,SAAS,KAAKH,eAAeH,aAAaI,SAAS,SAAA;MACnDG,YAAY,KAAKJ,eAAeH,aAAaI,SAAS,QAAA;IACxD;AAEA,WAAOH,kBAAkBF,GAAAA;EAC3B;EAEA,OAAeI,eAAeK,UAAgC;AAC5D,YAAQA,UAAAA;MACN,KAAK;AACH,eAAOC;MACT,KAAK;AACH,eAAOC;MACT,KAAK;AACH,eAAOC;MACT;AACE,eAAOF;IACX;EACF;AACF;","names":["Inject","token","target","_propertyKey","parameterIndex","constructor","existingInjectedParams","Reflect","getOwnMetadata","defineMetadata","MessageBuilder","Webhook","DiscordNotifier","webhook","constructor","options","Webhook","url","notify","error","context","embed","MessageBuilder","setTitle","addField","message","slice","request","method","JSON","stringify","params","query","headers","body","stack","setFooter","env","setTimestamp","send","NotificationErrorInMemory","errors","notify","error","context","console","log","push","message","Sentry","SentryNotifier","constructor","options","Sentry","init","dsn","environment","attachStacktrace","tracesSampleRate","maxBreadcrumbs","debug","notify","error","context","withScope","scope","setLevel","env","setTag","user","setUser","id","username","name","email","request","body","query","params","headers","method","url","requestId","setContext","captureException","NotificationFactory","define","env","definitions","defaultDefinition","test","defineProvider","local","development","staging","production","provider","NotificationErrorInMemory","DiscordNotifier","SentryNotifier"]}
1
+ {"version":3,"sources":["../../../../src/core/decorators/dependency-container.ts","../../../../src/infra/adapters/notifications/discord.ts","../../../../src/infra/adapters/notifications/in-memory.ts","../../../../src/infra/adapters/notifications/sentry.ts","../../../../src/infra/adapters/notifications/notification-factory.ts"],"sourcesContent":["import 'reflect-metadata'\n\ntype Class<T = any> = new (...args: any[]) => T\n\ntype Registration =\n | { type: 'class'; myClass: Class; singleton: boolean }\n | { type: 'value'; value: any }\n\nexport class DependencyContainer {\n static registry = new Map<string, Registration>()\n static singletons = new Map<string, any>()\n\n static register<T>(\n token: string,\n myClass: Class<T>,\n options: { singleton: boolean }\n ) {\n this.registry.set(token, {\n type: 'class',\n myClass,\n singleton: options.singleton,\n })\n }\n\n static registerValue<T>(token: string, value: T) {\n this.registry.set(token, { type: 'value', value })\n }\n\n static resolve<T>(target: Class<T>): T {\n const injectMetadata: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', target) || {}\n\n const paramCount = Object.keys(injectMetadata).length\n\n const params = Array.from({ length: paramCount }, (_, index) => {\n const token = injectMetadata[index]\n if (!token) {\n throw new Error(\n `Missing @Inject token for parameter index ${index} in ${target.name}`\n )\n }\n return this.resolveToken(token)\n })\n\n return new target(...params)\n }\n\n static resolveToken(token: string): any {\n const registration = this.registry.get(token)\n\n if (!registration) {\n throw new Error(\n `\"${token}\" not registered. Please register it in the container.`\n )\n }\n\n if (registration.type === 'value') {\n return registration.value\n }\n\n const { myClass, singleton } = registration\n\n if (singleton) {\n if (!this.singletons.has(token)) {\n const instance = this.resolve(myClass)\n this.singletons.set(token, instance)\n }\n return this.singletons.get(token)\n }\n\n return this.resolve(myClass)\n }\n}\n\nexport function Inject(token: string): ParameterDecorator {\n return (\n target: object,\n _propertyKey: string | symbol | undefined,\n parameterIndex: number\n ): void => {\n const constructor =\n typeof target === 'function' ? target : target.constructor\n\n const existingInjectedParams: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', constructor) || {}\n\n existingInjectedParams[parameterIndex] = token\n\n Reflect.defineMetadata('inject:params', existingInjectedParams, constructor)\n }\n}\n","import { Inject } from 'core/decorators/dependency-container'\nimport { MessageBuilder, Webhook } from 'discord-webhook-node'\n\nimport type { ContextError } from '../../../core/http/base-controller'\nimport type { IErrorNotifier } from '../../../core/http/error-notifier'\n\ntype DiscordOptions = {\n url: string\n env: string\n}\n\nexport class DiscordNotifier implements IErrorNotifier {\n private webhook: Webhook\n\n constructor(\n @Inject('DiscordConfig') private readonly options: DiscordOptions\n ) {\n this.webhook = new Webhook(this.options.url)\n }\n\n async notify(error: Error, context: ContextError): Promise<void> {\n const embed = new MessageBuilder()\n .setTitle('🚨 Error')\n .addField('Message', `\\`\\`\\`${error.message.slice(0, 300)}\\`\\`\\``)\n .addField(\n 'Route:',\n `\\`[${context?.request?.method}] ${context?.request?.url}\\``,\n true\n )\n .addField(\n 'Params:',\n '```json\\n' +\n JSON.stringify(context?.request?.params, null, 2) +\n '\\n```',\n true\n )\n .addField(\n 'Query:',\n '```json\\n' +\n JSON.stringify(context?.request?.query, null, 2) +\n '\\n```',\n true\n )\n .addField(\n 'Headers:',\n '```json\\n' +\n JSON.stringify(context?.request?.headers, null, 2) +\n '\\n```',\n true\n )\n .addField(\n 'Body:',\n '```json\\n' + JSON.stringify(context?.request?.body, null, 2) + '\\n```'\n )\n .addField(\n 'Stack Trace:',\n '```' + (error.stack || 'No stack provided').slice(0, 900) + '```'\n )\n .setFooter(`Env: ${this.options.env || 'development'}`)\n .setTimestamp()\n\n await this.webhook.send(embed)\n }\n}\n","import type { ContextError } from '../../../core/http/base-controller'\nimport type { IErrorNotifier } from '../../../core/http/error-notifier'\n\nexport class NotificationErrorInMemory implements IErrorNotifier {\n public errors: any[] = []\n\n async notify(error: Error, context?: ContextError): Promise<void> {\n console.log('NOTIFICATION ERROR: ', error)\n\n this.errors.push({\n error: error.message,\n context,\n })\n }\n}\n","import * as Sentry from '@sentry/node'\nimport type { ContextError } from 'core/http/base-controller'\n\nimport { Inject } from '../../../core/decorators/dependency-container'\nimport { IErrorNotifier } from '../../../core/http/error-notifier'\n\ntype SentryOptions = {\n dsn: string\n environment: string\n}\n\nexport class SentryNotifier implements IErrorNotifier {\n constructor(@Inject('SentryConfig') private readonly options: SentryOptions) {\n Sentry.init({\n dsn: this.options.dsn,\n environment: this.options.environment,\n attachStacktrace: true,\n tracesSampleRate: this.options.environment === 'production' ? 0.1 : 1.0,\n maxBreadcrumbs: 100,\n debug: this.options.environment !== 'production',\n })\n }\n\n async notify(error: Error, context: ContextError): Promise<void> {\n Sentry.withScope((scope) => {\n scope.setLevel('error')\n\n if (context?.env) scope.setTag('env', context.env)\n\n if (context?.user) {\n scope.setUser({\n id: context.user.id,\n username: context.user.name,\n email: context.user.email,\n })\n }\n\n if (context?.request) {\n const { body, query, params, headers, method, url, requestId } =\n context.request\n\n scope.setContext('http', {\n method,\n requestId,\n url,\n headers,\n query,\n body,\n params,\n })\n }\n\n Sentry.captureException(error)\n })\n }\n}\n","import type { z } from 'zod'\n\nimport type { baseEnvSchema } from '../../env'\n\nimport { DiscordNotifier } from './discord'\nimport { NotificationErrorInMemory } from './in-memory'\nimport { SentryNotifier } from './sentry'\n\ntype OptionsNotifications = 'console' | 'discord' | 'sentry'\ntype EnvironmentEnum = z.infer<typeof baseEnvSchema>['ENVIRONMENT']\n\ntype Props = {\n local?: OptionsNotifications\n test?: OptionsNotifications\n development?: OptionsNotifications\n staging?: OptionsNotifications\n production?: OptionsNotifications\n}\n\nexport class NotificationFactory {\n static define(env: EnvironmentEnum, definitions?: Props): any {\n const defaultDefinition = {\n test: this.defineProvider(definitions?.local ?? 'console'),\n development: this.defineProvider(definitions?.local ?? 'console'),\n staging: this.defineProvider(definitions?.local ?? 'discord'),\n production: this.defineProvider(definitions?.local ?? 'sentry'),\n }\n\n return defaultDefinition[env]\n }\n\n private static defineProvider(provider: OptionsNotifications) {\n switch (provider) {\n case 'console':\n return NotificationErrorInMemory\n case 'discord':\n return DiscordNotifier\n case 'sentry':\n return SentryNotifier\n default:\n return NotificationErrorInMemory\n }\n }\n}\n"],"mappings":"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","names":["Inject","token","target","_propertyKey","parameterIndex","constructor","existingInjectedParams","Reflect","getOwnMetadata","defineMetadata","MessageBuilder","Webhook","DiscordNotifier","webhook","constructor","options","Webhook","url","notify","error","context","embed","MessageBuilder","setTitle","addField","message","slice","request","method","JSON","stringify","params","query","headers","body","stack","setFooter","env","setTimestamp","send","NotificationErrorInMemory","errors","notify","error","context","console","log","push","message","Sentry","SentryNotifier","constructor","options","Sentry","init","dsn","environment","attachStacktrace","tracesSampleRate","maxBreadcrumbs","debug","notify","error","context","withScope","scope","setLevel","env","setTag","user","setUser","id","username","name","email","request","body","query","params","headers","method","url","requestId","setContext","captureException","NotificationFactory","define","env","definitions","defaultDefinition","test","defineProvider","local","development","staging","production","provider","NotificationErrorInMemory","DiscordNotifier","SentryNotifier"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/infra/adapters/notifications/sentry.ts","../../../../src/core/decorators/dependency-container.ts"],"sourcesContent":["import * as Sentry from '@sentry/node'\nimport type { ContextError } from 'core/http/base-controller'\n\nimport { Inject } from '../../../core/decorators/dependency-container'\nimport { IErrorNotifier } from '../../../core/http/error-notifier'\n\ntype SentryOptions = {\n dsn: string\n environment: string\n}\n\nexport class SentryNotifier implements IErrorNotifier {\n constructor(@Inject('SentryConfig') private readonly options: SentryOptions) {\n Sentry.init({\n dsn: this.options.dsn,\n environment: this.options.environment,\n attachStacktrace: true,\n tracesSampleRate: this.options.environment === 'production' ? 0.1 : 1.0,\n maxBreadcrumbs: 100,\n debug: this.options.environment !== 'production',\n })\n }\n\n async notify(error: Error, context: ContextError): Promise<void> {\n Sentry.withScope((scope) => {\n scope.setLevel('error')\n\n if (context?.env) scope.setTag('env', context.env)\n\n if (context?.user) {\n scope.setUser({\n id: context.user.id,\n username: context.user.name,\n email: context.user.email,\n })\n }\n\n if (context?.request) {\n const { body, query, params, headers, method, url, requestId } =\n context.request\n\n scope.setContext('http', {\n method,\n requestId,\n url,\n headers,\n query,\n body,\n params,\n })\n }\n\n Sentry.captureException(error)\n })\n }\n}\n","import 'reflect-metadata'\n\ntype Class<T = any> = new (...args: any[]) => T\n\ntype Registration =\n | { type: 'class'; myClass: Class; singleton: boolean }\n | { type: 'value'; value: any }\n\nexport class DependencyContainer {\n static registry = new Map<string, Registration>()\n static singletons = new Map<string, any>()\n\n static register<T>(\n token: string,\n myClass: Class<T>,\n options: { singleton: boolean }\n ) {\n this.registry.set(token, {\n type: 'class',\n myClass,\n singleton: options.singleton,\n })\n }\n\n static registerValue<T>(token: string, value: T) {\n this.registry.set(token, { type: 'value', value })\n }\n\n static resolve<T>(target: Class<T>): T {\n const paramTypes = Reflect.getMetadata('design:paramtypes', target) || []\n\n const injectMetadata: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', target) || {}\n\n const params = paramTypes.map((_: any, index: number) => {\n const token = injectMetadata[index]\n\n if (!token) {\n throw new Error(\n `Missing @Inject token for parameter index ${index} in ${target.name}`\n )\n }\n\n return this.resolveToken(token)\n })\n\n return new target(...params)\n }\n\n static resolveToken(token: string): any {\n const registration = this.registry.get(token)\n\n if (!registration) {\n throw new Error(\n `\"${token}\" not registered. Please register it in the container.`\n )\n }\n\n if (registration.type === 'value') {\n return registration.value\n }\n\n const { myClass, singleton } = registration\n\n if (singleton) {\n if (!this.singletons.has(token)) {\n const instance = this.resolve(myClass)\n this.singletons.set(token, instance)\n }\n return this.singletons.get(token)\n }\n\n return this.resolve(myClass)\n }\n}\n\nexport function Inject(token: string): ParameterDecorator {\n return (\n target: object,\n _propertyKey: string | symbol | undefined,\n parameterIndex: number\n ): void => {\n const constructor =\n typeof target === 'function' ? target : target.constructor\n\n const existingInjectedParams: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', constructor) || {}\n\n existingInjectedParams[parameterIndex] = token\n\n Reflect.defineMetadata('inject:params', existingInjectedParams, constructor)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,aAAwB;;;ACAxB,8BAAO;AA4EA,SAASA,OAAOC,OAAa;AAClC,SAAO,CACLC,QACAC,cACAC,mBAAAA;AAEA,UAAMC,cACJ,OAAOH,WAAW,aAAaA,SAASA,OAAOG;AAEjD,UAAMC,yBACJC,QAAQC,eAAe,iBAAiBH,WAAAA,KAAgB,CAAC;AAE3DC,2BAAuBF,cAAAA,IAAkBH;AAEzCM,YAAQE,eAAe,iBAAiBH,wBAAwBD,WAAAA;EAClE;AACF;AAhBgBL;;;;;;;;;;;;;;;;;;;;;;;;;ADjET,IAAMU,iBAAN,MAAMA;SAAAA;;;;EACXC,YAAqDC,SAAwB;SAAxBA,UAAAA;AACnDC,IAAOC,YAAK;MACVC,KAAK,KAAKH,QAAQG;MAClBC,aAAa,KAAKJ,QAAQI;MAC1BC,kBAAkB;MAClBC,kBAAkB,KAAKN,QAAQI,gBAAgB,eAAe,MAAM;MACpEG,gBAAgB;MAChBC,OAAO,KAAKR,QAAQI,gBAAgB;IACtC,CAAA;EACF;EAEA,MAAMK,OAAOC,OAAcC,SAAsC;AAC/DV,IAAOW,iBAAU,CAACC,UAAAA;AAChBA,YAAMC,SAAS,OAAA;AAEf,UAAIH,SAASI;AAAKF,cAAMG,OAAO,OAAOL,QAAQI,GAAG;AAEjD,UAAIJ,SAASM,MAAM;AACjBJ,cAAMK,QAAQ;UACZC,IAAIR,QAAQM,KAAKE;UACjBC,UAAUT,QAAQM,KAAKI;UACvBC,OAAOX,QAAQM,KAAKK;QACtB,CAAA;MACF;AAEA,UAAIX,SAASY,SAAS;AACpB,cAAM,EAAEC,MAAMC,OAAOC,QAAQC,SAASC,QAAQC,KAAKC,UAAS,IAC1DnB,QAAQY;AAEVV,cAAMkB,WAAW,QAAQ;UACvBH;UACAE;UACAD;UACAF;UACAF;UACAD;UACAE;QACF,CAAA;MACF;AAEAzB,MAAO+B,wBAAiBtB,KAAAA;IAC1B,CAAA;EACF;AACF;;;;;;;;","names":["Inject","token","target","_propertyKey","parameterIndex","constructor","existingInjectedParams","Reflect","getOwnMetadata","defineMetadata","SentryNotifier","constructor","options","Sentry","init","dsn","environment","attachStacktrace","tracesSampleRate","maxBreadcrumbs","debug","notify","error","context","withScope","scope","setLevel","env","setTag","user","setUser","id","username","name","email","request","body","query","params","headers","method","url","requestId","setContext","captureException"]}
1
+ {"version":3,"sources":["../../../../src/infra/adapters/notifications/sentry.ts","../../../../src/core/decorators/dependency-container.ts"],"sourcesContent":["import * as Sentry from '@sentry/node'\nimport type { ContextError } from 'core/http/base-controller'\n\nimport { Inject } from '../../../core/decorators/dependency-container'\nimport { IErrorNotifier } from '../../../core/http/error-notifier'\n\ntype SentryOptions = {\n dsn: string\n environment: string\n}\n\nexport class SentryNotifier implements IErrorNotifier {\n constructor(@Inject('SentryConfig') private readonly options: SentryOptions) {\n Sentry.init({\n dsn: this.options.dsn,\n environment: this.options.environment,\n attachStacktrace: true,\n tracesSampleRate: this.options.environment === 'production' ? 0.1 : 1.0,\n maxBreadcrumbs: 100,\n debug: this.options.environment !== 'production',\n })\n }\n\n async notify(error: Error, context: ContextError): Promise<void> {\n Sentry.withScope((scope) => {\n scope.setLevel('error')\n\n if (context?.env) scope.setTag('env', context.env)\n\n if (context?.user) {\n scope.setUser({\n id: context.user.id,\n username: context.user.name,\n email: context.user.email,\n })\n }\n\n if (context?.request) {\n const { body, query, params, headers, method, url, requestId } =\n context.request\n\n scope.setContext('http', {\n method,\n requestId,\n url,\n headers,\n query,\n body,\n params,\n })\n }\n\n Sentry.captureException(error)\n })\n }\n}\n","import 'reflect-metadata'\n\ntype Class<T = any> = new (...args: any[]) => T\n\ntype Registration =\n | { type: 'class'; myClass: Class; singleton: boolean }\n | { type: 'value'; value: any }\n\nexport class DependencyContainer {\n static registry = new Map<string, Registration>()\n static singletons = new Map<string, any>()\n\n static register<T>(\n token: string,\n myClass: Class<T>,\n options: { singleton: boolean }\n ) {\n this.registry.set(token, {\n type: 'class',\n myClass,\n singleton: options.singleton,\n })\n }\n\n static registerValue<T>(token: string, value: T) {\n this.registry.set(token, { type: 'value', value })\n }\n\n static resolve<T>(target: Class<T>): T {\n const injectMetadata: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', target) || {}\n\n const paramCount = Object.keys(injectMetadata).length\n\n const params = Array.from({ length: paramCount }, (_, index) => {\n const token = injectMetadata[index]\n if (!token) {\n throw new Error(\n `Missing @Inject token for parameter index ${index} in ${target.name}`\n )\n }\n return this.resolveToken(token)\n })\n\n return new target(...params)\n }\n\n static resolveToken(token: string): any {\n const registration = this.registry.get(token)\n\n if (!registration) {\n throw new Error(\n `\"${token}\" not registered. Please register it in the container.`\n )\n }\n\n if (registration.type === 'value') {\n return registration.value\n }\n\n const { myClass, singleton } = registration\n\n if (singleton) {\n if (!this.singletons.has(token)) {\n const instance = this.resolve(myClass)\n this.singletons.set(token, instance)\n }\n return this.singletons.get(token)\n }\n\n return this.resolve(myClass)\n }\n}\n\nexport function Inject(token: string): ParameterDecorator {\n return (\n target: object,\n _propertyKey: string | symbol | undefined,\n parameterIndex: number\n ): void => {\n const constructor =\n typeof target === 'function' ? target : target.constructor\n\n const existingInjectedParams: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', constructor) || {}\n\n existingInjectedParams[parameterIndex] = token\n\n Reflect.defineMetadata('inject:params', existingInjectedParams, constructor)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,aAAwB;;;ACAxB,8BAAO;AA0EA,SAASA,OAAOC,OAAa;AAClC,SAAO,CACLC,QACAC,cACAC,mBAAAA;AAEA,UAAMC,cACJ,OAAOH,WAAW,aAAaA,SAASA,OAAOG;AAEjD,UAAMC,yBACJC,QAAQC,eAAe,iBAAiBH,WAAAA,KAAgB,CAAC;AAE3DC,2BAAuBF,cAAAA,IAAkBH;AAEzCM,YAAQE,eAAe,iBAAiBH,wBAAwBD,WAAAA;EAClE;AACF;AAhBgBL;;;;;;;;;;;;;;;;;;;;;;;;;AD/DT,IAAMU,iBAAN,MAAMA;SAAAA;;;;EACXC,YAAqDC,SAAwB;SAAxBA,UAAAA;AACnDC,IAAOC,YAAK;MACVC,KAAK,KAAKH,QAAQG;MAClBC,aAAa,KAAKJ,QAAQI;MAC1BC,kBAAkB;MAClBC,kBAAkB,KAAKN,QAAQI,gBAAgB,eAAe,MAAM;MACpEG,gBAAgB;MAChBC,OAAO,KAAKR,QAAQI,gBAAgB;IACtC,CAAA;EACF;EAEA,MAAMK,OAAOC,OAAcC,SAAsC;AAC/DV,IAAOW,iBAAU,CAACC,UAAAA;AAChBA,YAAMC,SAAS,OAAA;AAEf,UAAIH,SAASI;AAAKF,cAAMG,OAAO,OAAOL,QAAQI,GAAG;AAEjD,UAAIJ,SAASM,MAAM;AACjBJ,cAAMK,QAAQ;UACZC,IAAIR,QAAQM,KAAKE;UACjBC,UAAUT,QAAQM,KAAKI;UACvBC,OAAOX,QAAQM,KAAKK;QACtB,CAAA;MACF;AAEA,UAAIX,SAASY,SAAS;AACpB,cAAM,EAAEC,MAAMC,OAAOC,QAAQC,SAASC,QAAQC,KAAKC,UAAS,IAC1DnB,QAAQY;AAEVV,cAAMkB,WAAW,QAAQ;UACvBH;UACAE;UACAD;UACAF;UACAF;UACAD;UACAE;QACF,CAAA;MACF;AAEAzB,MAAO+B,wBAAiBtB,KAAAA;IAC1B,CAAA;EACF;AACF;;;;;;;;","names":["Inject","token","target","_propertyKey","parameterIndex","constructor","existingInjectedParams","Reflect","getOwnMetadata","defineMetadata","SentryNotifier","constructor","options","Sentry","init","dsn","environment","attachStacktrace","tracesSampleRate","maxBreadcrumbs","debug","notify","error","context","withScope","scope","setLevel","env","setTag","user","setUser","id","username","name","email","request","body","query","params","headers","method","url","requestId","setContext","captureException"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/infra/adapters/notifications/sentry.ts","../../../../src/core/decorators/dependency-container.ts"],"sourcesContent":["import * as Sentry from '@sentry/node'\nimport type { ContextError } from 'core/http/base-controller'\n\nimport { Inject } from '../../../core/decorators/dependency-container'\nimport { IErrorNotifier } from '../../../core/http/error-notifier'\n\ntype SentryOptions = {\n dsn: string\n environment: string\n}\n\nexport class SentryNotifier implements IErrorNotifier {\n constructor(@Inject('SentryConfig') private readonly options: SentryOptions) {\n Sentry.init({\n dsn: this.options.dsn,\n environment: this.options.environment,\n attachStacktrace: true,\n tracesSampleRate: this.options.environment === 'production' ? 0.1 : 1.0,\n maxBreadcrumbs: 100,\n debug: this.options.environment !== 'production',\n })\n }\n\n async notify(error: Error, context: ContextError): Promise<void> {\n Sentry.withScope((scope) => {\n scope.setLevel('error')\n\n if (context?.env) scope.setTag('env', context.env)\n\n if (context?.user) {\n scope.setUser({\n id: context.user.id,\n username: context.user.name,\n email: context.user.email,\n })\n }\n\n if (context?.request) {\n const { body, query, params, headers, method, url, requestId } =\n context.request\n\n scope.setContext('http', {\n method,\n requestId,\n url,\n headers,\n query,\n body,\n params,\n })\n }\n\n Sentry.captureException(error)\n })\n }\n}\n","import 'reflect-metadata'\n\ntype Class<T = any> = new (...args: any[]) => T\n\ntype Registration =\n | { type: 'class'; myClass: Class; singleton: boolean }\n | { type: 'value'; value: any }\n\nexport class DependencyContainer {\n static registry = new Map<string, Registration>()\n static singletons = new Map<string, any>()\n\n static register<T>(\n token: string,\n myClass: Class<T>,\n options: { singleton: boolean }\n ) {\n this.registry.set(token, {\n type: 'class',\n myClass,\n singleton: options.singleton,\n })\n }\n\n static registerValue<T>(token: string, value: T) {\n this.registry.set(token, { type: 'value', value })\n }\n\n static resolve<T>(target: Class<T>): T {\n const paramTypes = Reflect.getMetadata('design:paramtypes', target) || []\n\n const injectMetadata: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', target) || {}\n\n const params = paramTypes.map((_: any, index: number) => {\n const token = injectMetadata[index]\n\n if (!token) {\n throw new Error(\n `Missing @Inject token for parameter index ${index} in ${target.name}`\n )\n }\n\n return this.resolveToken(token)\n })\n\n return new target(...params)\n }\n\n static resolveToken(token: string): any {\n const registration = this.registry.get(token)\n\n if (!registration) {\n throw new Error(\n `\"${token}\" not registered. Please register it in the container.`\n )\n }\n\n if (registration.type === 'value') {\n return registration.value\n }\n\n const { myClass, singleton } = registration\n\n if (singleton) {\n if (!this.singletons.has(token)) {\n const instance = this.resolve(myClass)\n this.singletons.set(token, instance)\n }\n return this.singletons.get(token)\n }\n\n return this.resolve(myClass)\n }\n}\n\nexport function Inject(token: string): ParameterDecorator {\n return (\n target: object,\n _propertyKey: string | symbol | undefined,\n parameterIndex: number\n ): void => {\n const constructor =\n typeof target === 'function' ? target : target.constructor\n\n const existingInjectedParams: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', constructor) || {}\n\n existingInjectedParams[parameterIndex] = token\n\n Reflect.defineMetadata('inject:params', existingInjectedParams, constructor)\n }\n}\n"],"mappings":";;;;AAAA,YAAYA,YAAY;;;ACAxB,OAAO;AA4EA,SAASC,OAAOC,OAAa;AAClC,SAAO,CACLC,QACAC,cACAC,mBAAAA;AAEA,UAAMC,cACJ,OAAOH,WAAW,aAAaA,SAASA,OAAOG;AAEjD,UAAMC,yBACJC,QAAQC,eAAe,iBAAiBH,WAAAA,KAAgB,CAAC;AAE3DC,2BAAuBF,cAAAA,IAAkBH;AAEzCM,YAAQE,eAAe,iBAAiBH,wBAAwBD,WAAAA;EAClE;AACF;AAhBgBL;;;;;;;;;;;;;;;;;;;;;;;;;ADjET,IAAMU,iBAAN,MAAMA;SAAAA;;;;EACXC,YAAqDC,SAAwB;SAAxBA,UAAAA;AACnDC,IAAOC,YAAK;MACVC,KAAK,KAAKH,QAAQG;MAClBC,aAAa,KAAKJ,QAAQI;MAC1BC,kBAAkB;MAClBC,kBAAkB,KAAKN,QAAQI,gBAAgB,eAAe,MAAM;MACpEG,gBAAgB;MAChBC,OAAO,KAAKR,QAAQI,gBAAgB;IACtC,CAAA;EACF;EAEA,MAAMK,OAAOC,OAAcC,SAAsC;AAC/DV,IAAOW,iBAAU,CAACC,UAAAA;AAChBA,YAAMC,SAAS,OAAA;AAEf,UAAIH,SAASI;AAAKF,cAAMG,OAAO,OAAOL,QAAQI,GAAG;AAEjD,UAAIJ,SAASM,MAAM;AACjBJ,cAAMK,QAAQ;UACZC,IAAIR,QAAQM,KAAKE;UACjBC,UAAUT,QAAQM,KAAKI;UACvBC,OAAOX,QAAQM,KAAKK;QACtB,CAAA;MACF;AAEA,UAAIX,SAASY,SAAS;AACpB,cAAM,EAAEC,MAAMC,OAAOC,QAAQC,SAASC,QAAQC,KAAKC,UAAS,IAC1DnB,QAAQY;AAEVV,cAAMkB,WAAW,QAAQ;UACvBH;UACAE;UACAD;UACAF;UACAF;UACAD;UACAE;QACF,CAAA;MACF;AAEAzB,MAAO+B,wBAAiBtB,KAAAA;IAC1B,CAAA;EACF;AACF;;;;;;;;","names":["Sentry","Inject","token","target","_propertyKey","parameterIndex","constructor","existingInjectedParams","Reflect","getOwnMetadata","defineMetadata","SentryNotifier","constructor","options","Sentry","init","dsn","environment","attachStacktrace","tracesSampleRate","maxBreadcrumbs","debug","notify","error","context","withScope","scope","setLevel","env","setTag","user","setUser","id","username","name","email","request","body","query","params","headers","method","url","requestId","setContext","captureException"]}
1
+ {"version":3,"sources":["../../../../src/infra/adapters/notifications/sentry.ts","../../../../src/core/decorators/dependency-container.ts"],"sourcesContent":["import * as Sentry from '@sentry/node'\nimport type { ContextError } from 'core/http/base-controller'\n\nimport { Inject } from '../../../core/decorators/dependency-container'\nimport { IErrorNotifier } from '../../../core/http/error-notifier'\n\ntype SentryOptions = {\n dsn: string\n environment: string\n}\n\nexport class SentryNotifier implements IErrorNotifier {\n constructor(@Inject('SentryConfig') private readonly options: SentryOptions) {\n Sentry.init({\n dsn: this.options.dsn,\n environment: this.options.environment,\n attachStacktrace: true,\n tracesSampleRate: this.options.environment === 'production' ? 0.1 : 1.0,\n maxBreadcrumbs: 100,\n debug: this.options.environment !== 'production',\n })\n }\n\n async notify(error: Error, context: ContextError): Promise<void> {\n Sentry.withScope((scope) => {\n scope.setLevel('error')\n\n if (context?.env) scope.setTag('env', context.env)\n\n if (context?.user) {\n scope.setUser({\n id: context.user.id,\n username: context.user.name,\n email: context.user.email,\n })\n }\n\n if (context?.request) {\n const { body, query, params, headers, method, url, requestId } =\n context.request\n\n scope.setContext('http', {\n method,\n requestId,\n url,\n headers,\n query,\n body,\n params,\n })\n }\n\n Sentry.captureException(error)\n })\n }\n}\n","import 'reflect-metadata'\n\ntype Class<T = any> = new (...args: any[]) => T\n\ntype Registration =\n | { type: 'class'; myClass: Class; singleton: boolean }\n | { type: 'value'; value: any }\n\nexport class DependencyContainer {\n static registry = new Map<string, Registration>()\n static singletons = new Map<string, any>()\n\n static register<T>(\n token: string,\n myClass: Class<T>,\n options: { singleton: boolean }\n ) {\n this.registry.set(token, {\n type: 'class',\n myClass,\n singleton: options.singleton,\n })\n }\n\n static registerValue<T>(token: string, value: T) {\n this.registry.set(token, { type: 'value', value })\n }\n\n static resolve<T>(target: Class<T>): T {\n const injectMetadata: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', target) || {}\n\n const paramCount = Object.keys(injectMetadata).length\n\n const params = Array.from({ length: paramCount }, (_, index) => {\n const token = injectMetadata[index]\n if (!token) {\n throw new Error(\n `Missing @Inject token for parameter index ${index} in ${target.name}`\n )\n }\n return this.resolveToken(token)\n })\n\n return new target(...params)\n }\n\n static resolveToken(token: string): any {\n const registration = this.registry.get(token)\n\n if (!registration) {\n throw new Error(\n `\"${token}\" not registered. Please register it in the container.`\n )\n }\n\n if (registration.type === 'value') {\n return registration.value\n }\n\n const { myClass, singleton } = registration\n\n if (singleton) {\n if (!this.singletons.has(token)) {\n const instance = this.resolve(myClass)\n this.singletons.set(token, instance)\n }\n return this.singletons.get(token)\n }\n\n return this.resolve(myClass)\n }\n}\n\nexport function Inject(token: string): ParameterDecorator {\n return (\n target: object,\n _propertyKey: string | symbol | undefined,\n parameterIndex: number\n ): void => {\n const constructor =\n typeof target === 'function' ? target : target.constructor\n\n const existingInjectedParams: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', constructor) || {}\n\n existingInjectedParams[parameterIndex] = token\n\n Reflect.defineMetadata('inject:params', existingInjectedParams, constructor)\n }\n}\n"],"mappings":";;;;AAAA,YAAYA,YAAY;;;ACAxB,OAAO;AA0EA,SAASC,OAAOC,OAAa;AAClC,SAAO,CACLC,QACAC,cACAC,mBAAAA;AAEA,UAAMC,cACJ,OAAOH,WAAW,aAAaA,SAASA,OAAOG;AAEjD,UAAMC,yBACJC,QAAQC,eAAe,iBAAiBH,WAAAA,KAAgB,CAAC;AAE3DC,2BAAuBF,cAAAA,IAAkBH;AAEzCM,YAAQE,eAAe,iBAAiBH,wBAAwBD,WAAAA;EAClE;AACF;AAhBgBL;;;;;;;;;;;;;;;;;;;;;;;;;AD/DT,IAAMU,iBAAN,MAAMA;SAAAA;;;;EACXC,YAAqDC,SAAwB;SAAxBA,UAAAA;AACnDC,IAAOC,YAAK;MACVC,KAAK,KAAKH,QAAQG;MAClBC,aAAa,KAAKJ,QAAQI;MAC1BC,kBAAkB;MAClBC,kBAAkB,KAAKN,QAAQI,gBAAgB,eAAe,MAAM;MACpEG,gBAAgB;MAChBC,OAAO,KAAKR,QAAQI,gBAAgB;IACtC,CAAA;EACF;EAEA,MAAMK,OAAOC,OAAcC,SAAsC;AAC/DV,IAAOW,iBAAU,CAACC,UAAAA;AAChBA,YAAMC,SAAS,OAAA;AAEf,UAAIH,SAASI;AAAKF,cAAMG,OAAO,OAAOL,QAAQI,GAAG;AAEjD,UAAIJ,SAASM,MAAM;AACjBJ,cAAMK,QAAQ;UACZC,IAAIR,QAAQM,KAAKE;UACjBC,UAAUT,QAAQM,KAAKI;UACvBC,OAAOX,QAAQM,KAAKK;QACtB,CAAA;MACF;AAEA,UAAIX,SAASY,SAAS;AACpB,cAAM,EAAEC,MAAMC,OAAOC,QAAQC,SAASC,QAAQC,KAAKC,UAAS,IAC1DnB,QAAQY;AAEVV,cAAMkB,WAAW,QAAQ;UACvBH;UACAE;UACAD;UACAF;UACAF;UACAD;UACAE;QACF,CAAA;MACF;AAEAzB,MAAO+B,wBAAiBtB,KAAAA;IAC1B,CAAA;EACF;AACF;;;;;;;;","names":["Sentry","Inject","token","target","_propertyKey","parameterIndex","constructor","existingInjectedParams","Reflect","getOwnMetadata","defineMetadata","SentryNotifier","constructor","options","Sentry","init","dsn","environment","attachStacktrace","tracesSampleRate","maxBreadcrumbs","debug","notify","error","context","withScope","scope","setLevel","env","setTag","user","setUser","id","username","name","email","request","body","query","params","headers","method","url","requestId","setContext","captureException"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plutin",
3
- "version": "1.2.2",
3
+ "version": "1.3.0",
4
4
  "description": "Plutin lib",
5
5
  "private": false,
6
6
  "publishConfig": {