json-rest-api 1.0.14 → 1.0.16

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.
Files changed (118) hide show
  1. package/connectors_ideas/fastify.js +66 -68
  2. package/connectors_ideas/koa-plugin.js +50 -51
  3. package/eslint.config.js +11 -2
  4. package/examples/url-override-example.js +63 -63
  5. package/index.js +13 -13
  6. package/lib/enhanced-logger.js +51 -51
  7. package/lib/error-formatter.js +61 -61
  8. package/lib/rest-api-errors.js +28 -28
  9. package/package.json +1 -1
  10. package/plugins/core/bulk-operations-plugin.js +142 -145
  11. package/plugins/core/connectors/express-plugin.js +210 -217
  12. package/plugins/core/connectors/lib/busboy-detector.js +84 -84
  13. package/plugins/core/connectors/lib/formidable-detector.js +50 -50
  14. package/plugins/core/connectors/lib/request-helpers.js +74 -74
  15. package/plugins/core/file-handling-plugin.js +125 -125
  16. package/plugins/core/lib/anyapi/anyapi-registry.js +254 -254
  17. package/plugins/core/lib/anyapi/query/anyapi-query-adapter.js +287 -287
  18. package/plugins/core/lib/anyapi/schema-utils.js +101 -101
  19. package/plugins/core/lib/anyapi/utils/descriptor-helpers.js +41 -41
  20. package/plugins/core/lib/dbTablesOperations.js +134 -135
  21. package/plugins/core/lib/fractional-positioning.js +74 -76
  22. package/plugins/core/lib/querying/knex-cross-table-search.js +320 -320
  23. package/plugins/core/lib/querying/knex-json-api-transformers-querying.js +144 -144
  24. package/plugins/core/lib/querying/knex-pagination-helpers.js +164 -164
  25. package/plugins/core/lib/querying/knex-process-includes.js +50 -50
  26. package/plugins/core/lib/querying/knex-query-helpers-base.js +31 -31
  27. package/plugins/core/lib/querying/knex-query-helpers.js +451 -452
  28. package/plugins/core/lib/querying/knex-relationship-includes.js +1160 -1170
  29. package/plugins/core/lib/querying/knex-window-queries.js +89 -89
  30. package/plugins/core/lib/querying/url-helpers.js +35 -35
  31. package/plugins/core/lib/querying-writing/compile-schemas.js +99 -99
  32. package/plugins/core/lib/querying-writing/connectors-query-parser.js +31 -31
  33. package/plugins/core/lib/querying-writing/database-capabilities.js +94 -94
  34. package/plugins/core/lib/querying-writing/database-value-normalizers.js +76 -76
  35. package/plugins/core/lib/querying-writing/default-data-helpers.js +27 -27
  36. package/plugins/core/lib/querying-writing/field-utils.js +44 -42
  37. package/plugins/core/lib/querying-writing/knex-constants.js +15 -16
  38. package/plugins/core/lib/querying-writing/knex-field-helpers.js +117 -115
  39. package/plugins/core/lib/querying-writing/knex-json-api-transformers.js +41 -41
  40. package/plugins/core/lib/querying-writing/payload-validators.js +275 -275
  41. package/plugins/core/lib/querying-writing/schema-helpers.js +129 -129
  42. package/plugins/core/lib/querying-writing/scope-validations.js +143 -146
  43. package/plugins/core/lib/querying-writing/simplified-helpers.js +133 -129
  44. package/plugins/core/lib/storage/storage-adapter.js +68 -68
  45. package/plugins/core/lib/writing/knex-json-api-transformers-writing.js +31 -31
  46. package/plugins/core/lib/writing/many-to-many-manipulations.js +81 -81
  47. package/plugins/core/lib/writing/relationship-processor.js +58 -58
  48. package/plugins/core/rest-api-access.js +11 -15
  49. package/plugins/core/rest-api-anyapi-knex-plugin.js +920 -920
  50. package/plugins/core/rest-api-cors-plugin.js +170 -171
  51. package/plugins/core/rest-api-knex-plugin.js +482 -493
  52. package/plugins/core/rest-api-multihome-plugin.js +247 -251
  53. package/plugins/core/rest-api-plugin-hooks/compile-resource-schemas.js +5 -5
  54. package/plugins/core/rest-api-plugin-hooks/register-relationship-routes.js +20 -21
  55. package/plugins/core/rest-api-plugin-hooks/register-scope-routes.js +44 -44
  56. package/plugins/core/rest-api-plugin-hooks/turn-scope-init-into-vars.js +23 -23
  57. package/plugins/core/rest-api-plugin-hooks/validate-include-configurations.js +15 -15
  58. package/plugins/core/rest-api-plugin-methods/add-route.js +9 -9
  59. package/plugins/core/rest-api-plugin-methods/check-permissions.js +5 -6
  60. package/plugins/core/rest-api-plugin-methods/common.js +295 -297
  61. package/plugins/core/rest-api-plugin-methods/delete-relationship.js +35 -37
  62. package/plugins/core/rest-api-plugin-methods/delete.js +57 -59
  63. package/plugins/core/rest-api-plugin-methods/enrich-attributes.js +172 -171
  64. package/plugins/core/rest-api-plugin-methods/get-related.js +96 -96
  65. package/plugins/core/rest-api-plugin-methods/get-relationship.js +16 -18
  66. package/plugins/core/rest-api-plugin-methods/get.js +86 -86
  67. package/plugins/core/rest-api-plugin-methods/patch-relationship.js +16 -17
  68. package/plugins/core/rest-api-plugin-methods/patch.js +63 -64
  69. package/plugins/core/rest-api-plugin-methods/post-relationship.js +54 -55
  70. package/plugins/core/rest-api-plugin-methods/post.js +61 -62
  71. package/plugins/core/rest-api-plugin-methods/put.js +86 -87
  72. package/plugins/core/rest-api-plugin-methods/query.js +88 -88
  73. package/plugins/core/rest-api-plugin-methods/release.js +5 -6
  74. package/plugins/core/rest-api-plugin.js +76 -78
  75. package/plugins/core/rest-api-positioning-plugin.js +251 -252
  76. package/plugins/core/socketio-plugin.js +240 -236
  77. package/plugins/storage/local-storage.js +103 -103
  78. package/plugins/storage/s3-storage.js +41 -42
  79. package/quickTest.js +37 -37
  80. package/scripts/debug-anyapi-review-filter.mjs +18 -18
  81. package/scripts/inspect-anyapi-descriptor-country.mjs +10 -10
  82. package/scripts/inspect-anyapi-descriptor.mjs +10 -10
  83. package/scripts/run-docs.js +112 -113
  84. package/test-debug.js +28 -28
  85. package/tests/TEST_TEMPLATE.test.js +51 -51
  86. package/tests/anyapi-basic.test.js +42 -42
  87. package/tests/anyapi-cursor-pagination.test.js +48 -48
  88. package/tests/bulk-operations.test.js +208 -208
  89. package/tests/computed-fields.test.js +204 -204
  90. package/tests/cors.test.js +412 -413
  91. package/tests/curl.test.js +275 -276
  92. package/tests/custom-idproperty-relationships.test.js +266 -266
  93. package/tests/field-getters.test.js +132 -132
  94. package/tests/field-setters.test.js +110 -110
  95. package/tests/fixtures/api-configs.js +699 -699
  96. package/tests/helpers/storage-mode.js +32 -32
  97. package/tests/helpers/test-utils.js +76 -76
  98. package/tests/include-depth-validation.test.js +76 -76
  99. package/tests/includes.test.js +145 -145
  100. package/tests/multihome.test.js +175 -175
  101. package/tests/nested-includes.test.js +255 -255
  102. package/tests/pagination-cursor-multifield.test.js +164 -164
  103. package/tests/pagination-enhanced.test.js +225 -225
  104. package/tests/polymorphic-relationships.test.js +96 -96
  105. package/tests/polymorphic-simple.test.js +44 -44
  106. package/tests/positioning-advanced.test.js +226 -226
  107. package/tests/positioning-extended.test.js +399 -399
  108. package/tests/positioning-multifilter.test.js +204 -204
  109. package/tests/positioning.test.js +266 -266
  110. package/tests/queries.test.js +184 -184
  111. package/tests/query-limits.test.js +154 -155
  112. package/tests/relationship-endpoints.test.js +127 -127
  113. package/tests/relationships.test.js +178 -179
  114. package/tests/rest-api-access.test.js +86 -86
  115. package/tests/rest-api.test.js +103 -103
  116. package/tests/searchschema-merge.test.js +93 -93
  117. package/tests/socketio.test.js +326 -326
  118. package/tests/virtual-fields.test.js +164 -164
@@ -1,13 +1,13 @@
1
- import { describe, it, before, after, beforeEach } from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import knexLib from 'knex';
4
- import { createExtendedApi } from './fixtures/api-configs.js';
1
+ import { describe, it, before, after, beforeEach } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+ import knexLib from 'knex'
4
+ import { createExtendedApi } from './fixtures/api-configs.js'
5
5
  import {
6
6
  validateJsonApiStructure,
7
7
  cleanTables,
8
8
  createJsonApiDocument,
9
9
  createRelationship
10
- } from './helpers/test-utils.js';
10
+ } from './helpers/test-utils.js'
11
11
 
12
12
  // Create Knex instance for tests
13
13
  const knex = knexLib({
@@ -16,30 +16,30 @@ const knex = knexLib({
16
16
  filename: ':memory:'
17
17
  },
18
18
  useNullAsDefault: true
19
- });
19
+ })
20
20
 
21
21
  // API instance
22
- let api;
22
+ let api
23
23
 
24
24
  describe('Polymorphic Relationship Operations', () => {
25
25
  before(async () => {
26
26
  // Initialize API
27
- api = await createExtendedApi(knex);
28
- });
27
+ api = await createExtendedApi(knex)
28
+ })
29
29
 
30
30
  after(async () => {
31
31
  // Close database connection
32
- await knex.destroy();
33
- });
32
+ await knex.destroy()
33
+ })
34
34
 
35
35
  describe('Creating Reviews with Polymorphic Relationships', () => {
36
36
  beforeEach(async () => {
37
37
  // Clean all tables before each test
38
38
  await cleanTables(knex, [
39
- 'ext_countries', 'ext_publishers', 'ext_authors', 'ext_books',
39
+ 'ext_countries', 'ext_publishers', 'ext_authors', 'ext_books',
40
40
  'ext_book_authors', 'ext_reviews'
41
- ]);
42
- });
41
+ ])
42
+ })
43
43
 
44
44
  it('should create a review for a book', async () => {
45
45
  // Create a country first
@@ -48,7 +48,7 @@ describe('Polymorphic Relationship Operations', () => {
48
48
  name: 'USA',
49
49
  code: 'US'
50
50
  })
51
- });
51
+ })
52
52
 
53
53
  // Create a book
54
54
  const book = await api.resources.books.post({
@@ -57,7 +57,7 @@ describe('Polymorphic Relationship Operations', () => {
57
57
  }, {
58
58
  country: createRelationship({ type: 'countries', id: country.data.id })
59
59
  })
60
- });
60
+ })
61
61
 
62
62
  // Create a review for the book
63
63
  const review = await api.resources.reviews.post({
@@ -69,14 +69,14 @@ describe('Polymorphic Relationship Operations', () => {
69
69
  reviewable_type: 'books',
70
70
  reviewable_id: book.data.id
71
71
  })
72
- });
72
+ })
73
73
 
74
- validateJsonApiStructure(review);
75
- assert.equal(review.data.type, 'reviews');
76
- assert.equal(review.data.attributes.rating, 5);
74
+ validateJsonApiStructure(review)
75
+ assert.equal(review.data.type, 'reviews')
76
+ assert.equal(review.data.attributes.rating, 5)
77
77
  // Since polymorphic fields are filtered out from POST responses,
78
78
  // we need to GET the record to verify the relationship was saved correctly
79
- });
79
+ })
80
80
 
81
81
  it('should create a review for an author', async () => {
82
82
  // Create an author
@@ -84,7 +84,7 @@ describe('Polymorphic Relationship Operations', () => {
84
84
  inputRecord: createJsonApiDocument('authors', {
85
85
  name: 'Jane Doe'
86
86
  })
87
- });
87
+ })
88
88
 
89
89
  // Create a review for the author
90
90
  const review = await api.resources.reviews.post({
@@ -96,13 +96,13 @@ describe('Polymorphic Relationship Operations', () => {
96
96
  reviewable_type: 'authors',
97
97
  reviewable_id: author.data.id
98
98
  })
99
- });
99
+ })
100
100
 
101
- validateJsonApiStructure(review);
101
+ validateJsonApiStructure(review)
102
102
  // Polymorphic fields are no longer in attributes, they're in relationships
103
- assert.equal(review.data.relationships.reviewable.data.type, 'authors');
104
- assert.equal(review.data.relationships.reviewable.data.id, String(author.data.id));
105
- });
103
+ assert.equal(review.data.relationships.reviewable.data.type, 'authors')
104
+ assert.equal(review.data.relationships.reviewable.data.id, String(author.data.id))
105
+ })
106
106
 
107
107
  it('should create a review for a publisher', async () => {
108
108
  // Create a country
@@ -111,7 +111,7 @@ describe('Polymorphic Relationship Operations', () => {
111
111
  name: 'UK',
112
112
  code: 'GB'
113
113
  })
114
- });
114
+ })
115
115
 
116
116
  // Create a publisher
117
117
  const publisher = await api.resources.publishers.post({
@@ -120,7 +120,7 @@ describe('Polymorphic Relationship Operations', () => {
120
120
  }, {
121
121
  country: createRelationship({ type: 'countries', id: country.data.id })
122
122
  })
123
- });
123
+ })
124
124
 
125
125
  // Create a review for the publisher
126
126
  const review = await api.resources.reviews.post({
@@ -132,28 +132,28 @@ describe('Polymorphic Relationship Operations', () => {
132
132
  reviewable_type: 'publishers',
133
133
  reviewable_id: publisher.data.id
134
134
  })
135
- });
135
+ })
136
136
 
137
- validateJsonApiStructure(review);
137
+ validateJsonApiStructure(review)
138
138
  // Polymorphic fields are no longer in attributes, they're in relationships
139
- assert.equal(review.data.relationships.reviewable.data.type, 'publishers');
140
- assert.equal(review.data.relationships.reviewable.data.id, String(publisher.data.id));
141
- });
139
+ assert.equal(review.data.relationships.reviewable.data.type, 'publishers')
140
+ assert.equal(review.data.relationships.reviewable.data.id, String(publisher.data.id))
141
+ })
142
142
 
143
143
  it('should fail to create review with invalid reviewable_type', async () => {
144
144
  // Skip this test for now - polymorphic validation happens at relationship level
145
145
  // not at the attribute level, so we need to create a proper relationship
146
146
  // This would require more complex validation implementation
147
- });
148
- });
147
+ })
148
+ })
149
149
 
150
150
  describe('Querying Reviews with Polymorphic Relationships', () => {
151
151
  beforeEach(async () => {
152
152
  await cleanTables(knex, [
153
- 'ext_countries', 'ext_publishers', 'ext_authors', 'ext_books',
153
+ 'ext_countries', 'ext_publishers', 'ext_authors', 'ext_books',
154
154
  'ext_book_authors', 'ext_reviews'
155
- ]);
156
- });
155
+ ])
156
+ })
157
157
 
158
158
  it('should query reviews and include polymorphic reviewable resource', async () => {
159
159
  // Create test data
@@ -162,7 +162,7 @@ describe('Polymorphic Relationship Operations', () => {
162
162
  name: 'France',
163
163
  code: 'FR'
164
164
  })
165
- });
165
+ })
166
166
 
167
167
  const book = await api.resources.books.post({
168
168
  inputRecord: createJsonApiDocument('books', {
@@ -170,7 +170,7 @@ describe('Polymorphic Relationship Operations', () => {
170
170
  }, {
171
171
  country: createRelationship({ type: 'countries', id: country.data.id })
172
172
  })
173
- });
173
+ })
174
174
 
175
175
  await api.resources.reviews.post({
176
176
  inputRecord: createJsonApiDocument('reviews', {
@@ -181,26 +181,26 @@ describe('Polymorphic Relationship Operations', () => {
181
181
  reviewable_type: 'books',
182
182
  reviewable_id: book.data.id
183
183
  })
184
- });
184
+ })
185
185
 
186
186
  // Query reviews with include
187
187
  const result = await api.resources.reviews.query({
188
188
  queryParams: {
189
189
  include: ['reviewable']
190
190
  }
191
- });
191
+ })
192
+
193
+ validateJsonApiStructure(result, true) // It's a collection
194
+ assert.equal(result.data.length, 1)
195
+ assert.equal(result.data[0].type, 'reviews')
192
196
 
193
- validateJsonApiStructure(result, true); // It's a collection
194
- assert.equal(result.data.length, 1);
195
- assert.equal(result.data[0].type, 'reviews');
196
-
197
197
  // Check included resources
198
- assert(result.included);
199
- assert.equal(result.included.length, 1);
200
- assert.equal(result.included[0].type, 'books');
201
- assert.equal(result.included[0].id, book.data.id);
202
- assert.equal(result.included[0].attributes.title, 'Test Book for Review');
203
- });
198
+ assert(result.included)
199
+ assert.equal(result.included.length, 1)
200
+ assert.equal(result.included[0].type, 'books')
201
+ assert.equal(result.included[0].id, book.data.id)
202
+ assert.equal(result.included[0].attributes.title, 'Test Book for Review')
203
+ })
204
204
 
205
205
  it('should handle mixed polymorphic types in a single query', async () => {
206
206
  // Create test data
@@ -209,7 +209,7 @@ describe('Polymorphic Relationship Operations', () => {
209
209
  name: 'Germany',
210
210
  code: 'DE'
211
211
  })
212
- });
212
+ })
213
213
 
214
214
  const book = await api.resources.books.post({
215
215
  inputRecord: createJsonApiDocument('books', {
@@ -217,13 +217,13 @@ describe('Polymorphic Relationship Operations', () => {
217
217
  }, {
218
218
  country: createRelationship({ type: 'countries', id: country.data.id })
219
219
  })
220
- });
220
+ })
221
221
 
222
222
  const author = await api.resources.authors.post({
223
223
  inputRecord: createJsonApiDocument('authors', {
224
224
  name: 'German Author'
225
225
  })
226
- });
226
+ })
227
227
 
228
228
  // Create reviews for different types
229
229
  await api.resources.reviews.post({
@@ -235,7 +235,7 @@ describe('Polymorphic Relationship Operations', () => {
235
235
  reviewable_type: 'books',
236
236
  reviewable_id: book.data.id
237
237
  })
238
- });
238
+ })
239
239
 
240
240
  await api.resources.reviews.post({
241
241
  inputRecord: createJsonApiDocument('reviews', {
@@ -246,41 +246,41 @@ describe('Polymorphic Relationship Operations', () => {
246
246
  reviewable_type: 'authors',
247
247
  reviewable_id: author.data.id
248
248
  })
249
- });
249
+ })
250
250
 
251
251
  // Query all reviews with includes
252
252
  const result = await api.resources.reviews.query({
253
253
  queryParams: {
254
254
  include: ['reviewable']
255
255
  }
256
- });
256
+ })
257
+
258
+ validateJsonApiStructure(result, true) // It's a collection
259
+ assert.equal(result.data.length, 2)
257
260
 
258
- validateJsonApiStructure(result, true); // It's a collection
259
- assert.equal(result.data.length, 2);
260
-
261
261
  // Check included resources
262
- assert(result.included);
263
- assert.equal(result.included.length, 2);
264
-
262
+ assert(result.included)
263
+ assert.equal(result.included.length, 2)
264
+
265
265
  // Find each type in included
266
- const includedBook = result.included.find(r => r.type === 'books');
267
- const includedAuthor = result.included.find(r => r.type === 'authors');
268
-
269
- assert(includedBook);
270
- assert.equal(includedBook.attributes.title, 'German Book');
271
-
272
- assert(includedAuthor);
273
- assert.equal(includedAuthor.attributes.name, 'German Author');
274
- });
275
- });
266
+ const includedBook = result.included.find(r => r.type === 'books')
267
+ const includedAuthor = result.included.find(r => r.type === 'authors')
268
+
269
+ assert(includedBook)
270
+ assert.equal(includedBook.attributes.title, 'German Book')
271
+
272
+ assert(includedAuthor)
273
+ assert.equal(includedAuthor.attributes.name, 'German Author')
274
+ })
275
+ })
276
276
 
277
277
  describe('Reverse Polymorphic Queries', () => {
278
278
  beforeEach(async () => {
279
279
  await cleanTables(knex, [
280
- 'ext_countries', 'ext_publishers', 'ext_authors', 'ext_books',
280
+ 'ext_countries', 'ext_publishers', 'ext_authors', 'ext_books',
281
281
  'ext_book_authors', 'ext_reviews'
282
- ]);
283
- });
282
+ ])
283
+ })
284
284
 
285
285
  it('should query books and include their reviews', async () => {
286
286
  // Create test data
@@ -289,7 +289,7 @@ describe('Polymorphic Relationship Operations', () => {
289
289
  name: 'Spain',
290
290
  code: 'ES'
291
291
  })
292
- });
292
+ })
293
293
 
294
294
  const book = await api.resources.books.post({
295
295
  inputRecord: createJsonApiDocument('books', {
@@ -297,7 +297,7 @@ describe('Polymorphic Relationship Operations', () => {
297
297
  }, {
298
298
  country: createRelationship({ type: 'countries', id: country.data.id })
299
299
  })
300
- });
300
+ })
301
301
 
302
302
  // Create multiple reviews for the book
303
303
  await api.resources.reviews.post({
@@ -309,7 +309,7 @@ describe('Polymorphic Relationship Operations', () => {
309
309
  reviewable_type: 'books',
310
310
  reviewable_id: book.data.id
311
311
  })
312
- });
312
+ })
313
313
 
314
314
  await api.resources.reviews.post({
315
315
  inputRecord: createJsonApiDocument('reviews', {
@@ -320,7 +320,7 @@ describe('Polymorphic Relationship Operations', () => {
320
320
  reviewable_type: 'books',
321
321
  reviewable_id: book.data.id
322
322
  })
323
- });
323
+ })
324
324
 
325
325
  // Query book with reviews
326
326
  const result = await api.resources.books.get({
@@ -328,20 +328,20 @@ describe('Polymorphic Relationship Operations', () => {
328
328
  queryParams: {
329
329
  include: ['reviews']
330
330
  }
331
- });
331
+ })
332
+
333
+ validateJsonApiStructure(result)
334
+ assert.equal(result.data.type, 'books')
332
335
 
333
- validateJsonApiStructure(result);
334
- assert.equal(result.data.type, 'books');
335
-
336
336
  // Check included reviews
337
- console.log('Result included:', JSON.stringify(result.included, null, 2));
338
- assert(result.included);
339
- assert.equal(result.included.length, 2);
340
- assert(result.included.every(r => r.type === 'reviews'));
341
- assert(result.included.every(r =>
342
- r.relationships.reviewable.data.type === 'books' &&
337
+ console.log('Result included:', JSON.stringify(result.included, null, 2))
338
+ assert(result.included)
339
+ assert.equal(result.included.length, 2)
340
+ assert(result.included.every(r => r.type === 'reviews'))
341
+ assert(result.included.every(r =>
342
+ r.relationships.reviewable.data.type === 'books' &&
343
343
  String(r.relationships.reviewable.data.id) === String(book.data.id)
344
- ));
345
- });
346
- });
347
- });
344
+ ))
345
+ })
346
+ })
347
+ })
@@ -1,13 +1,13 @@
1
- import { describe, it, before, after, beforeEach } from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import knexLib from 'knex';
4
- import { createExtendedApi } from './fixtures/api-configs.js';
1
+ import { describe, it, before, after, beforeEach } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+ import knexLib from 'knex'
4
+ import { createExtendedApi } from './fixtures/api-configs.js'
5
5
  import {
6
6
  validateJsonApiStructure,
7
7
  cleanTables,
8
8
  createJsonApiDocument,
9
9
  createRelationship
10
- } from './helpers/test-utils.js';
10
+ } from './helpers/test-utils.js'
11
11
 
12
12
  // Create Knex instance for tests
13
13
  const knex = knexLib({
@@ -16,29 +16,29 @@ const knex = knexLib({
16
16
  filename: ':memory:'
17
17
  },
18
18
  useNullAsDefault: true
19
- });
19
+ })
20
20
 
21
21
  // API instance
22
- let api;
22
+ let api
23
23
 
24
24
  describe('Polymorphic Relationships - Basic Tests', () => {
25
25
  before(async () => {
26
26
  // Initialize API
27
- api = await createExtendedApi(knex);
28
- });
27
+ api = await createExtendedApi(knex)
28
+ })
29
29
 
30
30
  after(async () => {
31
31
  // Close database connection
32
- await knex.destroy();
33
- });
32
+ await knex.destroy()
33
+ })
34
34
 
35
35
  beforeEach(async () => {
36
36
  // Clean all tables before each test
37
37
  await cleanTables(knex, [
38
- 'ext_countries', 'ext_publishers', 'ext_authors', 'ext_books',
38
+ 'ext_countries', 'ext_publishers', 'ext_authors', 'ext_books',
39
39
  'ext_book_authors', 'ext_reviews'
40
- ]);
41
- });
40
+ ])
41
+ })
42
42
 
43
43
  it('should create and retrieve a review for a book', async () => {
44
44
  // Create a country first
@@ -47,7 +47,7 @@ describe('Polymorphic Relationships - Basic Tests', () => {
47
47
  name: 'USA',
48
48
  code: 'US'
49
49
  })
50
- });
50
+ })
51
51
 
52
52
  // Create a book
53
53
  const book = await api.resources.books.post({
@@ -56,7 +56,7 @@ describe('Polymorphic Relationships - Basic Tests', () => {
56
56
  }, {
57
57
  country: createRelationship({ type: 'countries', id: country.data.id })
58
58
  })
59
- });
59
+ })
60
60
 
61
61
  // Create a review for the book
62
62
  const review = await api.resources.reviews.post({
@@ -68,22 +68,22 @@ describe('Polymorphic Relationships - Basic Tests', () => {
68
68
  }, {
69
69
  reviewable: { data: { type: 'books', id: book.data.id } }
70
70
  })
71
- });
71
+ })
72
+
73
+ validateJsonApiStructure(review)
74
+ assert.equal(review.data.type, 'reviews')
75
+ assert.equal(review.data.attributes.rating, 5)
72
76
 
73
- validateJsonApiStructure(review);
74
- assert.equal(review.data.type, 'reviews');
75
- assert.equal(review.data.attributes.rating, 5);
76
-
77
77
  // Get the review back
78
78
  const retrievedReview = await api.resources.reviews.get({
79
79
  id: review.data.id
80
- });
81
-
82
- validateJsonApiStructure(retrievedReview);
80
+ })
81
+
82
+ validateJsonApiStructure(retrievedReview)
83
83
  // Polymorphic fields are no longer in attributes, they're in relationships
84
- assert.equal(retrievedReview.data.relationships.reviewable.data.type, 'books');
85
- assert.equal(retrievedReview.data.relationships.reviewable.data.id, String(book.data.id));
86
- });
84
+ assert.equal(retrievedReview.data.relationships.reviewable.data.type, 'books')
85
+ assert.equal(retrievedReview.data.relationships.reviewable.data.id, String(book.data.id))
86
+ })
87
87
 
88
88
  it('should query all reviews', async () => {
89
89
  // Create test data
@@ -92,7 +92,7 @@ describe('Polymorphic Relationships - Basic Tests', () => {
92
92
  name: 'UK',
93
93
  code: 'GB'
94
94
  })
95
- });
95
+ })
96
96
 
97
97
  const book = await api.resources.books.post({
98
98
  inputRecord: createJsonApiDocument('books', {
@@ -100,13 +100,13 @@ describe('Polymorphic Relationships - Basic Tests', () => {
100
100
  }, {
101
101
  country: createRelationship({ type: 'countries', id: country.data.id })
102
102
  })
103
- });
103
+ })
104
104
 
105
105
  const author = await api.resources.authors.post({
106
106
  inputRecord: createJsonApiDocument('authors', {
107
107
  name: 'Author 1'
108
108
  })
109
- });
109
+ })
110
110
 
111
111
  // Create reviews
112
112
  await api.resources.reviews.post({
@@ -118,7 +118,7 @@ describe('Polymorphic Relationships - Basic Tests', () => {
118
118
  }, {
119
119
  reviewable: { data: { type: 'books', id: book.data.id } }
120
120
  })
121
- });
121
+ })
122
122
 
123
123
  await api.resources.reviews.post({
124
124
  inputRecord: createJsonApiDocument('reviews', {
@@ -129,20 +129,20 @@ describe('Polymorphic Relationships - Basic Tests', () => {
129
129
  }, {
130
130
  reviewable: { data: { type: 'authors', id: author.data.id } }
131
131
  })
132
- });
132
+ })
133
133
 
134
134
  // Query all reviews
135
- const result = await api.resources.reviews.query({});
136
-
137
- validateJsonApiStructure(result, true);
138
- assert.equal(result.data.length, 2);
139
-
135
+ const result = await api.resources.reviews.query({})
136
+
137
+ validateJsonApiStructure(result, true)
138
+ assert.equal(result.data.length, 2)
139
+
140
140
  // Check we have one of each type
141
141
  // Polymorphic fields are no longer in attributes, they're in relationships
142
- const bookReview = result.data.find(r => r.relationships.reviewable.data.type === 'books');
143
- const authorReview = result.data.find(r => r.relationships.reviewable.data.type === 'authors');
144
-
145
- assert(bookReview, 'Should have a book review');
146
- assert(authorReview, 'Should have an author review');
147
- });
148
- });
142
+ const bookReview = result.data.find(r => r.relationships.reviewable.data.type === 'books')
143
+ const authorReview = result.data.find(r => r.relationships.reviewable.data.type === 'authors')
144
+
145
+ assert(bookReview, 'Should have a book review')
146
+ assert(authorReview, 'Should have an author review')
147
+ })
148
+ })