@unito/integration-sdk 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/src/handler.js +12 -1
- package/dist/test/handler.test.js +25 -1
- package/package.json +1 -1
- package/src/handler.ts +18 -1
- package/test/handler.test.ts +35 -1
package/README.md
CHANGED
package/dist/src/handler.js
CHANGED
|
@@ -9,6 +9,17 @@ function assertValidPath(path) {
|
|
|
9
9
|
throw new InvalidHandler(`The provided path '${path}' is invalid. Paths must not end with a '/'.`);
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
+
function assertValidConfiguration(path, pathWithIdentifier, handlers) {
|
|
13
|
+
if (path === pathWithIdentifier) {
|
|
14
|
+
const individualHandlers = ['getItem', 'updateItem', 'deleteItem'];
|
|
15
|
+
const collectionHandlers = ['getCollection', 'createItem'];
|
|
16
|
+
const hasIndividualHandlers = individualHandlers.some(handler => handler in handlers);
|
|
17
|
+
const hasCollectionHandlers = collectionHandlers.some(handler => handler in handlers);
|
|
18
|
+
if (hasIndividualHandlers && hasCollectionHandlers) {
|
|
19
|
+
throw new InvalidHandler(`The provided path '${path}' doesn't differentiate between individual and collection level operation, so you cannot define both. `);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
12
23
|
function parsePath(path) {
|
|
13
24
|
const pathParts = path.split('/');
|
|
14
25
|
const lastPart = pathParts.at(-1);
|
|
@@ -60,9 +71,9 @@ export class Handler {
|
|
|
60
71
|
pathWithIdentifier;
|
|
61
72
|
handlers;
|
|
62
73
|
constructor(inputPath, handlers) {
|
|
63
|
-
// Build paths.
|
|
64
74
|
assertValidPath(inputPath);
|
|
65
75
|
const { pathWithIdentifier, path } = parsePath(inputPath);
|
|
76
|
+
assertValidConfiguration(path, pathWithIdentifier, handlers);
|
|
66
77
|
this.pathWithIdentifier = pathWithIdentifier;
|
|
67
78
|
this.path = path;
|
|
68
79
|
this.handlers = handlers;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import assert from 'node:assert/strict';
|
|
2
2
|
import { afterEach, beforeEach, describe, it, mock } from 'node:test';
|
|
3
|
-
import { Handler } from '../src/handler.js';
|
|
3
|
+
import { Handler, } from '../src/handler.js';
|
|
4
4
|
import { BadRequestError } from '../src/httpErrors.js';
|
|
5
5
|
describe('Handler', () => {
|
|
6
6
|
beforeEach(() => {
|
|
@@ -36,6 +36,30 @@ describe('Handler', () => {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
});
|
|
39
|
+
it('validates configuration', () => {
|
|
40
|
+
const getItem = (() => { });
|
|
41
|
+
const updateItem = (() => { });
|
|
42
|
+
const deleteItem = (() => { });
|
|
43
|
+
const getCollection = (() => { });
|
|
44
|
+
const createItem = (() => { });
|
|
45
|
+
const paths = [
|
|
46
|
+
['/foo', { getItem }, true],
|
|
47
|
+
['/foo', { getCollection }, true],
|
|
48
|
+
['/foo', { getItem, getCollection }, false],
|
|
49
|
+
['/foo', { updateItem, createItem }, false],
|
|
50
|
+
['/foo', { deleteItem, createItem }, false],
|
|
51
|
+
['/foo/:bar', { getItem, getCollection }, true],
|
|
52
|
+
['/foo/:bar', { getItem, updateItem, deleteItem, createItem, getCollection }, true],
|
|
53
|
+
];
|
|
54
|
+
for (const [path, handlers, valid] of paths) {
|
|
55
|
+
if (valid) {
|
|
56
|
+
assert.doesNotThrow(() => new Handler(path, handlers));
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
assert.throws(() => new Handler(path, handlers));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
});
|
|
39
63
|
});
|
|
40
64
|
describe('generate', () => {
|
|
41
65
|
async function executeHandler(handler, request = {}) {
|
package/package.json
CHANGED
package/src/handler.ts
CHANGED
|
@@ -118,6 +118,22 @@ function assertValidPath(path: string): asserts path is Path {
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
function assertValidConfiguration(path: Path, pathWithIdentifier: Path, handlers: Handlers) {
|
|
122
|
+
if (path === pathWithIdentifier) {
|
|
123
|
+
const individualHandlers = ['getItem', 'updateItem', 'deleteItem'];
|
|
124
|
+
const collectionHandlers = ['getCollection', 'createItem'];
|
|
125
|
+
|
|
126
|
+
const hasIndividualHandlers = individualHandlers.some(handler => handler in handlers);
|
|
127
|
+
const hasCollectionHandlers = collectionHandlers.some(handler => handler in handlers);
|
|
128
|
+
|
|
129
|
+
if (hasIndividualHandlers && hasCollectionHandlers) {
|
|
130
|
+
throw new InvalidHandler(
|
|
131
|
+
`The provided path '${path}' doesn't differentiate between individual and collection level operation, so you cannot define both. `,
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
121
137
|
function parsePath(path: Path) {
|
|
122
138
|
const pathParts = path.split('/');
|
|
123
139
|
|
|
@@ -185,11 +201,12 @@ export class Handler {
|
|
|
185
201
|
private handlers: Handlers;
|
|
186
202
|
|
|
187
203
|
constructor(inputPath: string, handlers: HandlersInput) {
|
|
188
|
-
// Build paths.
|
|
189
204
|
assertValidPath(inputPath);
|
|
190
205
|
|
|
191
206
|
const { pathWithIdentifier, path } = parsePath(inputPath);
|
|
192
207
|
|
|
208
|
+
assertValidConfiguration(path, pathWithIdentifier, handlers);
|
|
209
|
+
|
|
193
210
|
this.pathWithIdentifier = pathWithIdentifier;
|
|
194
211
|
this.path = path;
|
|
195
212
|
|
package/test/handler.test.ts
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import { Request, Response } from 'express';
|
|
2
2
|
import assert from 'node:assert/strict';
|
|
3
3
|
import { afterEach, beforeEach, describe, it, mock } from 'node:test';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
Handler,
|
|
6
|
+
HandlersInput,
|
|
7
|
+
GetItemHandler,
|
|
8
|
+
GetCollectionHandler,
|
|
9
|
+
UpdateItemHandler,
|
|
10
|
+
DeleteItemHandler,
|
|
11
|
+
CreateItemHandler,
|
|
12
|
+
} from '../src/handler.js';
|
|
5
13
|
import { BadRequestError } from '../src/httpErrors.js';
|
|
6
14
|
|
|
7
15
|
describe('Handler', () => {
|
|
@@ -42,6 +50,32 @@ describe('Handler', () => {
|
|
|
42
50
|
}
|
|
43
51
|
}
|
|
44
52
|
});
|
|
53
|
+
|
|
54
|
+
it('validates configuration', () => {
|
|
55
|
+
const getItem = (() => {}) as unknown as GetItemHandler;
|
|
56
|
+
const updateItem = (() => {}) as unknown as UpdateItemHandler;
|
|
57
|
+
const deleteItem = (() => {}) as unknown as DeleteItemHandler;
|
|
58
|
+
const getCollection = (() => {}) as unknown as GetCollectionHandler;
|
|
59
|
+
const createItem = (() => {}) as unknown as CreateItemHandler;
|
|
60
|
+
|
|
61
|
+
const paths: [string, HandlersInput, boolean][] = [
|
|
62
|
+
['/foo', { getItem }, true],
|
|
63
|
+
['/foo', { getCollection }, true],
|
|
64
|
+
['/foo', { getItem, getCollection }, false],
|
|
65
|
+
['/foo', { updateItem, createItem }, false],
|
|
66
|
+
['/foo', { deleteItem, createItem }, false],
|
|
67
|
+
['/foo/:bar', { getItem, getCollection }, true],
|
|
68
|
+
['/foo/:bar', { getItem, updateItem, deleteItem, createItem, getCollection }, true],
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
for (const [path, handlers, valid] of paths) {
|
|
72
|
+
if (valid) {
|
|
73
|
+
assert.doesNotThrow(() => new Handler(path, handlers));
|
|
74
|
+
} else {
|
|
75
|
+
assert.throws(() => new Handler(path, handlers));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
});
|
|
45
79
|
});
|
|
46
80
|
|
|
47
81
|
describe('generate', () => {
|