@furystack/repository 10.1.11 → 11.0.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.
- package/CHANGELOG.md +10 -0
- package/README.md +74 -36
- package/esm/data-set.spec.d.ts +2 -0
- package/esm/data-set.spec.d.ts.map +1 -0
- package/esm/data-set.spec.js +348 -0
- package/esm/data-set.spec.js.map +1 -0
- package/esm/define-data-set.d.ts +89 -0
- package/esm/define-data-set.d.ts.map +1 -0
- package/esm/define-data-set.js +75 -0
- package/esm/define-data-set.js.map +1 -0
- package/esm/define-data-set.spec.d.ts +2 -0
- package/esm/define-data-set.spec.d.ts.map +1 -0
- package/esm/define-data-set.spec.js +134 -0
- package/esm/define-data-set.spec.js.map +1 -0
- package/esm/helpers.d.ts +21 -22
- package/esm/helpers.d.ts.map +1 -1
- package/esm/helpers.js +17 -21
- package/esm/helpers.js.map +1 -1
- package/esm/index.d.ts +2 -2
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +2 -2
- package/esm/index.js.map +1 -1
- package/package.json +4 -4
- package/src/data-set.spec.ts +396 -0
- package/src/define-data-set.spec.ts +145 -0
- package/src/define-data-set.ts +140 -0
- package/src/helpers.ts +23 -26
- package/src/index.ts +2 -2
- package/esm/dataset.spec.d.ts +0 -2
- package/esm/dataset.spec.d.ts.map +0 -1
- package/esm/dataset.spec.js +0 -552
- package/esm/dataset.spec.js.map +0 -1
- package/esm/repository.d.ts +0 -15
- package/esm/repository.d.ts.map +0 -1
- package/esm/repository.js +0 -50
- package/esm/repository.js.map +0 -1
- package/esm/repository.spec.d.ts +0 -2
- package/esm/repository.spec.d.ts.map +0 -1
- package/esm/repository.spec.js +0 -18
- package/esm/repository.spec.js.map +0 -1
- package/src/dataset.spec.ts +0 -641
- package/src/repository.spec.ts +0 -19
- package/src/repository.ts +0 -50
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [11.0.0] - 2026-04-25
|
|
4
|
+
|
|
5
|
+
### 💥 Breaking Changes
|
|
6
|
+
|
|
7
|
+
The `Repository` class is gone — DataSets are now first-class DI tokens. See the [v7 migration guide](../../docs/migrations/v7-functional-di.md) for rationale, recipes, and pitfalls.
|
|
8
|
+
|
|
9
|
+
- Removed `Repository`, `getRepository(injector)`, `Repository.createDataSet(Model, 'pk', settings)`. Declare DataSets with `defineDataSet({ name, store, settings? })` at module scope; the returned `DataSetToken<T, PK>` resolves a configured `DataSet`.
|
|
10
|
+
- `getDataSetFor(injector, DataSetToken)` now takes a single token argument. The old `(injector, Model, 'pk')` overload is gone.
|
|
11
|
+
- Every consumer that used to take `{ model, primaryKey }` (endpoint generators, `registerModel`, etc.) now takes a `DataSetToken` directly.
|
|
12
|
+
|
|
3
13
|
## [10.1.11] - 2026-04-17
|
|
4
14
|
|
|
5
15
|
### ⬆️ Dependencies
|
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @furystack/repository
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
DataSet implementation for FuryStack. A DataSet wraps a physical store with
|
|
4
|
+
entity-level business logic — authorization, modification hooks, and change
|
|
5
|
+
events — in a structured way.
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -12,14 +12,17 @@ npm install @furystack/repository
|
|
|
12
12
|
yarn add @furystack/repository
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
## Setting Up a
|
|
15
|
+
## Setting Up a DataSet
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
A DataSet is declared with `defineDataSet`. It takes the underlying
|
|
18
|
+
`StoreToken` (from `@furystack/core` or a backend adapter) and optional
|
|
19
|
+
settings (authorizers, modifiers, event callbacks). The returned
|
|
20
|
+
`DataSetToken` is a DI token that resolves to a ready-to-use `DataSet`.
|
|
18
21
|
|
|
19
22
|
```ts
|
|
20
|
-
import {
|
|
21
|
-
import { InMemoryStore,
|
|
22
|
-
import {
|
|
23
|
+
import { createInjector } from '@furystack/inject'
|
|
24
|
+
import { InMemoryStore, defineStore } from '@furystack/core'
|
|
25
|
+
import { defineDataSet, getDataSetFor } from '@furystack/repository'
|
|
23
26
|
import { getLogger } from '@furystack/logging'
|
|
24
27
|
|
|
25
28
|
class MyModel {
|
|
@@ -27,57 +30,88 @@ class MyModel {
|
|
|
27
30
|
declare value: string
|
|
28
31
|
}
|
|
29
32
|
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
const MyStore = defineStore({
|
|
34
|
+
name: 'my-app/MyStore',
|
|
35
|
+
model: MyModel,
|
|
36
|
+
primaryKey: 'id',
|
|
37
|
+
factory: () => new InMemoryStore({ model: MyModel, primaryKey: 'id' }),
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
const MyDataSet = defineDataSet({
|
|
41
|
+
name: 'my-app/MyDataSet',
|
|
42
|
+
store: MyStore,
|
|
43
|
+
settings: {
|
|
44
|
+
onEntityAdded: ({ injector, entity }) => {
|
|
45
|
+
getLogger(injector).verbose({ message: `An entity was added with value '${entity.value}'` })
|
|
46
|
+
},
|
|
47
|
+
authorizeUpdate: async () => ({
|
|
48
|
+
isAllowed: false,
|
|
49
|
+
message: 'This is a read-only dataset. No update is allowed. :(',
|
|
50
|
+
}),
|
|
35
51
|
},
|
|
36
|
-
authorizeUpdate: async () => ({
|
|
37
|
-
isAllowed: false,
|
|
38
|
-
message: 'This is a read-only dataset. No update is allowed. :(',
|
|
39
|
-
}),
|
|
40
52
|
})
|
|
41
|
-
```
|
|
42
53
|
|
|
43
|
-
|
|
44
|
-
|
|
54
|
+
const myInjector = createInjector()
|
|
55
|
+
```
|
|
45
56
|
|
|
46
57
|
### Working with the DataSet
|
|
47
58
|
|
|
48
|
-
|
|
49
|
-
|
|
59
|
+
Resolve via `injector.get(MyDataSet)` or the convenience helper
|
|
60
|
+
`getDataSetFor(injector, MyDataSet)`:
|
|
50
61
|
|
|
51
62
|
```ts
|
|
52
|
-
const dataSet = getDataSetFor(myInjector,
|
|
53
|
-
dataSet.add(myInjector, { id: 1, value: 'foo' }) // <--
|
|
54
|
-
dataSet.update(myInjector, 1, { id: 1, value: 'bar' }) //
|
|
63
|
+
const dataSet = getDataSetFor(myInjector, MyDataSet)
|
|
64
|
+
await dataSet.add(myInjector, { id: 1, value: 'foo' }) // <-- logs via onEntityAdded
|
|
65
|
+
await dataSet.update(myInjector, 1, { id: 1, value: 'bar' }) // <-- rejected by authorizeUpdate
|
|
55
66
|
```
|
|
56
67
|
|
|
57
68
|
### Events
|
|
58
69
|
|
|
59
|
-
Events are great for logging
|
|
70
|
+
Events are great for logging, monitoring DataSet changes, or distributing
|
|
71
|
+
changes to clients. They are optional callbacks — if defined, they are called
|
|
72
|
+
on a specific event. Supported events: `onEntityAdded`, `onEntityUpdated`,
|
|
73
|
+
`onEntityRemoved`.
|
|
60
74
|
|
|
61
75
|
### Authorizing operations
|
|
62
76
|
|
|
63
|
-
**Authorizers** are similar callbacks
|
|
77
|
+
**Authorizers** are similar callbacks that return a promise with an
|
|
78
|
+
`AuthorizationResult`. You can allow or deny CRUD operations, or add
|
|
79
|
+
additional filters to collections. Supported authorizers: `authorizeAdd`,
|
|
80
|
+
`authorizeUpdate`, `authorizeUpdateEntity` (reloads the entity, compares with
|
|
81
|
+
the original), `authorizeRemove`, `authorizeRemoveEntity`, `authorizeGet`,
|
|
82
|
+
`authorizeGetEntity`.
|
|
64
83
|
|
|
65
84
|
### Modifiers and additional filters
|
|
66
85
|
|
|
67
|
-
|
|
68
|
-
|
|
86
|
+
`modifyOnAdd` / `modifyOnUpdate` transform entities before persisting (e.g.
|
|
87
|
+
fill `createdByUser` / `lastModifiedByUser`). `addFilter` injects a
|
|
88
|
+
pre-filter condition **before** a user-supplied filter expression is
|
|
89
|
+
evaluated, ensuring the caller only ever sees entities they have permission
|
|
90
|
+
for.
|
|
69
91
|
|
|
70
92
|
### Getting the Context
|
|
71
93
|
|
|
72
|
-
|
|
94
|
+
Every callback receives an `injector` — use it to resolve request-scoped
|
|
95
|
+
services like `HttpUserContext` to identify the caller.
|
|
73
96
|
|
|
74
97
|
### Server-side writes and the elevated IdentityContext
|
|
75
98
|
|
|
76
|
-
The DataSet is the **recommended write gateway** for all entity mutations.
|
|
99
|
+
The DataSet is the **recommended write gateway** for all entity mutations.
|
|
100
|
+
Writing through the DataSet ensures that authorization rules, modification
|
|
101
|
+
hooks, and change events (`onEntityAdded`, `onEntityUpdated`,
|
|
102
|
+
`onEntityRemoved`) all fire. These events are required for features like
|
|
103
|
+
[entity sync](./../entity-sync-service/README.md) to work correctly.
|
|
77
104
|
|
|
78
|
-
> **Warning:** Writing directly to the underlying physical store bypasses
|
|
105
|
+
> **Warning:** Writing directly to the underlying physical store bypasses
|
|
106
|
+
> the DataSet layer entirely. No authorization checks, hooks, or events
|
|
107
|
+
> fire, and downstream consumers (such as entity sync) will **not** be
|
|
108
|
+
> notified of the change. The `furystack/no-direct-store-token` lint rule
|
|
109
|
+
> guards against this in application code.
|
|
79
110
|
|
|
80
|
-
For server-side or background operations that don't originate from an HTTP
|
|
111
|
+
For server-side or background operations that don't originate from an HTTP
|
|
112
|
+
request (e.g. scheduled jobs, migrations, seed scripts), you won't have a
|
|
113
|
+
user session. Use `useSystemIdentityContext` from `@furystack/core` to
|
|
114
|
+
create a scoped child injector with elevated privileges:
|
|
81
115
|
|
|
82
116
|
```ts
|
|
83
117
|
import { useSystemIdentityContext } from '@furystack/core'
|
|
@@ -85,12 +119,16 @@ import { getDataSetFor } from '@furystack/repository'
|
|
|
85
119
|
import { usingAsync } from '@furystack/utils'
|
|
86
120
|
|
|
87
121
|
await usingAsync(useSystemIdentityContext({ injector, username: 'background-job' }), async (systemInjector) => {
|
|
88
|
-
const dataSet = getDataSetFor(systemInjector,
|
|
122
|
+
const dataSet = getDataSetFor(systemInjector, MyDataSet)
|
|
89
123
|
await dataSet.add(systemInjector, { value: 'created by background job' })
|
|
90
124
|
})
|
|
91
125
|
// systemInjector is disposed here -- all scoped instances cleaned up
|
|
92
126
|
```
|
|
93
127
|
|
|
94
|
-
> **Warning:** `useSystemIdentityContext` bypasses **all** authorization
|
|
128
|
+
> **Warning:** `useSystemIdentityContext` bypasses **all** authorization
|
|
129
|
+
> checks. Only use it in trusted server-side contexts. Never pass the
|
|
130
|
+
> returned injector to user-facing request handlers.
|
|
95
131
|
|
|
96
|
-
This pattern ensures that all writes go through the same pipeline, keeping
|
|
132
|
+
This pattern ensures that all writes go through the same pipeline, keeping
|
|
133
|
+
authorization, hooks, and event-driven features consistent regardless of
|
|
134
|
+
the caller.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-set.spec.d.ts","sourceRoot":"","sources":["../src/data-set.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
import { AuthorizationError, defineStore, InMemoryStore } from '@furystack/core';
|
|
2
|
+
import { createInjector } from '@furystack/inject';
|
|
3
|
+
import { usingAsync } from '@furystack/utils';
|
|
4
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
5
|
+
import { defineDataSet } from './define-data-set.js';
|
|
6
|
+
import { getDataSetFor } from './helpers.js';
|
|
7
|
+
class TestClass {
|
|
8
|
+
}
|
|
9
|
+
// Token declared at module scope so TypeScript preserves the literal primary
|
|
10
|
+
// key. The explicit `StoreToken<TestClass, 'id'>` annotation keeps
|
|
11
|
+
// `TPrimaryKey` narrow when the token is later passed to `defineDataSet`;
|
|
12
|
+
// inferred return types from `defineStore` tend to widen back to
|
|
13
|
+
// `keyof TestClass` in downstream inference contexts.
|
|
14
|
+
const TestStore = defineStore({
|
|
15
|
+
name: 'test/DataSetSpecStore',
|
|
16
|
+
model: TestClass,
|
|
17
|
+
primaryKey: 'id',
|
|
18
|
+
factory: () => new InMemoryStore({ model: TestClass, primaryKey: 'id' }),
|
|
19
|
+
});
|
|
20
|
+
/**
|
|
21
|
+
* Builds a fresh injector with a disposable {@link InMemoryStore} bound as the
|
|
22
|
+
* backing store for a {@link TestClass} dataset. Each call mints a new
|
|
23
|
+
* dataset token so the injector cache starts from scratch for every test.
|
|
24
|
+
*/
|
|
25
|
+
const withDataSet = async (settings, fn) => {
|
|
26
|
+
const TestDataSet = defineDataSet({
|
|
27
|
+
name: `test/DataSet-${Math.random()}`,
|
|
28
|
+
store: TestStore,
|
|
29
|
+
settings,
|
|
30
|
+
});
|
|
31
|
+
await usingAsync(createInjector(), async (i) => {
|
|
32
|
+
const dataSet = getDataSetFor(i, TestDataSet);
|
|
33
|
+
await fn({ i, dataSet });
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
describe('DataSet', () => {
|
|
37
|
+
describe('Authorizers', () => {
|
|
38
|
+
describe('Add', () => {
|
|
39
|
+
it('adds an entity when no settings are provided', async () => {
|
|
40
|
+
await withDataSet(undefined, async ({ i, dataSet }) => {
|
|
41
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
42
|
+
const result = await dataSet.get(i, 1);
|
|
43
|
+
expect(result?.value).toBe('asd');
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
it('runs authorizeAdd and persists the entity on pass', async () => {
|
|
47
|
+
const authorizeAdd = vi.fn(async () => ({ isAllowed: true }));
|
|
48
|
+
await withDataSet({ authorizeAdd }, async ({ i, dataSet }) => {
|
|
49
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
50
|
+
expect(authorizeAdd).toHaveBeenCalled();
|
|
51
|
+
expect((await dataSet.get(i, 1))?.value).toBe('asd');
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
it('throws and does not persist when authorizeAdd fails', async () => {
|
|
55
|
+
const authorizeAdd = vi.fn(async () => ({ isAllowed: false, message: '...' }));
|
|
56
|
+
await withDataSet({ authorizeAdd }, async ({ i, dataSet }) => {
|
|
57
|
+
await expect(dataSet.add(i, { id: 1, value: 'asd' })).rejects.toBeInstanceOf(AuthorizationError);
|
|
58
|
+
expect(authorizeAdd).toHaveBeenCalled();
|
|
59
|
+
expect(await dataSet.get(i, 1)).toBeUndefined();
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
it('applies modifyOnAdd before persisting', async () => {
|
|
63
|
+
const modifyOnAdd = vi.fn(async ({ entity }) => ({
|
|
64
|
+
...entity,
|
|
65
|
+
value: entity.value.toUpperCase(),
|
|
66
|
+
}));
|
|
67
|
+
await withDataSet({ modifyOnAdd }, async ({ i, dataSet }) => {
|
|
68
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
69
|
+
const result = await dataSet.get(i, 1);
|
|
70
|
+
expect(modifyOnAdd).toHaveBeenCalled();
|
|
71
|
+
expect(result?.value).toBe('ASD');
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
it('emits onEntityAdded after a successful add', async () => {
|
|
75
|
+
await withDataSet(undefined, async ({ i, dataSet }) => {
|
|
76
|
+
const listener = vi.fn();
|
|
77
|
+
dataSet.addListener('onEntityAdded', listener);
|
|
78
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
79
|
+
expect(listener).toHaveBeenCalledWith(expect.objectContaining({ entity: { id: 1, value: 'asd' } }));
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
describe('Update', () => {
|
|
84
|
+
it('updates an entity when no settings are provided', async () => {
|
|
85
|
+
await withDataSet(undefined, async ({ i, dataSet }) => {
|
|
86
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
87
|
+
await dataSet.update(i, 1, { id: 1, value: 'asd2' });
|
|
88
|
+
expect((await dataSet.get(i, 1))?.value).toBe('asd2');
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
it('runs authorizeUpdate and persists on pass', async () => {
|
|
92
|
+
const authorizeUpdate = vi.fn(async () => ({ isAllowed: true }));
|
|
93
|
+
await withDataSet({ authorizeUpdate }, async ({ i, dataSet }) => {
|
|
94
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
95
|
+
await dataSet.update(i, 1, { id: 1, value: 'asd2' });
|
|
96
|
+
expect(authorizeUpdate).toHaveBeenCalled();
|
|
97
|
+
expect((await dataSet.get(i, 1))?.value).toBe('asd2');
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
it('throws when authorizeUpdate fails and leaves the entity untouched', async () => {
|
|
101
|
+
const authorizeUpdate = vi.fn(async () => ({ isAllowed: false, message: '...' }));
|
|
102
|
+
await withDataSet({ authorizeUpdate }, async ({ i, dataSet }) => {
|
|
103
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
104
|
+
await expect(dataSet.update(i, 1, { id: 1, value: 'asd2' })).rejects.toBeInstanceOf(AuthorizationError);
|
|
105
|
+
expect((await dataSet.get(i, 1))?.value).toBe('asd');
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
it('runs authorizeUpdateEntity against the loaded entity and persists on pass', async () => {
|
|
109
|
+
const authorizeUpdateEntity = vi.fn(async () => ({ isAllowed: true }));
|
|
110
|
+
await withDataSet({ authorizeUpdateEntity }, async ({ i, dataSet }) => {
|
|
111
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
112
|
+
await dataSet.update(i, 1, { id: 1, value: 'asd2' });
|
|
113
|
+
expect(authorizeUpdateEntity).toHaveBeenCalled();
|
|
114
|
+
expect((await dataSet.get(i, 1))?.value).toBe('asd2');
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
it('throws and leaves the entity untouched when authorizeUpdateEntity fails', async () => {
|
|
118
|
+
const authorizeUpdateEntity = vi.fn(async () => ({ isAllowed: false, message: '...' }));
|
|
119
|
+
await withDataSet({ authorizeUpdateEntity }, async ({ i, dataSet }) => {
|
|
120
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
121
|
+
await expect(dataSet.update(i, 1, { id: 1, value: 'asd2' })).rejects.toBeInstanceOf(AuthorizationError);
|
|
122
|
+
expect((await dataSet.get(i, 1))?.value).toBe('asd');
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
it('applies modifyOnUpdate before persisting', async () => {
|
|
126
|
+
const modifyOnUpdate = vi.fn(async ({ entity }) => ({
|
|
127
|
+
...entity,
|
|
128
|
+
value: entity.value?.toUpperCase() ?? '',
|
|
129
|
+
}));
|
|
130
|
+
await withDataSet({ modifyOnUpdate }, async ({ i, dataSet }) => {
|
|
131
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
132
|
+
await dataSet.update(i, 1, { id: 1, value: 'asd2' });
|
|
133
|
+
expect(modifyOnUpdate).toHaveBeenCalled();
|
|
134
|
+
expect((await dataSet.get(i, 1))?.value).toBe('ASD2');
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
it('emits onEntityUpdated with the applied change', async () => {
|
|
138
|
+
await withDataSet(undefined, async ({ i, dataSet }) => {
|
|
139
|
+
const listener = vi.fn();
|
|
140
|
+
dataSet.addListener('onEntityUpdated', listener);
|
|
141
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
142
|
+
await dataSet.update(i, 1, { id: 1, value: 'asd2' });
|
|
143
|
+
expect(listener).toHaveBeenCalledWith(expect.objectContaining({ change: { id: 1, value: 'asd2' }, id: 1 }));
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
describe('Count', () => {
|
|
148
|
+
it('returns the count when no settings are provided', async () => {
|
|
149
|
+
await withDataSet(undefined, async ({ i, dataSet }) => {
|
|
150
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
151
|
+
expect(await dataSet.count(i)).toBe(1);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
it('returns the count when authorizeGet passes', async () => {
|
|
155
|
+
const authorizeGet = vi.fn(async () => ({ isAllowed: true, message: '' }));
|
|
156
|
+
await withDataSet({ authorizeGet }, async ({ i, dataSet }) => {
|
|
157
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
158
|
+
expect(await dataSet.count(i)).toBe(1);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
it('throws when authorizeGet fails', async () => {
|
|
162
|
+
const authorizeGet = vi.fn(async () => ({ isAllowed: false, message: ':(' }));
|
|
163
|
+
await withDataSet({ authorizeGet }, async ({ i, dataSet }) => {
|
|
164
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
165
|
+
await expect(dataSet.count(i)).rejects.toBeInstanceOf(AuthorizationError);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
describe('filter', () => {
|
|
171
|
+
it('returns the unfiltered result when no settings are provided', async () => {
|
|
172
|
+
await withDataSet(undefined, async ({ i, dataSet }) => {
|
|
173
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
174
|
+
expect((await dataSet.find(i, {})).length).toBe(1);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
it('returns the unfiltered result when authorizeGet passes', async () => {
|
|
178
|
+
const authorizeGet = vi.fn(async () => ({ isAllowed: true, message: '' }));
|
|
179
|
+
await withDataSet({ authorizeGet }, async ({ i, dataSet }) => {
|
|
180
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
181
|
+
expect((await dataSet.find(i, {})).length).toBe(1);
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
it('throws when authorizeGet fails', async () => {
|
|
185
|
+
const authorizeGet = vi.fn(async () => ({ isAllowed: false, message: ':(' }));
|
|
186
|
+
await withDataSet({ authorizeGet }, async ({ i, dataSet }) => {
|
|
187
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
188
|
+
await expect(dataSet.find(i, {})).rejects.toBeInstanceOf(AuthorizationError);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
describe('get', () => {
|
|
193
|
+
it('returns the entity when no settings are provided', async () => {
|
|
194
|
+
await withDataSet(undefined, async ({ i, dataSet }) => {
|
|
195
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
196
|
+
expect((await dataSet.get(i, 1))?.id).toBe(1);
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
it('returns the entity when authorizeGet passes', async () => {
|
|
200
|
+
const authorizeGet = vi.fn(async () => ({ isAllowed: true, message: '' }));
|
|
201
|
+
await withDataSet({ authorizeGet }, async ({ i, dataSet }) => {
|
|
202
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
203
|
+
expect((await dataSet.get(i, 1))?.id).toBe(1);
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
it('throws when authorizeGet fails', async () => {
|
|
207
|
+
const authorizeGet = vi.fn(async () => ({ isAllowed: false, message: ':(' }));
|
|
208
|
+
await withDataSet({ authorizeGet }, async ({ i, dataSet }) => {
|
|
209
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
210
|
+
await expect(dataSet.get(i, 1)).rejects.toBeInstanceOf(AuthorizationError);
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
it('returns the entity when authorizeGetEntity passes', async () => {
|
|
214
|
+
const authorizeGetEntity = vi.fn(async () => ({ isAllowed: true, message: '' }));
|
|
215
|
+
await withDataSet({ authorizeGetEntity }, async ({ i, dataSet }) => {
|
|
216
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
217
|
+
expect((await dataSet.get(i, 1))?.id).toBe(1);
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
it('throws when authorizeGetEntity fails', async () => {
|
|
221
|
+
const authorizeGetEntity = vi.fn(async () => ({ isAllowed: false, message: ':(' }));
|
|
222
|
+
await withDataSet({ authorizeGetEntity }, async ({ i, dataSet }) => {
|
|
223
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
224
|
+
await expect(dataSet.get(i, 1)).rejects.toBeInstanceOf(AuthorizationError);
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
it('receives the full entity in authorizeGetEntity even when select is used', async () => {
|
|
228
|
+
const authorizeGetEntity = vi.fn(async () => ({ isAllowed: true, message: '' }));
|
|
229
|
+
await withDataSet({ authorizeGetEntity }, async ({ i, dataSet }) => {
|
|
230
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
231
|
+
const result = await dataSet.get(i, 1, ['value']);
|
|
232
|
+
expect(authorizeGetEntity).toHaveBeenCalledTimes(1);
|
|
233
|
+
const firstCall = authorizeGetEntity.mock.calls[0];
|
|
234
|
+
expect(firstCall[0].entity).toEqual({ id: 1, value: 'asd' });
|
|
235
|
+
expect(result).toEqual({ value: 'asd' });
|
|
236
|
+
expect(result).not.toHaveProperty('id');
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
it('returns undefined without calling authorizeGetEntity when the entity does not exist', async () => {
|
|
240
|
+
const authorizeGetEntity = vi.fn(async () => ({ isAllowed: true, message: '' }));
|
|
241
|
+
await withDataSet({ authorizeGetEntity }, async ({ i, dataSet }) => {
|
|
242
|
+
const result = await dataSet.get(i, 999);
|
|
243
|
+
expect(result).toBeUndefined();
|
|
244
|
+
expect(authorizeGetEntity).not.toHaveBeenCalled();
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
describe('remove', () => {
|
|
249
|
+
it('removes the entity when no settings are provided', async () => {
|
|
250
|
+
await withDataSet(undefined, async ({ i, dataSet }) => {
|
|
251
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
252
|
+
await dataSet.remove(i, 1);
|
|
253
|
+
expect(await dataSet.count(i)).toBe(0);
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
it('removes the entity when authorizeRemove passes', async () => {
|
|
257
|
+
const authorizeRemove = vi.fn(async () => ({ isAllowed: true, message: '' }));
|
|
258
|
+
await withDataSet({ authorizeRemove }, async ({ i, dataSet }) => {
|
|
259
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
260
|
+
await dataSet.remove(i, 1);
|
|
261
|
+
expect(await dataSet.count(i)).toBe(0);
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
it('throws and preserves the entity when authorizeRemove fails', async () => {
|
|
265
|
+
const authorizeRemove = vi.fn(async () => ({ isAllowed: false, message: ':(' }));
|
|
266
|
+
await withDataSet({ authorizeRemove }, async ({ i, dataSet }) => {
|
|
267
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
268
|
+
await expect(dataSet.remove(i, 1)).rejects.toBeInstanceOf(AuthorizationError);
|
|
269
|
+
expect(await dataSet.count(i)).toBe(1);
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
it('removes the entity when authorizeRemoveEntity passes', async () => {
|
|
273
|
+
const authorizeRemoveEntity = vi.fn(async () => ({ isAllowed: true, message: '' }));
|
|
274
|
+
await withDataSet({ authorizeRemoveEntity }, async ({ i, dataSet }) => {
|
|
275
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
276
|
+
await dataSet.remove(i, 1);
|
|
277
|
+
expect(await dataSet.count(i)).toBe(0);
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
it('throws and preserves the entity when authorizeRemoveEntity fails', async () => {
|
|
281
|
+
const authorizeRemoveEntity = vi.fn(async () => ({ isAllowed: false, message: ':(' }));
|
|
282
|
+
await withDataSet({ authorizeRemoveEntity }, async ({ i, dataSet }) => {
|
|
283
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
284
|
+
await expect(dataSet.remove(i, 1)).rejects.toBeInstanceOf(AuthorizationError);
|
|
285
|
+
expect(await dataSet.count(i)).toBe(1);
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
it('emits onEntityRemoved after a successful remove', async () => {
|
|
289
|
+
await withDataSet(undefined, async ({ i, dataSet }) => {
|
|
290
|
+
const listener = vi.fn();
|
|
291
|
+
dataSet.addListener('onEntityRemoved', listener);
|
|
292
|
+
await dataSet.add(i, { id: 1, value: 'asd' });
|
|
293
|
+
await dataSet.remove(i, 1);
|
|
294
|
+
expect(listener).toHaveBeenCalledWith(expect.objectContaining({ key: 1 }));
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
it('removes multiple entities at once', async () => {
|
|
298
|
+
await withDataSet(undefined, async ({ i, dataSet }) => {
|
|
299
|
+
await dataSet.add(i, { id: 1, value: 'a' }, { id: 2, value: 'b' }, { id: 3, value: 'c' });
|
|
300
|
+
await dataSet.remove(i, 1, 3);
|
|
301
|
+
expect(await dataSet.count(i)).toBe(1);
|
|
302
|
+
expect((await dataSet.get(i, 2))?.value).toBe('b');
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
it('emits onEntityRemoved for each removed key', async () => {
|
|
306
|
+
await withDataSet(undefined, async ({ i, dataSet }) => {
|
|
307
|
+
const removedKeys = [];
|
|
308
|
+
dataSet.addListener('onEntityRemoved', ({ key }) => {
|
|
309
|
+
removedKeys.push(key);
|
|
310
|
+
});
|
|
311
|
+
await dataSet.add(i, { id: 1, value: 'a' }, { id: 2, value: 'b' });
|
|
312
|
+
await dataSet.remove(i, 1, 2);
|
|
313
|
+
expect(removedKeys).toEqual([1, 2]);
|
|
314
|
+
});
|
|
315
|
+
});
|
|
316
|
+
it('authorizes each entity when authorizeRemoveEntity is set', async () => {
|
|
317
|
+
const authorizeRemoveEntity = vi.fn(async () => ({ isAllowed: true, message: '' }));
|
|
318
|
+
await withDataSet({ authorizeRemoveEntity }, async ({ i, dataSet }) => {
|
|
319
|
+
await dataSet.add(i, { id: 1, value: 'a' }, { id: 2, value: 'b' });
|
|
320
|
+
await dataSet.remove(i, 1, 2);
|
|
321
|
+
expect(authorizeRemoveEntity).toHaveBeenCalledTimes(2);
|
|
322
|
+
expect(await dataSet.count(i)).toBe(0);
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
it('does not remove anything when authorizeRemoveEntity fails for one entity (all-or-nothing)', async () => {
|
|
326
|
+
const authorizeRemoveEntity = vi.fn(async ({ entity }) => {
|
|
327
|
+
if (entity.id === 2) {
|
|
328
|
+
return { isAllowed: false, message: 'forbidden' };
|
|
329
|
+
}
|
|
330
|
+
return { isAllowed: true };
|
|
331
|
+
});
|
|
332
|
+
await withDataSet({ authorizeRemoveEntity }, async ({ i, dataSet }) => {
|
|
333
|
+
await dataSet.add(i, { id: 1, value: 'a' }, { id: 2, value: 'b' }, { id: 3, value: 'c' });
|
|
334
|
+
await expect(dataSet.remove(i, 1, 2, 3)).rejects.toBeInstanceOf(AuthorizationError);
|
|
335
|
+
expect(await dataSet.count(i)).toBe(3);
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
it('no-ops when called without keys', async () => {
|
|
339
|
+
await withDataSet(undefined, async ({ i, dataSet }) => {
|
|
340
|
+
const listener = vi.fn();
|
|
341
|
+
dataSet.addListener('onEntityRemoved', listener);
|
|
342
|
+
await dataSet.remove(i);
|
|
343
|
+
expect(listener).not.toHaveBeenCalled();
|
|
344
|
+
});
|
|
345
|
+
});
|
|
346
|
+
});
|
|
347
|
+
});
|
|
348
|
+
//# sourceMappingURL=data-set.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-set.spec.js","sourceRoot":"","sources":["../src/data-set.spec.ts"],"names":[],"mappings":"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"}
|