@furystack/sequelize-store 7.0.0 → 7.0.1
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/CHANGELOG.md +17 -0
- package/esm/define-sequelize-store.d.ts +2 -6
- package/esm/define-sequelize-store.d.ts.map +1 -1
- package/esm/define-sequelize-store.js.map +1 -1
- package/esm/sequelize-store.d.ts +11 -16
- package/esm/sequelize-store.d.ts.map +1 -1
- package/esm/sequelize-store.js +11 -2
- package/esm/sequelize-store.js.map +1 -1
- package/package.json +6 -6
- package/src/define-sequelize-store.ts +2 -6
- package/src/sequelize-store.ts +14 -18
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [7.0.1] - 2026-05-21
|
|
4
|
+
|
|
5
|
+
### ♻️ Refactoring
|
|
6
|
+
|
|
7
|
+
### `update` throws `NotFoundError` for missing entities
|
|
8
|
+
|
|
9
|
+
`SequelizeStore.update` now throws `NotFoundError` from `@furystack/core` (instead of a plain `Error('Entity not found')`) when zero rows match the primary key. The new message also includes the offending id (`Entity not found with id 'X', cannot update`) so logs are actionable. Callers can branch on `instanceof NotFoundError` without parsing messages — string matches on the bare `Entity not found` keep working as a substring.
|
|
10
|
+
|
|
11
|
+
### ⬆️ Dependencies
|
|
12
|
+
|
|
13
|
+
- Bump dev `vitest` to `^4.1.5`.
|
|
14
|
+
- Bumped `@types/node` to `^25.9.1` and `vitest` to `^4.1.7`. No source changes — dev-tooling bump only.
|
|
15
|
+
|
|
16
|
+
### 📚 Documentation
|
|
17
|
+
|
|
18
|
+
- Rewrote JSDoc on `SequelizeStore`, `SequelizeStoreSettings`, and `defineSequelizeStore` to follow the new value-test guidance: dropped restate-the-type narration, called out the lazy-init + memoized `initModel` contract, and the fact that the store has no `[Symbol.asyncDispose]` because client lifetime belongs to `SequelizeClientFactory`.
|
|
19
|
+
|
|
3
20
|
## [7.0.0] - 2026-04-25
|
|
4
21
|
|
|
5
22
|
### 💥 Breaking Changes
|
|
@@ -4,17 +4,13 @@ import type { Model, ModelStatic, Options, Sequelize } from 'sequelize';
|
|
|
4
4
|
* Options accepted by {@link defineSequelizeStore}.
|
|
5
5
|
*/
|
|
6
6
|
export type DefineSequelizeStoreOptions<T extends object, M extends Model<T>, TPrimaryKey extends keyof T> = {
|
|
7
|
-
/** Human-readable token name used for debug/readability. */
|
|
8
7
|
name: string;
|
|
9
|
-
/** Entity model constructor. */
|
|
10
8
|
model: Constructable<T>;
|
|
11
|
-
/** The Sequelize Model class. */
|
|
12
9
|
sequelizeModel: ModelStatic<M>;
|
|
13
|
-
/** Primary key field name. */
|
|
14
10
|
primaryKey: TPrimaryKey;
|
|
15
|
-
/** Sequelize client options (dialect, storage, etc.). */
|
|
11
|
+
/** Sequelize client options (dialect, storage, etc.) — also acts as the pool key. */
|
|
16
12
|
options: Options;
|
|
17
|
-
/**
|
|
13
|
+
/** Runs once per store before the first DB call (e.g. `Model.init(...)` + `sequelize.sync()`). */
|
|
18
14
|
initModel?: (sequelize: Sequelize) => Promise<void>;
|
|
19
15
|
};
|
|
20
16
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-sequelize-store.d.ts","sourceRoot":"","sources":["../src/define-sequelize-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEhE,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAIvE;;GAEG;AACH,MAAM,MAAM,2BAA2B,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,SAAS,MAAM,CAAC,IAAI;IAC3G,
|
|
1
|
+
{"version":3,"file":"define-sequelize-store.d.ts","sourceRoot":"","sources":["../src/define-sequelize-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEhE,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAIvE;;GAEG;AACH,MAAM,MAAM,2BAA2B,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,SAAS,MAAM,CAAC,IAAI;IAC3G,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAA;IACvB,cAAc,EAAE,WAAW,CAAC,CAAC,CAAC,CAAA;IAC9B,UAAU,EAAE,WAAW,CAAA;IACvB,qFAAqF;IACrF,OAAO,EAAE,OAAO,CAAA;IAChB,kGAAkG;IAClG,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACpD,CAAA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,SAAS,MAAM,CAAC,EAC1G,MAAM,2BAA2B,CAAC,CAAC,EAAE,CAAC,EAAE,WAAW,CAAC,KACnD,UAAU,CAAC,CAAC,EAAE,WAAW,CAexB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-sequelize-store.js","sourceRoot":"","sources":["../src/define-sequelize-store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAE7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"define-sequelize-store.js","sourceRoot":"","sources":["../src/define-sequelize-store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAE7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAgBrD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,IAAoD,EACxB,EAAE,CAC9B,WAAW,CAAiB;IAC1B,IAAI,EAAE,IAAI,CAAC,IAAI;IACf,KAAK,EAAE,IAAI,CAAC,KAAK;IACjB,UAAU,EAAE,IAAI,CAAC,UAAU;IAC3B,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;QACtB,MAAM,OAAO,GAAG,MAAM,CAAC,sBAAsB,CAAC,CAAA;QAC9C,OAAO,IAAI,cAAc,CAAoB;YAC3C,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,kBAAkB,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC;YAClE,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAA;IACJ,CAAC;CACF,CAAC,CAAA"}
|
package/esm/sequelize-store.d.ts
CHANGED
|
@@ -2,29 +2,24 @@ import type { Constructable, CreateResult, FilterType, FindOptions, PartialResul
|
|
|
2
2
|
import { EventHub } from '@furystack/utils';
|
|
3
3
|
import type { Model, ModelStatic, Sequelize } from 'sequelize';
|
|
4
4
|
export interface SequelizeStoreSettings<T extends object, M extends Model<T>, TPrimaryKey extends keyof T> {
|
|
5
|
-
/**
|
|
6
|
-
* The Model to use
|
|
7
|
-
*/
|
|
8
5
|
model: Constructable<T>;
|
|
9
|
-
/**
|
|
10
|
-
* The Sequelize Model class
|
|
11
|
-
*/
|
|
12
6
|
sequelizeModel: ModelStatic<M>;
|
|
13
|
-
/**
|
|
14
|
-
* The Primary key field
|
|
15
|
-
*/
|
|
16
7
|
primaryKey: TPrimaryKey;
|
|
17
|
-
/**
|
|
18
|
-
* Callback that returns the Sequelize client (provided by the client factory)
|
|
19
|
-
*/
|
|
8
|
+
/** Resolves the pooled Sequelize client (typically delegated to {@link SequelizeClientFactory}). */
|
|
20
9
|
getSequelizeClient: () => Sequelize;
|
|
21
|
-
/**
|
|
22
|
-
* Optional callback that will initialize the Model for the Sequelize instance
|
|
23
|
-
*/
|
|
10
|
+
/** Runs once before the first DB call (e.g. `Model.init(...)` + `sequelize.sync()`). */
|
|
24
11
|
initModel?: (sequelize: Sequelize) => Promise<void>;
|
|
25
12
|
}
|
|
26
13
|
/**
|
|
27
|
-
*
|
|
14
|
+
* {@link PhysicalStore} backed by a Sequelize Model.
|
|
15
|
+
*
|
|
16
|
+
* The Sequelize client is resolved lazily on the first DB call via
|
|
17
|
+
* {@link getModel}. {@link SequelizeStoreSettings.initModel} runs once and is
|
|
18
|
+
* memoized; if it throws the cached promise is cleared so the next call retries.
|
|
19
|
+
*
|
|
20
|
+
* The store has no `[Symbol.asyncDispose]` — client lifetime belongs to
|
|
21
|
+
* {@link SequelizeClientFactory}, which closes pooled clients on injector
|
|
22
|
+
* teardown.
|
|
28
23
|
*/
|
|
29
24
|
export declare class SequelizeStore<T extends object, M extends Model<T>, TPrimaryKey extends keyof T, TWriteableData = WithOptionalId<T, TPrimaryKey>> extends EventHub<{
|
|
30
25
|
onEntityAdded: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequelize-store.d.ts","sourceRoot":"","sources":["../src/sequelize-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,UAAU,EACV,WAAW,EACX,aAAa,EACb,aAAa,EACb,cAAc,EACf,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"sequelize-store.d.ts","sourceRoot":"","sources":["../src/sequelize-store.ts"],"names":[],"mappings":"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"}
|
package/esm/sequelize-store.js
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
|
+
import { NotFoundError } from '@furystack/core';
|
|
1
2
|
import { EventHub } from '@furystack/utils';
|
|
2
3
|
/**
|
|
3
|
-
*
|
|
4
|
+
* {@link PhysicalStore} backed by a Sequelize Model.
|
|
5
|
+
*
|
|
6
|
+
* The Sequelize client is resolved lazily on the first DB call via
|
|
7
|
+
* {@link getModel}. {@link SequelizeStoreSettings.initModel} runs once and is
|
|
8
|
+
* memoized; if it throws the cached promise is cleared so the next call retries.
|
|
9
|
+
*
|
|
10
|
+
* The store has no `[Symbol.asyncDispose]` — client lifetime belongs to
|
|
11
|
+
* {@link SequelizeClientFactory}, which closes pooled clients on injector
|
|
12
|
+
* teardown.
|
|
4
13
|
*/
|
|
5
14
|
export class SequelizeStore extends EventHub {
|
|
6
15
|
options;
|
|
@@ -56,7 +65,7 @@ export class SequelizeStore extends EventHub {
|
|
|
56
65
|
const model = await this.getModel();
|
|
57
66
|
const result = await model.update(data, { where: { [this.primaryKey]: id } });
|
|
58
67
|
if (result[0] < 1) {
|
|
59
|
-
throw
|
|
68
|
+
throw new NotFoundError(`Entity not found with id '${String(id)}', cannot update`);
|
|
60
69
|
}
|
|
61
70
|
this.emit('onEntityUpdated', { id, change: data });
|
|
62
71
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequelize-store.js","sourceRoot":"","sources":["../src/sequelize-store.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"sequelize-store.js","sourceRoot":"","sources":["../src/sequelize-store.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@furystack/sequelize-store",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.1",
|
|
4
4
|
"description": "Sequelize-based Store implementation for FuryStack",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -38,16 +38,16 @@
|
|
|
38
38
|
},
|
|
39
39
|
"homepage": "https://github.com/furystack/furystack",
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@furystack/core": "^17.
|
|
42
|
-
"@furystack/inject": "^13.0.
|
|
43
|
-
"@furystack/utils": "^9.0.
|
|
41
|
+
"@furystack/core": "^17.1.0",
|
|
42
|
+
"@furystack/inject": "^13.0.1",
|
|
43
|
+
"@furystack/utils": "^9.0.1",
|
|
44
44
|
"sequelize": "^6.37.8"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@types/node": "^25.
|
|
47
|
+
"@types/node": "^25.9.1",
|
|
48
48
|
"sqlite3": "6.0.1",
|
|
49
49
|
"typescript": "^6.0.3",
|
|
50
|
-
"vitest": "^4.1.
|
|
50
|
+
"vitest": "^4.1.7"
|
|
51
51
|
},
|
|
52
52
|
"engines": {
|
|
53
53
|
"node": ">=22.0.0"
|
|
@@ -8,17 +8,13 @@ import { SequelizeStore } from './sequelize-store.js'
|
|
|
8
8
|
* Options accepted by {@link defineSequelizeStore}.
|
|
9
9
|
*/
|
|
10
10
|
export type DefineSequelizeStoreOptions<T extends object, M extends Model<T>, TPrimaryKey extends keyof T> = {
|
|
11
|
-
/** Human-readable token name used for debug/readability. */
|
|
12
11
|
name: string
|
|
13
|
-
/** Entity model constructor. */
|
|
14
12
|
model: Constructable<T>
|
|
15
|
-
/** The Sequelize Model class. */
|
|
16
13
|
sequelizeModel: ModelStatic<M>
|
|
17
|
-
/** Primary key field name. */
|
|
18
14
|
primaryKey: TPrimaryKey
|
|
19
|
-
/** Sequelize client options (dialect, storage, etc.). */
|
|
15
|
+
/** Sequelize client options (dialect, storage, etc.) — also acts as the pool key. */
|
|
20
16
|
options: Options
|
|
21
|
-
/**
|
|
17
|
+
/** Runs once per store before the first DB call (e.g. `Model.init(...)` + `sequelize.sync()`). */
|
|
22
18
|
initModel?: (sequelize: Sequelize) => Promise<void>
|
|
23
19
|
}
|
|
24
20
|
|
package/src/sequelize-store.ts
CHANGED
|
@@ -7,35 +7,31 @@ import type {
|
|
|
7
7
|
PhysicalStore,
|
|
8
8
|
WithOptionalId,
|
|
9
9
|
} from '@furystack/core'
|
|
10
|
+
import { NotFoundError } from '@furystack/core'
|
|
10
11
|
import { EventHub } from '@furystack/utils'
|
|
11
12
|
import type { FindAttributeOptions, Identifier, Model, ModelStatic, Sequelize, WhereOptions } from 'sequelize'
|
|
13
|
+
import type { SequelizeClientFactory } from './sequelize-client-factory.js'
|
|
12
14
|
|
|
13
15
|
export interface SequelizeStoreSettings<T extends object, M extends Model<T>, TPrimaryKey extends keyof T> {
|
|
14
|
-
/**
|
|
15
|
-
* The Model to use
|
|
16
|
-
*/
|
|
17
16
|
model: Constructable<T>
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* The Sequelize Model class
|
|
21
|
-
*/
|
|
22
17
|
sequelizeModel: ModelStatic<M>
|
|
23
|
-
/**
|
|
24
|
-
* The Primary key field
|
|
25
|
-
*/
|
|
26
18
|
primaryKey: TPrimaryKey
|
|
27
|
-
/**
|
|
28
|
-
* Callback that returns the Sequelize client (provided by the client factory)
|
|
29
|
-
*/
|
|
19
|
+
/** Resolves the pooled Sequelize client (typically delegated to {@link SequelizeClientFactory}). */
|
|
30
20
|
getSequelizeClient: () => Sequelize
|
|
31
|
-
/**
|
|
32
|
-
* Optional callback that will initialize the Model for the Sequelize instance
|
|
33
|
-
*/
|
|
21
|
+
/** Runs once before the first DB call (e.g. `Model.init(...)` + `sequelize.sync()`). */
|
|
34
22
|
initModel?: (sequelize: Sequelize) => Promise<void>
|
|
35
23
|
}
|
|
36
24
|
|
|
37
25
|
/**
|
|
38
|
-
*
|
|
26
|
+
* {@link PhysicalStore} backed by a Sequelize Model.
|
|
27
|
+
*
|
|
28
|
+
* The Sequelize client is resolved lazily on the first DB call via
|
|
29
|
+
* {@link getModel}. {@link SequelizeStoreSettings.initModel} runs once and is
|
|
30
|
+
* memoized; if it throws the cached promise is cleared so the next call retries.
|
|
31
|
+
*
|
|
32
|
+
* The store has no `[Symbol.asyncDispose]` — client lifetime belongs to
|
|
33
|
+
* {@link SequelizeClientFactory}, which closes pooled clients on injector
|
|
34
|
+
* teardown.
|
|
39
35
|
*/
|
|
40
36
|
export class SequelizeStore<
|
|
41
37
|
T extends object,
|
|
@@ -113,7 +109,7 @@ export class SequelizeStore<
|
|
|
113
109
|
|
|
114
110
|
const result = await model.update(data, { where: { [this.primaryKey]: id } as WhereOptions<T> })
|
|
115
111
|
if (result[0] < 1) {
|
|
116
|
-
throw
|
|
112
|
+
throw new NotFoundError(`Entity not found with id '${String(id)}', cannot update`)
|
|
117
113
|
}
|
|
118
114
|
this.emit('onEntityUpdated', { id, change: data })
|
|
119
115
|
}
|