@unito/integration-sdk 1.4.4 → 1.5.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.
@@ -98,6 +98,7 @@ export class Handler {
98
98
  signal: res.locals.signal,
99
99
  params: req.params,
100
100
  query: req.query,
101
+ relations: res.locals.relations,
101
102
  });
102
103
  res.status(200).send(collection);
103
104
  });
@@ -529,6 +529,7 @@ class Handler {
529
529
  signal: res.locals.signal,
530
530
  params: req.params,
531
531
  query: req.query,
532
+ relations: res.locals.relations,
532
533
  });
533
534
  res.status(200).send(collection);
534
535
  });
@@ -939,6 +940,12 @@ function extractSelects(req, res, next) {
939
940
  next();
940
941
  }
941
942
 
943
+ function extractRelations(req, res, next) {
944
+ const rawRelations = req.query.relations;
945
+ res.locals.relations = typeof rawRelations === 'string' ? rawRelations.split(',') : [];
946
+ next();
947
+ }
948
+
942
949
  const OPERATION_DEADLINE_HEADER = 'X-Unito-Operation-Deadline';
943
950
  function extractOperationDeadline(req, res, next) {
944
951
  const operationDeadlineHeader = Number(req.header(OPERATION_DEADLINE_HEADER));
@@ -1075,6 +1082,7 @@ class Integration {
1075
1082
  app.use(extractSecrets);
1076
1083
  app.use(extractFilters);
1077
1084
  app.use(extractSelects);
1085
+ app.use(extractRelations);
1078
1086
  app.use(extractOperationDeadline);
1079
1087
  // Load handlers as needed.
1080
1088
  if (this.handlers.length) {
@@ -11,6 +11,7 @@ import loggerMiddleware from './middlewares/logger.js';
11
11
  import startMiddleware from './middlewares/start.js';
12
12
  import secretsMiddleware from './middlewares/secrets.js';
13
13
  import selectsMiddleware from './middlewares/selects.js';
14
+ import relationsMiddleware from './middlewares/relations.js';
14
15
  import signalMiddleware from './middlewares/signal.js';
15
16
  function printErrorMessage(message) {
16
17
  console.error();
@@ -131,6 +132,7 @@ export default class Integration {
131
132
  app.use(secretsMiddleware);
132
133
  app.use(filtersMiddleware);
133
134
  app.use(selectsMiddleware);
135
+ app.use(relationsMiddleware);
134
136
  app.use(signalMiddleware);
135
137
  // Load handlers as needed.
136
138
  if (this.handlers.length) {
@@ -0,0 +1,10 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+ declare global {
3
+ namespace Express {
4
+ interface Locals {
5
+ relations: string[];
6
+ }
7
+ }
8
+ }
9
+ declare function extractRelations(req: Request, res: Response, next: NextFunction): void;
10
+ export default extractRelations;
@@ -0,0 +1,6 @@
1
+ function extractRelations(req, res, next) {
2
+ const rawRelations = req.query.relations;
3
+ res.locals.relations = typeof rawRelations === 'string' ? rawRelations.split(',') : [];
4
+ next();
5
+ }
6
+ export default extractRelations;
@@ -100,6 +100,16 @@ export type GetCollectionContext<P extends Maybe<Params> = Empty, Q extends Quer
100
100
  * ['name', 'department.name']
101
101
  */
102
102
  selects: string[];
103
+ /**
104
+ * Parsed relations query param yielding a list of relation for which the path should be returned.
105
+ *
106
+ * Given a relations query param:
107
+ * `relations=items,subitems`
108
+ *
109
+ * Context.relations will be:
110
+ * ['items', 'subitems']
111
+ */
112
+ relations: string[];
103
113
  };
104
114
  export type CreateItemContext<P extends Maybe<Params> = Empty, Q extends Maybe<Query> = Empty, B extends CreateItemBody = API.CreateItemRequestPayload> = Context<P, Q> & {
105
115
  body: B;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
1
+ import assert from 'node:assert/strict';
2
+ import { describe, it } from 'node:test';
3
+ import extractRelations from '../../src/middlewares/relations.js';
4
+ describe('relations middleware', () => {
5
+ it('data', () => {
6
+ const request = { query: { relations: 'foo,bar,baz' } };
7
+ const response = { locals: {} };
8
+ extractRelations(request, response, () => { });
9
+ assert.deepEqual(response.locals, {
10
+ relations: ['foo', 'bar', 'baz'],
11
+ });
12
+ });
13
+ it('no data', () => {
14
+ const request = { query: {} };
15
+ const response = { locals: {} };
16
+ extractRelations(request, response, () => { });
17
+ assert.deepEqual(response.locals, {
18
+ relations: [],
19
+ });
20
+ });
21
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unito/integration-sdk",
3
- "version": "1.4.4",
3
+ "version": "1.5.0",
4
4
  "description": "Integration SDK",
5
5
  "type": "module",
6
6
  "types": "dist/src/index.d.ts",
package/src/handler.ts CHANGED
@@ -303,6 +303,7 @@ export class Handler {
303
303
  signal: res.locals.signal,
304
304
  params: req.params,
305
305
  query: req.query,
306
+ relations: res.locals.relations,
306
307
  });
307
308
 
308
309
  res.status(200).send(collection);
@@ -13,6 +13,7 @@ import loggerMiddleware from './middlewares/logger.js';
13
13
  import startMiddleware from './middlewares/start.js';
14
14
  import secretsMiddleware from './middlewares/secrets.js';
15
15
  import selectsMiddleware from './middlewares/selects.js';
16
+ import relationsMiddleware from './middlewares/relations.js';
16
17
  import signalMiddleware from './middlewares/signal.js';
17
18
 
18
19
  function printErrorMessage(message: string) {
@@ -149,6 +150,7 @@ export default class Integration {
149
150
  app.use(secretsMiddleware);
150
151
  app.use(filtersMiddleware);
151
152
  app.use(selectsMiddleware);
153
+ app.use(relationsMiddleware);
152
154
  app.use(signalMiddleware);
153
155
 
154
156
  // Load handlers as needed.
@@ -0,0 +1,27 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+
3
+ declare global {
4
+ // eslint-disable-next-line @typescript-eslint/no-namespace
5
+ namespace Express {
6
+ interface Locals {
7
+ // When the query params contains...
8
+ //
9
+ // relations=items,subitems
10
+ //
11
+ // ... it becomes available as follow in handlers:
12
+ //
13
+ // ['items', 'subitems']
14
+ relations: string[];
15
+ }
16
+ }
17
+ }
18
+
19
+ function extractRelations(req: Request, res: Response, next: NextFunction) {
20
+ const rawRelations = req.query.relations;
21
+
22
+ res.locals.relations = typeof rawRelations === 'string' ? rawRelations.split(',') : [];
23
+
24
+ next();
25
+ }
26
+
27
+ export default extractRelations;
@@ -106,6 +106,16 @@ export type GetCollectionContext<P extends Maybe<Params> = Empty, Q extends Quer
106
106
  * ['name', 'department.name']
107
107
  */
108
108
  selects: string[];
109
+ /**
110
+ * Parsed relations query param yielding a list of relation for which the path should be returned.
111
+ *
112
+ * Given a relations query param:
113
+ * `relations=items,subitems`
114
+ *
115
+ * Context.relations will be:
116
+ * ['items', 'subitems']
117
+ */
118
+ relations: string[];
109
119
  };
110
120
 
111
121
  export type CreateItemContext<
@@ -0,0 +1,35 @@
1
+ import express from 'express';
2
+ import assert from 'node:assert/strict';
3
+ import { describe, it } from 'node:test';
4
+
5
+ import extractRelations from '../../src/middlewares/relations.js';
6
+
7
+ describe('relations middleware', () => {
8
+ it('data', () => {
9
+ const request = { query: { relations: 'foo,bar,baz' } } as express.Request<
10
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
+ any,
12
+ object,
13
+ object,
14
+ { relations: string }
15
+ >;
16
+ const response = { locals: {} } as express.Response;
17
+
18
+ extractRelations(request, response, () => {});
19
+
20
+ assert.deepEqual(response.locals, {
21
+ relations: ['foo', 'bar', 'baz'],
22
+ });
23
+ });
24
+
25
+ it('no data', () => {
26
+ const request = { query: {} } as express.Request;
27
+ const response = { locals: {} } as express.Response;
28
+
29
+ extractRelations(request, response, () => {});
30
+
31
+ assert.deepEqual(response.locals, {
32
+ relations: [],
33
+ });
34
+ });
35
+ });