@autofleet/sequelize-utils 6.1.1 → 6.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -4
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +91 -8
- package/dist/index.d.ts +91 -8
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +10 -15
package/README.md
CHANGED
|
@@ -1,6 +1,91 @@
|
|
|
1
|
-
#
|
|
1
|
+
# v6 Migration Guide
|
|
2
|
+
|
|
3
|
+
## What changed (breaking)
|
|
4
|
+
|
|
5
|
+
* `@autofleet/events` **and** `@autofleet/logger` are now **peerDependencies** of this package, instead of being direct deps.
|
|
6
|
+
* `@autofleet/events` minimum version was changed from **v4** to **v5**, removing the implicit dep on `@autofleet/zehut`
|
|
7
|
+
* `registerModelEventHooks` now **requires** an `events` instance.
|
|
8
|
+
* Minimum Node.js version is **18**.
|
|
9
|
+
|
|
10
|
+
## Why
|
|
11
|
+
|
|
12
|
+
* Peer deps ensure a single shared instance of `logger`/`events` across services, keeping trace context intact.
|
|
13
|
+
* Requiring `events` at hook registration avoids hidden globals and makes wiring explicit.
|
|
14
|
+
|
|
15
|
+
## Install/upgrade
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# npm
|
|
19
|
+
npm i @autofleet/events@latest @autofleet/logger
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Ensure Node ≥ 18:
|
|
23
|
+
|
|
24
|
+
## API changes
|
|
25
|
+
|
|
26
|
+
**Init**
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
// was
|
|
30
|
+
sequelizeUtilsInit(sequelize)
|
|
31
|
+
|
|
32
|
+
// now (logger is optional but recommended to preserve trace context)
|
|
33
|
+
sequelizeUtilsInit(sequelize, logger)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Hooks**
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
// was
|
|
40
|
+
registerModelEventHooks(mapping)
|
|
41
|
+
|
|
42
|
+
// now (events is required)
|
|
43
|
+
registerModelEventHooks(mapping, events)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Migration steps
|
|
47
|
+
|
|
48
|
+
1. **Install peers**: `@autofleet/events` (v5) and `@autofleet/logger`.
|
|
49
|
+
2. **Pass logger at init** to keep original trace context.
|
|
50
|
+
3. **Pass events to hooks** (required).
|
|
51
|
+
4. **Run on Node 18+**.
|
|
52
|
+
|
|
53
|
+
## Before / After
|
|
54
|
+
|
|
55
|
+
**Before**
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import sequelizeUtilsInit from '@autofleet/sequelize-utils';
|
|
59
|
+
import { Sequelize } from 'sequelize-typescript';
|
|
60
|
+
|
|
61
|
+
const modelEventsTableMapping = {
|
|
62
|
+
SequelizeModel: { tableName: 'big_query_table' },
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const { registerModelEventHooks } = sequelizeUtilsInit(sequelize);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**After**
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
import sequelizeUtilsInit from '@autofleet/sequelize-utils';
|
|
72
|
+
import { Sequelize } from 'sequelize-typescript';
|
|
73
|
+
import logger from '../../logger';
|
|
74
|
+
import events from '../../events';
|
|
75
|
+
|
|
76
|
+
const modelEventsTableMapping = {
|
|
77
|
+
SequelizeModel: { tableName: 'big_query_table' },
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// pass logger to preserve trace context
|
|
81
|
+
const { registerModelEventHooks } = sequelizeUtilsInit(sequelize, logger);
|
|
82
|
+
|
|
83
|
+
// events is now required
|
|
84
|
+
registerModelEventHooks(modelEventsTableMapping, events);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Reference
|
|
88
|
+
|
|
89
|
+
Read the `@autofleet/events` v5 changes here: README: [link](https://github.com/Autofleet/autorepo/blob/60a175c70ebdba217612c2ee58be8f31881d6540/packages/events/README.md)
|
|
2
90
|
|
|
3
|
-
The breaking change in this version is the **implicit** upgrade of `zehut` from v3 to v4, via the upgrade of `@autofleet/events`.
|
|
4
|
-
The required version of zehut is now `^4.0.0`.
|
|
5
91
|
|
|
6
|
-
Additionally, the minimum node version is now 18, due to the minimum version of node defined in `zehut`.
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));const c=s(require(`@autofleet/logger`)),l=s(require(`sequelize`)),u=s(require(`debug`)),d=(0,c.default)();var f=d;const p=async(e,t)=>{t.transaction?t.transaction.afterCommit(()=>e()):await e()};var m=p;const h=e=>e instanceof Date||Object.prototype.toString.call(e)===`[object Date]`,g=e=>{let t={};for(let[n,r]of Object.entries(e)){let e=h(r)?r.getTime()/1e3:r;t[n]=e}return t},_=(e,t,n,r)=>{if(!n){
|
|
1
|
+
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));const c=s(require(`@autofleet/logger`)),l=s(require(`sequelize`)),u=s(require(`debug`)),d=(0,c.default)();var f=d;const p=async(e,t)=>{t.transaction?t.transaction.afterCommit(()=>e()):await e()};var m=p;const h=e=>e instanceof Date||Object.prototype.toString.call(e)===`[object Date]`,g=e=>{let t={};for(let[n,r]of Object.entries(e)){let e=h(r)?r.getTime()/1e3:r;t[n]=e}return t},_=(e,t,n,r)=>{let i=r??f;if(!n){i.warn(`Events object must be provided to addModelEventHooks`);return}let a=(e,r=!1)=>{try{let a=e.get();r&&Object.assign(a,{deletedAt:new Date});let o=t[e.constructor.name]?.tableName,s=g(a);if(!o)return;n.sendObject(o,`1`,s,Object.keys(e.rawAttributes)).catch(e=>{i.error(`sendObject error`,{tableName:o,eventVersion:`1`,e})})}catch(e){i.error(`dimTables error`,{e})}};e.addHook(`afterSave`,(e,t)=>m(()=>a(e),t)),e.addHook(`afterDestroy`,(e,t)=>m(()=>a(e,!0),t))};var v=_;const y=(0,u.default)(`sequelize-utils`),b=async(e,t,n=2,r={})=>{if(typeof t!=`function`)throw Error(`funcToRun must be a function`);if(typeof n!=`number`)throw Error(`if defined, retriesCount must be a number`);if(n<0)throw Error(`retriesCount must be a positive number`);try{let n=await e.transaction(r,async e=>{let n=await t(e);return n});return n}catch(i){if((i instanceof l.DatabaseError||i?.constructor?.name===`DatabaseError`)&&--n>=0)return y(`error inside transactionWithRetry - will retry times ${n}`,i),b(e,t,n,r);throw n===-1&&y(`error inside transactionWithRetry - will stop retry`,i),i}},x=`rollback has been called on this transaction`,S=`Transaction cancelled due to request cancellation`,C=(e,t,n,r)=>{let i=!1;if(t.socket.destroyed)throw y(S),Error(S);return e.transaction(async e=>{let a=async()=>{y(S),!i&&(i=!0,await e.rollback())},o=async()=>{let t=!n.writableFinished;if(t){if(y(S),i)return;i=!0,await e.rollback()}};t.socket.once(`close`,a),n.once(`close`,o);let s=()=>{t.socket.removeListener(`close`,a),n.removeListener(`close`,o)};try{let t=await r(e);return s(),t}catch(e){throw s(),e.message.includes(`rollback has been called on this transaction`)?Error(S):e}})};var w=(e,t)=>{let n=(t,n,r)=>b(e,t,n,r),r=(t,n,r)=>C(e,t,n,r),i=(n,r)=>v(e,n,r,t),a=(e,t)=>e?t(e):n(t,0);return{httpBasedTransaction:r,transactionWithRetry:n,registerModelEventHooks:i,runAfterTransactionCommits:m,useOrCreateTransaction:a}};module.exports=w;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["defaultExport: LoggerInstanceManager","cb: () => void | Promise<void>","options: Transactionable","input: unknown","obj: object","sequelize: Sequelize","modelTableMapping: ModelMapping","events: Events","logger?: LoggerInstanceManager","object: Model","packageLogger","sequelize","runAfterTransactionCommits","debugLog: debug.Debugger","sequelize: Sequelize","funcToRun: (transaction: Transaction) => Promise<T>","options: TransactionOptions","sequelize","DatabaseError","sequelize: Sequelize","req: IncomingMessage","res: ServerResponse","cb: (transaction: Transaction) => Promise<T>","sequelize","transaction: Transaction","sequelize: Sequelize","logger?: LoggerInstanceManager","transactionWithRetry","funcToRun: (transaction: Transaction) => Promise<T>","retriesCount?: number","options?: TransactionOptions","_transactionWithRetry","sequelize","httpBasedTransaction","req: IncomingMessage","res: ServerResponse","cb: (transaction: Transaction) => Promise<T>","_httpBasedTransaction","modelTableMapping: ModelMapping","events: Events","addModelEventHooks","transaction: Transaction","cb: (t: Transaction) => Promise<T>"],"sources":["../src/logger.ts","../src/runAfterTransactionCommits.ts","../src/model-event-hooks.ts","../src/common.ts","../src/transaction-with-retry.ts","../src/http-based-transaction.ts","../src/index.ts"],"sourcesContent":["import Logger, { LoggerInstanceManager } from '@autofleet/logger';\n\nconst defaultExport: LoggerInstanceManager = Logger();\nexport default defaultExport;\n","import { Transactionable } from 'sequelize';\n\nconst runAfterTransactionCommits = async (cb: () => void | Promise<void>, options: Transactionable): Promise<void> => {\n if (options.transaction) {\n options.transaction.afterCommit(() => cb());\n } else {\n await cb();\n }\n};\nexport default runAfterTransactionCommits;\n","import type { Model, Sequelize } from 'sequelize';\nimport type Events from '@autofleet/events';\nimport type { LoggerInstanceManager } from '@autofleet/logger';\nimport packageLogger from './logger';\nimport runAfterTransactionCommits from './runAfterTransactionCommits';\n\nexport interface ModelMapping {\n [ModelName: string]: {\n tableName: string\n };\n}\nconst isDate = (input: unknown): input is Date => input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n// eslint-disable-next-line @typescript-eslint/ban-types\nconst formatDatesInObject = (obj: object) => {\n const newObj = {};\n // eslint-disable-next-line no-restricted-syntax\n for (const [key, value] of Object.entries(obj)) {\n const valueToUse = isDate(value) ? value.getTime() / 1000 : value;\n newObj[key] = valueToUse;\n }\n return newObj;\n};\n\nconst addModelEventHooks = (sequelize: Sequelize, modelTableMapping: ModelMapping, events: Events, logger?: LoggerInstanceManager): void => {\n if (!events) {\n logger.warn('Events object must be provided to addModelEventHooks');\n return;\n }\n const updateEventToDimTable = (object: Model, isDelete = false) => {\n const localLogger = logger || packageLogger;\n try {\n const objectToSend = object.get();\n if (isDelete) {\n Object.assign(objectToSend, { deletedAt: new Date() });\n }\n const tableName = modelTableMapping[object.constructor.name]?.tableName;\n const eventVersion = '1';\n const objectToSendFormatted = formatDatesInObject(objectToSend);\n if (!tableName) {\n return;\n }\n events.sendObject(\n tableName,\n eventVersion,\n objectToSendFormatted,\n // @ts-expect-error the rawAttributes is typed as static, while it actually is on the instance level.\n Object.keys(object.rawAttributes),\n ).catch((e) => {\n localLogger.error('sendObject error', { tableName, eventVersion, e });\n });\n } catch (e) {\n localLogger.error('dimTables error', { e });\n }\n };\n\n sequelize.addHook('afterSave', (savedObject, options) => runAfterTransactionCommits(() => updateEventToDimTable(savedObject), options));\n sequelize.addHook('afterDestroy', (savedObject, options) => runAfterTransactionCommits(() => updateEventToDimTable(savedObject, true), options));\n};\n\nexport default addModelEventHooks;\n","import debug from 'debug';\n\nexport const debugLog: debug.Debugger = debug('sequelize-utils');\n","import {\n DatabaseError, type Sequelize, type Transaction, type TransactionOptions,\n} from 'sequelize';\nimport { debugLog } from './common';\n\nexport const transactionWithRetry = async <T>(sequelize: Sequelize, funcToRun: (transaction: Transaction) => Promise<T>, retriesCount = 2, options: TransactionOptions = {}): Promise<T> => {\n if (typeof funcToRun !== 'function') {\n throw new Error('funcToRun must be a function');\n }\n if (typeof retriesCount !== 'number') {\n throw new Error('if defined, retriesCount must be a number');\n }\n if (retriesCount < 0) {\n throw new Error('retriesCount must be a positive number');\n }\n try {\n const transValue = await sequelize.transaction(options, async (transaction) => {\n const funcValue = await funcToRun(transaction);\n return funcValue;\n });\n return transValue;\n } catch (e) {\n if ((e instanceof DatabaseError || e?.constructor?.name === 'DatabaseError') && --retriesCount >= 0) {\n debugLog(`error inside transactionWithRetry - will retry times ${retriesCount}`, e);\n return transactionWithRetry(sequelize, funcToRun, retriesCount, options);\n }\n if (retriesCount === -1) {\n debugLog('error inside transactionWithRetry - will stop retry', e);\n }\n throw e;\n }\n};\n","import type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { Sequelize, Transaction } from 'sequelize';\nimport { debugLog } from './common';\n\nconst rollbackErrorText = 'rollback has been called on this transaction';\nconst abortErrorText = 'Transaction cancelled due to request cancellation';\n\nexport const httpBasedTransaction = <T>(sequelize: Sequelize, req: IncomingMessage, res: ServerResponse, cb: (transaction: Transaction) => Promise<T>): Promise<T> => {\n let aborted = false;\n if (req.socket.destroyed) {\n debugLog(abortErrorText);\n throw new Error(abortErrorText);\n }\n return sequelize.transaction(async (transaction: Transaction) => {\n // https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/test/parallel/test-http-aborted.js#L9\n\n // 2023-04-13: Node.js 16.0.0\n // Added also the `res.writableFinished` check, because it seems that the socket is not destroyed when the request is aborted, but the response is not finished.\n // https://github.com/Jimbly/http-proxy-node16/commit/ba0c414cd03799e357c5d867c11dea06a9c34ec8#diff-b2d1e3b7c5f3b424a0af7971c582c822fd25a5ea279040ef6dc93fc4b2cf619dR151\n\n const rollback = async () => {\n debugLog(abortErrorText);\n if (aborted) return;\n aborted = true;\n await transaction.rollback();\n };\n const resRollback = async () => {\n const didNotFinishWrite = !res.writableFinished;\n if (didNotFinishWrite) {\n debugLog(abortErrorText);\n if (aborted) return;\n aborted = true;\n await transaction.rollback();\n }\n };\n req.socket.once('close', rollback);\n res.once('close', resRollback);\n\n const removeListeners = () => {\n req.socket.removeListener('close', rollback);\n res.removeListener('close', resRollback);\n };\n\n try {\n const response = await cb(transaction);\n removeListeners();\n return response;\n } catch (e) {\n removeListeners();\n if (e.message.includes(rollbackErrorText)) {\n throw new Error(abortErrorText);\n }\n throw e;\n }\n });\n};\n","/* eslint-disable import/prefer-default-export */\nimport type {\n Sequelize,\n Transaction,\n TransactionOptions,\n} from 'sequelize';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { LoggerInstanceManager } from '@autofleet/logger';\nimport type Events from '@autofleet/events';\nimport addModelEventHooks, { ModelMapping } from './model-event-hooks';\nimport { transactionWithRetry as _transactionWithRetry } from './transaction-with-retry';\nimport { httpBasedTransaction as _httpBasedTransaction } from './http-based-transaction';\nimport runAfterTransactionCommits from './runAfterTransactionCommits';\n\ntype ArgsWithoutSequelize<T> = T extends (arg1: Sequelize, ...args: infer U) => unknown ? U : never;\n\nexport default (sequelize: Sequelize, logger?: LoggerInstanceManager): {\n transactionWithRetry: <T>(...args: ArgsWithoutSequelize<typeof _transactionWithRetry<T>>) => Promise<T>;\n httpBasedTransaction: <T>(...args: ArgsWithoutSequelize<typeof _httpBasedTransaction<T>>) => Promise<T>;\n registerModelEventHooks: (modelTableMapping: ModelMapping, events: Events) => void;\n runAfterTransactionCommits: typeof runAfterTransactionCommits;\n useOrCreateTransaction: <T>(transaction: Transaction, cb: (t: Transaction) => Promise<T>) => Promise<T>;\n} => {\n const transactionWithRetry = <T>(funcToRun: (transaction: Transaction) => Promise<T>, retriesCount?: number, options?: TransactionOptions): Promise<T> => _transactionWithRetry(sequelize, funcToRun, retriesCount, options);\n const httpBasedTransaction = <T>(req: IncomingMessage, res: ServerResponse, cb: (transaction: Transaction) => Promise<T>): Promise<T> => _httpBasedTransaction(sequelize, req, res, cb);\n const registerModelEventHooks = (modelTableMapping: ModelMapping, events: Events) => addModelEventHooks(sequelize, modelTableMapping, events, logger);\n const useOrCreateTransaction = <T>(transaction: Transaction, cb: (t: Transaction) => Promise<T>) => {\n if (transaction) {\n return cb(transaction);\n }\n return transactionWithRetry(cb, 0);\n };\n\n return {\n httpBasedTransaction,\n transactionWithRetry,\n registerModelEventHooks,\n runAfterTransactionCommits,\n useOrCreateTransaction,\n };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["defaultExport: LoggerInstanceManager","cb: () => void | Promise<void>","options: Transactionable","input: unknown","obj: object","newObj: Record<string, unknown>","sequelize: Sequelize","modelTableMapping: ModelMapping","events: Events","logger?: LoggerInstanceManager","packageLogger","object: Model","sequelize","runAfterTransactionCommits","debugLog: debug.Debugger","sequelize: Sequelize","funcToRun: (transaction: Transaction) => Promise<T>","options: TransactionOptions","sequelize","DatabaseError","sequelize: Sequelize","req: IncomingMessage","res: ServerResponse","cb: (transaction: Transaction) => Promise<T>","sequelize","transaction: Transaction","sequelize: Sequelize","logger?: LoggerInstanceManager","transactionWithRetry","funcToRun: (transaction: Transaction) => Promise<T>","retriesCount?: number","options?: TransactionOptions","_transactionWithRetry","sequelize","httpBasedTransaction","req: IncomingMessage","res: ServerResponse","cb: (transaction: Transaction) => Promise<T>","_httpBasedTransaction","modelTableMapping: ModelMapping","events: Events","addModelEventHooks","transaction: Transaction | null | undefined","cb: (t: Transaction) => Promise<T>"],"sources":["../src/logger.ts","../src/runAfterTransactionCommits.ts","../src/model-event-hooks.ts","../src/common.ts","../src/transaction-with-retry.ts","../src/http-based-transaction.ts","../src/index.ts"],"sourcesContent":["import Logger, { type LoggerInstanceManager } from '@autofleet/logger';\n\nconst defaultExport: LoggerInstanceManager = Logger();\nexport default defaultExport;\n","import type { Transactionable } from 'sequelize';\n\nconst runAfterTransactionCommits = async (cb: () => void | Promise<void>, options: Transactionable): Promise<void> => {\n if (options.transaction) {\n options.transaction.afterCommit(() => cb());\n } else {\n await cb();\n }\n};\nexport default runAfterTransactionCommits;\n","import type { Model, Sequelize } from 'sequelize';\nimport type Events from '@autofleet/events';\nimport type { LoggerInstanceManager } from '@autofleet/logger';\nimport packageLogger from './logger';\nimport runAfterTransactionCommits from './runAfterTransactionCommits';\n\nexport type ModelMapping = Record<string, { tableName: string; }>;\n\nconst isDate = (input: unknown): input is Date => input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\nconst formatDatesInObject = (obj: object) => {\n const newObj: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n const valueToUse = isDate(value) ? value.getTime() / 1000 : value;\n newObj[key] = valueToUse;\n }\n return newObj;\n};\n\nconst addModelEventHooks = (sequelize: Sequelize, modelTableMapping: ModelMapping, events: Events, logger?: LoggerInstanceManager): void => {\n const localLogger = logger ?? packageLogger;\n if (!events) {\n localLogger.warn('Events object must be provided to addModelEventHooks');\n return;\n }\n const updateEventToDimTable = (object: Model, isDelete = false) => {\n try {\n const objectToSend = object.get();\n if (isDelete) {\n Object.assign(objectToSend, { deletedAt: new Date() });\n }\n const tableName = modelTableMapping[object.constructor.name]?.tableName;\n const eventVersion = '1';\n const objectToSendFormatted = formatDatesInObject(objectToSend);\n if (!tableName) {\n return;\n }\n events.sendObject(\n tableName,\n eventVersion,\n objectToSendFormatted,\n // @ts-expect-error the rawAttributes is typed as static, while it actually is on the instance level.\n Object.keys(object.rawAttributes),\n ).catch((e) => {\n localLogger.error('sendObject error', { tableName, eventVersion, e });\n });\n } catch (e) {\n localLogger.error('dimTables error', { e });\n }\n };\n\n sequelize.addHook('afterSave', (savedObject, options) => runAfterTransactionCommits(() => updateEventToDimTable(savedObject), options));\n sequelize.addHook('afterDestroy', (savedObject, options) => runAfterTransactionCommits(() => updateEventToDimTable(savedObject, true), options));\n};\n\nexport default addModelEventHooks;\n","import debug from 'debug';\n\nexport const debugLog: debug.Debugger = debug('sequelize-utils');\n","import {\n DatabaseError, type Sequelize, type Transaction, type TransactionOptions,\n} from 'sequelize';\nimport { debugLog } from './common';\n\nexport const transactionWithRetry = async <T>(sequelize: Sequelize, funcToRun: (transaction: Transaction) => Promise<T>, retriesCount = 2, options: TransactionOptions = {}): Promise<T> => {\n if (typeof funcToRun !== 'function') {\n throw new Error('funcToRun must be a function');\n }\n if (typeof retriesCount !== 'number') {\n throw new Error('if defined, retriesCount must be a number');\n }\n if (retriesCount < 0) {\n throw new Error('retriesCount must be a positive number');\n }\n try {\n const transValue = await sequelize.transaction(options, async (transaction) => {\n const funcValue = await funcToRun(transaction);\n return funcValue;\n });\n return transValue;\n } catch (e) {\n if ((e instanceof DatabaseError || e?.constructor?.name === 'DatabaseError') && --retriesCount >= 0) {\n debugLog(`error inside transactionWithRetry - will retry times ${retriesCount}`, e);\n return transactionWithRetry(sequelize, funcToRun, retriesCount, options);\n }\n if (retriesCount === -1) {\n debugLog('error inside transactionWithRetry - will stop retry', e);\n }\n throw e;\n }\n};\n","import type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { Sequelize, Transaction } from 'sequelize';\nimport { debugLog } from './common';\n\nconst rollbackErrorText = 'rollback has been called on this transaction';\nconst abortErrorText = 'Transaction cancelled due to request cancellation';\n\nexport const httpBasedTransaction = <T>(sequelize: Sequelize, req: IncomingMessage, res: ServerResponse, cb: (transaction: Transaction) => Promise<T>): Promise<T> => {\n let aborted = false;\n if (req.socket.destroyed) {\n debugLog(abortErrorText);\n throw new Error(abortErrorText);\n }\n return sequelize.transaction(async (transaction: Transaction) => {\n // https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/test/parallel/test-http-aborted.js#L9\n\n // 2023-04-13: Node.js 16.0.0\n // Added also the `res.writableFinished` check, because it seems that the socket is not destroyed when the request is aborted, but the response is not finished.\n // https://github.com/Jimbly/http-proxy-node16/commit/ba0c414cd03799e357c5d867c11dea06a9c34ec8#diff-b2d1e3b7c5f3b424a0af7971c582c822fd25a5ea279040ef6dc93fc4b2cf619dR151\n\n const rollback = async () => {\n debugLog(abortErrorText);\n if (aborted) return;\n aborted = true;\n await transaction.rollback();\n };\n const resRollback = async () => {\n const didNotFinishWrite = !res.writableFinished;\n if (didNotFinishWrite) {\n debugLog(abortErrorText);\n if (aborted) return;\n aborted = true;\n await transaction.rollback();\n }\n };\n req.socket.once('close', rollback);\n res.once('close', resRollback);\n\n const removeListeners = () => {\n req.socket.removeListener('close', rollback);\n res.removeListener('close', resRollback);\n };\n\n try {\n const response = await cb(transaction);\n removeListeners();\n return response;\n } catch (e) {\n removeListeners();\n if (e.message.includes(rollbackErrorText)) {\n throw new Error(abortErrorText);\n }\n throw e;\n }\n });\n};\n","import type {\n Sequelize,\n Transaction,\n TransactionOptions,\n} from 'sequelize';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { LoggerInstanceManager } from '@autofleet/logger';\nimport type Events from '@autofleet/events';\nimport addModelEventHooks, { type ModelMapping } from './model-event-hooks';\nimport { transactionWithRetry as _transactionWithRetry } from './transaction-with-retry';\nimport { httpBasedTransaction as _httpBasedTransaction } from './http-based-transaction';\nimport runAfterTransactionCommits from './runAfterTransactionCommits';\n\ntype ArgsWithoutSequelize<T> = T extends (arg1: Sequelize, ...args: infer U) => unknown ? U : never;\n\nexport default (sequelize: Sequelize, logger?: LoggerInstanceManager): {\n transactionWithRetry: <T>(...args: ArgsWithoutSequelize<typeof _transactionWithRetry<T>>) => Promise<T>;\n httpBasedTransaction: <T>(...args: ArgsWithoutSequelize<typeof _httpBasedTransaction<T>>) => Promise<T>;\n registerModelEventHooks: (modelTableMapping: ModelMapping, events: Events) => void;\n runAfterTransactionCommits: typeof runAfterTransactionCommits;\n useOrCreateTransaction: <T>(transaction: Transaction | null | undefined, cb: (t: Transaction) => Promise<T>) => Promise<T>;\n} => {\n const transactionWithRetry = <T>(\n funcToRun: (transaction: Transaction) => Promise<T>,\n retriesCount?: number,\n options?: TransactionOptions,\n ): Promise<T> => _transactionWithRetry(sequelize, funcToRun, retriesCount, options);\n const httpBasedTransaction = <T>(req: IncomingMessage, res: ServerResponse, cb: (transaction: Transaction) => Promise<T>): Promise<T> => _httpBasedTransaction(sequelize, req, res, cb);\n const registerModelEventHooks = (modelTableMapping: ModelMapping, events: Events) => addModelEventHooks(sequelize, modelTableMapping, events, logger);\n const useOrCreateTransaction = <T>(transaction: Transaction | null | undefined, cb: (t: Transaction) => Promise<T>) => {\n if (transaction) {\n return cb(transaction);\n }\n return transactionWithRetry(cb, 0);\n };\n\n return {\n httpBasedTransaction,\n transactionWithRetry,\n registerModelEventHooks,\n runAfterTransactionCommits,\n useOrCreateTransaction,\n };\n};\n"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,14 +1,97 @@
|
|
|
1
1
|
import { Sequelize, Transaction, TransactionOptions, Transactionable } from "sequelize";
|
|
2
|
-
import
|
|
3
|
-
import Events from "@autofleet/events";
|
|
2
|
+
import Pino from "pino";
|
|
4
3
|
import { IncomingMessage, ServerResponse } from "node:http";
|
|
5
4
|
|
|
6
|
-
//#region src/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
//#region ../logger/src/index.d.ts
|
|
6
|
+
declare enum LogLevel {
|
|
7
|
+
trace = "trace",
|
|
8
|
+
debug = "debug",
|
|
9
|
+
info = "info",
|
|
10
|
+
warn = "warn",
|
|
11
|
+
error = "error",
|
|
12
|
+
fatal = "fatal",
|
|
13
|
+
}
|
|
14
|
+
type MiddlewareFunction = () => Record<string, unknown>;
|
|
15
|
+
declare class LoggerInstanceManager {
|
|
16
|
+
#private;
|
|
17
|
+
constructor(logLevel?: LogLevel);
|
|
18
|
+
private winstonLikeLoggerCall;
|
|
19
|
+
private addMetadata;
|
|
20
|
+
addContextMiddleware: (middleware: MiddlewareFunction) => number;
|
|
21
|
+
trace: (message: string, meta?: unknown) => void;
|
|
22
|
+
debug: (message: string, meta?: unknown) => void;
|
|
23
|
+
info: (message: string, meta?: unknown) => void;
|
|
24
|
+
warn: (message: string, meta?: unknown) => void;
|
|
25
|
+
error: (message: string, meta?: unknown) => void;
|
|
26
|
+
fatal: (message: string, meta?: unknown) => void;
|
|
27
|
+
child: (metadata: Record<string, unknown>) => Pino.Logger;
|
|
28
|
+
get level(): Pino.LevelWithSilentOrString;
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region ../events/src/events.d.ts
|
|
32
|
+
type LoggerFn = (...args: any[]) => void;
|
|
33
|
+
interface Logger {
|
|
34
|
+
info: LoggerFn;
|
|
35
|
+
error: LoggerFn;
|
|
11
36
|
}
|
|
37
|
+
interface UserEventPayload {
|
|
38
|
+
event_timestamp?: Date;
|
|
39
|
+
[key: string]: any;
|
|
40
|
+
}
|
|
41
|
+
declare class Events {
|
|
42
|
+
private exitHandlerRun;
|
|
43
|
+
private readonly logger;
|
|
44
|
+
private readonly versions;
|
|
45
|
+
private readonly eventsEnvironment;
|
|
46
|
+
private readonly project;
|
|
47
|
+
private readonly pubsubClient;
|
|
48
|
+
private readonly topic;
|
|
49
|
+
private getUserId;
|
|
50
|
+
private getTraceId;
|
|
51
|
+
constructor({
|
|
52
|
+
logger,
|
|
53
|
+
versions,
|
|
54
|
+
getUserId,
|
|
55
|
+
getTraceId
|
|
56
|
+
}: {
|
|
57
|
+
logger?: Logger;
|
|
58
|
+
versions?: Record<string, string>;
|
|
59
|
+
getUserId: (payload: UserEventPayload) => string;
|
|
60
|
+
getTraceId?: () => string;
|
|
61
|
+
});
|
|
62
|
+
private logPublishError;
|
|
63
|
+
private logError;
|
|
64
|
+
private exitHandler;
|
|
65
|
+
send(eventName: string, eventVersion: string, eventObject: UserEventPayload, setEnrichmentObject?: any): Promise<boolean>;
|
|
66
|
+
sendObject(eventName: string, eventVersion: string, camelCaseObject: any, objectFields?: null | string[]): Promise<boolean>;
|
|
67
|
+
sendFleetEvent(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
68
|
+
sendMatchingEvent(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
69
|
+
sendPlacementEvent(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
70
|
+
sendLocationTraceEvent(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
71
|
+
sendVehicleDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
72
|
+
sendVehicleIndicatorsDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
73
|
+
sendDesiredStateDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
74
|
+
sendIndefleetEvent(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
75
|
+
sendBusinessModelStatus(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
76
|
+
sendSearchEvent(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
77
|
+
sendBookingEvent(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
78
|
+
sendApiEvent(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
79
|
+
sendDriverDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
80
|
+
sendVendorDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
81
|
+
sendBusinessModelDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
82
|
+
sendBusinessModelTerritoryDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
83
|
+
sendBusinessModelFleetMappingDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
84
|
+
sendBusinessModelDemandSourceMappingDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
85
|
+
sendDemandSourceDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
86
|
+
sendFleetDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
87
|
+
sendProvidersAbsEvent(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
88
|
+
sendMapsProviderFlowEvent(flowName: string, businessModelId: string): Promise<boolean>;
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/model-event-hooks.d.ts
|
|
92
|
+
type ModelMapping = Record<string, {
|
|
93
|
+
tableName: string;
|
|
94
|
+
}>;
|
|
12
95
|
//#endregion
|
|
13
96
|
//#region src/transaction-with-retry.d.ts
|
|
14
97
|
declare const transactionWithRetry: <T>(sequelize: Sequelize, funcToRun: (transaction: Transaction) => Promise<T>, retriesCount?: number, options?: TransactionOptions) => Promise<T>;
|
|
@@ -26,7 +109,7 @@ declare const _default: (sequelize: Sequelize, logger?: LoggerInstanceManager) =
|
|
|
26
109
|
httpBasedTransaction: <T>(...args: ArgsWithoutSequelize<typeof httpBasedTransaction<T>>) => Promise<T>;
|
|
27
110
|
registerModelEventHooks: (modelTableMapping: ModelMapping, events: Events) => void;
|
|
28
111
|
runAfterTransactionCommits: typeof runAfterTransactionCommits;
|
|
29
|
-
useOrCreateTransaction: <T>(transaction: Transaction, cb: (t: Transaction) => Promise<T>) => Promise<T>;
|
|
112
|
+
useOrCreateTransaction: <T>(transaction: Transaction | null | undefined, cb: (t: Transaction) => Promise<T>) => Promise<T>;
|
|
30
113
|
};
|
|
31
114
|
//#endregion
|
|
32
115
|
export { _default as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,97 @@
|
|
|
1
|
-
import { LoggerInstanceManager } from "@autofleet/logger";
|
|
2
1
|
import { Sequelize, Transaction, TransactionOptions, Transactionable } from "sequelize";
|
|
3
|
-
import
|
|
2
|
+
import Pino from "pino";
|
|
4
3
|
import { IncomingMessage, ServerResponse } from "node:http";
|
|
5
4
|
|
|
6
|
-
//#region src/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
//#region ../logger/src/index.d.ts
|
|
6
|
+
declare enum LogLevel {
|
|
7
|
+
trace = "trace",
|
|
8
|
+
debug = "debug",
|
|
9
|
+
info = "info",
|
|
10
|
+
warn = "warn",
|
|
11
|
+
error = "error",
|
|
12
|
+
fatal = "fatal",
|
|
13
|
+
}
|
|
14
|
+
type MiddlewareFunction = () => Record<string, unknown>;
|
|
15
|
+
declare class LoggerInstanceManager {
|
|
16
|
+
#private;
|
|
17
|
+
constructor(logLevel?: LogLevel);
|
|
18
|
+
private winstonLikeLoggerCall;
|
|
19
|
+
private addMetadata;
|
|
20
|
+
addContextMiddleware: (middleware: MiddlewareFunction) => number;
|
|
21
|
+
trace: (message: string, meta?: unknown) => void;
|
|
22
|
+
debug: (message: string, meta?: unknown) => void;
|
|
23
|
+
info: (message: string, meta?: unknown) => void;
|
|
24
|
+
warn: (message: string, meta?: unknown) => void;
|
|
25
|
+
error: (message: string, meta?: unknown) => void;
|
|
26
|
+
fatal: (message: string, meta?: unknown) => void;
|
|
27
|
+
child: (metadata: Record<string, unknown>) => Pino.Logger;
|
|
28
|
+
get level(): Pino.LevelWithSilentOrString;
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region ../events/src/events.d.ts
|
|
32
|
+
type LoggerFn = (...args: any[]) => void;
|
|
33
|
+
interface Logger {
|
|
34
|
+
info: LoggerFn;
|
|
35
|
+
error: LoggerFn;
|
|
11
36
|
}
|
|
37
|
+
interface UserEventPayload {
|
|
38
|
+
event_timestamp?: Date;
|
|
39
|
+
[key: string]: any;
|
|
40
|
+
}
|
|
41
|
+
declare class Events {
|
|
42
|
+
private exitHandlerRun;
|
|
43
|
+
private readonly logger;
|
|
44
|
+
private readonly versions;
|
|
45
|
+
private readonly eventsEnvironment;
|
|
46
|
+
private readonly project;
|
|
47
|
+
private readonly pubsubClient;
|
|
48
|
+
private readonly topic;
|
|
49
|
+
private getUserId;
|
|
50
|
+
private getTraceId;
|
|
51
|
+
constructor({
|
|
52
|
+
logger,
|
|
53
|
+
versions,
|
|
54
|
+
getUserId,
|
|
55
|
+
getTraceId
|
|
56
|
+
}: {
|
|
57
|
+
logger?: Logger;
|
|
58
|
+
versions?: Record<string, string>;
|
|
59
|
+
getUserId: (payload: UserEventPayload) => string;
|
|
60
|
+
getTraceId?: () => string;
|
|
61
|
+
});
|
|
62
|
+
private logPublishError;
|
|
63
|
+
private logError;
|
|
64
|
+
private exitHandler;
|
|
65
|
+
send(eventName: string, eventVersion: string, eventObject: UserEventPayload, setEnrichmentObject?: any): Promise<boolean>;
|
|
66
|
+
sendObject(eventName: string, eventVersion: string, camelCaseObject: any, objectFields?: null | string[]): Promise<boolean>;
|
|
67
|
+
sendFleetEvent(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
68
|
+
sendMatchingEvent(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
69
|
+
sendPlacementEvent(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
70
|
+
sendLocationTraceEvent(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
71
|
+
sendVehicleDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
72
|
+
sendVehicleIndicatorsDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
73
|
+
sendDesiredStateDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
74
|
+
sendIndefleetEvent(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
75
|
+
sendBusinessModelStatus(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
76
|
+
sendSearchEvent(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
77
|
+
sendBookingEvent(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
78
|
+
sendApiEvent(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
79
|
+
sendDriverDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
80
|
+
sendVendorDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
81
|
+
sendBusinessModelDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
82
|
+
sendBusinessModelTerritoryDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
83
|
+
sendBusinessModelFleetMappingDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
84
|
+
sendBusinessModelDemandSourceMappingDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
85
|
+
sendDemandSourceDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
86
|
+
sendFleetDim(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
87
|
+
sendProvidersAbsEvent(eventObject: any, setEnrichmentObject?: any): Promise<boolean>;
|
|
88
|
+
sendMapsProviderFlowEvent(flowName: string, businessModelId: string): Promise<boolean>;
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/model-event-hooks.d.ts
|
|
92
|
+
type ModelMapping = Record<string, {
|
|
93
|
+
tableName: string;
|
|
94
|
+
}>;
|
|
12
95
|
//#endregion
|
|
13
96
|
//#region src/transaction-with-retry.d.ts
|
|
14
97
|
declare const transactionWithRetry: <T>(sequelize: Sequelize, funcToRun: (transaction: Transaction) => Promise<T>, retriesCount?: number, options?: TransactionOptions) => Promise<T>;
|
|
@@ -26,7 +109,7 @@ declare const _default: (sequelize: Sequelize, logger?: LoggerInstanceManager) =
|
|
|
26
109
|
httpBasedTransaction: <T>(...args: ArgsWithoutSequelize<typeof httpBasedTransaction<T>>) => Promise<T>;
|
|
27
110
|
registerModelEventHooks: (modelTableMapping: ModelMapping, events: Events) => void;
|
|
28
111
|
runAfterTransactionCommits: typeof runAfterTransactionCommits;
|
|
29
|
-
useOrCreateTransaction: <T>(transaction: Transaction, cb: (t: Transaction) => Promise<T>) => Promise<T>;
|
|
112
|
+
useOrCreateTransaction: <T>(transaction: Transaction | null | undefined, cb: (t: Transaction) => Promise<T>) => Promise<T>;
|
|
30
113
|
};
|
|
31
114
|
//#endregion
|
|
32
115
|
export { _default as default };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import e from"@autofleet/logger";import{DatabaseError as t}from"sequelize";import n from"debug";const r=e();var i=r;const a=async(e,t)=>{t.transaction?t.transaction.afterCommit(()=>e()):await e()};var o=a;const s=e=>e instanceof Date||Object.prototype.toString.call(e)===`[object Date]`,c=e=>{let t={};for(let[n,r]of Object.entries(e)){let e=s(r)?r.getTime()/1e3:r;t[n]=e}return t},l=(e,t,n,r)=>{if(!n){
|
|
1
|
+
import e from"@autofleet/logger";import{DatabaseError as t}from"sequelize";import n from"debug";const r=e();var i=r;const a=async(e,t)=>{t.transaction?t.transaction.afterCommit(()=>e()):await e()};var o=a;const s=e=>e instanceof Date||Object.prototype.toString.call(e)===`[object Date]`,c=e=>{let t={};for(let[n,r]of Object.entries(e)){let e=s(r)?r.getTime()/1e3:r;t[n]=e}return t},l=(e,t,n,r)=>{let a=r??i;if(!n){a.warn(`Events object must be provided to addModelEventHooks`);return}let s=(e,r=!1)=>{try{let i=e.get();r&&Object.assign(i,{deletedAt:new Date});let o=t[e.constructor.name]?.tableName,s=c(i);if(!o)return;n.sendObject(o,`1`,s,Object.keys(e.rawAttributes)).catch(e=>{a.error(`sendObject error`,{tableName:o,eventVersion:`1`,e})})}catch(e){a.error(`dimTables error`,{e})}};e.addHook(`afterSave`,(e,t)=>o(()=>s(e),t)),e.addHook(`afterDestroy`,(e,t)=>o(()=>s(e,!0),t))};var u=l;const d=n(`sequelize-utils`),f=async(e,n,r=2,i={})=>{if(typeof n!=`function`)throw Error(`funcToRun must be a function`);if(typeof r!=`number`)throw Error(`if defined, retriesCount must be a number`);if(r<0)throw Error(`retriesCount must be a positive number`);try{let t=await e.transaction(i,async e=>{let t=await n(e);return t});return t}catch(a){if((a instanceof t||a?.constructor?.name===`DatabaseError`)&&--r>=0)return d(`error inside transactionWithRetry - will retry times ${r}`,a),f(e,n,r,i);throw r===-1&&d(`error inside transactionWithRetry - will stop retry`,a),a}},p=`Transaction cancelled due to request cancellation`,m=(e,t,n,r)=>{let i=!1;if(t.socket.destroyed)throw d(p),Error(p);return e.transaction(async e=>{let a=async()=>{d(p),!i&&(i=!0,await e.rollback())},o=async()=>{let t=!n.writableFinished;if(t){if(d(p),i)return;i=!0,await e.rollback()}};t.socket.once(`close`,a),n.once(`close`,o);let s=()=>{t.socket.removeListener(`close`,a),n.removeListener(`close`,o)};try{let t=await r(e);return s(),t}catch(e){throw s(),e.message.includes(`rollback has been called on this transaction`)?Error(p):e}})};var h=(e,t)=>{let n=(t,n,r)=>f(e,t,n,r),r=(t,n,r)=>m(e,t,n,r),i=(n,r)=>u(e,n,r,t),a=(e,t)=>e?t(e):n(t,0);return{httpBasedTransaction:r,transactionWithRetry:n,registerModelEventHooks:i,runAfterTransactionCommits:o,useOrCreateTransaction:a}};export{h as default};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["defaultExport: LoggerInstanceManager","cb: () => void | Promise<void>","options: Transactionable","input: unknown","obj: object","sequelize: Sequelize","modelTableMapping: ModelMapping","events: Events","logger?: LoggerInstanceManager","object: Model","packageLogger","runAfterTransactionCommits","debugLog: debug.Debugger","sequelize: Sequelize","funcToRun: (transaction: Transaction) => Promise<T>","options: TransactionOptions","sequelize: Sequelize","req: IncomingMessage","res: ServerResponse","cb: (transaction: Transaction) => Promise<T>","transaction: Transaction","sequelize: Sequelize","logger?: LoggerInstanceManager","transactionWithRetry","funcToRun: (transaction: Transaction) => Promise<T>","retriesCount?: number","options?: TransactionOptions","_transactionWithRetry","httpBasedTransaction","req: IncomingMessage","res: ServerResponse","cb: (transaction: Transaction) => Promise<T>","_httpBasedTransaction","modelTableMapping: ModelMapping","events: Events","addModelEventHooks","transaction: Transaction","cb: (t: Transaction) => Promise<T>"],"sources":["../src/logger.ts","../src/runAfterTransactionCommits.ts","../src/model-event-hooks.ts","../src/common.ts","../src/transaction-with-retry.ts","../src/http-based-transaction.ts","../src/index.ts"],"sourcesContent":["import Logger, { LoggerInstanceManager } from '@autofleet/logger';\n\nconst defaultExport: LoggerInstanceManager = Logger();\nexport default defaultExport;\n","import { Transactionable } from 'sequelize';\n\nconst runAfterTransactionCommits = async (cb: () => void | Promise<void>, options: Transactionable): Promise<void> => {\n if (options.transaction) {\n options.transaction.afterCommit(() => cb());\n } else {\n await cb();\n }\n};\nexport default runAfterTransactionCommits;\n","import type { Model, Sequelize } from 'sequelize';\nimport type Events from '@autofleet/events';\nimport type { LoggerInstanceManager } from '@autofleet/logger';\nimport packageLogger from './logger';\nimport runAfterTransactionCommits from './runAfterTransactionCommits';\n\nexport interface ModelMapping {\n [ModelName: string]: {\n tableName: string\n };\n}\nconst isDate = (input: unknown): input is Date => input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n// eslint-disable-next-line @typescript-eslint/ban-types\nconst formatDatesInObject = (obj: object) => {\n const newObj = {};\n // eslint-disable-next-line no-restricted-syntax\n for (const [key, value] of Object.entries(obj)) {\n const valueToUse = isDate(value) ? value.getTime() / 1000 : value;\n newObj[key] = valueToUse;\n }\n return newObj;\n};\n\nconst addModelEventHooks = (sequelize: Sequelize, modelTableMapping: ModelMapping, events: Events, logger?: LoggerInstanceManager): void => {\n if (!events) {\n logger.warn('Events object must be provided to addModelEventHooks');\n return;\n }\n const updateEventToDimTable = (object: Model, isDelete = false) => {\n const localLogger = logger || packageLogger;\n try {\n const objectToSend = object.get();\n if (isDelete) {\n Object.assign(objectToSend, { deletedAt: new Date() });\n }\n const tableName = modelTableMapping[object.constructor.name]?.tableName;\n const eventVersion = '1';\n const objectToSendFormatted = formatDatesInObject(objectToSend);\n if (!tableName) {\n return;\n }\n events.sendObject(\n tableName,\n eventVersion,\n objectToSendFormatted,\n // @ts-expect-error the rawAttributes is typed as static, while it actually is on the instance level.\n Object.keys(object.rawAttributes),\n ).catch((e) => {\n localLogger.error('sendObject error', { tableName, eventVersion, e });\n });\n } catch (e) {\n localLogger.error('dimTables error', { e });\n }\n };\n\n sequelize.addHook('afterSave', (savedObject, options) => runAfterTransactionCommits(() => updateEventToDimTable(savedObject), options));\n sequelize.addHook('afterDestroy', (savedObject, options) => runAfterTransactionCommits(() => updateEventToDimTable(savedObject, true), options));\n};\n\nexport default addModelEventHooks;\n","import debug from 'debug';\n\nexport const debugLog: debug.Debugger = debug('sequelize-utils');\n","import {\n DatabaseError, type Sequelize, type Transaction, type TransactionOptions,\n} from 'sequelize';\nimport { debugLog } from './common';\n\nexport const transactionWithRetry = async <T>(sequelize: Sequelize, funcToRun: (transaction: Transaction) => Promise<T>, retriesCount = 2, options: TransactionOptions = {}): Promise<T> => {\n if (typeof funcToRun !== 'function') {\n throw new Error('funcToRun must be a function');\n }\n if (typeof retriesCount !== 'number') {\n throw new Error('if defined, retriesCount must be a number');\n }\n if (retriesCount < 0) {\n throw new Error('retriesCount must be a positive number');\n }\n try {\n const transValue = await sequelize.transaction(options, async (transaction) => {\n const funcValue = await funcToRun(transaction);\n return funcValue;\n });\n return transValue;\n } catch (e) {\n if ((e instanceof DatabaseError || e?.constructor?.name === 'DatabaseError') && --retriesCount >= 0) {\n debugLog(`error inside transactionWithRetry - will retry times ${retriesCount}`, e);\n return transactionWithRetry(sequelize, funcToRun, retriesCount, options);\n }\n if (retriesCount === -1) {\n debugLog('error inside transactionWithRetry - will stop retry', e);\n }\n throw e;\n }\n};\n","import type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { Sequelize, Transaction } from 'sequelize';\nimport { debugLog } from './common';\n\nconst rollbackErrorText = 'rollback has been called on this transaction';\nconst abortErrorText = 'Transaction cancelled due to request cancellation';\n\nexport const httpBasedTransaction = <T>(sequelize: Sequelize, req: IncomingMessage, res: ServerResponse, cb: (transaction: Transaction) => Promise<T>): Promise<T> => {\n let aborted = false;\n if (req.socket.destroyed) {\n debugLog(abortErrorText);\n throw new Error(abortErrorText);\n }\n return sequelize.transaction(async (transaction: Transaction) => {\n // https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/test/parallel/test-http-aborted.js#L9\n\n // 2023-04-13: Node.js 16.0.0\n // Added also the `res.writableFinished` check, because it seems that the socket is not destroyed when the request is aborted, but the response is not finished.\n // https://github.com/Jimbly/http-proxy-node16/commit/ba0c414cd03799e357c5d867c11dea06a9c34ec8#diff-b2d1e3b7c5f3b424a0af7971c582c822fd25a5ea279040ef6dc93fc4b2cf619dR151\n\n const rollback = async () => {\n debugLog(abortErrorText);\n if (aborted) return;\n aborted = true;\n await transaction.rollback();\n };\n const resRollback = async () => {\n const didNotFinishWrite = !res.writableFinished;\n if (didNotFinishWrite) {\n debugLog(abortErrorText);\n if (aborted) return;\n aborted = true;\n await transaction.rollback();\n }\n };\n req.socket.once('close', rollback);\n res.once('close', resRollback);\n\n const removeListeners = () => {\n req.socket.removeListener('close', rollback);\n res.removeListener('close', resRollback);\n };\n\n try {\n const response = await cb(transaction);\n removeListeners();\n return response;\n } catch (e) {\n removeListeners();\n if (e.message.includes(rollbackErrorText)) {\n throw new Error(abortErrorText);\n }\n throw e;\n }\n });\n};\n","/* eslint-disable import/prefer-default-export */\nimport type {\n Sequelize,\n Transaction,\n TransactionOptions,\n} from 'sequelize';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { LoggerInstanceManager } from '@autofleet/logger';\nimport type Events from '@autofleet/events';\nimport addModelEventHooks, { ModelMapping } from './model-event-hooks';\nimport { transactionWithRetry as _transactionWithRetry } from './transaction-with-retry';\nimport { httpBasedTransaction as _httpBasedTransaction } from './http-based-transaction';\nimport runAfterTransactionCommits from './runAfterTransactionCommits';\n\ntype ArgsWithoutSequelize<T> = T extends (arg1: Sequelize, ...args: infer U) => unknown ? U : never;\n\nexport default (sequelize: Sequelize, logger?: LoggerInstanceManager): {\n transactionWithRetry: <T>(...args: ArgsWithoutSequelize<typeof _transactionWithRetry<T>>) => Promise<T>;\n httpBasedTransaction: <T>(...args: ArgsWithoutSequelize<typeof _httpBasedTransaction<T>>) => Promise<T>;\n registerModelEventHooks: (modelTableMapping: ModelMapping, events: Events) => void;\n runAfterTransactionCommits: typeof runAfterTransactionCommits;\n useOrCreateTransaction: <T>(transaction: Transaction, cb: (t: Transaction) => Promise<T>) => Promise<T>;\n} => {\n const transactionWithRetry = <T>(funcToRun: (transaction: Transaction) => Promise<T>, retriesCount?: number, options?: TransactionOptions): Promise<T> => _transactionWithRetry(sequelize, funcToRun, retriesCount, options);\n const httpBasedTransaction = <T>(req: IncomingMessage, res: ServerResponse, cb: (transaction: Transaction) => Promise<T>): Promise<T> => _httpBasedTransaction(sequelize, req, res, cb);\n const registerModelEventHooks = (modelTableMapping: ModelMapping, events: Events) => addModelEventHooks(sequelize, modelTableMapping, events, logger);\n const useOrCreateTransaction = <T>(transaction: Transaction, cb: (t: Transaction) => Promise<T>) => {\n if (transaction) {\n return cb(transaction);\n }\n return transactionWithRetry(cb, 0);\n };\n\n return {\n httpBasedTransaction,\n transactionWithRetry,\n registerModelEventHooks,\n runAfterTransactionCommits,\n useOrCreateTransaction,\n };\n};\n"],"mappings":"gGAEA,MAAMA,EAAuC,GAAQ,CACrD,IAAA,EAAe,ECDf,MAAM,EAA6B,MAAOC,EAAgCC,IAA4C,CAChH,EAAQ,YACV,EAAQ,YAAY,YAAY,IAAM,GAAI,CAAC,CAE3C,MAAM,GAAI,AAEb,EACD,IAAA,EAAe,ECEf,MAAM,EAAS,AAACC,GAAkC,aAAiB,MAAQ,OAAO,UAAU,SAAS,KAAK,EAAM,GAAK,gBAE/G,EAAsB,AAACC,GAAgB,CAC3C,IAAM,EAAS,CAAE,EAEjB,IAAK,GAAM,CAAC,EAAK,EAAM,GAAI,OAAO,QAAQ,EAAI,CAAE,CAC9C,IAAM,EAAa,EAAO,EAAM,CAAG,EAAM,SAAS,CAAG,IAAO,EAC5D,EAAO,GAAO,CACf,CACD,OAAO,CACR,EAEK,EAAqB,CAACiB,EAAsBY,EAAiCC,EAAgBZ,IAAyC,CAC1I,GAAI,CAAC,EAAQ,CACX,EAAO,KAAK,uDAAuD,CACnE,MACD,CACD,IAAM,EAAwB,CAACb,EAAe,EAAW,KAAU,CACjE,IAAM,EAAc,GAAUC,EAC9B,GAAI,CACF,IAAM,EAAe,EAAO,KAAK,CAC7B,GACF,OAAO,OAAO,EAAc,CAAE,UAAW,IAAI,IAAQ,EAAC,CAExD,IAAM,EAAY,EAAkB,EAAO,YAAY,OAAO,UACxD,EAAe,IACf,EAAwB,EAAoB,EAAa,CAC/D,GAAI,CAAC,EACH,OAEF,EAAO,WACL,EACA,EACA,EAEA,OAAO,KAAK,EAAO,cAAc,CAClC,CAAC,MAAM,AAAC,GAAM,CACb,EAAY,MAAM,mBAAoB,CAAE,YAAW,eAAc,CAAG,EAAC,AACtE,EAAC,AACH,OAAQ,EAAG,CACV,EAAY,MAAM,kBAAmB,CAAE,CAAG,EAAC,AAC5C,CACF,EAED,EAAU,QAAQ,YAAa,CAAC,EAAa,IAAYC,EAA2B,IAAM,EAAsB,EAAY,CAAE,EAAQ,CAAC,CACvI,EAAU,QAAQ,eAAgB,CAAC,EAAa,IAAYA,EAA2B,IAAM,EAAsB,EAAa,GAAK,CAAE,EAAQ,CAAC,AACjJ,EAED,IAAA,EAAe,ECzDf,MAAaC,EAA2B,EAAM,kBAAkB,CCGnD,EAAuB,MAAUS,EAAsBG,EAAqD,EAAe,EAAGT,EAA8B,CAAE,IAAiB,CAC1L,GAAI,OAAO,GAAc,WACvB,MAAU,MAAM,+BAAA,CAElB,GAAI,OAAO,GAAiB,SAC1B,MAAU,MAAM,4CAAA,CAElB,GAAI,EAAe,EACjB,MAAU,MAAM,yCAAA,CAElB,GAAI,CACF,IAAM,EAAa,MAAM,EAAU,YAAY,EAAS,MAAO,GAAgB,CAC7E,IAAM,EAAY,MAAM,EAAU,EAAY,CAC9C,OAAO,CACR,EAAC,CACF,OAAO,CACR,OAAQ,EAAG,CACV,IAAK,aAAa,GAAiB,GAAG,aAAa,OAAS,kBAAoB,EAAE,GAAgB,EAEhG,OADA,EAAS,CAAC,qDAAqD,EAAE,GAAc,CAAE,EAAE,CAC5E,EAAqB,EAAW,EAAW,EAAc,EAAQ,CAK1E,MAHI,IAAiB,IACnB,EAAS,sDAAuD,EAAE,CAE9D,CACP,CACF,EC3BK,EAAoB,+CACpB,EAAiB,oDAEV,EAAuB,CAAIM,EAAsBQ,EAAsBC,EAAqBC,IAA6D,CACpK,IAAI,EAAU,GACd,GAAI,EAAI,OAAO,UAEb,MADA,EAAS,EAAe,CACd,MAAM,EAAA,CAElB,OAAO,EAAU,YAAY,MAAOK,GAA6B,CAO/D,IAAM,EAAW,SAAY,CAC3B,EAAS,EAAe,CACpB,KACJ,EAAU,GACV,MAAM,EAAY,UAAU,CAC7B,EACK,EAAc,SAAY,CAC9B,IAAM,EAAoB,CAAC,EAAI,iBAC/B,GAAI,EAAmB,CAErB,GADA,EAAS,EAAe,CACpB,EAAS,OACb,EAAU,GACV,MAAM,EAAY,UAAU,AAC7B,CACF,EACD,EAAI,OAAO,KAAK,QAAS,EAAS,CAClC,EAAI,KAAK,QAAS,EAAY,CAE9B,IAAM,EAAkB,IAAM,CAC5B,EAAI,OAAO,eAAe,QAAS,EAAS,CAC5C,EAAI,eAAe,QAAS,EAAY,AACzC,EAED,GAAI,CACF,IAAM,EAAW,MAAM,EAAG,EAAY,CAEtC,OADA,GAAiB,CACV,CACR,OAAQ,EAAG,CAKV,MAJA,GAAiB,CACb,EAAE,QAAQ,SAAS,EAAkB,CAC7B,MAAM,EAAA,CAEZ,CACP,CACF,EAAC,AACH,ECvCD,IAAA,EAAe,CAACf,EAAsBC,IAMjC,CACH,IAAMC,EAAuB,CAAIC,EAAqDC,EAAuBC,IAA6CC,EAAsB,EAAW,EAAW,EAAc,EAAQ,CACtNC,EAAuB,CAAIC,EAAsBC,EAAqBC,IAA6DC,EAAsB,EAAW,EAAK,EAAK,EAAG,CACjL,EAA0B,CAACC,EAAiCC,IAAmBC,EAAmB,EAAW,EAAmB,EAAQ,EAAO,CAC/I,EAAyB,CAAIC,EAA0BC,IACvD,EACK,EAAG,EAAY,CAEjBd,EAAqB,EAAI,EAAE,CAGpC,MAAO,CACL,qBAAA,EACA,qBAAA,EACA,0BACA,2BAAA,EACA,wBACD,CACF"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["defaultExport: LoggerInstanceManager","cb: () => void | Promise<void>","options: Transactionable","input: unknown","obj: object","newObj: Record<string, unknown>","sequelize: Sequelize","modelTableMapping: ModelMapping","events: Events","logger?: LoggerInstanceManager","packageLogger","object: Model","runAfterTransactionCommits","debugLog: debug.Debugger","sequelize: Sequelize","funcToRun: (transaction: Transaction) => Promise<T>","options: TransactionOptions","sequelize: Sequelize","req: IncomingMessage","res: ServerResponse","cb: (transaction: Transaction) => Promise<T>","transaction: Transaction","sequelize: Sequelize","logger?: LoggerInstanceManager","transactionWithRetry","funcToRun: (transaction: Transaction) => Promise<T>","retriesCount?: number","options?: TransactionOptions","_transactionWithRetry","httpBasedTransaction","req: IncomingMessage","res: ServerResponse","cb: (transaction: Transaction) => Promise<T>","_httpBasedTransaction","modelTableMapping: ModelMapping","events: Events","addModelEventHooks","transaction: Transaction | null | undefined","cb: (t: Transaction) => Promise<T>"],"sources":["../src/logger.ts","../src/runAfterTransactionCommits.ts","../src/model-event-hooks.ts","../src/common.ts","../src/transaction-with-retry.ts","../src/http-based-transaction.ts","../src/index.ts"],"sourcesContent":["import Logger, { type LoggerInstanceManager } from '@autofleet/logger';\n\nconst defaultExport: LoggerInstanceManager = Logger();\nexport default defaultExport;\n","import type { Transactionable } from 'sequelize';\n\nconst runAfterTransactionCommits = async (cb: () => void | Promise<void>, options: Transactionable): Promise<void> => {\n if (options.transaction) {\n options.transaction.afterCommit(() => cb());\n } else {\n await cb();\n }\n};\nexport default runAfterTransactionCommits;\n","import type { Model, Sequelize } from 'sequelize';\nimport type Events from '@autofleet/events';\nimport type { LoggerInstanceManager } from '@autofleet/logger';\nimport packageLogger from './logger';\nimport runAfterTransactionCommits from './runAfterTransactionCommits';\n\nexport type ModelMapping = Record<string, { tableName: string; }>;\n\nconst isDate = (input: unknown): input is Date => input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\nconst formatDatesInObject = (obj: object) => {\n const newObj: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n const valueToUse = isDate(value) ? value.getTime() / 1000 : value;\n newObj[key] = valueToUse;\n }\n return newObj;\n};\n\nconst addModelEventHooks = (sequelize: Sequelize, modelTableMapping: ModelMapping, events: Events, logger?: LoggerInstanceManager): void => {\n const localLogger = logger ?? packageLogger;\n if (!events) {\n localLogger.warn('Events object must be provided to addModelEventHooks');\n return;\n }\n const updateEventToDimTable = (object: Model, isDelete = false) => {\n try {\n const objectToSend = object.get();\n if (isDelete) {\n Object.assign(objectToSend, { deletedAt: new Date() });\n }\n const tableName = modelTableMapping[object.constructor.name]?.tableName;\n const eventVersion = '1';\n const objectToSendFormatted = formatDatesInObject(objectToSend);\n if (!tableName) {\n return;\n }\n events.sendObject(\n tableName,\n eventVersion,\n objectToSendFormatted,\n // @ts-expect-error the rawAttributes is typed as static, while it actually is on the instance level.\n Object.keys(object.rawAttributes),\n ).catch((e) => {\n localLogger.error('sendObject error', { tableName, eventVersion, e });\n });\n } catch (e) {\n localLogger.error('dimTables error', { e });\n }\n };\n\n sequelize.addHook('afterSave', (savedObject, options) => runAfterTransactionCommits(() => updateEventToDimTable(savedObject), options));\n sequelize.addHook('afterDestroy', (savedObject, options) => runAfterTransactionCommits(() => updateEventToDimTable(savedObject, true), options));\n};\n\nexport default addModelEventHooks;\n","import debug from 'debug';\n\nexport const debugLog: debug.Debugger = debug('sequelize-utils');\n","import {\n DatabaseError, type Sequelize, type Transaction, type TransactionOptions,\n} from 'sequelize';\nimport { debugLog } from './common';\n\nexport const transactionWithRetry = async <T>(sequelize: Sequelize, funcToRun: (transaction: Transaction) => Promise<T>, retriesCount = 2, options: TransactionOptions = {}): Promise<T> => {\n if (typeof funcToRun !== 'function') {\n throw new Error('funcToRun must be a function');\n }\n if (typeof retriesCount !== 'number') {\n throw new Error('if defined, retriesCount must be a number');\n }\n if (retriesCount < 0) {\n throw new Error('retriesCount must be a positive number');\n }\n try {\n const transValue = await sequelize.transaction(options, async (transaction) => {\n const funcValue = await funcToRun(transaction);\n return funcValue;\n });\n return transValue;\n } catch (e) {\n if ((e instanceof DatabaseError || e?.constructor?.name === 'DatabaseError') && --retriesCount >= 0) {\n debugLog(`error inside transactionWithRetry - will retry times ${retriesCount}`, e);\n return transactionWithRetry(sequelize, funcToRun, retriesCount, options);\n }\n if (retriesCount === -1) {\n debugLog('error inside transactionWithRetry - will stop retry', e);\n }\n throw e;\n }\n};\n","import type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { Sequelize, Transaction } from 'sequelize';\nimport { debugLog } from './common';\n\nconst rollbackErrorText = 'rollback has been called on this transaction';\nconst abortErrorText = 'Transaction cancelled due to request cancellation';\n\nexport const httpBasedTransaction = <T>(sequelize: Sequelize, req: IncomingMessage, res: ServerResponse, cb: (transaction: Transaction) => Promise<T>): Promise<T> => {\n let aborted = false;\n if (req.socket.destroyed) {\n debugLog(abortErrorText);\n throw new Error(abortErrorText);\n }\n return sequelize.transaction(async (transaction: Transaction) => {\n // https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/test/parallel/test-http-aborted.js#L9\n\n // 2023-04-13: Node.js 16.0.0\n // Added also the `res.writableFinished` check, because it seems that the socket is not destroyed when the request is aborted, but the response is not finished.\n // https://github.com/Jimbly/http-proxy-node16/commit/ba0c414cd03799e357c5d867c11dea06a9c34ec8#diff-b2d1e3b7c5f3b424a0af7971c582c822fd25a5ea279040ef6dc93fc4b2cf619dR151\n\n const rollback = async () => {\n debugLog(abortErrorText);\n if (aborted) return;\n aborted = true;\n await transaction.rollback();\n };\n const resRollback = async () => {\n const didNotFinishWrite = !res.writableFinished;\n if (didNotFinishWrite) {\n debugLog(abortErrorText);\n if (aborted) return;\n aborted = true;\n await transaction.rollback();\n }\n };\n req.socket.once('close', rollback);\n res.once('close', resRollback);\n\n const removeListeners = () => {\n req.socket.removeListener('close', rollback);\n res.removeListener('close', resRollback);\n };\n\n try {\n const response = await cb(transaction);\n removeListeners();\n return response;\n } catch (e) {\n removeListeners();\n if (e.message.includes(rollbackErrorText)) {\n throw new Error(abortErrorText);\n }\n throw e;\n }\n });\n};\n","import type {\n Sequelize,\n Transaction,\n TransactionOptions,\n} from 'sequelize';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { LoggerInstanceManager } from '@autofleet/logger';\nimport type Events from '@autofleet/events';\nimport addModelEventHooks, { type ModelMapping } from './model-event-hooks';\nimport { transactionWithRetry as _transactionWithRetry } from './transaction-with-retry';\nimport { httpBasedTransaction as _httpBasedTransaction } from './http-based-transaction';\nimport runAfterTransactionCommits from './runAfterTransactionCommits';\n\ntype ArgsWithoutSequelize<T> = T extends (arg1: Sequelize, ...args: infer U) => unknown ? U : never;\n\nexport default (sequelize: Sequelize, logger?: LoggerInstanceManager): {\n transactionWithRetry: <T>(...args: ArgsWithoutSequelize<typeof _transactionWithRetry<T>>) => Promise<T>;\n httpBasedTransaction: <T>(...args: ArgsWithoutSequelize<typeof _httpBasedTransaction<T>>) => Promise<T>;\n registerModelEventHooks: (modelTableMapping: ModelMapping, events: Events) => void;\n runAfterTransactionCommits: typeof runAfterTransactionCommits;\n useOrCreateTransaction: <T>(transaction: Transaction | null | undefined, cb: (t: Transaction) => Promise<T>) => Promise<T>;\n} => {\n const transactionWithRetry = <T>(\n funcToRun: (transaction: Transaction) => Promise<T>,\n retriesCount?: number,\n options?: TransactionOptions,\n ): Promise<T> => _transactionWithRetry(sequelize, funcToRun, retriesCount, options);\n const httpBasedTransaction = <T>(req: IncomingMessage, res: ServerResponse, cb: (transaction: Transaction) => Promise<T>): Promise<T> => _httpBasedTransaction(sequelize, req, res, cb);\n const registerModelEventHooks = (modelTableMapping: ModelMapping, events: Events) => addModelEventHooks(sequelize, modelTableMapping, events, logger);\n const useOrCreateTransaction = <T>(transaction: Transaction | null | undefined, cb: (t: Transaction) => Promise<T>) => {\n if (transaction) {\n return cb(transaction);\n }\n return transactionWithRetry(cb, 0);\n };\n\n return {\n httpBasedTransaction,\n transactionWithRetry,\n registerModelEventHooks,\n runAfterTransactionCommits,\n useOrCreateTransaction,\n };\n};\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autofleet/sequelize-utils",
|
|
3
|
-
"version": "6.1.
|
|
3
|
+
"version": "6.1.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -29,6 +29,14 @@
|
|
|
29
29
|
"test-local": "vitest",
|
|
30
30
|
"coverage": "vitest --coverage"
|
|
31
31
|
},
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/Autofleet/autorepo.git"
|
|
35
|
+
},
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/Autofleet/autorepo/issues"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://github.com/Autofleet/autorepo/tree/master/packages/sequelize-utils#readme",
|
|
32
40
|
"author": "",
|
|
33
41
|
"license": "Proprietary",
|
|
34
42
|
"engines": {
|
|
@@ -48,23 +56,10 @@
|
|
|
48
56
|
"@types/debug": "^4.1.6",
|
|
49
57
|
"@types/express": "^4.17.13",
|
|
50
58
|
"@types/node": "^22.16.5",
|
|
51
|
-
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
52
|
-
"@typescript-eslint/parser": "^7.18.0",
|
|
53
|
-
"@vitest/coverage-v8": "^3.2.4",
|
|
54
59
|
"axios": "^0.30.0",
|
|
55
|
-
"eslint": "^8.57.0",
|
|
56
|
-
"eslint-config-airbnb-base": "^15.0.0",
|
|
57
|
-
"eslint-plugin-import": "^2.31.0",
|
|
58
60
|
"express": "^4.21.2",
|
|
59
61
|
"pg": "^8.13.1",
|
|
60
62
|
"sequelize": "^6.37.7",
|
|
61
|
-
"ts-node": "^10.1.0"
|
|
62
|
-
"tsdown": "^0.13.0",
|
|
63
|
-
"typescript": "^5.5.4",
|
|
64
|
-
"vitest": "^3.2.4"
|
|
65
|
-
},
|
|
66
|
-
"optionalDependencies": {
|
|
67
|
-
"@rolldown/binding-linux-x64-gnu": "*",
|
|
68
|
-
"@rollup/rollup-linux-x64-gnu": "*"
|
|
63
|
+
"ts-node": "^10.1.0"
|
|
69
64
|
}
|
|
70
65
|
}
|