Skip to content

Commit 75d1016

Browse files
committed
feat: add configuration to exclude keys from events when filtering subs
1 parent 4fae0b1 commit 75d1016

File tree

6 files changed

+43
-25
lines changed

6 files changed

+43
-25
lines changed

docs/interfaces/SubscriptionServer.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@
1515

1616
### complete
1717

18-
**complete**: (`event`: { `payload?`: `Record`<`string`, `any`\> ; `topic`: `string` }) => `Promise`<`void`\>
18+
**complete**: (`event`: { `payload?`: `Record`<`string`, `any`\> ; `topic`: `string` }, `excludeKeys?`: `string`[]) => `Promise`<`void`\>
1919

2020
#### Type declaration
2121

22-
▸ (`event`): `Promise`<`void`\>
22+
▸ (`event`, `excludeKeys`): `Promise`<`void`\>
2323

2424
Send a complete message and end all relevant subscriptions. This might take some time depending on how many subscriptions there are.
2525

@@ -32,6 +32,7 @@ The payload if present will be used to match against any filters the subscriptio
3232
| `event` | `Object` |
3333
| `event.payload?` | `Record`<`string`, `any`\> |
3434
| `event.topic` | `string` |
35+
| `excludeKeys?` | `string`[] |
3536

3637
##### Returns
3738

@@ -41,11 +42,11 @@ ___
4142

4243
### publish
4344

44-
**publish**: (`event`: { `payload`: `Record`<`string`, `any`\> ; `topic`: `string` }) => `Promise`<`void`\>
45+
**publish**: (`event`: { `payload`: `Record`<`string`, `any`\> ; `topic`: `string` }, `excludeKeys?`: `string`[]) => `Promise`<`void`\>
4546

4647
#### Type declaration
4748

48-
▸ (`event`): `Promise`<`void`\>
49+
▸ (`event`, `excludeKeys`): `Promise`<`void`\>
4950

5051
Publish an event to all relevant subscriptions. This might take some time depending on how many subscriptions there are.
5152

@@ -58,6 +59,7 @@ The payload if present will be used to match against any filters the subscriptio
5859
| `event` | `Object` |
5960
| `event.payload` | `Record`<`string`, `any`\> |
6061
| `event.topic` | `string` |
62+
| `excludeKeys?` | `string`[] |
6163

6264
##### Returns
6365

lib/pubsub/complete.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import { getResolverAndArgs } from '../utils/getResolverAndArgs'
99
import { isArray } from '../utils/isArray'
1010
import { getFilteredSubs } from './getFilteredSubs'
1111

12-
export const complete = (serverPromise: Promise<ServerClosure> | ServerClosure): SubscriptionServer['complete'] => async event => {
12+
export const complete = (serverPromise: Promise<ServerClosure> | ServerClosure): SubscriptionServer['complete'] => async (event, excludeKeys) => {
1313
const server = await serverPromise
14-
const subscriptions = await getFilteredSubs({ server, event })
14+
const subscriptions = await getFilteredSubs({ server, event, excludeKeys })
1515
server.log('pubsub:complete', { event, subscriptions })
1616

1717
const iters = subscriptions.map(async (sub) => {

lib/pubsub/getFilteredSubs-test.ts

+15
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,21 @@ describe('collapseKeys', () => {
2121
'a.3.b': 4,
2222
})
2323
})
24+
25+
it('excludes excluded keys', () => {
26+
assert.deepEqual(collapseKeys({ a: 4, b: { c: 5, d: 'hi', e: { f: false } } }, ['a', 'b.d']), {
27+
'b.c': 5,
28+
'b.e.f': false,
29+
})
30+
assert.deepEqual(collapseKeys({ a: [1, 2, 3, { b: 4, c: [], d: null, e: undefined }], f: { g: [{ h: 5 }, { i: 6 }], j: [7, 8, 9] } }, ['f.g', 'f.j.1']), {
31+
'a.0': 1,
32+
'a.1': 2,
33+
'a.2': 3,
34+
'a.3.b': 4,
35+
'f.j.0': 7,
36+
'f.j.2': 9,
37+
})
38+
})
2439
})
2540

2641

lib/pubsub/getFilteredSubs.ts

+15-14
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
import { collect } from 'streaming-iterables'
33
import { ServerClosure, Subscription } from '../types'
44

5-
export const getFilteredSubs = async ({ server, event }: { server: Omit<ServerClosure, 'gateway'>, event: { topic: string, payload?: Record<string, any> } }): Promise<Subscription[]> => {
5+
export const getFilteredSubs = async ({ server, event, excludeKeys = [] }: { server: Omit<ServerClosure, 'gateway'>, event: { topic: string, payload?: Record<string, any> }, excludeKeys?: string[] }): Promise<Subscription[]> => {
66
if (!event.payload || Object.keys(event.payload).length === 0) {
7-
server.log('getFilteredSubs', { event })
7+
server.log('getFilteredSubs', { event, excludeKeys })
88

99
const iterator = server.models.subscription.query({
1010
IndexName: 'TopicIndex',
@@ -15,7 +15,7 @@ export const getFilteredSubs = async ({ server, event }: { server: Omit<ServerCl
1515

1616
return await collect(iterator)
1717
}
18-
const flattenPayload = collapseKeys(event.payload)
18+
const flattenPayload = collapseKeys(event.payload, excludeKeys)
1919

2020
const filterExpressions: string[] = []
2121
const expressionAttributeValues: { [key: string]: string | number | boolean } = {}
@@ -29,7 +29,7 @@ export const getFilteredSubs = async ({ server, event }: { server: Omit<ServerCl
2929
filterExpressions.push(`(#filter.#${aliasNumber} = :${aliasNumber} OR attribute_not_exists(#filter.#${aliasNumber}))`)
3030
}
3131

32-
server.log('getFilteredSubs', { event, expressionAttributeNames, expressionAttributeValues, filterExpressions })
32+
server.log('getFilteredSubs', { event, excludeKeys, expressionAttributeNames, expressionAttributeValues, filterExpressions })
3333

3434
const iterator = server.models.subscription.query({
3535
IndexName: 'TopicIndex',
@@ -51,24 +51,25 @@ export const getFilteredSubs = async ({ server, event }: { server: Omit<ServerCl
5151

5252
export const collapseKeys = (
5353
obj: Record<string, any>,
54+
excludeKeys: string[] = [],
55+
parent: string[] = [],
5456
): Record<string, number | string | boolean> => {
5557
const record = {}
5658
for (const [k1, v1] of Object.entries(obj)) {
59+
const path = [...parent, k1]
60+
const key = path.join('.')
61+
if (excludeKeys.includes(key)) {
62+
continue
63+
}
5764
if (typeof v1 === 'string' || typeof v1 === 'number' || typeof v1 === 'boolean') {
58-
record[k1] = v1
65+
record[key] = v1
5966
continue
6067
}
61-
6268
if (v1 && typeof v1 === 'object') {
63-
const next = {}
64-
65-
for (const [k2, v2] of Object.entries(v1)) {
66-
next[`${k1}.${k2}`] = v2
67-
}
68-
69-
for (const [k1, v1] of Object.entries(collapseKeys(next))) {
70-
record[k1] = v1
69+
for (const [k2, v2] of Object.entries(collapseKeys(v1, excludeKeys, path))) {
70+
record[k2] = v2
7171
}
72+
continue
7273
}
7374
}
7475
return record

lib/pubsub/publish.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import { postToConnection } from '../utils/postToConnection'
55
import { buildContext } from '../utils/buildContext'
66
import { getFilteredSubs } from './getFilteredSubs'
77

8-
export const publish = (serverPromise: Promise<ServerClosure> | ServerClosure): SubscriptionServer['publish'] => async event => {
8+
export const publish = (serverPromise: Promise<ServerClosure> | ServerClosure): SubscriptionServer['publish'] => async (event, excludeKeys) => {
99
const server = await serverPromise
10-
server.log('pubsub:publish', { event })
11-
const subscriptions = await getFilteredSubs({ server, event })
10+
server.log('pubsub:publish', { event, excludeKeys })
11+
const subscriptions = await getFilteredSubs({ server, event, excludeKeys })
1212
server.log('pubsub:publish', { subscriptions: subscriptions.map(({ connectionId, filter, subscription }) => ({ connectionId, filter, subscription }) ) })
1313

1414
const iters = subscriptions.map(async (sub) => {

lib/types.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,13 @@ export interface SubscriptionServer {
106106
*
107107
* The payload if present will be used to match against any filters the subscriptions might have.
108108
*/
109-
publish: (event: { topic: string, payload: Record<string, any>}) => Promise<void>
109+
publish: (event: { topic: string, payload: Record<string, any>}, excludeKeys?: string[]) => Promise<void>
110110
/**
111111
* Send a complete message and end all relevant subscriptions. This might take some time depending on how many subscriptions there are.
112112
*
113113
* The payload if present will be used to match against any filters the subscriptions might have.
114114
*/
115-
complete: (event: { topic: string, payload?: Record<string, any> }) => Promise<void>
115+
complete: (event: { topic: string, payload?: Record<string, any> }, excludeKeys?: string[]) => Promise<void>
116116
}
117117

118118
/**

0 commit comments

Comments
 (0)