@@ -61,7 +61,391 @@ yarn add @flex-development/decorator-regex@flex-development/decorator-regex
61
61
62
62
## Use
63
63
64
- ** TODO** : usage example.
64
+ Suppose we have the following module:
65
+
66
+ ``` typescript
67
+ import { DECORATOR_REGEX } from ' @flex-development/decorator-regex'
68
+ import { omit } from ' radash'
69
+ import { dedent } from ' ts-dedent'
70
+
71
+ const code: string = dedent `
72
+ /**
73
+ * [Data access object][1] for the {@linkcode DatabaseTable.USERS} table.
74
+ *
75
+ * [1]: https://en.wikipedia.org/wiki/Data_access_object
76
+ *
77
+ * @extends {Entity<IUserRaw,CreateUserDTO,IUser>}
78
+ * @implements {IUser}
79
+ */
80
+ @Table<User>({
81
+ defaultScope: {
82
+ attributes: ['created_at', 'email', 'id', 'provider'],
83
+ order: [['id', OrderDirection.ASC]],
84
+ raw: false
85
+ },
86
+ deletedAt: false,
87
+ hooks: {
88
+ /**
89
+ * Normalizes data before a user is persisted to the database.
90
+ *
91
+ * This includes:
92
+ *
93
+ * - Trimming and lowercasing string fields
94
+ *
95
+ * @param {User} instance - Current user instance
96
+ * @return {void} Nothing when complete
97
+ */
98
+ beforeSave(instance: User): void {
99
+ trimmedLowercasedFields(instance.dataValues)
100
+ }
101
+ },
102
+ omitNull: false,
103
+ paranoid: false,
104
+ tableName: DatabaseTable.USERS,
105
+ timestamps: true
106
+ })
107
+ class User
108
+ extends Entity<IUserRaw, CreateUserDTO, IUser> implements IUser {
109
+ @ApiProperty({ description: 'When user was created', type: Number })
110
+ @Column({
111
+ allowNull: false,
112
+ defaultValue: User.CURRENT_TIMESTAMP,
113
+ type: DataType.BIGINT,
114
+ validate: { isUnixTimestamp: User.isUnixTimestamp }
115
+ })
116
+ declare created_at: IUser['created_at']
117
+
118
+ @ApiProperty({
119
+ description: 'Email address',
120
+ maxLength: 254,
121
+ minLength: 3,
122
+ type: String
123
+ })
124
+ @Column({
125
+ allowNull: false,
126
+ type: DataType.STRING(254),
127
+ unique: true,
128
+ validate: { isEmail: true, len: [3, 254] }
129
+ })
130
+ declare email: IUser['email']
131
+
132
+ @ApiProperty({ description: 'Unique identifier', type: Number })
133
+ @Column({
134
+ allowNull: false,
135
+ autoIncrementIdentity: true,
136
+ defaultValue: Sequelize.fn('nextval', DatabaseSequence.USERS),
137
+ primaryKey: true,
138
+ type: 'NUMERIC',
139
+ unique: true,
140
+ validate: { notNull: true }
141
+ })
142
+ declare id: IUser['id']
143
+
144
+ @ApiProperty({
145
+ description: 'Authentication provider',
146
+ enum: OAuthProvider,
147
+ enumName: 'OAuthProvider',
148
+ nullable: true
149
+ })
150
+ @Column({
151
+ allowNull: true,
152
+ defaultValue: null,
153
+ type: DataType.ENUM(...User.AUTH_PROVIDERS)
154
+ })
155
+ declare provider: IUser['provider']
156
+
157
+ @HasMany(() => Token)
158
+ declare tokens: Token[]
159
+ }
160
+ `
161
+
162
+ const print = (matches : IterableIterator <RegExpMatchArray >): void => {
163
+ console .debug ([... matches ].map (match => omit (match , [' input' ])))
164
+ }
165
+
166
+ print (code .matchAll (DECORATOR_REGEX ))
167
+ ```
168
+
169
+ ...running that yields:
170
+
171
+ ``` sh
172
+ [
173
+ {
174
+ ' 0' : ' @Table<User>({\n' +
175
+ ' defaultScope: {\n' +
176
+ " attributes: ['created_at', 'email', 'id', 'provider'],\n" +
177
+ " order: [['id', OrderDirection.ASC]],\n" +
178
+ ' raw: false\n' +
179
+ ' },\n' +
180
+ ' deletedAt: false,\n' +
181
+ ' hooks: {\n' +
182
+ ' /**\n' +
183
+ ' * Normalizes data before a user is persisted to the database.\n' +
184
+ ' *\n' +
185
+ ' * This includes:\n' +
186
+ ' *\n' +
187
+ ' * - Trimming and lowercasing string fields\n' +
188
+ ' *\n' +
189
+ ' * @param {User} instance - Current user instance\n' +
190
+ ' * @return {void} Nothing when complete\n' +
191
+ ' */\n' +
192
+ ' beforeSave(instance: User): void {\n' +
193
+ ' trimmedLowercasedFields(instance.dataValues)\n' +
194
+ ' }\n' +
195
+ ' },\n' +
196
+ ' omitNull: false,\n' +
197
+ ' paranoid: false,\n' +
198
+ ' tableName: DatabaseTable.USERS,\n' +
199
+ ' timestamps: true\n' +
200
+ ' })' ,
201
+ ' 1' : ' Table' ,
202
+ ' 2' : ' ({\n' +
203
+ ' defaultScope: {\n' +
204
+ " attributes: ['created_at', 'email', 'id', 'provider'],\n" +
205
+ " order: [['id', OrderDirection.ASC]],\n" +
206
+ ' raw: false\n' +
207
+ ' },\n' +
208
+ ' deletedAt: false,\n' +
209
+ ' hooks: {\n' +
210
+ ' /**\n' +
211
+ ' * Normalizes data before a user is persisted to the database.\n' +
212
+ ' *\n' +
213
+ ' * This includes:\n' +
214
+ ' *\n' +
215
+ ' * - Trimming and lowercasing string fields\n' +
216
+ ' *\n' +
217
+ ' * @param {User} instance - Current user instance\n' +
218
+ ' * @return {void} Nothing when complete\n' +
219
+ ' */\n' +
220
+ ' beforeSave(instance: User): void {\n' +
221
+ ' trimmedLowercasedFields(instance.dataValues)\n' +
222
+ ' }\n' +
223
+ ' },\n' +
224
+ ' omitNull: false,\n' +
225
+ ' paranoid: false,\n' +
226
+ ' tableName: DatabaseTable.USERS,\n' +
227
+ ' timestamps: true\n' +
228
+ ' })' ,
229
+ index: 227,
230
+ groups: [Object: null prototype] {
231
+ identifier: ' Table' ,
232
+ parameters: ' ({\n' +
233
+ ' defaultScope: {\n' +
234
+ " attributes: ['created_at', 'email', 'id', 'provider'],\n" +
235
+ " order: [['id', OrderDirection.ASC]],\n" +
236
+ ' raw: false\n' +
237
+ ' },\n' +
238
+ ' deletedAt: false,\n' +
239
+ ' hooks: {\n' +
240
+ ' /**\n' +
241
+ ' * Normalizes data before a user is persisted to the database.\n' +
242
+ ' *\n' +
243
+ ' * This includes:\n' +
244
+ ' *\n' +
245
+ ' * - Trimming and lowercasing string fields\n' +
246
+ ' *\n' +
247
+ ' * @param {User} instance - Current user instance\n' +
248
+ ' * @return {void} Nothing when complete\n' +
249
+ ' */\n' +
250
+ ' beforeSave(instance: User): void {\n' +
251
+ ' trimmedLowercasedFields(instance.dataValues)\n' +
252
+ ' }\n' +
253
+ ' },\n' +
254
+ ' omitNull: false,\n' +
255
+ ' paranoid: false,\n' +
256
+ ' tableName: DatabaseTable.USERS,\n' +
257
+ ' timestamps: true\n' +
258
+ ' })'
259
+ }
260
+ },
261
+ {
262
+ ' 0' : " @ApiProperty({ description: 'When user was created', type: Number })" ,
263
+ ' 1' : ' ApiProperty' ,
264
+ ' 2' : " ({ description: 'When user was created', type: Number })" ,
265
+ index: 994,
266
+ groups: [Object: null prototype] {
267
+ identifier: ' ApiProperty' ,
268
+ parameters: " ({ description: 'When user was created', type: Number })"
269
+ }
270
+ },
271
+ {
272
+ ' 0' : ' @Column({\n' +
273
+ ' allowNull: false,\n' +
274
+ ' defaultValue: User.CURRENT_TIMESTAMP,\n' +
275
+ ' type: DataType.BIGINT,\n' +
276
+ ' validate: { isUnixTimestamp: User.isUnixTimestamp }\n' +
277
+ ' })' ,
278
+ ' 1' : ' Column' ,
279
+ ' 2' : ' ({\n' +
280
+ ' allowNull: false,\n' +
281
+ ' defaultValue: User.CURRENT_TIMESTAMP,\n' +
282
+ ' type: DataType.BIGINT,\n' +
283
+ ' validate: { isUnixTimestamp: User.isUnixTimestamp }\n' +
284
+ ' })' ,
285
+ index: 1068,
286
+ groups: [Object: null prototype] {
287
+ identifier: ' Column' ,
288
+ parameters: ' ({\n' +
289
+ ' allowNull: false,\n' +
290
+ ' defaultValue: User.CURRENT_TIMESTAMP,\n' +
291
+ ' type: DataType.BIGINT,\n' +
292
+ ' validate: { isUnixTimestamp: User.isUnixTimestamp }\n' +
293
+ ' })'
294
+ }
295
+ },
296
+ {
297
+ ' 0' : ' @ApiProperty({\n' +
298
+ " description: 'Email address',\n" +
299
+ ' maxLength: 254,\n' +
300
+ ' minLength: 3,\n' +
301
+ ' type: String\n' +
302
+ ' })' ,
303
+ ' 1' : ' ApiProperty' ,
304
+ ' 2' : ' ({\n' +
305
+ " description: 'Email address',\n" +
306
+ ' maxLength: 254,\n' +
307
+ ' minLength: 3,\n' +
308
+ ' type: String\n' +
309
+ ' })' ,
310
+ index: 1296,
311
+ groups: [Object: null prototype] {
312
+ identifier: ' ApiProperty' ,
313
+ parameters: ' ({\n' +
314
+ " description: 'Email address',\n" +
315
+ ' maxLength: 254,\n' +
316
+ ' minLength: 3,\n' +
317
+ ' type: String\n' +
318
+ ' })'
319
+ }
320
+ },
321
+ {
322
+ ' 0' : ' @Column({\n' +
323
+ ' allowNull: false,\n' +
324
+ ' type: DataType.STRING(254),\n' +
325
+ ' unique: true,\n' +
326
+ ' validate: { isEmail: true, len: [3, 254] }\n' +
327
+ ' })' ,
328
+ ' 1' : ' Column' ,
329
+ ' 2' : ' ({\n' +
330
+ ' allowNull: false,\n' +
331
+ ' type: DataType.STRING(254),\n' +
332
+ ' unique: true,\n' +
333
+ ' validate: { isEmail: true, len: [3, 254] }\n' +
334
+ ' })' ,
335
+ index: 1425,
336
+ groups: [Object: null prototype] {
337
+ identifier: ' Column' ,
338
+ parameters: ' ({\n' +
339
+ ' allowNull: false,\n' +
340
+ ' type: DataType.STRING(254),\n' +
341
+ ' unique: true,\n' +
342
+ ' validate: { isEmail: true, len: [3, 254] }\n' +
343
+ ' })'
344
+ }
345
+ },
346
+ {
347
+ ' 0' : " @ApiProperty({ description: 'Unique identifier', type: Number })" ,
348
+ ' 1' : ' ApiProperty' ,
349
+ ' 2' : " ({ description: 'Unique identifier', type: Number })" ,
350
+ index: 1615,
351
+ groups: [Object: null prototype] {
352
+ identifier: ' ApiProperty' ,
353
+ parameters: " ({ description: 'Unique identifier', type: Number })"
354
+ }
355
+ },
356
+ {
357
+ ' 0' : ' @Column({\n' +
358
+ ' allowNull: false,\n' +
359
+ ' autoIncrementIdentity: true,\n' +
360
+ " defaultValue: Sequelize.fn('nextval', DatabaseSequence.USERS),\n" +
361
+ ' primaryKey: true,\n' +
362
+ " type: 'NUMERIC',\n" +
363
+ ' unique: true,\n' +
364
+ ' validate: { notNull: true }\n' +
365
+ ' })' ,
366
+ ' 1' : ' Column' ,
367
+ ' 2' : ' ({\n' +
368
+ ' allowNull: false,\n' +
369
+ ' autoIncrementIdentity: true,\n' +
370
+ " defaultValue: Sequelize.fn('nextval', DatabaseSequence.USERS),\n" +
371
+ ' primaryKey: true,\n' +
372
+ " type: 'NUMERIC',\n" +
373
+ ' unique: true,\n' +
374
+ ' validate: { notNull: true }\n' +
375
+ ' })' ,
376
+ index: 1685,
377
+ groups: [Object: null prototype] {
378
+ identifier: ' Column' ,
379
+ parameters: ' ({\n' +
380
+ ' allowNull: false,\n' +
381
+ ' autoIncrementIdentity: true,\n' +
382
+ " defaultValue: Sequelize.fn('nextval', DatabaseSequence.USERS),\n" +
383
+ ' primaryKey: true,\n' +
384
+ " type: 'NUMERIC',\n" +
385
+ ' unique: true,\n' +
386
+ ' validate: { notNull: true }\n' +
387
+ ' })'
388
+ }
389
+ },
390
+ {
391
+ ' 0' : ' @ApiProperty({\n' +
392
+ " description: 'Authentication provider',\n" +
393
+ ' enum: OAuthProvider,\n' +
394
+ " enumName: 'OAuthProvider',\n" +
395
+ ' nullable: true\n' +
396
+ ' })' ,
397
+ ' 1' : ' ApiProperty' ,
398
+ ' 2' : ' ({\n' +
399
+ " description: 'Authentication provider',\n" +
400
+ ' enum: OAuthProvider,\n' +
401
+ " enumName: 'OAuthProvider',\n" +
402
+ ' nullable: true\n' +
403
+ ' })' ,
404
+ index: 1974,
405
+ groups: [Object: null prototype] {
406
+ identifier: ' ApiProperty' ,
407
+ parameters: ' ({\n' +
408
+ " description: 'Authentication provider',\n" +
409
+ ' enum: OAuthProvider,\n' +
410
+ " enumName: 'OAuthProvider',\n" +
411
+ ' nullable: true\n' +
412
+ ' })'
413
+ }
414
+ },
415
+ {
416
+ ' 0' : ' @Column({\n' +
417
+ ' allowNull: true,\n' +
418
+ ' defaultValue: null,\n' +
419
+ ' type: DataType.ENUM(...User.AUTH_PROVIDERS)\n' +
420
+ ' })' ,
421
+ ' 1' : ' Column' ,
422
+ ' 2' : ' ({\n' +
423
+ ' allowNull: true,\n' +
424
+ ' defaultValue: null,\n' +
425
+ ' type: DataType.ENUM(...User.AUTH_PROVIDERS)\n' +
426
+ ' })' ,
427
+ index: 2133,
428
+ groups: [Object: null prototype] {
429
+ identifier: ' Column' ,
430
+ parameters: ' ({\n' +
431
+ ' allowNull: true,\n' +
432
+ ' defaultValue: null,\n' +
433
+ ' type: DataType.ENUM(...User.AUTH_PROVIDERS)\n' +
434
+ ' })'
435
+ }
436
+ },
437
+ {
438
+ ' 0' : ' @HasMany(() => Token)' ,
439
+ ' 1' : ' HasMany' ,
440
+ ' 2' : ' (() => Token)' ,
441
+ index: 2300,
442
+ groups: [Object: null prototype] {
443
+ identifier: ' HasMany' ,
444
+ parameters: ' (() => Token)'
445
+ }
446
+ }
447
+ ]
448
+ ```
65
449
66
450
## API
67
451
0 commit comments