@opensaas/stack-core 0.37.0 → 0.39.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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +191 -0
- package/CLAUDE.md +42 -3
- package/dist/access/access-filter.d.ts +70 -113
- package/dist/access/access-filter.d.ts.map +1 -1
- package/dist/access/access-filter.js +183 -210
- package/dist/access/access-filter.js.map +1 -1
- package/dist/access/access-filter.test.js +148 -188
- package/dist/access/access-filter.test.js.map +1 -1
- package/dist/access/declared-dependencies.d.ts +66 -26
- package/dist/access/declared-dependencies.d.ts.map +1 -1
- package/dist/access/declared-dependencies.js +62 -17
- package/dist/access/declared-dependencies.js.map +1 -1
- package/dist/access/declared-dependencies.test.d.ts +2 -0
- package/dist/access/declared-dependencies.test.d.ts.map +1 -0
- package/dist/access/declared-dependencies.test.js +226 -0
- package/dist/access/declared-dependencies.test.js.map +1 -0
- package/dist/access/depth-limits.d.ts +8 -7
- package/dist/access/depth-limits.d.ts.map +1 -1
- package/dist/access/depth-limits.js +8 -7
- package/dist/access/depth-limits.js.map +1 -1
- package/dist/access/engine.d.ts +0 -20
- package/dist/access/engine.d.ts.map +1 -1
- package/dist/access/engine.js +0 -25
- package/dist/access/engine.js.map +1 -1
- package/dist/access/errors.d.ts +61 -8
- package/dist/access/errors.d.ts.map +1 -1
- package/dist/access/errors.js +91 -12
- package/dist/access/errors.js.map +1 -1
- package/dist/access/field-access.d.ts +39 -1
- package/dist/access/field-access.d.ts.map +1 -1
- package/dist/access/field-access.js +108 -42
- package/dist/access/field-access.js.map +1 -1
- package/dist/access/field-access.test.js +229 -2
- package/dist/access/field-access.test.js.map +1 -1
- package/dist/access/field-transforms.d.ts +0 -27
- package/dist/access/field-transforms.d.ts.map +1 -1
- package/dist/access/field-visibility.d.ts +2 -5
- package/dist/access/field-visibility.d.ts.map +1 -1
- package/dist/access/field-visibility.js +89 -41
- package/dist/access/field-visibility.js.map +1 -1
- package/dist/access/index.d.ts +6 -3
- package/dist/access/index.d.ts.map +1 -1
- package/dist/access/index.js +12 -2
- package/dist/access/index.js.map +1 -1
- package/dist/access/query-validation.d.ts +121 -0
- package/dist/access/query-validation.d.ts.map +1 -0
- package/dist/access/query-validation.js +292 -0
- package/dist/access/query-validation.js.map +1 -0
- package/dist/access/relationship-count.d.ts +1 -1
- package/dist/access/relationship-count.d.ts.map +1 -1
- package/dist/access/relationship-count.js +2 -10
- package/dist/access/relationship-count.js.map +1 -1
- package/dist/access/relationship-label-filter.d.ts +23 -23
- package/dist/access/relationship-label-filter.d.ts.map +1 -1
- package/dist/access/relationship-label-filter.js +5 -76
- package/dist/access/relationship-label-filter.js.map +1 -1
- package/dist/access/relationship-label-filter.test.js +19 -56
- package/dist/access/relationship-label-filter.test.js.map +1 -1
- package/dist/access/transaction-registry.d.ts +45 -0
- package/dist/access/transaction-registry.d.ts.map +1 -0
- package/dist/access/transaction-registry.js +37 -0
- package/dist/access/transaction-registry.js.map +1 -0
- package/dist/access/types.d.ts +55 -59
- package/dist/access/types.d.ts.map +1 -1
- package/dist/config/index.d.ts +9 -7
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +10 -18
- package/dist/config/index.js.map +1 -1
- package/dist/config/label.d.ts +6 -13
- package/dist/config/label.d.ts.map +1 -1
- package/dist/config/label.js +6 -13
- package/dist/config/label.js.map +1 -1
- package/dist/config/nav-count.d.ts +11 -19
- package/dist/config/nav-count.d.ts.map +1 -1
- package/dist/config/nav-count.js +11 -19
- package/dist/config/nav-count.js.map +1 -1
- package/dist/config/plugin-engine.d.ts +0 -10
- package/dist/config/plugin-engine.d.ts.map +1 -1
- package/dist/config/plugin-engine.js +1 -37
- package/dist/config/plugin-engine.js.map +1 -1
- package/dist/config/types.d.ts +94 -109
- package/dist/config/types.d.ts.map +1 -1
- package/dist/context/apply-defaults.d.ts +8 -31
- package/dist/context/apply-defaults.d.ts.map +1 -1
- package/dist/context/apply-defaults.js +12 -41
- package/dist/context/apply-defaults.js.map +1 -1
- package/dist/context/hook-pipeline.d.ts +4 -29
- package/dist/context/hook-pipeline.d.ts.map +1 -1
- package/dist/context/hook-pipeline.js +8 -41
- package/dist/context/hook-pipeline.js.map +1 -1
- package/dist/context/index.d.ts +4 -15
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js +223 -215
- package/dist/context/index.js.map +1 -1
- package/dist/context/nested-operations.d.ts +7 -26
- package/dist/context/nested-operations.d.ts.map +1 -1
- package/dist/context/nested-operations.js +73 -171
- package/dist/context/nested-operations.js.map +1 -1
- package/dist/context/transaction-boundary.d.ts +36 -47
- package/dist/context/transaction-boundary.d.ts.map +1 -1
- package/dist/context/transaction-boundary.js +92 -79
- package/dist/context/transaction-boundary.js.map +1 -1
- package/dist/context/write-pipeline.d.ts +25 -64
- package/dist/context/write-pipeline.d.ts.map +1 -1
- package/dist/context/write-pipeline.js +81 -111
- package/dist/context/write-pipeline.js.map +1 -1
- package/dist/fields/format-prisma-default.d.ts.map +1 -1
- package/dist/fields/format-prisma-default.js +4 -7
- package/dist/fields/format-prisma-default.js.map +1 -1
- package/dist/fields/index.d.ts +17 -2
- package/dist/fields/index.d.ts.map +1 -1
- package/dist/fields/index.js +136 -147
- package/dist/fields/index.js.map +1 -1
- package/dist/filter/collect.d.ts +26 -3
- package/dist/filter/collect.d.ts.map +1 -1
- package/dist/filter/collect.js +30 -12
- package/dist/filter/collect.js.map +1 -1
- package/dist/filter/filter.test.js +98 -15
- package/dist/filter/filter.test.js.map +1 -1
- package/dist/filter/index.d.ts +1 -0
- package/dist/filter/index.d.ts.map +1 -1
- package/dist/filter/index.js.map +1 -1
- package/dist/filter/map.d.ts.map +1 -1
- package/dist/filter/map.js +0 -5
- package/dist/filter/map.js.map +1 -1
- package/dist/filter/parse.d.ts.map +1 -1
- package/dist/filter/parse.js +2 -9
- package/dist/filter/parse.js.map +1 -1
- package/dist/filter/serialize.d.ts.map +1 -1
- package/dist/filter/serialize.js +2 -4
- package/dist/filter/serialize.js.map +1 -1
- package/dist/hooks/index.d.ts +4 -42
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +5 -59
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -4
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +1 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +4 -0
- package/dist/internal.js.map +1 -1
- package/dist/lib/case-utils.d.ts +0 -32
- package/dist/lib/case-utils.d.ts.map +1 -1
- package/dist/lib/case-utils.js +0 -32
- package/dist/lib/case-utils.js.map +1 -1
- package/dist/mcp/handler.d.ts +0 -4
- package/dist/mcp/handler.d.ts.map +1 -1
- package/dist/mcp/handler.js +12 -69
- package/dist/mcp/handler.js.map +1 -1
- package/dist/query/index.d.ts +55 -227
- package/dist/query/index.d.ts.map +1 -1
- package/dist/query/index.js +41 -117
- package/dist/query/index.js.map +1 -1
- package/dist/query/relationship-options.d.ts +1 -1
- package/dist/query/relationship-options.js +1 -1
- package/dist/utils/password.d.ts +0 -68
- package/dist/utils/password.d.ts.map +1 -1
- package/dist/utils/password.js +7 -76
- package/dist/utils/password.js.map +1 -1
- package/dist/validation/field-config.d.ts.map +1 -1
- package/dist/validation/field-config.js +0 -6
- package/dist/validation/field-config.js.map +1 -1
- package/dist/validation/schema.d.ts +0 -7
- package/dist/validation/schema.d.ts.map +1 -1
- package/dist/validation/schema.js +0 -10
- package/dist/validation/schema.js.map +1 -1
- package/package.json +1 -1
- package/src/access/access-filter.test.ts +205 -275
- package/src/access/access-filter.ts +236 -272
- package/src/access/declared-dependencies.test.ts +277 -0
- package/src/access/declared-dependencies.ts +117 -37
- package/src/access/depth-limits.ts +8 -7
- package/src/access/engine.ts +0 -25
- package/src/access/errors.ts +97 -12
- package/src/access/field-access.test.ts +312 -2
- package/src/access/field-access.ts +118 -42
- package/src/access/field-transforms.ts +8 -39
- package/src/access/field-visibility.ts +99 -45
- package/src/access/index.ts +17 -5
- package/src/access/query-validation.ts +359 -0
- package/src/access/relationship-count.ts +3 -11
- package/src/access/relationship-label-filter.test.ts +19 -68
- package/src/access/relationship-label-filter.ts +27 -104
- package/src/access/transaction-registry.ts +58 -0
- package/src/access/types.ts +83 -86
- package/src/config/index.ts +10 -22
- package/src/config/label.ts +6 -13
- package/src/config/nav-count.ts +11 -19
- package/src/config/plugin-engine.ts +1 -37
- package/src/config/types.ts +95 -110
- package/src/context/apply-defaults.ts +12 -44
- package/src/context/hook-pipeline.ts +12 -67
- package/src/context/index.ts +311 -276
- package/src/context/nested-operations.ts +94 -226
- package/src/context/transaction-boundary.ts +113 -109
- package/src/context/write-pipeline.ts +99 -155
- package/src/fields/format-prisma-default.ts +4 -7
- package/src/fields/index.ts +155 -147
- package/src/filter/collect.ts +48 -12
- package/src/filter/filter.test.ts +153 -15
- package/src/filter/index.ts +1 -0
- package/src/filter/map.ts +0 -5
- package/src/filter/parse.ts +2 -9
- package/src/filter/serialize.ts +2 -4
- package/src/hooks/index.ts +5 -59
- package/src/index.ts +23 -4
- package/src/internal.ts +5 -0
- package/src/lib/case-utils.ts +0 -32
- package/src/mcp/handler.ts +13 -71
- package/src/query/index.ts +82 -235
- package/src/query/relationship-options.ts +1 -1
- package/src/utils/password.ts +7 -76
- package/src/validation/field-config.ts +0 -6
- package/src/validation/schema.ts +0 -10
- package/tests/access-relationships.test.ts +18 -16
- package/tests/computed-field-selective-evaluation.test.ts +418 -0
- package/tests/context.test.ts +727 -1
- package/tests/field-types.test.ts +222 -0
- package/tests/mcp-handler.test.ts +34 -0
- package/tests/needs-declared-dependencies.test.ts +7 -4
- package/tests/resolve-chain.test.ts +11 -11
- package/tests/transaction-boundary-outermost.test.ts +530 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { filterWritableFields } from './field-access.js';
|
|
1
|
+
import { describe, it, expect, expectTypeOf } from 'vitest';
|
|
2
|
+
import { checkFieldAccess, filterWritableFields, isFieldReadableForPredicate, } from './field-access.js';
|
|
3
|
+
import { InvalidFieldAccessResultError } from './errors.js';
|
|
3
4
|
import { ValidationError } from '../hooks/index.js';
|
|
4
5
|
// A non-sudo access context. The cast is localized to test setup (mirrors the
|
|
5
6
|
// existing sudo-context casts in this file): the runtime AccessContext carries
|
|
@@ -18,6 +19,210 @@ function sudoContext() {
|
|
|
18
19
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
19
20
|
};
|
|
20
21
|
}
|
|
22
|
+
// ── #914: `FieldAccess['read']`'s `item` must type as present, matching what
|
|
23
|
+
// Field Visibility (field-visibility.ts) actually passes ──
|
|
24
|
+
describe("FieldAccess['read'] item typing (issue #914)", () => {
|
|
25
|
+
it('types item as present for a read rule that reads a property off it — no cast, no `any`', () => {
|
|
26
|
+
const fieldAccess = {
|
|
27
|
+
read: ({ session, item }) => item.ownerId === session?.userId,
|
|
28
|
+
};
|
|
29
|
+
expect(typeof fieldAccess.read).toBe('function');
|
|
30
|
+
});
|
|
31
|
+
it('still compiles a read rule that ignores item entirely', () => {
|
|
32
|
+
const fieldAccess = {
|
|
33
|
+
read: () => true,
|
|
34
|
+
};
|
|
35
|
+
expect(typeof fieldAccess.read).toBe('function');
|
|
36
|
+
});
|
|
37
|
+
it('leaves the create branch unchanged — item is still absent, there genuinely is no row yet', () => {
|
|
38
|
+
expectTypeOf().toEqualTypeOf();
|
|
39
|
+
});
|
|
40
|
+
// Type-level pin: `resolveReadableFieldValue` (field-visibility.ts) is the
|
|
41
|
+
// sole caller of `checkFieldAccess` for `operation: 'read'`, and always
|
|
42
|
+
// supplies `item: accessItem` — a full row, never `undefined`. This
|
|
43
|
+
// assertion has no runtime effect (`expectTypeOf` is a no-op outside
|
|
44
|
+
// `vitest --typecheck`); its value is that `pnpm build`/`tsc` fails on this
|
|
45
|
+
// file the moment `FieldAccess['read']`'s `item` type drifts back to
|
|
46
|
+
// optional/absent, so the declared type and the call site cannot silently
|
|
47
|
+
// diverge again.
|
|
48
|
+
it("pins FieldAccess['read']'s item type against the field-visibility.ts call site", () => {
|
|
49
|
+
expectTypeOf().toEqualTypeOf();
|
|
50
|
+
expectTypeOf().toEqualTypeOf();
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
// ── #913: a field rule returning a filter must not be granted blanket access ──
|
|
54
|
+
describe('checkFieldAccess', () => {
|
|
55
|
+
it('allows when the rule returns true', async () => {
|
|
56
|
+
const allowed = await checkFieldAccess({ read: () => true }, 'read', {
|
|
57
|
+
session: null,
|
|
58
|
+
item: { ownerId: 'someone-else' },
|
|
59
|
+
context: nonSudoContext(),
|
|
60
|
+
});
|
|
61
|
+
expect(allowed).toBe(true);
|
|
62
|
+
});
|
|
63
|
+
it('denies when the rule returns false', async () => {
|
|
64
|
+
const allowed = await checkFieldAccess({ read: () => false }, 'read', {
|
|
65
|
+
session: null,
|
|
66
|
+
item: { ownerId: 'someone-else' },
|
|
67
|
+
context: nonSudoContext(),
|
|
68
|
+
});
|
|
69
|
+
expect(allowed).toBe(false);
|
|
70
|
+
});
|
|
71
|
+
it('allows when no field access is configured', async () => {
|
|
72
|
+
const allowed = await checkFieldAccess(undefined, 'read', {
|
|
73
|
+
session: null,
|
|
74
|
+
context: nonSudoContext(),
|
|
75
|
+
});
|
|
76
|
+
expect(allowed).toBe(true);
|
|
77
|
+
});
|
|
78
|
+
it('allows when no rule is configured for the operation', async () => {
|
|
79
|
+
const allowed = await checkFieldAccess({ update: () => false }, 'read', {
|
|
80
|
+
session: null,
|
|
81
|
+
context: nonSudoContext(),
|
|
82
|
+
});
|
|
83
|
+
expect(allowed).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
it('throws InvalidFieldAccessResultError, not allow, when a read rule returns a filter', async () => {
|
|
86
|
+
// The exact reproduction from the issue: a rule written to scope a field
|
|
87
|
+
// by row, which the previous fail-open default granted full access to.
|
|
88
|
+
const fieldAccess = {
|
|
89
|
+
read: () => ({ ownerId: { equals: 'someone-else' } }),
|
|
90
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
91
|
+
};
|
|
92
|
+
await expect(checkFieldAccess(fieldAccess, 'read', {
|
|
93
|
+
session: null,
|
|
94
|
+
item: { ownerId: 'the-owner' },
|
|
95
|
+
context: nonSudoContext(),
|
|
96
|
+
})).rejects.toThrow(InvalidFieldAccessResultError);
|
|
97
|
+
});
|
|
98
|
+
it('throws for a filter-returning rule on create, where there is no item to test it against', async () => {
|
|
99
|
+
const fieldAccess = {
|
|
100
|
+
create: () => ({ ownerId: { equals: 'someone-else' } }),
|
|
101
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
102
|
+
};
|
|
103
|
+
await expect(checkFieldAccess(fieldAccess, 'create', {
|
|
104
|
+
session: null,
|
|
105
|
+
context: nonSudoContext(),
|
|
106
|
+
inputData: { ownerId: 'the-owner' },
|
|
107
|
+
})).rejects.toThrow(InvalidFieldAccessResultError);
|
|
108
|
+
});
|
|
109
|
+
it('throws for a filter-returning rule on update', async () => {
|
|
110
|
+
const fieldAccess = {
|
|
111
|
+
update: () => ({ ownerId: { equals: 'someone-else' } }),
|
|
112
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
113
|
+
};
|
|
114
|
+
await expect(checkFieldAccess(fieldAccess, 'update', {
|
|
115
|
+
session: null,
|
|
116
|
+
item: { ownerId: 'the-owner' },
|
|
117
|
+
context: nonSudoContext(),
|
|
118
|
+
inputData: { ownerId: 'someone-else' },
|
|
119
|
+
})).rejects.toThrow(InvalidFieldAccessResultError);
|
|
120
|
+
});
|
|
121
|
+
it('throws for a non-boolean, non-filter result too (e.g. undefined)', async () => {
|
|
122
|
+
const fieldAccess = {
|
|
123
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
124
|
+
read: () => undefined,
|
|
125
|
+
};
|
|
126
|
+
await expect(checkFieldAccess(fieldAccess, 'read', {
|
|
127
|
+
session: null,
|
|
128
|
+
item: {},
|
|
129
|
+
context: nonSudoContext(),
|
|
130
|
+
})).rejects.toThrow(InvalidFieldAccessResultError);
|
|
131
|
+
});
|
|
132
|
+
it('throws with a descriptive message for null, and for other primitive results', async () => {
|
|
133
|
+
const nullAccess = {
|
|
134
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
135
|
+
read: () => null,
|
|
136
|
+
};
|
|
137
|
+
await expect(checkFieldAccess(nullAccess, 'read', {
|
|
138
|
+
session: null,
|
|
139
|
+
item: {},
|
|
140
|
+
context: nonSudoContext(),
|
|
141
|
+
})).rejects.toThrow(/returned null, not a boolean/);
|
|
142
|
+
const numberAccess = {
|
|
143
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
144
|
+
read: () => 42,
|
|
145
|
+
};
|
|
146
|
+
await expect(checkFieldAccess(numberAccess, 'read', {
|
|
147
|
+
session: null,
|
|
148
|
+
item: {},
|
|
149
|
+
context: nonSudoContext(),
|
|
150
|
+
})).rejects.toThrow(/returned a number, not a boolean/);
|
|
151
|
+
});
|
|
152
|
+
it('sudo bypasses the rule entirely, so a filter-returning rule never reaches the throw', async () => {
|
|
153
|
+
const fieldAccess = {
|
|
154
|
+
read: () => ({ ownerId: { equals: 'someone-else' } }),
|
|
155
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
156
|
+
};
|
|
157
|
+
const allowed = await checkFieldAccess(fieldAccess, 'read', {
|
|
158
|
+
session: null,
|
|
159
|
+
item: { ownerId: 'the-owner' },
|
|
160
|
+
context: sudoContext(),
|
|
161
|
+
});
|
|
162
|
+
expect(allowed).toBe(true);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
describe('isFieldReadableForPredicate (#915)', () => {
|
|
166
|
+
it('allows when there is no field access configured', async () => {
|
|
167
|
+
const readable = await isFieldReadableForPredicate(undefined, {
|
|
168
|
+
session: null,
|
|
169
|
+
context: nonSudoContext(),
|
|
170
|
+
});
|
|
171
|
+
expect(readable).toBe(true);
|
|
172
|
+
});
|
|
173
|
+
it('allows when the rule only inspects session (never touches item)', async () => {
|
|
174
|
+
const readable = await isFieldReadableForPredicate({ read: ({ session }) => session?.userId === 'admin' }, { session: { userId: 'admin' }, context: nonSudoContext() });
|
|
175
|
+
expect(readable).toBe(true);
|
|
176
|
+
});
|
|
177
|
+
it('denies when the rule returns false', async () => {
|
|
178
|
+
const readable = await isFieldReadableForPredicate({ read: () => false }, { session: null, context: nonSudoContext() });
|
|
179
|
+
expect(readable).toBe(false);
|
|
180
|
+
});
|
|
181
|
+
it('denies a row-dependent rule that dereferences `item` directly', async () => {
|
|
182
|
+
const readable = await isFieldReadableForPredicate({ read: ({ item, session }) => item.ownerId === session?.userId }, { session: { userId: 'user-1' }, context: nonSudoContext() });
|
|
183
|
+
expect(readable).toBe(false);
|
|
184
|
+
});
|
|
185
|
+
it('denies a row-dependent rule even when it reads `item` via optional chaining', async () => {
|
|
186
|
+
// This is the exact idiom `InvalidFieldAccessResultError`'s own message
|
|
187
|
+
// recommends (`item?.ownerId === session?.userId`) — it must still deny,
|
|
188
|
+
// not silently misevaluate `undefined === session?.userId` against a
|
|
189
|
+
// poisoned `item`.
|
|
190
|
+
const readable = await isFieldReadableForPredicate({ read: ({ item, session }) => item?.ownerId === session?.userId }, { session: null, context: nonSudoContext() });
|
|
191
|
+
expect(readable).toBe(false);
|
|
192
|
+
});
|
|
193
|
+
it('denies a row-dependent rule that only enumerates `item`s keys', async () => {
|
|
194
|
+
const readable = await isFieldReadableForPredicate(
|
|
195
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
196
|
+
{ read: ({ item }) => Object.keys(item).length > 0 }, { session: null, context: nonSudoContext() });
|
|
197
|
+
expect(readable).toBe(false);
|
|
198
|
+
});
|
|
199
|
+
it('propagates InvalidFieldAccessResultError instead of folding it into a denial', async () => {
|
|
200
|
+
const fieldAccess = {
|
|
201
|
+
read: () => ({ ownerId: { equals: 'someone-else' } }),
|
|
202
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
203
|
+
};
|
|
204
|
+
await expect(isFieldReadableForPredicate(fieldAccess, { session: null, context: nonSudoContext() })).rejects.toThrow(InvalidFieldAccessResultError);
|
|
205
|
+
});
|
|
206
|
+
it('propagates a genuine error the rule throws for its own reasons, not just non-boolean results', async () => {
|
|
207
|
+
// The rule never touches `item` — it throws for a reason of its own.
|
|
208
|
+
// This must NOT be folded into an ordinary `false` denial (that would
|
|
209
|
+
// mask a real bug in the rule as "field not readable"), matching how the
|
|
210
|
+
// post-query path (`filterReadableFields`) already lets such a throw
|
|
211
|
+
// propagate unchanged.
|
|
212
|
+
const fieldAccess = {
|
|
213
|
+
read: ({ session }) => {
|
|
214
|
+
if (session === null)
|
|
215
|
+
throw new Error('unexpected anonymous access');
|
|
216
|
+
return true;
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
await expect(isFieldReadableForPredicate(fieldAccess, { session: null, context: nonSudoContext() })).rejects.toThrow('unexpected anonymous access');
|
|
220
|
+
});
|
|
221
|
+
it('sudo bypasses the rule entirely, so a row-dependent rule never denies', async () => {
|
|
222
|
+
const readable = await isFieldReadableForPredicate({ read: ({ item, session }) => item.ownerId === session?.userId }, { session: null, context: sudoContext() });
|
|
223
|
+
expect(readable).toBe(true);
|
|
224
|
+
});
|
|
225
|
+
});
|
|
21
226
|
describe('filterWritableFields', () => {
|
|
22
227
|
it('should filter out foreign key fields when their corresponding relationship field exists', async () => {
|
|
23
228
|
// Setup: Define field configs with a relationship field
|
|
@@ -303,6 +508,28 @@ describe('filterWritableFields', () => {
|
|
|
303
508
|
inputData: data,
|
|
304
509
|
})).rejects.toThrow(/status/);
|
|
305
510
|
});
|
|
511
|
+
// ── #913: a field rule returning a filter must not grant blanket write access ──
|
|
512
|
+
it('throws InvalidFieldAccessResultError, not a blanket write, when field access returns a filter (non-sudo)', async () => {
|
|
513
|
+
const fieldConfigs = {
|
|
514
|
+
title: { type: 'text' },
|
|
515
|
+
status: {
|
|
516
|
+
type: 'text',
|
|
517
|
+
access: {
|
|
518
|
+
// Written as a row-scoping rule; field access does not honour filters.
|
|
519
|
+
update: () => ({ status: { equals: 'draft' } }),
|
|
520
|
+
create: () => ({ status: { equals: 'draft' } }),
|
|
521
|
+
},
|
|
522
|
+
},
|
|
523
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
524
|
+
};
|
|
525
|
+
const data = { title: 'Test', status: 'published' };
|
|
526
|
+
await expect(filterWritableFields(data, fieldConfigs, 'update', {
|
|
527
|
+
session: null,
|
|
528
|
+
item: { id: 'post-1', status: 'draft' },
|
|
529
|
+
context: nonSudoContext(),
|
|
530
|
+
inputData: data,
|
|
531
|
+
})).rejects.toThrow(InvalidFieldAccessResultError);
|
|
532
|
+
});
|
|
306
533
|
it('does NOT throw on a would-be-denied field under sudo', async () => {
|
|
307
534
|
const fieldConfigs = {
|
|
308
535
|
title: { type: 'text' },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field-access.test.js","sourceRoot":"","sources":["../../src/access/field-access.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAEnD,8EAA8E;AAC9E,+EAA+E;AAC/E,qDAAqD;AACrD,SAAS,cAAc;IACrB,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,KAAK;QACd,8DAA8D;KACxD,CAAA;AACV,CAAC;AAED,SAAS,WAAW;IAClB,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,IAAI;QACb,8DAA8D;KACxD,CAAA;AACV,CAAC;AAED,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,yFAAyF,EAAE,KAAK,IAAI,EAAE;QACvG,wDAAwD;QACxD,MAAM,YAAY,GAAG;YACnB,KAAK,EAAE;gBACL,IAAI,EAAE,MAAM;aACb;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,cAAc;gBACpB,IAAI,EAAE,KAAK;aACZ;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,cAAc;gBACpB,IAAI,EAAE,IAAI,EAAE,qDAAqD;aAClE;SACF,CAAA;QAED,sEAAsE;QACtE,MAAM,IAAI,GAAG;YACX,KAAK,EAAE,WAAW;YAClB,QAAQ,EAAE,UAAU,EAAE,8BAA8B;YACpD,MAAM,EAAE,SAAS,EAAE,kDAAkD;YACrE,MAAM,EAAE;gBACN,OAAO,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE;aAC5B;SACF,CAAA;QAED,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE;YACxE,OAAO,EAAE,IAAI;YACb,OAAO,EAAE;gBACP,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,IAAI,EAAE,2CAA2C;gBAC1D,8DAA8D;aACxD;YACR,SAAS,EAAE,IAAI;SAChB,CAAC,CAAA;QAEF,kCAAkC;QAClC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,UAAU,CAAC,CAAA;QAE/C,sBAAsB;QACtB,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;QAErD,oCAAoC;QACpC,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAA;QACzC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;QAEhE,yEAAyE;QACzE,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,YAAY,GAAG;YACnB,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;SACxB,CAAA;QAED,MAAM,IAAI,GAAG;YACX,EAAE,EAAE,UAAU;YACd,KAAK,EAAE,MAAM;YACb,SAAS,EAAE,IAAI,IAAI,EAAE;YACrB,SAAS,EAAE,IAAI,IAAI,EAAE;SACtB,CAAA;QAED,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE;YACxE,OAAO,EAAE,IAAI;YACb,OAAO,EAAE;gBACP,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,IAAI;gBACb,8DAA8D;aACxD;YACR,SAAS,EAAE,IAAI;SAChB,CAAC,CAAA;QAEF,uCAAuC;QACvC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;QACzC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,WAAW,CAAC,CAAA;QAChD,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,WAAW,CAAC,CAAA;QAEhD,+BAA+B;QAC/B,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IAClD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,YAAY,GAAG;YACnB,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;YACvB,MAAM,EAAE;gBACN,IAAI,EAAE,cAAc;gBACpB,IAAI,EAAE,KAAK;aACZ;SACF,CAAA;QAED,MAAM,IAAI,GAAG;YACX,KAAK,EAAE,eAAe;YACtB,QAAQ,EAAE,UAAU,EAAE,yBAAyB;YAC/C,MAAM,EAAE;gBACN,OAAO,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE;aAC5B;SACF,CAAA;QAED,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE;YACxE,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE;YACxB,OAAO,EAAE;gBACP,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,IAAI;gBACb,8DAA8D;aACxD;YACR,SAAS,EAAE,IAAI;SAChB,CAAC,CAAA;QAEF,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,UAAU,CAAC,CAAA;QAC/C,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,OAAO,EAAE,eAAe,CAAC,CAAA;QACzD,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAA;IAC3C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;QAC9F,MAAM,YAAY,GAAG;YACnB,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,8CAA8C;YAC5E,MAAM,EAAE;gBACN,IAAI,EAAE,cAAc;gBACpB,IAAI,EAAE,KAAK;aACZ;SACF,CAAA;QAED,MAAM,IAAI,GAAG;YACX,UAAU,EAAE,WAAW,EAAE,gDAAgD;YACzE,QAAQ,EAAE,UAAU,EAAE,0CAA0C;SACjE,CAAA;QAED,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE;YACxE,OAAO,EAAE,IAAI;YACb,OAAO,EAAE;gBACP,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,IAAI;gBACb,8DAA8D;aACxD;YACR,SAAS,EAAE,IAAI;SAChB,CAAC,CAAA;QAEF,qDAAqD;QACrD,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,YAAY,EAAE,WAAW,CAAC,CAAA;QAE1D,8EAA8E;QAC9E,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,UAAU,CAAC,CAAA;IACjD,CAAC,CAAC,CAAA;IAEF,gFAAgF;IAEhF,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,YAAY,GAAG,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAA;QAChD,MAAM,IAAI,GAAG;YACX,KAAK,EAAE,MAAM;YACb,sEAAsE;YACtE,4EAA4E;YAC5E,sBAAsB,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;SACvD,CAAA;QAED,MAAM,MAAM,CACV,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE;YACjD,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,cAAc,EAAE;YACzB,SAAS,EAAE,IAAI;SAChB,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;QAClC,MAAM,MAAM,CACV,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE;YACjD,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,cAAc,EAAE;YACzB,SAAS,EAAE,IAAI;SAChB,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAA;IAC7C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,YAAY,GAAG,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAA;QAChD,MAAM,IAAI,GAAG;YACX,KAAK,EAAE,SAAS;YAChB,QAAQ,EAAE,OAAO;SAClB,CAAA;QAED,MAAM,MAAM,CACV,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE;YACjD,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;YACtB,OAAO,EAAE,cAAc,EAAE;YACzB,SAAS,EAAE,IAAI;SAChB,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IAC/B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4EAA4E,EAAE,KAAK,IAAI,EAAE;QAC1F,MAAM,YAAY,GAAG,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAA;QAChD,MAAM,IAAI,GAAG;YACX,KAAK,EAAE,MAAM;YACb,sBAAsB,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;SACvD,CAAA;QAED,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE;YACxE,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,WAAW,EAAE;YACtB,SAAS,EAAE,IAAI;SAChB,CAAC,CAAA;QAEF,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;QAChD,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,wBAAwB,CAAC,CAAA;IAC3D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,mFAAmF,EAAE,KAAK,IAAI,EAAE;QACjG,MAAM,YAAY,GAAG;YACnB,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;YACvB,MAAM,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,KAAK,EAAE;SAC9C,CAAA;QACD,MAAM,IAAI,GAAG;YACX,EAAE,EAAE,QAAQ;YACZ,SAAS,EAAE,IAAI,IAAI,EAAE;YACrB,SAAS,EAAE,IAAI,IAAI,EAAE;YACrB,KAAK,EAAE,MAAM;YACb,QAAQ,EAAE,QAAQ,EAAE,2BAA2B;SAChD,CAAA;QAED,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE;YACxE,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,cAAc,EAAE;YACzB,SAAS,EAAE,IAAI;SAChB,CAAC,CAAA;QAEF,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;QACzC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,WAAW,CAAC,CAAA;QAChD,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,WAAW,CAAC,CAAA;QAChD,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,UAAU,CAAC,CAAA;QAC/C,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IAClD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oGAAoG,EAAE,KAAK,IAAI,EAAE;QAClH,0EAA0E;QAC1E,0EAA0E;QAC1E,yDAAyD;QACzD,MAAM,YAAY,GAAG;YACnB,KAAK,EAAE;gBACL,IAAI,EAAE,OAAO;gBACb,cAAc,EAAE,CAAC,SAAiB,EAAE,EAAE,CAAC,CAAC,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,OAAO,CAAC;aACjF;SACF,CAAA;QACD,MAAM,IAAI,GAAG;YACX,SAAS,EAAE,iBAAiB;YAC5B,UAAU,EAAE,EAAE;SACf,CAAA;QAED,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE;YACxE,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,cAAc,EAAE;YACzB,SAAS,EAAE,IAAI;SAChB,CAAC,CAAA;QAEF,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAA;QAC/D,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gGAAgG,EAAE,KAAK,IAAI,EAAE;QAC9G,2EAA2E;QAC3E,qEAAqE;QACrE,4EAA4E;QAC5E,6DAA6D;QAC7D,MAAM,YAAY,GAAG;YACnB,KAAK,EAAE;gBACL,IAAI,EAAE,OAAO;gBACb,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE;gBACpD,cAAc,EAAE,CAAC,SAAiB,EAAE,EAAE,CAAC,CAAC,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,OAAO,CAAC;aACjF;SACF,CAAA;QACD,MAAM,IAAI,GAAG;YACX,SAAS,EAAE,oBAAoB;YAC/B,UAAU,EAAE,CAAC;SACd,CAAA;QAED,kEAAkE;QAClE,MAAM,MAAM,CACV,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE;YACjD,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,cAAc,EAAE;YACzB,SAAS,EAAE,IAAI;SAChB,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;QAClC,MAAM,MAAM,CACV,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE;YACjD,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;YACtB,OAAO,EAAE,cAAc,EAAE;YACzB,SAAS,EAAE,IAAI;SAChB,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC5B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sFAAsF,EAAE,KAAK,IAAI,EAAE;QACpG,2EAA2E;QAC3E,qEAAqE;QACrE,MAAM,YAAY,GAAG;YACnB,KAAK,EAAE;gBACL,IAAI,EAAE,OAAO;gBACb,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE;gBACpD,cAAc,EAAE,CAAC,SAAiB,EAAE,EAAE,CAAC,CAAC,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,OAAO,CAAC;aACjF;SACF,CAAA;QACD,MAAM,IAAI,GAAG;YACX,SAAS,EAAE,iBAAiB;YAC5B,UAAU,EAAE,EAAE;SACf,CAAA;QAED,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE;YACxE,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,WAAW,EAAE;YACtB,SAAS,EAAE,IAAI;SAChB,CAAC,CAAA;QAEF,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAA;QAC/D,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;IAEF,gFAAgF;IAEhF,EAAE,CAAC,yEAAyE,EAAE,KAAK,IAAI,EAAE;QACvF,MAAM,YAAY,GAAG;YACnB,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;YACvB,MAAM,EAAE;gBACN,IAAI,EAAE,MAAM;gBACZ,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE;aACrD;SACF,CAAA;QACD,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;QAEnD,MAAM,MAAM,CACV,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE;YACjD,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;YACtB,OAAO,EAAE,cAAc,EAAE;YACzB,SAAS,EAAE,IAAI;SAChB,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,YAAY,GAAG;YACnB,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;YACvB,MAAM,EAAE;gBACN,IAAI,EAAE,MAAM;gBACZ,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE;aACrD;SACF,CAAA;QACD,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;QAEnD,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE;YACxE,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;YACtB,OAAO,EAAE,WAAW,EAAE;YACtB,SAAS,EAAE,IAAI;SAChB,CAAC,CAAA;QAEF,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;QAChD,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAA;IACxD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;QAC5F,MAAM,YAAY,GAAG;YACnB,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;YACvB,MAAM,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,KAAK,EAAE;SAC9C,CAAA;QACD,MAAM,IAAI,GAAG;YACX,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;SACtC,CAAA;QAED,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE;YACxE,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,cAAc,EAAE;YACzB,SAAS,EAAE,IAAI;SAChB,CAAC,CAAA;QAEF,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAA;QACzC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAA;IAChE,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"field-access.test.js","sourceRoot":"","sources":["../../src/access/field-access.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,46 +1,19 @@
|
|
|
1
1
|
import type { OpenSaasConfig, FieldConfig } from '../config/types.js';
|
|
2
2
|
import type { HashedPassword } from '../utils/password.js';
|
|
3
|
-
/**
|
|
4
|
-
* Extract the return type of a field's afterOperation hook
|
|
5
|
-
* If the field has an afterOperation hook, infer its return type
|
|
6
|
-
* Otherwise, use the original type
|
|
7
|
-
*/
|
|
8
3
|
export type InferFieldReadType<TField extends FieldConfig, TOriginal> = TField extends {
|
|
9
4
|
hooks?: {
|
|
10
5
|
afterOperation?: (...args: any[]) => infer R;
|
|
11
6
|
};
|
|
12
7
|
} ? R extends never ? TOriginal : R : TOriginal;
|
|
13
|
-
/**
|
|
14
|
-
* Transform a Prisma model's field types based on OpenSaas field configs
|
|
15
|
-
* This applies afterOperation hook transformations to field types
|
|
16
|
-
*/
|
|
17
8
|
export type TransformModelFields<TModel extends Record<string, any>, TFields extends Record<string, FieldConfig>> = {
|
|
18
9
|
[K in keyof TModel]: K extends keyof TFields ? InferFieldReadType<TFields[K], TModel[K]> : TModel[K];
|
|
19
10
|
};
|
|
20
|
-
/**
|
|
21
|
-
* Get the field configs for a specific list from the OpenSaas config
|
|
22
|
-
*/
|
|
23
11
|
export type GetListFields<TConfig extends OpenSaasConfig, TListKey extends keyof TConfig['lists']> = TConfig['lists'][TListKey]['fields'];
|
|
24
|
-
/**
|
|
25
|
-
* Transform a Prisma model result based on OpenSaas config
|
|
26
|
-
* Applies field hooks transformations
|
|
27
|
-
*/
|
|
28
12
|
export type TransformResult<TConfig extends OpenSaasConfig, TListKey extends keyof TConfig['lists'], TResult> = TResult extends Record<string, any> ? TransformModelFields<TResult, GetListFields<TConfig, TListKey>> : TResult;
|
|
29
|
-
/**
|
|
30
|
-
* Transform a Prisma operation's return type
|
|
31
|
-
* Handles single results, arrays, and null cases
|
|
32
|
-
*/
|
|
33
13
|
export type TransformOperationResult<TConfig extends OpenSaasConfig, TListKey extends keyof TConfig['lists'], TResult> = TResult extends Promise<infer R> ? Promise<R extends Array<infer Item> ? Array<TransformResult<TConfig, TListKey, Item>> : R extends null ? null : TransformResult<TConfig, TListKey, R>> : never;
|
|
34
|
-
/**
|
|
35
|
-
* Known field type mappings for afterOperation hooks
|
|
36
|
-
* These provide concrete type hints for common field transformations
|
|
37
|
-
*/
|
|
38
14
|
export interface FieldTypeTransforms {
|
|
39
15
|
password: HashedPassword;
|
|
40
16
|
}
|
|
41
|
-
/**
|
|
42
|
-
* Helper to infer field type based on field config type
|
|
43
|
-
*/
|
|
44
17
|
export type InferFieldTypeTransform<TField extends FieldConfig> = TField extends {
|
|
45
18
|
type: infer TType;
|
|
46
19
|
} ? TType extends keyof FieldTypeTransforms ? FieldTypeTransforms[TType] : never : never;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field-transforms.d.ts","sourceRoot":"","sources":["../../src/access/field-transforms.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE1D
|
|
1
|
+
{"version":3,"file":"field-transforms.d.ts","sourceRoot":"","sources":["../../src/access/field-transforms.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE1D,MAAM,MAAM,kBAAkB,CAAC,MAAM,SAAS,WAAW,EAAE,SAAS,IAAI,MAAM,SAAS;IAIrF,KAAK,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,CAAC,CAAA;KAAE,CAAA;CACzD,GACG,CAAC,SAAS,KAAK,GACb,SAAS,GACT,CAAC,GACH,SAAS,CAAA;AAEb,MAAM,MAAM,oBAAoB,CAI9B,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAClC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,IACzC;KACD,CAAC,IAAI,MAAM,MAAM,GAAG,CAAC,SAAS,MAAM,OAAO,GACxC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,GACzC,MAAM,CAAC,CAAC,CAAC;CACd,CAAA;AAED,MAAM,MAAM,aAAa,CACvB,OAAO,SAAS,cAAc,EAC9B,QAAQ,SAAS,MAAM,OAAO,CAAC,OAAO,CAAC,IACrC,OAAO,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAA;AAExC,MAAM,MAAM,eAAe,CACzB,OAAO,SAAS,cAAc,EAC9B,QAAQ,SAAS,MAAM,OAAO,CAAC,OAAO,CAAC,EACvC,OAAO,IAIP,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC/B,oBAAoB,CAAC,OAAO,EAAE,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,GAC/D,OAAO,CAAA;AAEb,MAAM,MAAM,wBAAwB,CAClC,OAAO,SAAS,cAAc,EAC9B,QAAQ,SAAS,MAAM,OAAO,CAAC,OAAO,CAAC,EACvC,OAAO,IAEP,OAAO,SAAS,OAAO,CAAC,MAAM,CAAC,CAAC,GAC5B,OAAO,CACL,CAAC,SAAS,KAAK,CAAC,MAAM,IAAI,CAAC,GACvB,KAAK,CAAC,eAAe,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,GAC/C,CAAC,SAAS,IAAI,GACZ,IAAI,GACJ,eAAe,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,CAC5C,GACD,KAAK,CAAA;AAEX,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,cAAc,CAAA;CACzB;AAED,MAAM,MAAM,uBAAuB,CAAC,MAAM,SAAS,WAAW,IAAI,MAAM,SAAS;IAC/E,IAAI,EAAE,MAAM,KAAK,CAAA;CAClB,GACG,KAAK,SAAS,MAAM,mBAAmB,GACrC,mBAAmB,CAAC,KAAK,CAAC,GAC1B,KAAK,GACP,KAAK,CAAA"}
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import type { Session, AccessContext } from './types.js';
|
|
2
2
|
import type { OpenSaasConfig, FieldConfig } from '../config/types.js';
|
|
3
3
|
import type { DeclaredOnlyTree } from './declared-dependencies.js';
|
|
4
|
-
|
|
5
|
-
* Filter fields from an object based on read access
|
|
6
|
-
* Recursively applies access control to nested relationships
|
|
7
|
-
*/
|
|
4
|
+
import type { FieldSelectionScope } from '../query/index.js';
|
|
8
5
|
export declare function filterReadableFields<T extends Record<string, unknown>>(item: T, fieldConfigs: Record<string, FieldConfig>, args: {
|
|
9
6
|
session: Session | null;
|
|
10
7
|
context: AccessContext & {
|
|
11
8
|
_isSudo?: boolean;
|
|
12
9
|
};
|
|
13
|
-
}, config?: OpenSaasConfig, depth?: number, listKey?: string, declaredOnly?: DeclaredOnlyTree): Promise<Partial<T>>;
|
|
10
|
+
}, config?: OpenSaasConfig, depth?: number, listKey?: string, declaredOnly?: DeclaredOnlyTree, selection?: FieldSelectionScope): Promise<Partial<T>>;
|
|
14
11
|
//# sourceMappingURL=field-visibility.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field-visibility.d.ts","sourceRoot":"","sources":["../../src/access/field-visibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAKrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"field-visibility.d.ts","sourceRoot":"","sources":["../../src/access/field-visibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAKrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAElE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAwK5D,wBAAsB,oBAAoB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1E,IAAI,EAAE,CAAC,EACP,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACzC,IAAI,EAAE;IACJ,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IACvB,OAAO,EAAE,aAAa,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;CAC/C,EACD,MAAM,CAAC,EAAE,cAAc,EACvB,KAAK,GAAE,MAAU,EACjB,OAAO,CAAC,EAAE,MAAM,EAMhB,YAAY,GAAE,gBAA0C,EAGxD,SAAS,CAAC,EAAE,mBAAmB,GAC9B,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAmOrB"}
|
|
@@ -54,12 +54,14 @@ function deriveResolveOutputContext(context, link, config) {
|
|
|
54
54
|
* from the result.
|
|
55
55
|
*
|
|
56
56
|
* `accessItem` is the row used to evaluate field access; `hookItem` is the
|
|
57
|
-
* object passed to the hook as `item
|
|
58
|
-
*
|
|
57
|
+
* object passed to the hook as `item`. For a stored field, both are
|
|
58
|
+
* `workingItem` (the row's own stored/fetched columns). For a virtual field,
|
|
59
|
+
* `hookItem` is `computedFieldItem` instead — the same stored columns with
|
|
60
|
+
* every skipped-or-denied key removed — so it never sees another computed
|
|
61
|
+
* field's resolved value (ADR-0027).
|
|
59
62
|
*/
|
|
60
63
|
async function resolveReadableFieldValue(params) {
|
|
61
64
|
const { fieldConfig, fieldName, value, accessItem, hookItem, listKey, args, config } = params;
|
|
62
|
-
// Check field access (checkFieldAccess already handles sudo mode)
|
|
63
65
|
const canRead = await checkFieldAccess(fieldConfig?.access, 'read', {
|
|
64
66
|
...args,
|
|
65
67
|
item: accessItem,
|
|
@@ -67,10 +69,9 @@ async function resolveReadableFieldValue(params) {
|
|
|
67
69
|
if (!canRead) {
|
|
68
70
|
return { readable: false };
|
|
69
71
|
}
|
|
70
|
-
// Apply resolveOutput hook if present
|
|
71
72
|
if (fieldConfig?.hooks?.resolveOutput && listKey) {
|
|
72
|
-
//
|
|
73
|
-
//
|
|
73
|
+
// The hook is erased to this runtime shape here; at the actual call it
|
|
74
|
+
// receives the value typed for its own field.
|
|
74
75
|
const hook = fieldConfig.hooks.resolveOutput;
|
|
75
76
|
const link = { listKey, fieldKey: fieldName };
|
|
76
77
|
const chain = args.context._resolveOutputChain;
|
|
@@ -91,7 +92,6 @@ async function resolveReadableFieldValue(params) {
|
|
|
91
92
|
`not an access denial.`);
|
|
92
93
|
return { readable: false };
|
|
93
94
|
}
|
|
94
|
-
// Use Promise.resolve() to handle both sync and async hooks
|
|
95
95
|
const resolved = await Promise.resolve(hook({
|
|
96
96
|
value,
|
|
97
97
|
operation: 'query',
|
|
@@ -104,17 +104,16 @@ async function resolveReadableFieldValue(params) {
|
|
|
104
104
|
}
|
|
105
105
|
return { readable: true, value };
|
|
106
106
|
}
|
|
107
|
-
/**
|
|
108
|
-
* Filter fields from an object based on read access
|
|
109
|
-
* Recursively applies access control to nested relationships
|
|
110
|
-
*/
|
|
111
107
|
export async function filterReadableFields(item, fieldConfigs, args, config, depth = 0, listKey,
|
|
112
108
|
// Relation keys added purely to satisfy a field's `needs` (ADR-0025) at
|
|
113
109
|
// THIS level, and the same tree for each nested relation reached via a
|
|
114
110
|
// caller-named branch. Stripped from `filtered` right before it is
|
|
115
111
|
// returned — after resolveOutput has had a chance to read them — so a
|
|
116
112
|
// declared dependency never widens what the caller receives.
|
|
117
|
-
declaredOnly = emptyDeclaredOnlyTree()
|
|
113
|
+
declaredOnly = emptyDeclaredOnlyTree(),
|
|
114
|
+
// The fragment scope this level was reached under (ADR-0027, see module doc
|
|
115
|
+
// above), and the same tree one level down for each nested relation.
|
|
116
|
+
selection) {
|
|
118
117
|
const filtered = {};
|
|
119
118
|
// Multi-column fields (e.g. storage image()/file() in Keystone-parity mode)
|
|
120
119
|
// back several physical columns rather than one. Before the per-field pass,
|
|
@@ -139,17 +138,31 @@ declaredOnly = emptyDeclaredOnlyTree()) {
|
|
|
139
138
|
}
|
|
140
139
|
workingItem[fieldName] = assembled;
|
|
141
140
|
}
|
|
141
|
+
// Keys denied by field-level read access during the pass below — as opposed
|
|
142
|
+
// to a key merely skipped by `selection` or held back only for
|
|
143
|
+
// `declaredOnly` stripping. Tracked separately because a denied key must
|
|
144
|
+
// stay invisible to a computed field's hook (below), while a declared-only
|
|
145
|
+
// key must stay VISIBLE to one — that is the entire point of declaring it
|
|
146
|
+
// (ADR-0025) — even though `selection` above skipped adding it to
|
|
147
|
+
// `filtered` because the caller's fragment never asked for it.
|
|
148
|
+
const accessDeniedKeys = new Set();
|
|
142
149
|
// Process existing fields from the database result
|
|
143
150
|
for (const [fieldName, value] of Object.entries(workingItem)) {
|
|
144
151
|
const fieldConfig = fieldConfigs[fieldName];
|
|
145
|
-
// Always include id, createdAt, updatedAt
|
|
146
152
|
if (['id', 'createdAt', 'updatedAt'].includes(fieldName)) {
|
|
147
153
|
filtered[fieldName] = value;
|
|
148
154
|
continue;
|
|
149
155
|
}
|
|
150
|
-
//
|
|
151
|
-
//
|
|
152
|
-
//
|
|
156
|
+
// Projection-aware skip (ADR-0027, see module doc above): a field this
|
|
157
|
+
// level's fragment did not select gets no read-access check, no
|
|
158
|
+
// resolveOutput, and no recursion into a relation — none of that work
|
|
159
|
+
// happens for a value the read isn't going to return.
|
|
160
|
+
if (selection?.fields && !selection.fields.has(fieldName)) {
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
// Row/relation-level access is already scoped at the DB level via
|
|
164
|
+
// buildAccessScopedInclude; this only handles field-level access (hiding
|
|
165
|
+
// sensitive fields).
|
|
153
166
|
//
|
|
154
167
|
// Deliberately uncapped: the row/relation scoping in access-filter.ts bounds
|
|
155
168
|
// what gets FETCHED (a caller include past its depth cap is now a denial,
|
|
@@ -165,12 +178,12 @@ declaredOnly = emptyDeclaredOnlyTree()) {
|
|
|
165
178
|
fieldConfig.ref &&
|
|
166
179
|
value !== null &&
|
|
167
180
|
value !== undefined) {
|
|
168
|
-
// Gate the relationship on read access before recursing.
|
|
169
181
|
const canRead = await checkFieldAccess(fieldConfig?.access, 'read', {
|
|
170
182
|
...args,
|
|
171
183
|
item: workingItem,
|
|
172
184
|
});
|
|
173
185
|
if (!canRead) {
|
|
186
|
+
accessDeniedKeys.add(fieldName);
|
|
174
187
|
continue;
|
|
175
188
|
}
|
|
176
189
|
const relatedConfig = getRelatedListConfig(fieldConfig.ref, config);
|
|
@@ -179,26 +192,27 @@ declaredOnly = emptyDeclaredOnlyTree()) {
|
|
|
179
192
|
// back to an empty tree when this relation isn't declaration-related at
|
|
180
193
|
// all — the common case.
|
|
181
194
|
const nestedDeclaredOnly = declaredOnly.nested[fieldName] ?? emptyDeclaredOnlyTree();
|
|
195
|
+
// This relation's own fragment scope, if the caller's fragment named it
|
|
196
|
+
// with a nested Fragment/RelationSelector. `undefined` (a bare `true`
|
|
197
|
+
// selector, or no `selection` at all) means the nested list computes
|
|
198
|
+
// unrestricted — matching what naming a relation without narrowing it
|
|
199
|
+
// further has always meant.
|
|
200
|
+
const nestedSelection = selection?.nested[fieldName];
|
|
182
201
|
if (relatedConfig) {
|
|
183
|
-
// For many relationships (arrays) - recursively filter fields in each item
|
|
184
|
-
// The recursive call already handles applying resolveOutput hooks
|
|
185
202
|
if (Array.isArray(value)) {
|
|
186
|
-
filtered[fieldName] = await Promise.all(value.map((relatedItem) => filterReadableFields(relatedItem, relatedConfig.listConfig.fields, args, config, depth + 1, relatedConfig.listName, nestedDeclaredOnly)));
|
|
203
|
+
filtered[fieldName] = await Promise.all(value.map((relatedItem) => filterReadableFields(relatedItem, relatedConfig.listConfig.fields, args, config, depth + 1, relatedConfig.listName, nestedDeclaredOnly, nestedSelection)));
|
|
187
204
|
}
|
|
188
|
-
// For single relationships (objects) - recursively filter fields
|
|
189
|
-
// The recursive call already handles applying resolveOutput hooks
|
|
190
205
|
else if (typeof value === 'object') {
|
|
191
|
-
filtered[fieldName] = await filterReadableFields(value, relatedConfig.listConfig.fields, args, config, depth + 1, relatedConfig.listName, nestedDeclaredOnly);
|
|
206
|
+
filtered[fieldName] = await filterReadableFields(value, relatedConfig.listConfig.fields, args, config, depth + 1, relatedConfig.listName, nestedDeclaredOnly, nestedSelection);
|
|
192
207
|
}
|
|
193
208
|
}
|
|
194
209
|
else {
|
|
195
|
-
// Related config not found, include the value as-is
|
|
196
210
|
filtered[fieldName] = value;
|
|
197
211
|
}
|
|
198
212
|
continue;
|
|
199
213
|
}
|
|
200
|
-
// Non-relationship field
|
|
201
|
-
//
|
|
214
|
+
// Non-relationship field, or a relationship field whose value is not
|
|
215
|
+
// includable (null/undefined) — falls through to the shared helper.
|
|
202
216
|
const result = await resolveReadableFieldValue({
|
|
203
217
|
fieldConfig,
|
|
204
218
|
fieldName,
|
|
@@ -212,33 +226,66 @@ declaredOnly = emptyDeclaredOnlyTree()) {
|
|
|
212
226
|
if (result.readable) {
|
|
213
227
|
filtered[fieldName] = result.value;
|
|
214
228
|
}
|
|
229
|
+
else {
|
|
230
|
+
accessDeniedKeys.add(fieldName);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// The item a virtual field's hook sees: stored columns and fetched
|
|
234
|
+
// relations (from `workingItem`, never a resolved value — no hook's output
|
|
235
|
+
// is ever written back into `workingItem`). A key is visible here if it
|
|
236
|
+
// either survived into `filtered` (selected and allowed) OR exists only to
|
|
237
|
+
// satisfy a `needs` declaration (`declaredOnly` — that IS the point of
|
|
238
|
+
// declaring it: fetched for a hook, never for the caller, ADR-0025).
|
|
239
|
+
// Everything else — field-level denied, or skipped by `selection` and
|
|
240
|
+
// declared by no one — is deleted. A computed field reaches for exactly its
|
|
241
|
+
// own declared dependencies and nothing another field's hook produced
|
|
242
|
+
// (ADR-0027): reaching for a sibling that was denied or skipped-and-
|
|
243
|
+
// undeclared finds nothing there, the same as reaching for one never
|
|
244
|
+
// declared at all, and reaching for a sibling that DID survive finds its
|
|
245
|
+
// raw stored form, never another hook's resolved value — a virtual field
|
|
246
|
+
// computed earlier in declaration order is exactly as invisible as one
|
|
247
|
+
// computed later.
|
|
248
|
+
const computedFieldItem = { ...workingItem };
|
|
249
|
+
for (const key of Object.keys(workingItem)) {
|
|
250
|
+
if (['id', 'createdAt', 'updatedAt'].includes(key))
|
|
251
|
+
continue;
|
|
252
|
+
if (accessDeniedKeys.has(key)) {
|
|
253
|
+
delete computedFieldItem[key];
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
if (key in filtered)
|
|
257
|
+
continue;
|
|
258
|
+
if (declaredOnly.keys.has(key))
|
|
259
|
+
continue;
|
|
260
|
+
delete computedFieldItem[key];
|
|
215
261
|
}
|
|
216
|
-
// Process virtual fields - compute values from other fields
|
|
217
|
-
// Virtual fields don't exist in the database result, so we need to compute them separately
|
|
218
262
|
for (const [fieldName, fieldConfig] of Object.entries(fieldConfigs)) {
|
|
219
|
-
// Skip if already processed (from database result)
|
|
220
263
|
if (fieldName in filtered) {
|
|
221
264
|
continue;
|
|
222
265
|
}
|
|
223
|
-
// Only process virtual fields
|
|
224
266
|
if (!fieldConfig.virtual) {
|
|
225
267
|
continue;
|
|
226
268
|
}
|
|
227
|
-
//
|
|
228
|
-
//
|
|
269
|
+
// Projection-aware skip (ADR-0027): same rule as the stored-field pass
|
|
270
|
+
// above — a fragment that does not select this virtual field does no
|
|
271
|
+
// work for it at all.
|
|
272
|
+
if (selection?.fields && !selection.fields.has(fieldName)) {
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
// A virtual field with no resolveOutput hook can never produce a value
|
|
276
|
+
// on ANY read — there is nothing to compute, so there is nothing to do,
|
|
277
|
+
// including evaluating its read access (ADR-0027 reconciles the
|
|
278
|
+
// access-only evaluation this branch used to preserve: a field that
|
|
279
|
+
// never has output has no side effect worth preserving access for).
|
|
229
280
|
if (!(fieldConfig.hooks?.resolveOutput && listKey)) {
|
|
230
|
-
// Still evaluate read access to preserve any access-fn side effects.
|
|
231
|
-
await checkFieldAccess(fieldConfig.access, 'read', { ...args, item: workingItem });
|
|
232
281
|
continue;
|
|
233
282
|
}
|
|
234
|
-
// Check read access and compute the value via the shared helper. Virtual
|
|
235
|
-
// fields see the already-filtered item so they can read sibling fields.
|
|
236
283
|
const result = await resolveReadableFieldValue({
|
|
237
284
|
fieldConfig,
|
|
238
285
|
fieldName,
|
|
239
286
|
value: undefined, // Virtual fields don't have a database value
|
|
240
287
|
accessItem: workingItem,
|
|
241
|
-
hookItem:
|
|
288
|
+
hookItem: computedFieldItem,
|
|
242
289
|
listKey,
|
|
243
290
|
args,
|
|
244
291
|
config,
|
|
@@ -248,10 +295,11 @@ declaredOnly = emptyDeclaredOnlyTree()) {
|
|
|
248
295
|
}
|
|
249
296
|
}
|
|
250
297
|
// Strip relations that were fetched ONLY to satisfy a `needs` declaration
|
|
251
|
-
// (ADR-0025), now that every resolveOutput hook at this level
|
|
252
|
-
//
|
|
253
|
-
//
|
|
254
|
-
//
|
|
298
|
+
// (ADR-0025), now that every resolveOutput hook at this level has had the
|
|
299
|
+
// chance to see them (via `computedFieldItem`, never `filtered` itself — a
|
|
300
|
+
// declared dependency is read from stored columns, not from another
|
|
301
|
+
// field's resolved output). A declared dependency is private plumbing, not
|
|
302
|
+
// an implicit `include`: it never widens what the caller receives.
|
|
255
303
|
for (const key of declaredOnly.keys) {
|
|
256
304
|
delete filtered[key];
|
|
257
305
|
}
|