@mountainpass/waycharter 1.0.74 → 1.0.75

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 CHANGED
@@ -1,3 +1,9 @@
1
+ ## <small>1.0.75 (2021-12-13)</small>
2
+
3
+ * feat(collections): item endpoints can now be used when registering collections ([15fa46d](https://github.com/mountain-pass/waycharter/commit/15fa46d))
4
+
5
+
6
+
1
7
  ## <small>1.0.74 (2021-11-17)</small>
2
8
 
3
9
  * Merge pull request #357 from mountain-pass/dependabot/npm_and_yarn/snyk-1.763.0 ([ea63657](https://github.com/mountain-pass/waycharter/commit/ea63657)), closes [#357](https://github.com/mountain-pass/waycharter/issues/357)
package/README.md CHANGED
@@ -13,7 +13,7 @@ This library is compatible with Node.js 10.x, 12.x and 14.x
13
13
 
14
14
  <!-- [![Quality](https://img.shields.io/codacy/grade/940768d54f7545f7b42f89b26c23c751?logo=codacy)](https://www.codacy.com/gh/mountain-pass/waycharter/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=mountain-pass/waycharter&amp;utm_campaign=Badge_Grade) [![Coverage](https://img.shields.io/codacy/coverage/940768d54f7545f7b42f89b26c23c751?logo=codacy)](https://www.codacy.com/gh/mountain-pass/waycharter/dashboard?utm_source=github.com&utm_medium=referral&utm_content=mountain-pass/waycharter&utm_campaign=Badge_Coverage) -->
15
15
 
16
- [![source code vulnerabilities](https://img.shields.io/snyk/vulnerabilities/github/mountain-pass/waycharter?label=source%20code%20vulnerabilities&logo=snyk)](https://snyk.io/test/github/mountain-pass/waycharter) [![npm package vulnerabilities](https://img.shields.io/snyk/vulnerabilities/npm/@mountainpass/waycharter@1.0.74?label=npm%20package%20vulnerabilties&logo=snyk)](https://snyk.io/test/npm/@mountainpass/waycharter/1.0.74)
16
+ [![source code vulnerabilities](https://img.shields.io/snyk/vulnerabilities/github/mountain-pass/waycharter?label=source%20code%20vulnerabilities&logo=snyk)](https://snyk.io/test/github/mountain-pass/waycharter) [![npm package vulnerabilities](https://img.shields.io/snyk/vulnerabilities/npm/@mountainpass/waycharter@1.0.75?label=npm%20package%20vulnerabilties&logo=snyk)](https://snyk.io/test/npm/@mountainpass/waycharter/1.0.75)
17
17
 
18
18
 
19
19
  [![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
@@ -117,8 +117,12 @@ function buildLink({
117
117
  rel,
118
118
  uri,
119
119
  anchor,
120
- method: endpoint.method,
121
- parameters: endpoint.parameters || endpoint.bodyParameters,
120
+ ...(endpoint.method && {
121
+ method: endpoint.method
122
+ }),
123
+ ...((endpoint.parameters || endpoint.bodyParameters) && {
124
+ parameters: endpoint.parameters || endpoint.bodyParameters
125
+ }),
122
126
  ...((0, _methodCanHaveBody.methodCanHaveBody)(endpoint.method) && {
123
127
  accept: ['application/x-www-form-urlencoded', 'application/json', 'multipart/form-data']
124
128
  })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/collections/built-item-links.js"],"names":["builtItemLinks","array","arrayPointer","itemType","selfUri","itemOperations","itemLinks","canonicalLinks","length","push","rel","uri","path","anchor","relationship","endpoint","buildLink","pathTemplate","template","URI","Template","parameters","match","Object","keys","forEach","key","replace","method","bodyParameters","accept"],"mappings":"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","sourcesContent":["import { URI } from 'uri-template-lite'\nimport { methodCanHaveBody } from '../method-can-have-body'\n\n/**\n * @param array\n * @param arrayPointer\n * @param itemType\n * @param collectionPath\n * @param selfUri\n * @param itemOperations\n */\nexport function builtItemLinks (\n array,\n arrayPointer,\n itemType,\n selfUri,\n itemOperations\n) {\n const itemLinks = []\n const canonicalLinks = []\n if (array.length === 1) {\n itemLinks.push({\n rel: 'item',\n uri: `${selfUri}#${arrayPointer || ''}/0`\n })\n if (itemType) {\n canonicalLinks.push({\n rel: 'canonical',\n uri: itemType.path(array[0]),\n anchor: `#${arrayPointer || ''}/0`\n })\n }\n if (itemOperations) {\n for (const relationship in itemOperations) {\n const endpoint = itemOperations[relationship]\n itemLinks.push(\n buildLink({\n rel: relationship,\n uri: endpoint.path(array[0]),\n anchor: `#${arrayPointer || ''}/0`,\n endpoint,\n array,\n arrayPointer\n })\n )\n }\n }\n } else if (array.length > 0) {\n itemLinks.push({\n rel: 'item',\n uri: `${selfUri}#${arrayPointer || ''}/{[0..${array.length - 1}]}`\n })\n if (itemType) {\n let pathTemplate = itemType.pathTemplate + ''\n const template = new URI.Template(itemType.pathTemplate)\n const parameters = template.match(itemType.pathTemplate)\n Object.keys(parameters).forEach(key => {\n pathTemplate = pathTemplate.replace(parameters[key], `{this.${key}}`)\n })\n canonicalLinks.push({\n rel: 'canonical',\n uri: pathTemplate,\n anchor: `#${arrayPointer || ''}/{[0..${array.length - 1}]}`\n })\n }\n if (itemOperations) {\n for (const relationship in itemOperations) {\n const endpoint = itemOperations[relationship]\n let pathTemplate = endpoint.pathTemplate + ''\n const template = new URI.Template(endpoint.pathTemplate)\n const parameters = template.match(endpoint.pathTemplate)\n Object.keys(parameters).forEach(key => {\n pathTemplate = pathTemplate.replace(parameters[key], `{this.${key}}`)\n })\n itemLinks.push(\n buildLink({\n rel: relationship,\n uri: pathTemplate,\n anchor: `#${arrayPointer || ''}/{[0..${array.length - 1}]}`,\n endpoint,\n array,\n arrayPointer\n })\n )\n }\n }\n }\n return { itemLinks, canonicalLinks }\n}\n/**\n * @param root0\n * @param root0.rel\n * @param root0.uri\n * @param root0.anchor\n * @param root0.endpoint\n * @param root0.array\n * @param root0.arrayPointer\n */\nfunction buildLink ({ rel, uri, anchor, endpoint, array, arrayPointer }) {\n return {\n rel,\n uri,\n anchor,\n method: endpoint.method,\n parameters: endpoint.parameters || endpoint.bodyParameters,\n ...(methodCanHaveBody(endpoint.method) && {\n accept: [\n 'application/x-www-form-urlencoded',\n 'application/json',\n 'multipart/form-data'\n ]\n })\n }\n}\n"],"file":"built-item-links.js"}
1
+ {"version":3,"sources":["../../src/collections/built-item-links.js"],"names":["builtItemLinks","array","arrayPointer","itemType","selfUri","itemOperations","itemLinks","canonicalLinks","length","push","rel","uri","path","anchor","relationship","endpoint","buildLink","pathTemplate","template","URI","Template","parameters","match","Object","keys","forEach","key","replace","method","bodyParameters","accept"],"mappings":"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","sourcesContent":["import { URI } from 'uri-template-lite'\nimport { methodCanHaveBody } from '../method-can-have-body'\n\n/**\n * @param array\n * @param arrayPointer\n * @param itemType\n * @param collectionPath\n * @param selfUri\n * @param itemOperations\n */\nexport function builtItemLinks (\n array,\n arrayPointer,\n itemType,\n selfUri,\n itemOperations\n) {\n const itemLinks = []\n const canonicalLinks = []\n if (array.length === 1) {\n itemLinks.push({\n rel: 'item',\n uri: `${selfUri}#${arrayPointer || ''}/0`\n })\n if (itemType) {\n canonicalLinks.push({\n rel: 'canonical',\n uri: itemType.path(array[0]),\n anchor: `#${arrayPointer || ''}/0`\n })\n }\n if (itemOperations) {\n for (const relationship in itemOperations) {\n const endpoint = itemOperations[relationship]\n itemLinks.push(\n buildLink({\n rel: relationship,\n uri: endpoint.path(array[0]),\n anchor: `#${arrayPointer || ''}/0`,\n endpoint,\n array,\n arrayPointer\n })\n )\n }\n }\n } else if (array.length > 0) {\n itemLinks.push({\n rel: 'item',\n uri: `${selfUri}#${arrayPointer || ''}/{[0..${array.length - 1}]}`\n })\n if (itemType) {\n let pathTemplate = itemType.pathTemplate + ''\n const template = new URI.Template(itemType.pathTemplate)\n const parameters = template.match(itemType.pathTemplate)\n Object.keys(parameters).forEach(key => {\n pathTemplate = pathTemplate.replace(parameters[key], `{this.${key}}`)\n })\n canonicalLinks.push({\n rel: 'canonical',\n uri: pathTemplate,\n anchor: `#${arrayPointer || ''}/{[0..${array.length - 1}]}`\n })\n }\n if (itemOperations) {\n for (const relationship in itemOperations) {\n const endpoint = itemOperations[relationship]\n let pathTemplate = endpoint.pathTemplate + ''\n const template = new URI.Template(endpoint.pathTemplate)\n const parameters = template.match(endpoint.pathTemplate)\n Object.keys(parameters).forEach(key => {\n pathTemplate = pathTemplate.replace(parameters[key], `{this.${key}}`)\n })\n itemLinks.push(\n buildLink({\n rel: relationship,\n uri: pathTemplate,\n anchor: `#${arrayPointer || ''}/{[0..${array.length - 1}]}`,\n endpoint,\n array,\n arrayPointer\n })\n )\n }\n }\n }\n return { itemLinks, canonicalLinks }\n}\n/**\n * @param root0\n * @param root0.rel\n * @param root0.uri\n * @param root0.anchor\n * @param root0.endpoint\n * @param root0.array\n * @param root0.arrayPointer\n */\nfunction buildLink ({ rel, uri, anchor, endpoint, array, arrayPointer }) {\n return {\n rel,\n uri,\n anchor,\n ...(endpoint.method && { method: endpoint.method }),\n ...((endpoint.parameters || endpoint.bodyParameters) && {\n parameters: endpoint.parameters || endpoint.bodyParameters\n }),\n ...(methodCanHaveBody(endpoint.method) && {\n accept: [\n 'application/x-www-form-urlencoded',\n 'application/json',\n 'multipart/form-data'\n ]\n })\n }\n}\n"],"file":"built-item-links.js"}
@@ -56,7 +56,7 @@ class WayCharter {
56
56
  try {
57
57
  const resource = await loader({ ...request.params,
58
58
  ...request.query
59
- }, filteredHeaders, request.url);
59
+ }, filteredHeaders, request.url, request, response);
60
60
 
61
61
  if (loaderVaries) {
62
62
  response.header('vary', [...lowerCaseLoaderVaries]);
@@ -158,6 +158,7 @@ class WayCharter {
158
158
  }
159
159
 
160
160
  registerCollection({
161
+ itemEndpoint,
161
162
  itemPath,
162
163
  itemLoader,
163
164
  collectionPath,
@@ -165,12 +166,13 @@ class WayCharter {
165
166
  filters = []
166
167
  }) {
167
168
  // TODO: error handling for itemPath set, but itemLoader isn't and visa-versa
169
+ // TODO: error handling if itemEndpoint is set, and itemPath or itemLoader is set
168
170
  // TODO: error handling for collectionPath not set
169
171
  // TODO: error handling for collectionLoader not set
170
172
  const itemType = itemPath !== undefined && itemLoader !== undefined ? this.registerResourceType({
171
173
  path: `${collectionPath}${itemPath}`,
172
174
  loader: itemLoader
173
- }) : undefined;
175
+ }) : itemEndpoint;
174
176
  const linkTemplates = [];
175
177
 
176
178
  for (const filter of filters) {
@@ -185,7 +187,7 @@ class WayCharter {
185
187
  loader: async ({
186
188
  page,
187
189
  ...otherParameters
188
- }, filteredHeaders, selfUri) => {
190
+ }, filteredHeaders, selfUri, request, response) => {
189
191
  // ${collectionPath}?page=0 should redirect to ${collectionPath}
190
192
  if (page === '0') {
191
193
  return {
@@ -194,19 +196,35 @@ class WayCharter {
194
196
  location: collectionPath
195
197
  }
196
198
  };
197
- } // TODO: page is not a number
198
- // page should be >= 0
199
+ } // page should be >= 0
199
200
 
200
201
 
201
202
  const pageInt = Number.parseInt(page || '0');
202
203
 
203
- if (page < 0) {
204
+ if (Number.isNaN(pageInt)) {
204
205
  return {
205
- status: 400
206
+ status: 400,
207
+ body: {
208
+ error: "I don't understand what page you are trying to retrieve",
209
+ page
210
+ }
206
211
  };
207
212
  }
208
213
 
209
- const filteredParameters = {};
214
+ if (page < 0) {
215
+ return {
216
+ status: 400,
217
+ body: {
218
+ error: "You've asked for a negative page. I don't know what that means",
219
+ page
220
+ }
221
+ };
222
+ } // we only want to include query params that are part of the filter,
223
+ // but we can include all path params
224
+
225
+
226
+ const filteredParameters = { ...request.params
227
+ };
210
228
 
211
229
  for (const filter of filters) {
212
230
  for (const parameter of filter.parameters) {
@@ -221,11 +239,12 @@ class WayCharter {
221
239
  arrayPointer,
222
240
  hasMore,
223
241
  headers,
224
- itemOperations
242
+ itemOperations,
243
+ status
225
244
  } = await collectionLoader({
226
245
  page: pageInt,
227
246
  ...filteredParameters
228
- });
247
+ }, filteredHeaders, selfUri, request, response);
229
248
  const array = arrayPointer ? _jsonpointer.default.get(body, arrayPointer) : body;
230
249
  const {
231
250
  itemLinks,
@@ -235,7 +254,8 @@ class WayCharter {
235
254
  body,
236
255
  links: [...itemLinks, ...canonicalLinks, ...(0, _buildNextLink.buildNextLink)(hasMore, pageInt, collectionPath, otherParameters), ...(0, _buildPreviousLink.buildPreviousLink)(pageInt, collectionPath, otherParameters), ...(0, _buildFirstLink.buildFirstLink)(hasMore, pageInt, collectionPath, otherParameters)],
237
256
  linkTemplates,
238
- headers
257
+ headers,
258
+ status
239
259
  };
240
260
  }
241
261
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/waycharter.js"],"names":["routerToRfc6570","url","replace","WayCharter","constructor","router","registerResourceType","path","loader","loaderVaries","lowerCaseLoaderVaries","Set","map","header","toLowerCase","uriTemplate","get","request","response","next","filteredHeaders","Object","keys","headers","reduce","filtered","key","has","resource","params","query","sendResponse","rel","uri","error","console","status","json","pathTemplate","parameters","URI","expand","registerOperation","method","operation","bodyParameters","headerParameters","upperCaseMethod","toUpperCase","lowerCaseMethod","lowerCaseHeaderParameters","headerName","body","requestHeaders","requestUrl","template","Template","pathParameters","match","registerStaticResource","links","registerCollection","itemPath","itemLoader","collectionPath","collectionLoader","filters","itemType","undefined","linkTemplates","filter","push","join","type","page","otherParameters","selfUri","location","pageInt","Number","parseInt","filteredParameters","parameter","arrayPointer","hasMore","itemOperations","array","pointer","itemLinks","canonicalLinks","additionalPaths","registerStaticCollection","collection","pageSize","items","slice","length","additionalLinks","toString","end"],"mappings":"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","sourcesContent":["import { Router } from 'express'\nimport { URI } from 'uri-template-lite'\nimport pointer from 'jsonpointer'\nimport { methodCanHaveBody } from './method-can-have-body'\nimport { covertResourceLinks } from './convert-resource-links'\nimport { buildFirstLink } from './collections/build-first-link'\nimport { buildPreviousLink } from './collections/build-previous-link'\nimport { buildNextLink } from './collections/build-next-link'\nimport { builtItemLinks } from './collections/built-item-links'\nimport { methodIsCacheable } from './method-is-cacheable'\n\n/**\n * @param url\n */\nfunction routerToRfc6570 (url) {\n return url.replace(/:(\\w*)/g, '{+$1}')\n}\nexport class WayCharter {\n constructor () {\n this.router = Router()\n }\n\n registerResourceType ({ path, loader, loaderVaries }) {\n // TODO: error handling for path not set\n // TODO: error handling for loader not set\n const lowerCaseLoaderVaries = new Set(\n loaderVaries ? loaderVaries.map(header => header.toLowerCase()) : []\n )\n const uriTemplate = routerToRfc6570(path)\n this.router.get(path, async function (request, response, next) {\n const filteredHeaders = Object.keys(request.headers).reduce(\n (filtered, key) =>\n lowerCaseLoaderVaries.has(key)\n ? { ...filtered, [key]: request.headers[key] }\n : filtered,\n {}\n )\n try {\n const resource = await loader(\n { ...request.params, ...request.query },\n filteredHeaders,\n request.url\n )\n\n if (loaderVaries) {\n response.header('vary', [...lowerCaseLoaderVaries])\n }\n sendResponse(resource, response, request.url, [\n {\n rel: 'self',\n uri: request.url\n }\n ])\n } catch (error) {\n // next(error)\n console.error(error)\n response.status(500)\n response.json({})\n }\n })\n return {\n pathTemplate: uriTemplate,\n path: parameters => URI.expand(uriTemplate, parameters)\n }\n }\n\n registerOperation ({\n method,\n path,\n operation,\n bodyParameters,\n headerParameters\n }) {\n const upperCaseMethod = method.toUpperCase()\n const lowerCaseMethod = method.toLowerCase()\n const lowerCaseHeaderParameters =\n headerParameters &&\n new Set(headerParameters.map(header => header.toLowerCase()))\n this.router[lowerCaseMethod](path, async (request, response, next) => {\n try {\n let filteredHeaders = request.headers\n if (methodIsCacheable(upperCaseMethod) && headerParameters) {\n response.header('vary', [...lowerCaseHeaderParameters])\n filteredHeaders = {}\n for (const headerName in request.headers) {\n if (lowerCaseHeaderParameters.has(headerName)) {\n filteredHeaders[headerName] = request.headers[headerName]\n }\n }\n }\n\n const resource = await operation({\n parameters: {\n ...request.params,\n ...request.query,\n ...(methodCanHaveBody(upperCaseMethod) && request.body)\n },\n requestHeaders: filteredHeaders,\n requestUrl: request.url,\n request,\n response\n })\n sendResponse(resource, response, request.url)\n } catch (error) {\n // next(error)\n console.error(error)\n response.status(500)\n response.json({})\n }\n })\n const uriTemplate = routerToRfc6570(path)\n const template = new URI.Template(uriTemplate)\n const pathParameters = template.match(uriTemplate)\n return {\n method: upperCaseMethod,\n ...(methodCanHaveBody(upperCaseMethod) && { bodyParameters }),\n pathParameters,\n ...(methodIsCacheable(upperCaseMethod) && {\n headerParameters: lowerCaseHeaderParameters\n }),\n pathTemplate: uriTemplate,\n path: parameters => URI.expand(uriTemplate, parameters)\n }\n }\n\n registerStaticResource ({ path, body, links }) {\n // TODO: error handling for path not set\n // TODO: error handling for body not set\n\n return this.registerResourceType({\n path,\n loader: async () => {\n return {\n body,\n links\n }\n }\n })\n }\n\n registerCollection ({\n itemPath,\n itemLoader,\n collectionPath,\n collectionLoader,\n filters = []\n }) {\n // TODO: error handling for itemPath set, but itemLoader isn't and visa-versa\n // TODO: error handling for collectionPath not set\n // TODO: error handling for collectionLoader not set\n const itemType =\n itemPath !== undefined && itemLoader !== undefined\n ? this.registerResourceType({\n path: `${collectionPath}${itemPath}`,\n loader: itemLoader\n })\n : undefined\n\n const linkTemplates = []\n for (const filter of filters) {\n linkTemplates.push({\n rel: filter.rel,\n uri: `${collectionPath}{?${filter.parameters.join(',')}}`\n })\n }\n const type = this.registerResourceType({\n path: collectionPath,\n loader: async (\n { page, ...otherParameters },\n filteredHeaders,\n selfUri\n ) => {\n // ${collectionPath}?page=0 should redirect to ${collectionPath}\n if (page === '0') {\n return {\n status: 308,\n headers: {\n location: collectionPath\n }\n }\n }\n // TODO: page is not a number\n\n // page should be >= 0\n const pageInt = Number.parseInt(page || '0')\n if (page < 0) {\n return {\n status: 400\n }\n }\n const filteredParameters = {}\n for (const filter of filters) {\n for (const parameter of filter.parameters) {\n if (otherParameters[parameter] !== undefined) {\n filteredParameters[parameter] = otherParameters[parameter]\n }\n }\n }\n\n const {\n body,\n arrayPointer,\n hasMore,\n headers,\n itemOperations\n } = await collectionLoader({\n page: pageInt,\n ...filteredParameters\n })\n const array = arrayPointer ? pointer.get(body, arrayPointer) : body\n const { itemLinks, canonicalLinks } = builtItemLinks(\n array,\n arrayPointer,\n itemType,\n selfUri,\n itemOperations\n )\n return {\n body,\n links: [\n ...itemLinks,\n ...canonicalLinks,\n ...buildNextLink(hasMore, pageInt, collectionPath, otherParameters),\n ...buildPreviousLink(pageInt, collectionPath, otherParameters),\n ...buildFirstLink(hasMore, pageInt, collectionPath, otherParameters)\n ],\n linkTemplates,\n headers\n }\n }\n })\n return { ...type, additionalPaths: linkTemplates }\n }\n\n registerStaticCollection ({\n collectionPath,\n collection,\n pageSize,\n arrayPointer,\n headers\n }) {\n return this.registerCollection({\n collectionPath,\n collectionLoader: async ({ page }) => {\n const items = pageSize\n ? collection.slice(page * pageSize, (page + 1) * pageSize)\n : collection\n return {\n body: items,\n hasMore: pageSize && page < collection.length / pageSize - 1,\n arrayPointer,\n headers\n }\n }\n })\n }\n}\n/**\n * @param resource\n * @param response\n * @param requestUrl\n * @param additionalLinks\n */\nfunction sendResponse (resource, response, requestUrl, additionalLinks = []) {\n if (resource.links || additionalLinks.length > 0) {\n const links = covertResourceLinks([\n ...additionalLinks,\n ...(resource.links || [])\n ])\n response.header('link', links.toString())\n }\n if (resource.linkTemplates) {\n const linkTemplates = covertResourceLinks(resource.linkTemplates)\n response.header('link-template', linkTemplates.toString())\n }\n if (resource.status) {\n response.status(resource.status)\n }\n if (resource.headers) {\n for (const header in resource.headers) {\n response.header(header, resource.headers[header])\n }\n }\n if (resource.body) {\n response.json(resource.body)\n } else {\n response.end()\n }\n}\n"],"file":"waycharter.js"}
1
+ {"version":3,"sources":["../src/waycharter.js"],"names":["routerToRfc6570","url","replace","WayCharter","constructor","router","registerResourceType","path","loader","loaderVaries","lowerCaseLoaderVaries","Set","map","header","toLowerCase","uriTemplate","get","request","response","next","filteredHeaders","Object","keys","headers","reduce","filtered","key","has","resource","params","query","sendResponse","rel","uri","error","console","status","json","pathTemplate","parameters","URI","expand","registerOperation","method","operation","bodyParameters","headerParameters","upperCaseMethod","toUpperCase","lowerCaseMethod","lowerCaseHeaderParameters","headerName","body","requestHeaders","requestUrl","template","Template","pathParameters","match","registerStaticResource","links","registerCollection","itemEndpoint","itemPath","itemLoader","collectionPath","collectionLoader","filters","itemType","undefined","linkTemplates","filter","push","join","type","page","otherParameters","selfUri","location","pageInt","Number","parseInt","isNaN","filteredParameters","parameter","arrayPointer","hasMore","itemOperations","array","pointer","itemLinks","canonicalLinks","additionalPaths","registerStaticCollection","collection","pageSize","items","slice","length","additionalLinks","toString","end"],"mappings":"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","sourcesContent":["import { Router } from 'express'\nimport { URI } from 'uri-template-lite'\nimport pointer from 'jsonpointer'\nimport { methodCanHaveBody } from './method-can-have-body'\nimport { covertResourceLinks } from './convert-resource-links'\nimport { buildFirstLink } from './collections/build-first-link'\nimport { buildPreviousLink } from './collections/build-previous-link'\nimport { buildNextLink } from './collections/build-next-link'\nimport { builtItemLinks } from './collections/built-item-links'\nimport { methodIsCacheable } from './method-is-cacheable'\n\n/**\n * @param url\n */\nfunction routerToRfc6570 (url) {\n return url.replace(/:(\\w*)/g, '{+$1}')\n}\nexport class WayCharter {\n constructor () {\n this.router = Router()\n }\n\n registerResourceType ({ path, loader, loaderVaries }) {\n // TODO: error handling for path not set\n // TODO: error handling for loader not set\n const lowerCaseLoaderVaries = new Set(\n loaderVaries ? loaderVaries.map(header => header.toLowerCase()) : []\n )\n const uriTemplate = routerToRfc6570(path)\n this.router.get(path, async function (request, response, next) {\n const filteredHeaders = Object.keys(request.headers).reduce(\n (filtered, key) =>\n lowerCaseLoaderVaries.has(key)\n ? { ...filtered, [key]: request.headers[key] }\n : filtered,\n {}\n )\n try {\n const resource = await loader(\n { ...request.params, ...request.query },\n filteredHeaders,\n request.url,\n request,\n response\n )\n\n if (loaderVaries) {\n response.header('vary', [...lowerCaseLoaderVaries])\n }\n sendResponse(resource, response, request.url, [\n {\n rel: 'self',\n uri: request.url\n }\n ])\n } catch (error) {\n // next(error)\n console.error(error)\n response.status(500)\n response.json({})\n }\n })\n return {\n pathTemplate: uriTemplate,\n path: parameters => URI.expand(uriTemplate, parameters)\n }\n }\n\n registerOperation ({\n method,\n path,\n operation,\n bodyParameters,\n headerParameters\n }) {\n const upperCaseMethod = method.toUpperCase()\n const lowerCaseMethod = method.toLowerCase()\n const lowerCaseHeaderParameters =\n headerParameters &&\n new Set(headerParameters.map(header => header.toLowerCase()))\n this.router[lowerCaseMethod](path, async (request, response, next) => {\n try {\n let filteredHeaders = request.headers\n if (methodIsCacheable(upperCaseMethod) && headerParameters) {\n response.header('vary', [...lowerCaseHeaderParameters])\n filteredHeaders = {}\n for (const headerName in request.headers) {\n if (lowerCaseHeaderParameters.has(headerName)) {\n filteredHeaders[headerName] = request.headers[headerName]\n }\n }\n }\n\n const resource = await operation({\n parameters: {\n ...request.params,\n ...request.query,\n ...(methodCanHaveBody(upperCaseMethod) && request.body)\n },\n requestHeaders: filteredHeaders,\n requestUrl: request.url,\n request,\n response\n })\n sendResponse(resource, response, request.url)\n } catch (error) {\n // next(error)\n console.error(error)\n response.status(500)\n response.json({})\n }\n })\n const uriTemplate = routerToRfc6570(path)\n const template = new URI.Template(uriTemplate)\n const pathParameters = template.match(uriTemplate)\n return {\n method: upperCaseMethod,\n ...(methodCanHaveBody(upperCaseMethod) && { bodyParameters }),\n pathParameters,\n ...(methodIsCacheable(upperCaseMethod) && {\n headerParameters: lowerCaseHeaderParameters\n }),\n pathTemplate: uriTemplate,\n path: parameters => URI.expand(uriTemplate, parameters)\n }\n }\n\n registerStaticResource ({ path, body, links }) {\n // TODO: error handling for path not set\n // TODO: error handling for body not set\n\n return this.registerResourceType({\n path,\n loader: async () => {\n return {\n body,\n links\n }\n }\n })\n }\n\n registerCollection ({\n itemEndpoint,\n itemPath,\n itemLoader,\n collectionPath,\n collectionLoader,\n filters = []\n }) {\n // TODO: error handling for itemPath set, but itemLoader isn't and visa-versa\n // TODO: error handling if itemEndpoint is set, and itemPath or itemLoader is set\n // TODO: error handling for collectionPath not set\n // TODO: error handling for collectionLoader not set\n const itemType =\n itemPath !== undefined && itemLoader !== undefined\n ? this.registerResourceType({\n path: `${collectionPath}${itemPath}`,\n loader: itemLoader\n })\n : itemEndpoint\n\n const linkTemplates = []\n for (const filter of filters) {\n linkTemplates.push({\n rel: filter.rel,\n uri: `${collectionPath}{?${filter.parameters.join(',')}}`\n })\n }\n const type = this.registerResourceType({\n path: collectionPath,\n loader: async (\n { page, ...otherParameters },\n filteredHeaders,\n selfUri,\n request,\n response\n ) => {\n // ${collectionPath}?page=0 should redirect to ${collectionPath}\n if (page === '0') {\n return {\n status: 308,\n headers: {\n location: collectionPath\n }\n }\n }\n\n // page should be >= 0\n const pageInt = Number.parseInt(page || '0')\n\n if (Number.isNaN(pageInt)) {\n return {\n status: 400,\n body: {\n error: \"I don't understand what page you are trying to retrieve\",\n page\n }\n }\n }\n if (page < 0) {\n return {\n status: 400,\n body: {\n error:\n \"You've asked for a negative page. I don't know what that means\",\n page\n }\n }\n }\n // we only want to include query params that are part of the filter,\n // but we can include all path params\n const filteredParameters = { ...request.params }\n for (const filter of filters) {\n for (const parameter of filter.parameters) {\n if (otherParameters[parameter] !== undefined) {\n filteredParameters[parameter] = otherParameters[parameter]\n }\n }\n }\n\n const {\n body,\n arrayPointer,\n hasMore,\n headers,\n itemOperations,\n status\n } = await collectionLoader(\n {\n page: pageInt,\n ...filteredParameters\n },\n filteredHeaders,\n selfUri,\n request,\n response\n )\n const array = arrayPointer ? pointer.get(body, arrayPointer) : body\n const { itemLinks, canonicalLinks } = builtItemLinks(\n array,\n arrayPointer,\n itemType,\n selfUri,\n itemOperations\n )\n return {\n body,\n links: [\n ...itemLinks,\n ...canonicalLinks,\n ...buildNextLink(hasMore, pageInt, collectionPath, otherParameters),\n ...buildPreviousLink(pageInt, collectionPath, otherParameters),\n ...buildFirstLink(hasMore, pageInt, collectionPath, otherParameters)\n ],\n linkTemplates,\n headers,\n status\n }\n }\n })\n return { ...type, additionalPaths: linkTemplates }\n }\n\n registerStaticCollection ({\n collectionPath,\n collection,\n pageSize,\n arrayPointer,\n headers\n }) {\n return this.registerCollection({\n collectionPath,\n collectionLoader: async ({ page }) => {\n const items = pageSize\n ? collection.slice(page * pageSize, (page + 1) * pageSize)\n : collection\n return {\n body: items,\n hasMore: pageSize && page < collection.length / pageSize - 1,\n arrayPointer,\n headers\n }\n }\n })\n }\n}\n/**\n * @param resource\n * @param response\n * @param requestUrl\n * @param additionalLinks\n */\nfunction sendResponse (resource, response, requestUrl, additionalLinks = []) {\n if (resource.links || additionalLinks.length > 0) {\n const links = covertResourceLinks([\n ...additionalLinks,\n ...(resource.links || [])\n ])\n response.header('link', links.toString())\n }\n if (resource.linkTemplates) {\n const linkTemplates = covertResourceLinks(resource.linkTemplates)\n response.header('link-template', linkTemplates.toString())\n }\n if (resource.status) {\n response.status(resource.status)\n }\n if (resource.headers) {\n for (const header in resource.headers) {\n response.header(header, resource.headers[header])\n }\n }\n if (resource.body) {\n response.json(resource.body)\n } else {\n response.end()\n }\n}\n"],"file":"waycharter.js"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mountainpass/waycharter",
3
- "version": "1.0.74",
3
+ "version": "1.0.75",
4
4
  "description": "Express middleware creating for HATEOAS level 3 RESTful APIs that provide hypermedia controls",
5
5
  "repository": {
6
6
  "type": "git",