confluent-schema-registry 3.3.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.
Files changed (173) hide show
  1. package/.dockerignore +2 -0
  2. package/.prettierrc.js +8 -0
  3. package/CHANGELOG.md +166 -0
  4. package/Dockerfile +10 -0
  5. package/LICENSE +21 -0
  6. package/README.md +44 -0
  7. package/bin/avdlToAVSC.sh +9 -0
  8. package/dist/@types.d.ts +93 -0
  9. package/dist/@types.js +10 -0
  10. package/dist/@types.js.map +1 -0
  11. package/dist/AvroHelper.d.ts +12 -0
  12. package/dist/AvroHelper.js +67 -0
  13. package/dist/AvroHelper.js.map +1 -0
  14. package/dist/JsonHelper.d.ts +7 -0
  15. package/dist/JsonHelper.js +20 -0
  16. package/dist/JsonHelper.js.map +1 -0
  17. package/dist/JsonSchema.d.ts +31 -0
  18. package/dist/JsonSchema.js +58 -0
  19. package/dist/JsonSchema.js.map +1 -0
  20. package/dist/ProtoHelper.d.ts +7 -0
  21. package/dist/ProtoHelper.js +23 -0
  22. package/dist/ProtoHelper.js.map +1 -0
  23. package/dist/ProtoSchema.d.ts +14 -0
  24. package/dist/ProtoSchema.js +66 -0
  25. package/dist/ProtoSchema.js.map +1 -0
  26. package/dist/SchemaRegistry.d.ts +48 -0
  27. package/dist/SchemaRegistry.js +250 -0
  28. package/dist/SchemaRegistry.js.map +1 -0
  29. package/dist/api/index.d.ts +43 -0
  30. package/dist/api/index.js +90 -0
  31. package/dist/api/index.js.map +1 -0
  32. package/dist/api/middleware/confluentEncoderMiddleware.d.ts +3 -0
  33. package/dist/api/middleware/confluentEncoderMiddleware.js +31 -0
  34. package/dist/api/middleware/confluentEncoderMiddleware.js.map +1 -0
  35. package/dist/api/middleware/errorMiddleware.d.ts +3 -0
  36. package/dist/api/middleware/errorMiddleware.js +20 -0
  37. package/dist/api/middleware/errorMiddleware.js.map +1 -0
  38. package/dist/api/middleware/userAgent.d.ts +3 -0
  39. package/dist/api/middleware/userAgent.js +18 -0
  40. package/dist/api/middleware/userAgent.js.map +1 -0
  41. package/dist/cache.d.ts +20 -0
  42. package/dist/cache.js +24 -0
  43. package/dist/cache.js.map +1 -0
  44. package/dist/constants.d.ts +11 -0
  45. package/dist/constants.js +15 -0
  46. package/dist/constants.js.map +1 -0
  47. package/dist/errors.d.ts +14 -0
  48. package/dist/errors.js +26 -0
  49. package/dist/errors.js.map +1 -0
  50. package/dist/index.d.ts +4 -0
  51. package/dist/index.js +13 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/schemaTypeResolver.d.ts +4 -0
  54. package/dist/schemaTypeResolver.js +80 -0
  55. package/dist/schemaTypeResolver.js.map +1 -0
  56. package/dist/utils/avdlToAVSC.d.ts +2 -0
  57. package/dist/utils/avdlToAVSC.js +85 -0
  58. package/dist/utils/avdlToAVSC.js.map +1 -0
  59. package/dist/utils/index.d.ts +2 -0
  60. package/dist/utils/index.js +9 -0
  61. package/dist/utils/index.js.map +1 -0
  62. package/dist/utils/readAVSC.d.ts +3 -0
  63. package/dist/utils/readAVSC.js +33 -0
  64. package/dist/utils/readAVSC.js.map +1 -0
  65. package/dist/wireDecoder.d.ts +7 -0
  66. package/dist/wireDecoder.js +8 -0
  67. package/dist/wireDecoder.js.map +1 -0
  68. package/dist/wireEncoder.d.ts +3 -0
  69. package/dist/wireEncoder.js +10 -0
  70. package/dist/wireEncoder.js.map +1 -0
  71. package/dockest-error.json +11 -0
  72. package/dockest.ts +30 -0
  73. package/jest.setup.ts +60 -0
  74. package/package.json +56 -0
  75. package/release/CHANGELOG.md +166 -0
  76. package/release/LICENSE +21 -0
  77. package/release/README.md +44 -0
  78. package/release/dist/@types.d.ts +93 -0
  79. package/release/dist/@types.js +10 -0
  80. package/release/dist/@types.js.map +1 -0
  81. package/release/dist/AvroHelper.d.ts +12 -0
  82. package/release/dist/AvroHelper.js +67 -0
  83. package/release/dist/AvroHelper.js.map +1 -0
  84. package/release/dist/JsonHelper.d.ts +7 -0
  85. package/release/dist/JsonHelper.js +20 -0
  86. package/release/dist/JsonHelper.js.map +1 -0
  87. package/release/dist/JsonSchema.d.ts +31 -0
  88. package/release/dist/JsonSchema.js +58 -0
  89. package/release/dist/JsonSchema.js.map +1 -0
  90. package/release/dist/ProtoHelper.d.ts +7 -0
  91. package/release/dist/ProtoHelper.js +23 -0
  92. package/release/dist/ProtoHelper.js.map +1 -0
  93. package/release/dist/ProtoSchema.d.ts +14 -0
  94. package/release/dist/ProtoSchema.js +66 -0
  95. package/release/dist/ProtoSchema.js.map +1 -0
  96. package/release/dist/SchemaRegistry.d.ts +48 -0
  97. package/release/dist/SchemaRegistry.js +250 -0
  98. package/release/dist/SchemaRegistry.js.map +1 -0
  99. package/release/dist/api/index.d.ts +43 -0
  100. package/release/dist/api/index.js +90 -0
  101. package/release/dist/api/index.js.map +1 -0
  102. package/release/dist/api/middleware/confluentEncoderMiddleware.d.ts +3 -0
  103. package/release/dist/api/middleware/confluentEncoderMiddleware.js +31 -0
  104. package/release/dist/api/middleware/confluentEncoderMiddleware.js.map +1 -0
  105. package/release/dist/api/middleware/errorMiddleware.d.ts +3 -0
  106. package/release/dist/api/middleware/errorMiddleware.js +20 -0
  107. package/release/dist/api/middleware/errorMiddleware.js.map +1 -0
  108. package/release/dist/api/middleware/userAgent.d.ts +3 -0
  109. package/release/dist/api/middleware/userAgent.js +18 -0
  110. package/release/dist/api/middleware/userAgent.js.map +1 -0
  111. package/release/dist/cache.d.ts +20 -0
  112. package/release/dist/cache.js +24 -0
  113. package/release/dist/cache.js.map +1 -0
  114. package/release/dist/constants.d.ts +11 -0
  115. package/release/dist/constants.js +15 -0
  116. package/release/dist/constants.js.map +1 -0
  117. package/release/dist/errors.d.ts +14 -0
  118. package/release/dist/errors.js +26 -0
  119. package/release/dist/errors.js.map +1 -0
  120. package/release/dist/index.d.ts +4 -0
  121. package/release/dist/index.js +13 -0
  122. package/release/dist/index.js.map +1 -0
  123. package/release/dist/schemaTypeResolver.d.ts +4 -0
  124. package/release/dist/schemaTypeResolver.js +80 -0
  125. package/release/dist/schemaTypeResolver.js.map +1 -0
  126. package/release/dist/utils/avdlToAVSC.d.ts +2 -0
  127. package/release/dist/utils/avdlToAVSC.js +85 -0
  128. package/release/dist/utils/avdlToAVSC.js.map +1 -0
  129. package/release/dist/utils/index.d.ts +2 -0
  130. package/release/dist/utils/index.js +9 -0
  131. package/release/dist/utils/index.js.map +1 -0
  132. package/release/dist/utils/readAVSC.d.ts +3 -0
  133. package/release/dist/utils/readAVSC.js +33 -0
  134. package/release/dist/utils/readAVSC.js.map +1 -0
  135. package/release/dist/wireDecoder.d.ts +7 -0
  136. package/release/dist/wireDecoder.js +8 -0
  137. package/release/dist/wireDecoder.js.map +1 -0
  138. package/release/dist/wireEncoder.d.ts +3 -0
  139. package/release/dist/wireEncoder.js +10 -0
  140. package/release/dist/wireEncoder.js.map +1 -0
  141. package/release/package.json +56 -0
  142. package/src/@types.ts +105 -0
  143. package/src/AvroHelper.ts +91 -0
  144. package/src/JsonHelper.ts +35 -0
  145. package/src/JsonSchema.ts +80 -0
  146. package/src/ProtoHelper.ts +38 -0
  147. package/src/ProtoSchema.ts +80 -0
  148. package/src/SchemaRegistry.avro.spec.ts +558 -0
  149. package/src/SchemaRegistry.json.spec.ts +364 -0
  150. package/src/SchemaRegistry.newApi.spec.ts +622 -0
  151. package/src/SchemaRegistry.protobuf.spec.ts +372 -0
  152. package/src/SchemaRegistry.spec.ts +252 -0
  153. package/src/SchemaRegistry.ts +387 -0
  154. package/src/api/index.spec.ts +23 -0
  155. package/src/api/index.ts +121 -0
  156. package/src/api/middleware/confluentEncoderMiddleware.ts +36 -0
  157. package/src/api/middleware/errorMiddleware.spec.ts +67 -0
  158. package/src/api/middleware/errorMiddleware.ts +37 -0
  159. package/src/api/middleware/userAgent.spec.ts +53 -0
  160. package/src/api/middleware/userAgent.ts +19 -0
  161. package/src/cache.ts +34 -0
  162. package/src/constants.ts +13 -0
  163. package/src/errors.ts +26 -0
  164. package/src/index.ts +4 -0
  165. package/src/schemaTypeResolver.ts +101 -0
  166. package/src/utils/avdlToAVSC.spec.ts +79 -0
  167. package/src/utils/avdlToAVSC.ts +106 -0
  168. package/src/utils/index.ts +2 -0
  169. package/src/utils/readAVSC.spec.ts +23 -0
  170. package/src/utils/readAVSC.ts +36 -0
  171. package/src/wireDecoder.ts +5 -0
  172. package/src/wireEncoder.ts +10 -0
  173. package/tsconfig.json +22 -0
@@ -0,0 +1,558 @@
1
+ import SchemaRegistry, { RegisteredSchema } from './SchemaRegistry'
2
+ import API from './api'
3
+ import { AvroConfluentSchema, SchemaType } from './@types'
4
+ import avro from 'avsc'
5
+
6
+ const REGISTRY_HOST = 'http://localhost:8982'
7
+ const schemaRegistryAPIClientArgs = { host: REGISTRY_HOST }
8
+ const schemaRegistryArgs = { host: REGISTRY_HOST }
9
+
10
+ enum Color {
11
+ RED = 1,
12
+ GREEN = 2,
13
+ BLUE = 3,
14
+ }
15
+
16
+ enum Direction {
17
+ UP = 1,
18
+ DOWN = 2,
19
+ }
20
+
21
+ const TestSchemas = {
22
+ FirstLevelSchema: {
23
+ type: SchemaType.AVRO,
24
+ schema: `
25
+ {
26
+ "type" : "record",
27
+ "namespace" : "test",
28
+ "name" : "FirstLevel",
29
+ "fields" : [
30
+ { "name" : "id1" , "type" : "int" },
31
+ { "name" : "level1a" , "type" : "test.SecondLevelA" },
32
+ { "name" : "level1b" , "type" : "test.SecondLevelB" }
33
+ ]
34
+ }`,
35
+ references: [
36
+ {
37
+ name: 'test.SecondLevelA',
38
+ subject: 'Avro:SecondLevelA',
39
+ version: undefined,
40
+ },
41
+ {
42
+ name: 'test.SecondLevelB',
43
+ subject: 'Avro:SecondLevelB',
44
+ version: undefined,
45
+ },
46
+ ],
47
+ } as AvroConfluentSchema,
48
+
49
+ SecondLevelASchema: {
50
+ type: SchemaType.AVRO,
51
+ schema: `
52
+ {
53
+ "type" : "record",
54
+ "namespace" : "test",
55
+ "name" : "SecondLevelA",
56
+ "fields" : [
57
+ { "name" : "id2a" , "type" : "int" },
58
+ { "name" : "level2a" , "type" : "test.ThirdLevel" }
59
+ ]
60
+ }`,
61
+ references: [
62
+ {
63
+ name: 'test.ThirdLevel',
64
+ subject: 'Avro:ThirdLevel',
65
+ version: undefined,
66
+ },
67
+ ],
68
+ } as AvroConfluentSchema,
69
+
70
+ SecondLevelBSchema: {
71
+ type: SchemaType.AVRO,
72
+ schema: `
73
+ {
74
+ "type" : "record",
75
+ "namespace" : "test",
76
+ "name" : "SecondLevelB",
77
+ "fields" : [
78
+ { "name" : "id2b" , "type" : "int" },
79
+ { "name" : "level2b" , "type" : "test.ThirdLevel" }
80
+ ]
81
+ }`,
82
+ references: [
83
+ {
84
+ name: 'test.ThirdLevel',
85
+ subject: 'Avro:ThirdLevel',
86
+ version: undefined,
87
+ },
88
+ ],
89
+ } as AvroConfluentSchema,
90
+
91
+ ThirdLevelSchema: {
92
+ type: SchemaType.AVRO,
93
+ schema: `
94
+ {
95
+ "type" : "record",
96
+ "namespace" : "test",
97
+ "name" : "ThirdLevel",
98
+ "fields" : [
99
+ { "name" : "id3" , "type" : "int" }
100
+ ]
101
+ }`,
102
+ } as AvroConfluentSchema,
103
+
104
+ EnumSchema: {
105
+ type: SchemaType.AVRO,
106
+ schema: `
107
+ {
108
+ "type" : "record",
109
+ "namespace" : "test",
110
+ "name" : "EnumSchema",
111
+ "fields" : [
112
+ {
113
+ "name": "color",
114
+ "type": ["null", {
115
+ "type": "enum",
116
+ "name": "Color",
117
+ "symbols": ["RED", "GREEN", "BLUE"]
118
+ }
119
+ ]
120
+ }
121
+ ]
122
+ }`,
123
+ } as AvroConfluentSchema,
124
+
125
+ EnumWithReferencesSchema: {
126
+ type: SchemaType.AVRO,
127
+ schema: `
128
+ {
129
+ "type" : "record",
130
+ "namespace" : "test",
131
+ "name" : "EnumWithReferences",
132
+ "fields" : [
133
+ {
134
+ "name": "direction",
135
+ "type": ["null", {
136
+ "type": "enum",
137
+ "name": "Direction",
138
+ "symbols": ["UP", "DOWN"]
139
+ }
140
+ ]
141
+ },
142
+ { "name" : "attributes" , "type" : "test.EnumSchema" }
143
+ ]
144
+ }`,
145
+ references: [
146
+ {
147
+ name: 'test.EnumSchema',
148
+ subject: 'Avro:EnumSchema',
149
+ version: undefined,
150
+ },
151
+ ],
152
+ } as AvroConfluentSchema,
153
+ }
154
+
155
+ function apiResponse(result) {
156
+ return JSON.parse(result.responseData)
157
+ }
158
+
159
+ describe('SchemaRegistry', () => {
160
+ let schemaRegistry: SchemaRegistry
161
+ let registeredSchema: RegisteredSchema
162
+ let api
163
+
164
+ beforeEach(async () => {
165
+ api = API(schemaRegistryAPIClientArgs)
166
+ schemaRegistry = new SchemaRegistry(schemaRegistryArgs)
167
+ })
168
+
169
+ describe('when register', () => {
170
+ describe('when no reference', () => {
171
+ beforeEach(async () => {
172
+ registeredSchema = await schemaRegistry.register(TestSchemas.ThirdLevelSchema, {
173
+ subject: 'Avro:ThirdLevel',
174
+ })
175
+ })
176
+
177
+ it('should return schema id', async () => {
178
+ expect(registeredSchema.id).toEqual(expect.any(Number))
179
+ })
180
+
181
+ it('should be able to encode/decode', async () => {
182
+ const obj = { id3: 3 }
183
+
184
+ const buffer = await schemaRegistry.encode(registeredSchema.id, obj)
185
+ const resultObj = await schemaRegistry.decode(buffer)
186
+
187
+ expect(resultObj).toEqual(obj)
188
+ })
189
+ })
190
+
191
+ describe('with reference', () => {
192
+ let schemaId
193
+ let referenceSchema
194
+
195
+ beforeEach(async () => {
196
+ await schemaRegistry.register(TestSchemas.ThirdLevelSchema, {
197
+ subject: 'Avro:ThirdLevel',
198
+ })
199
+
200
+ const latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:ThirdLevel' }))
201
+ TestSchemas.SecondLevelASchema.references[0].version = latest.version
202
+ registeredSchema = await schemaRegistry.register(TestSchemas.SecondLevelASchema, {
203
+ subject: 'Avro:SecondLevelA',
204
+ })
205
+ schemaId = registeredSchema.id
206
+
207
+ const schemaRaw = apiResponse(await api.Schema.find({ id: schemaId }))
208
+ referenceSchema = schemaRaw.references[0].subject
209
+ })
210
+
211
+ it('should return schema id', async () => {
212
+ expect(schemaId).toEqual(expect.any(Number))
213
+ })
214
+
215
+ it('should create a schema with reference', async () => {
216
+ expect(referenceSchema).toEqual('Avro:ThirdLevel')
217
+ })
218
+
219
+ it('should be able to encode/decode', async () => {
220
+ const obj = { id2a: 2, level2a: { id3: 3 } }
221
+
222
+ const buffer = await schemaRegistry.encode(registeredSchema.id, obj)
223
+ const resultObj = await schemaRegistry.decode(buffer)
224
+
225
+ expect(resultObj).toEqual(obj)
226
+ })
227
+ })
228
+
229
+ describe('with multiple reference', () => {
230
+ beforeEach(async () => {
231
+ let latest
232
+
233
+ registeredSchema = await schemaRegistry.register(TestSchemas.ThirdLevelSchema, {
234
+ subject: 'Avro:ThirdLevel',
235
+ })
236
+
237
+ latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:ThirdLevel' }))
238
+ TestSchemas.SecondLevelASchema.references[0].version = latest.version
239
+ registeredSchema = await schemaRegistry.register(TestSchemas.SecondLevelASchema, {
240
+ subject: 'Avro:SecondLevelA',
241
+ })
242
+
243
+ latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:ThirdLevel' }))
244
+ TestSchemas.SecondLevelBSchema.references[0].version = latest.version
245
+ registeredSchema = await schemaRegistry.register(TestSchemas.SecondLevelBSchema, {
246
+ subject: 'Avro:SecondLevelB',
247
+ })
248
+
249
+ latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:SecondLevelA' }))
250
+ TestSchemas.FirstLevelSchema.references[0].version = latest.version
251
+ latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:SecondLevelB' }))
252
+ TestSchemas.FirstLevelSchema.references[1].version = latest.version
253
+ registeredSchema = await schemaRegistry.register(TestSchemas.FirstLevelSchema, {
254
+ subject: 'Avro:FirstLevel',
255
+ })
256
+ })
257
+
258
+ it('should be able to encode/decode', async () => {
259
+ const obj = {
260
+ id1: 1,
261
+ level1a: { id2a: 2, level2a: { id3: 3 } },
262
+ level1b: { id2b: 4, level2b: { id3: 5 } },
263
+ }
264
+
265
+ const buffer = await schemaRegistry.encode(registeredSchema.id, obj)
266
+ const resultObj = await schemaRegistry.decode(buffer)
267
+
268
+ expect(resultObj).toEqual(obj)
269
+ })
270
+
271
+ it('should be able to encode/decode independent', async () => {
272
+ const obj = {
273
+ id1: 1,
274
+ level1a: { id2a: 2, level2a: { id3: 3 } },
275
+ level1b: { id2b: 4, level2b: { id3: 5 } },
276
+ }
277
+
278
+ schemaRegistry = new SchemaRegistry(schemaRegistryArgs)
279
+ const buffer = await schemaRegistry.encode(registeredSchema.id, obj)
280
+
281
+ schemaRegistry = new SchemaRegistry(schemaRegistryArgs)
282
+ const resultObj = await schemaRegistry.decode(buffer)
283
+
284
+ expect(resultObj).toEqual(obj)
285
+ })
286
+ })
287
+ })
288
+
289
+ describe('_getSchema', () => {
290
+ let schema
291
+
292
+ describe('no references', () => {
293
+ beforeEach(async () => {
294
+ registeredSchema = await schemaRegistry.register(TestSchemas.ThirdLevelSchema, {
295
+ subject: 'Avro:ThirdLevel',
296
+ })
297
+ ;({ schema } = await schemaRegistry['_getSchema'](registeredSchema.id))
298
+ })
299
+
300
+ it('should return schema that match name', async () => {
301
+ expect(schema.name).toEqual('test.ThirdLevel')
302
+ })
303
+
304
+ it('should be able to encode/decode', async () => {
305
+ const obj = { id3: 3 }
306
+
307
+ const buffer = await schema.toBuffer(obj)
308
+ const resultObj = await schema.fromBuffer(buffer)
309
+
310
+ expect(resultObj).toEqual(obj)
311
+ })
312
+ })
313
+
314
+ describe('with references', () => {
315
+ beforeEach(async () => {
316
+ await schemaRegistry.register(TestSchemas.ThirdLevelSchema, { subject: 'Avro:ThirdLevel' })
317
+
318
+ const latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:ThirdLevel' }))
319
+ TestSchemas.SecondLevelASchema.references[0].version = latest.version
320
+ registeredSchema = await schemaRegistry.register(TestSchemas.SecondLevelASchema, {
321
+ subject: 'Avro:SecondLevelA',
322
+ })
323
+ ;({ schema } = await schemaRegistry['_getSchema'](registeredSchema.id))
324
+ })
325
+
326
+ it('should return schema that match name', async () => {
327
+ expect(schema.name).toEqual('test.SecondLevelA')
328
+ })
329
+
330
+ it('should be able to encode/decode', async () => {
331
+ const obj = { id2a: 2, level2a: { id3: 3 } }
332
+
333
+ const buffer = await schema.toBuffer(obj)
334
+ const resultObj = await schema.fromBuffer(buffer)
335
+
336
+ expect(resultObj).toEqual(obj)
337
+ })
338
+ })
339
+
340
+ describe('with multi references', () => {
341
+ beforeEach(async () => {
342
+ let latest
343
+
344
+ await schemaRegistry.register(TestSchemas.ThirdLevelSchema, {
345
+ subject: 'Avro:ThirdLevel',
346
+ })
347
+
348
+ latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:ThirdLevel' }))
349
+ TestSchemas.SecondLevelASchema.references[0].version = latest.version
350
+ registeredSchema = await schemaRegistry.register(TestSchemas.SecondLevelASchema, {
351
+ subject: 'Avro:SecondLevelA',
352
+ })
353
+
354
+ latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:ThirdLevel' }))
355
+ TestSchemas.SecondLevelBSchema.references[0].version = latest.version
356
+ registeredSchema = await schemaRegistry.register(TestSchemas.SecondLevelBSchema, {
357
+ subject: 'Avro:SecondLevelB',
358
+ })
359
+
360
+ latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:SecondLevelA' }))
361
+ TestSchemas.FirstLevelSchema.references[0].version = latest.version
362
+ latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:SecondLevelB' }))
363
+ TestSchemas.FirstLevelSchema.references[1].version = latest.version
364
+ registeredSchema = await schemaRegistry.register(TestSchemas.FirstLevelSchema, {
365
+ subject: 'Avro:FirstLevel',
366
+ })
367
+ ;({ schema } = await schemaRegistry['_getSchema'](registeredSchema.id))
368
+ })
369
+
370
+ it('should return schema that match name', async () => {
371
+ expect(schema.name).toEqual('test.FirstLevel')
372
+ })
373
+
374
+ it('should be able to encode/decode', async () => {
375
+ const obj = {
376
+ id1: 1,
377
+ level1a: { id2a: 2, level2a: { id3: 3 } },
378
+ level1b: { id2b: 4, level2b: { id3: 5 } },
379
+ }
380
+
381
+ const buffer = await schema.toBuffer(obj)
382
+ const resultObj = await schema.fromBuffer(buffer)
383
+
384
+ expect(resultObj).toEqual(obj)
385
+ })
386
+ })
387
+ })
388
+
389
+ describe('when document example', () => {
390
+ it('should encode/decode', async () => {
391
+ const schemaA = {
392
+ type: 'record',
393
+ namespace: 'test',
394
+ name: 'A',
395
+ fields: [
396
+ { name: 'id', type: 'int' },
397
+ { name: 'b', type: 'test.B' },
398
+ ],
399
+ }
400
+
401
+ const schemaB = {
402
+ type: 'record',
403
+ namespace: 'test',
404
+ name: 'B',
405
+ fields: [{ name: 'id', type: 'int' }],
406
+ }
407
+
408
+ await schemaRegistry.register(
409
+ { type: SchemaType.AVRO, schema: JSON.stringify(schemaB) },
410
+ { subject: 'Avro:B' },
411
+ )
412
+
413
+ const response = await schemaRegistry.api.Subject.latestVersion({ subject: 'Avro:B' })
414
+ const { version } = JSON.parse(response.responseData)
415
+
416
+ const { id } = await schemaRegistry.register(
417
+ {
418
+ type: SchemaType.AVRO,
419
+ schema: JSON.stringify(schemaA),
420
+ references: [
421
+ {
422
+ name: 'test.B',
423
+ subject: 'Avro:B',
424
+ version,
425
+ },
426
+ ],
427
+ },
428
+ { subject: 'Avro:A' },
429
+ )
430
+
431
+ const obj = { id: 1, b: { id: 2 } }
432
+
433
+ const buffer = await schemaRegistry.encode(id, obj)
434
+ const decodedObj = await schemaRegistry.decode(buffer)
435
+
436
+ expect(decodedObj).toEqual(obj)
437
+ })
438
+ })
439
+
440
+ describe('with EnumType types and nested schemas', () => {
441
+ /**
442
+ * Hook which will decode/encode enums to/from integers.
443
+ *
444
+ * The default `EnumType` implementation represents enum values as strings
445
+ * (consistent with the JSON representation). This hook can be used to provide
446
+ * an alternate representation (which is for example compatible with TypeScript
447
+ * enums).
448
+ *
449
+ * For simplicity, we don't do any bound checking here but we could by
450
+ * implementing a "bounded long" logical type and returning that instead.
451
+ *
452
+ * https://gist.github.com/mtth/c0088c745de048c4e466#file-long-enum-js
453
+ */
454
+ function typeHook(attrs, opts) {
455
+ if (attrs.type === 'enum') {
456
+ return avro.parse('long', opts)
457
+ }
458
+ }
459
+
460
+ let schema
461
+
462
+ describe('with no enum typeHook defined', () => {
463
+ beforeEach(async () => {
464
+ const schemaRegistry = new SchemaRegistry(schemaRegistryArgs)
465
+
466
+ await schemaRegistry.register(TestSchemas.EnumSchema, {
467
+ subject: 'Avro:EnumSchema',
468
+ })
469
+
470
+ const latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:EnumSchema' }))
471
+ TestSchemas.EnumWithReferencesSchema.references[0].version = latest.version
472
+ const registeredSchema = await schemaRegistry.register(
473
+ TestSchemas.EnumWithReferencesSchema,
474
+ {
475
+ subject: 'Avro:EnumWithReferences',
476
+ },
477
+ )
478
+ ;({ schema } = await schemaRegistry['_getSchema'](registeredSchema.id))
479
+ })
480
+
481
+ it('should not be able to encode/decode enums schemas', async () => {
482
+ const obj = {
483
+ direction: Direction.UP,
484
+ attributes: { color: Color.BLUE },
485
+ }
486
+
487
+ expect(() => schema.toBuffer(obj)).toThrow(Error)
488
+ })
489
+ })
490
+
491
+ describe('with enum typeHook defined', () => {
492
+ beforeEach(async () => {
493
+ const schemaRegistry = new SchemaRegistry(schemaRegistryArgs, {
494
+ [SchemaType.AVRO]: { typeHook },
495
+ })
496
+
497
+ await schemaRegistry.register(TestSchemas.EnumSchema, {
498
+ subject: 'Avro:EnumSchema',
499
+ })
500
+
501
+ const latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:EnumSchema' }))
502
+ TestSchemas.EnumWithReferencesSchema.references[0].version = latest.version
503
+ const registeredSchema = await schemaRegistry.register(
504
+ TestSchemas.EnumWithReferencesSchema,
505
+ {
506
+ subject: 'Avro:EnumWithReferences',
507
+ },
508
+ )
509
+ ;({ schema } = await schemaRegistry['_getSchema'](registeredSchema.id))
510
+ })
511
+
512
+ it('should be able to encode/decode enums schemas', async () => {
513
+ const obj = {
514
+ direction: Direction.UP,
515
+ attributes: { color: Color.BLUE },
516
+ }
517
+
518
+ const buffer = await schema.toBuffer(obj)
519
+ const resultObj = await schema.fromBuffer(buffer)
520
+
521
+ expect(resultObj).toEqual(obj)
522
+ })
523
+ })
524
+ describe('with enum typeHook defined as LegacyOptions', () => {
525
+ beforeEach(async () => {
526
+ const schemaRegistry = new SchemaRegistry(schemaRegistryArgs, {
527
+ forSchemaOptions: { typeHook },
528
+ })
529
+
530
+ await schemaRegistry.register(TestSchemas.EnumSchema, {
531
+ subject: 'Avro:EnumSchema',
532
+ })
533
+
534
+ const latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:EnumSchema' }))
535
+ TestSchemas.EnumWithReferencesSchema.references[0].version = latest.version
536
+ const registeredSchema = await schemaRegistry.register(
537
+ TestSchemas.EnumWithReferencesSchema,
538
+ {
539
+ subject: 'Avro:EnumWithReferences',
540
+ },
541
+ )
542
+ ;({ schema } = await schemaRegistry['_getSchema'](registeredSchema.id))
543
+ })
544
+
545
+ it('should be able to encode/decode enums schemas', async () => {
546
+ const obj = {
547
+ direction: Direction.UP,
548
+ attributes: { color: Color.BLUE },
549
+ }
550
+
551
+ const buffer = await schema.toBuffer(obj)
552
+ const resultObj = await schema.fromBuffer(buffer)
553
+
554
+ expect(resultObj).toEqual(obj)
555
+ })
556
+ })
557
+ })
558
+ })