sonamu 0.0.1

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 (60) hide show
  1. package/.pnp.cjs +15552 -0
  2. package/.pnp.loader.mjs +285 -0
  3. package/.vscode/extensions.json +6 -0
  4. package/.vscode/settings.json +9 -0
  5. package/.yarnrc.yml +5 -0
  6. package/dist/bin/cli.d.ts +2 -0
  7. package/dist/bin/cli.d.ts.map +1 -0
  8. package/dist/bin/cli.js +123 -0
  9. package/dist/bin/cli.js.map +1 -0
  10. package/dist/index.js +34 -0
  11. package/package.json +60 -0
  12. package/src/api/caster.ts +72 -0
  13. package/src/api/code-converters.ts +552 -0
  14. package/src/api/context.ts +20 -0
  15. package/src/api/decorators.ts +63 -0
  16. package/src/api/index.ts +5 -0
  17. package/src/api/init.ts +128 -0
  18. package/src/bin/cli.ts +115 -0
  19. package/src/database/base-model.ts +287 -0
  20. package/src/database/db.ts +95 -0
  21. package/src/database/knex-plugins/knex-on-duplicate-update.ts +41 -0
  22. package/src/database/upsert-builder.ts +231 -0
  23. package/src/exceptions/error-handler.ts +29 -0
  24. package/src/exceptions/so-exceptions.ts +91 -0
  25. package/src/index.ts +17 -0
  26. package/src/shared/web.shared.ts.txt +119 -0
  27. package/src/smd/migrator.ts +1462 -0
  28. package/src/smd/smd-manager.ts +141 -0
  29. package/src/smd/smd-utils.ts +266 -0
  30. package/src/smd/smd.ts +533 -0
  31. package/src/syncer/index.ts +1 -0
  32. package/src/syncer/syncer.ts +1283 -0
  33. package/src/templates/base-template.ts +19 -0
  34. package/src/templates/generated.template.ts +247 -0
  35. package/src/templates/generated_http.template.ts +114 -0
  36. package/src/templates/index.ts +1 -0
  37. package/src/templates/init_enums.template.ts +71 -0
  38. package/src/templates/init_generated.template.ts +44 -0
  39. package/src/templates/init_types.template.ts +38 -0
  40. package/src/templates/model.template.ts +168 -0
  41. package/src/templates/model_test.template.ts +39 -0
  42. package/src/templates/service.template.ts +263 -0
  43. package/src/templates/smd.template.ts +49 -0
  44. package/src/templates/view_enums_buttonset.template.ts +34 -0
  45. package/src/templates/view_enums_dropdown.template.ts +67 -0
  46. package/src/templates/view_enums_select.template.ts +60 -0
  47. package/src/templates/view_form.template.ts +397 -0
  48. package/src/templates/view_id_all_select.template.ts +34 -0
  49. package/src/templates/view_id_async_select.template.ts +113 -0
  50. package/src/templates/view_list.template.ts +652 -0
  51. package/src/templates/view_list_columns.template.ts +59 -0
  52. package/src/templates/view_search_input.template.ts +67 -0
  53. package/src/testing/fixture-manager.ts +271 -0
  54. package/src/types/types.ts +668 -0
  55. package/src/typings/knex.d.ts +24 -0
  56. package/src/utils/controller.ts +21 -0
  57. package/src/utils/lodash-able.ts +11 -0
  58. package/src/utils/model.ts +33 -0
  59. package/src/utils/utils.ts +28 -0
  60. package/tsconfig.json +47 -0
@@ -0,0 +1,552 @@
1
+ import { z, ZodRecord } from "zod";
2
+ import {
3
+ ApiParam,
4
+ ApiParamType,
5
+ isBelongsToOneRelationProp,
6
+ isBigIntegerProp,
7
+ isBooleanProp,
8
+ isDateProp,
9
+ isDateTimeProp,
10
+ isDecimalProp,
11
+ isDoubleProp,
12
+ isEnumProp,
13
+ isFloatProp,
14
+ isIntegerProp,
15
+ isJsonProp,
16
+ isOneToOneRelationProp,
17
+ isRelationProp,
18
+ isStringProp,
19
+ isTextProp,
20
+ isTimeProp,
21
+ isTimestampProp,
22
+ isUuidProp,
23
+ isVirtualProp,
24
+ SMDProp,
25
+ SMDPropNode,
26
+ TextProp,
27
+ } from "../types/types";
28
+ import { ExtendedApi } from "./decorators";
29
+
30
+ /*
31
+ ExtendedApi 에서 ZodObject 리턴
32
+ */
33
+ export function getZodObjectFromApi(
34
+ api: ExtendedApi,
35
+ references: {
36
+ [id: string]: z.ZodObject<any>;
37
+ } = {}
38
+ ) {
39
+ if (api.typeParameters?.length > 0) {
40
+ api.typeParameters.map((typeParam) => {
41
+ if (typeParam.constraint) {
42
+ let zodType = getZodTypeFromApiParamType(
43
+ typeParam.constraint,
44
+ references
45
+ );
46
+ (references[typeParam.id] as any) = zodType;
47
+ }
48
+ });
49
+ }
50
+
51
+ const ReqType = getZodObjectFromApiParams(
52
+ api.parameters.filter((param) => !ApiParamType.isContext(param.type)),
53
+ references
54
+ );
55
+ return ReqType;
56
+ }
57
+
58
+ /*
59
+ ZodObject를 통해 ApiParam 리턴
60
+ */
61
+ export function getZodObjectFromApiParams(
62
+ apiParams: ApiParam[],
63
+ references: {
64
+ [id: string]: z.ZodObject<any>;
65
+ } = {}
66
+ ): z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}> {
67
+ return z.object(
68
+ apiParams.reduce((r, param) => {
69
+ let zodType = getZodTypeFromApiParamType(param.type, references);
70
+ if (param.optional) {
71
+ zodType = zodType.optional();
72
+ }
73
+ return {
74
+ ...r,
75
+ [param.name]: zodType,
76
+ };
77
+ }, {})
78
+ );
79
+ }
80
+
81
+ /*
82
+ ApiParamType으로 ZodType 컨버팅
83
+ */
84
+ export function getZodTypeFromApiParamType(
85
+ paramType: ApiParamType,
86
+ references: {
87
+ [id: string]: z.ZodObject<any>;
88
+ }
89
+ ): z.ZodType<unknown> {
90
+ switch (paramType) {
91
+ case "string":
92
+ return z.string();
93
+ case "number":
94
+ return z.number();
95
+ case "boolean":
96
+ return z.boolean();
97
+ default:
98
+ const advType = paramType as { t: string };
99
+ switch (advType.t) {
100
+ case "string-literal":
101
+ case "numeric-literal":
102
+ return z.literal((advType as any).value);
103
+ case "object":
104
+ const objType = paramType as { t: string; props: ApiParam[] };
105
+ return getZodObjectFromApiParams(objType.props);
106
+ case "array":
107
+ const arrType = paramType as {
108
+ t: string;
109
+ elementsType: ApiParamType;
110
+ };
111
+ return z.array(
112
+ getZodTypeFromApiParamType(arrType.elementsType, references)
113
+ );
114
+ case "ref":
115
+ const refType = paramType as {
116
+ t: string;
117
+ id: string;
118
+ args?: ApiParamType[];
119
+ };
120
+
121
+ // 객체 키 관리 유틸리티
122
+ if (["Pick", "Omit"].includes(refType.id)) {
123
+ if (refType.args?.length !== 2) {
124
+ throw new Error(`잘못된 ${refType.id}`);
125
+ }
126
+ const [obj, literalOrUnion] = refType.args!.map((arg) =>
127
+ getZodTypeFromApiParamType(arg, references)
128
+ ) as [z.ZodObject<any>, z.ZodUnion<any> | z.ZodLiteral<string>];
129
+ let keys: string[] = [];
130
+ if (literalOrUnion instanceof z.ZodUnion) {
131
+ keys = literalOrUnion._def.options.map(
132
+ (option: { _def: { value: string } }) => option._def.value
133
+ );
134
+ } else {
135
+ keys = [(literalOrUnion as z.ZodLiteral<string>)._def.value];
136
+ }
137
+ const keyRecord = keys.reduce((result, key) => {
138
+ return {
139
+ ...result,
140
+ [key]: true,
141
+ };
142
+ }, {} as any);
143
+
144
+ if (refType.id === "Pick") {
145
+ if (obj.pick) {
146
+ return obj.pick(keyRecord);
147
+ }
148
+ } else {
149
+ if (obj.omit) {
150
+ return obj.omit(keyRecord);
151
+ }
152
+ }
153
+ }
154
+ if (["Partial"].includes(refType.id)) {
155
+ if (refType.args?.length !== 1) {
156
+ throw new Error(`잘못된 ${refType.id}`);
157
+ }
158
+ const obj = getZodTypeFromApiParamType(refType.args[0], references);
159
+ return (obj as any).partial();
160
+ }
161
+
162
+ const reference = references[refType.id];
163
+ if (reference === undefined) {
164
+ return z.string();
165
+ // throw new Error(`ref 참조 불가 ${refType.id}`);
166
+ }
167
+ return reference;
168
+ case "union":
169
+ const unionType = paramType as {
170
+ t: string;
171
+ types: ApiParamType[];
172
+ };
173
+ return z.union(
174
+ unionType.types.map((type) =>
175
+ getZodTypeFromApiParamType(type, references)
176
+ ) as any
177
+ );
178
+ case "intersection":
179
+ const intersectionType = paramType as {
180
+ t: string;
181
+ types: ApiParamType[];
182
+ };
183
+ return intersectionType.types.reduce((result, type, index) => {
184
+ const resolvedType = getZodTypeFromApiParamType(type, references);
185
+ if (index === 0) {
186
+ return resolvedType;
187
+ } else {
188
+ return z.intersection(result as any, resolvedType);
189
+ }
190
+ }, z.unknown() as any) as any;
191
+ case "tuple-type":
192
+ const tupleType = paramType as ApiParamType.TupleType;
193
+ return z.tuple(
194
+ tupleType.elements.map((elem) =>
195
+ getZodTypeFromApiParamType(elem, references)
196
+ ) as any
197
+ );
198
+ }
199
+ return z.unknown();
200
+ }
201
+ }
202
+
203
+ export function propNodeToZodTypeDef(
204
+ propNode: SMDPropNode,
205
+ injectImportKeys: string[]
206
+ ): string {
207
+ if (propNode.nodeType === "plain") {
208
+ return propToZodTypeDef(propNode.prop, injectImportKeys);
209
+ } else if (propNode.nodeType === "array") {
210
+ return [
211
+ propNode.prop ? `${propNode.prop.name}: ` : "",
212
+ "z.array(z.object({",
213
+ propNode.children
214
+ .map((childPropNode) =>
215
+ propNodeToZodTypeDef(childPropNode, injectImportKeys)
216
+ )
217
+ .join("\n"),
218
+ "",
219
+ "})),",
220
+ ].join("\n");
221
+ } else if (propNode.nodeType === "object") {
222
+ return [
223
+ propNode.prop ? `${propNode.prop.name}: ` : "",
224
+ "z.object({",
225
+ propNode.children
226
+ .map((childPropNode) =>
227
+ propNodeToZodTypeDef(childPropNode, injectImportKeys)
228
+ )
229
+ .join("\n"),
230
+ "",
231
+ "}),",
232
+ ].join("\n");
233
+ } else {
234
+ throw Error;
235
+ }
236
+ }
237
+
238
+ export function getTextTypeLength(textType: TextProp["textType"]): number {
239
+ switch (textType) {
240
+ case "text":
241
+ return 1024 * 64 - 1;
242
+ case "mediumtext":
243
+ return 1024 * 1024 * 16 - 1;
244
+ case "longtext":
245
+ return 1024 * 1024 * 1024 * 4 - 1;
246
+ }
247
+ }
248
+
249
+ export function propToZodTypeDef(
250
+ prop: SMDProp,
251
+ injectImportKeys: string[]
252
+ ): string {
253
+ let stmt: string;
254
+ if (isIntegerProp(prop)) {
255
+ stmt = `${prop.name}: z.number().int()`;
256
+ } else if (isBigIntegerProp(prop)) {
257
+ stmt = `${prop.name}: z.bigint()`;
258
+ } else if (isTextProp(prop)) {
259
+ stmt = `${prop.name}: z.string().max(${getTextTypeLength(prop.textType)})`;
260
+ } else if (isEnumProp(prop)) {
261
+ stmt = `${prop.name}: ${prop.id}`;
262
+ injectImportKeys.push(prop.id);
263
+ } else if (isStringProp(prop)) {
264
+ stmt = `${prop.name}: z.string().max(${prop.length})`;
265
+ } else if (isFloatProp(prop) || isDoubleProp(prop) || isDecimalProp(prop)) {
266
+ stmt = `${prop.name}: z.number()`;
267
+ } else if (isBooleanProp(prop)) {
268
+ stmt = `${prop.name}: z.boolean()`;
269
+ } else if (isDateProp(prop)) {
270
+ stmt = `${prop.name}: z.string().length(10)`;
271
+ } else if (isTimeProp(prop)) {
272
+ stmt = `${prop.name}: z.string().length(8)`;
273
+ } else if (isDateTimeProp(prop)) {
274
+ stmt = `${prop.name}: SQLDateTimeString`;
275
+ } else if (isTimestampProp(prop)) {
276
+ stmt = `${prop.name}: SQLDateTimeString`;
277
+ } else if (isJsonProp(prop)) {
278
+ if (prop.as instanceof z.ZodType) {
279
+ stmt = `${prop.name}: ${zodTypeToZodCode(prop.as)}`;
280
+ } else {
281
+ stmt = `${prop.name}: ${prop.as.ref}`;
282
+ injectImportKeys.push(prop.as.ref);
283
+ }
284
+ } else if (isUuidProp(prop)) {
285
+ stmt = `${prop.name}: z.string().uuid()`;
286
+ } else if (isVirtualProp(prop)) {
287
+ if (prop.as instanceof z.ZodType) {
288
+ stmt = `${prop.name}: ${zodTypeToZodCode(prop.as)}`;
289
+ } else {
290
+ stmt = `${prop.name}: ${prop.as.ref}`;
291
+ injectImportKeys.push(prop.as.ref);
292
+ }
293
+ } else if (isRelationProp(prop)) {
294
+ if (
295
+ isBelongsToOneRelationProp(prop) ||
296
+ (isOneToOneRelationProp(prop) && prop.hasJoinColumn)
297
+ ) {
298
+ stmt = `${prop.name}_id: z.number().int()`;
299
+ } else {
300
+ // 그외 relation 케이스 제외
301
+ return `// ${prop.name}: ${prop.relationType} ${prop.with}`;
302
+ }
303
+ } else {
304
+ return "// unable to resolve";
305
+ }
306
+
307
+ if ((prop as { unsigned?: boolean }).unsigned) {
308
+ stmt += ".nonnegative()";
309
+ }
310
+ if (prop.nullable) {
311
+ stmt += ".nullable()";
312
+ }
313
+
314
+ return stmt + ",";
315
+ }
316
+
317
+ export function zodTypeToZodCode(
318
+ zt: z.ZodFirstPartySchemaTypes | z.ZodObject<any>
319
+ ): string {
320
+ switch (zt._def.typeName) {
321
+ case "ZodString":
322
+ return "z.string()";
323
+ case "ZodNumber":
324
+ return "z.number()";
325
+ case "ZodBoolean":
326
+ return "z.boolean()";
327
+ case "ZodBigInt":
328
+ return "z.bigint()";
329
+ case "ZodDate":
330
+ return "z.date()";
331
+ case "ZodNull":
332
+ return "z.null()";
333
+ case "ZodUndefined":
334
+ return "z.undefined()";
335
+ case "ZodAny":
336
+ return "z.any()";
337
+ case "ZodUnknown":
338
+ return "z.unknown()";
339
+ case "ZodNever":
340
+ return "z.never()";
341
+ case "ZodNullable":
342
+ return zodTypeToZodCode(zt._def.innerType) + ".nullable()";
343
+ case "ZodDefault":
344
+ return (
345
+ zodTypeToZodCode(zt._def.innerType) +
346
+ `.default(${zt._def.defaultValue()})`
347
+ );
348
+ case "ZodRecord":
349
+ return `z.record(${zodTypeToZodCode(zt._def.keyType)}, ${zodTypeToZodCode(
350
+ zt._def.valueType
351
+ )})`;
352
+ case "ZodLiteral":
353
+ if (typeof zt._def.value === "string") {
354
+ return `z.literal("${zt._def.value}")`;
355
+ } else {
356
+ return `z.literal(${zt._def.value})`;
357
+ }
358
+ case "ZodUnion":
359
+ return `z.union([${zt._def.options
360
+ .map((option: z.ZodTypeAny) => zodTypeToZodCode(option))
361
+ .join(",")}])`;
362
+ case "ZodEnum":
363
+ return `z.enum([${zt._def.values
364
+ .map((val: string) => `"${val}"`)
365
+ .join(", ")}])`;
366
+ case "ZodArray":
367
+ return `z.array(${zodTypeToZodCode(zt._def.type)})`;
368
+ case "ZodObject":
369
+ const shape = (zt as any).shape;
370
+ return [
371
+ "z.object({",
372
+ ...Object.keys(shape).map(
373
+ (key) => `${key}: ${zodTypeToZodCode(shape[key])},`
374
+ ),
375
+ "})",
376
+ ].join("\n");
377
+ case "ZodOptional":
378
+ return zodTypeToZodCode(zt._def.innerType) + ".optional()";
379
+ default:
380
+ throw new Error(`처리되지 않은 ZodType ${zt._def.typeName}`);
381
+ }
382
+ }
383
+
384
+ export function apiParamToTsCode(
385
+ params: ApiParam[],
386
+ injectImportKeys: string[]
387
+ ): string {
388
+ return params
389
+ .map((param) => {
390
+ return `${param.name}${
391
+ param.optional && !param.defaultDef ? "?" : ""
392
+ }: ${apiParamTypeToTsType(param.type, injectImportKeys)}${
393
+ param.defaultDef ? `= ${param.defaultDef}` : ""
394
+ }`;
395
+ })
396
+ .join(", ");
397
+ }
398
+
399
+ export function apiParamTypeToTsType(
400
+ paramType: ApiParamType,
401
+ injectImportKeys: string[]
402
+ ): string {
403
+ if (
404
+ [
405
+ "string",
406
+ "number",
407
+ "boolean",
408
+ "true",
409
+ "false",
410
+ "null",
411
+ "undefined",
412
+ "void",
413
+ "any",
414
+ "unknown",
415
+ ].includes(paramType as string)
416
+ ) {
417
+ return paramType as string;
418
+ } else if (ApiParamType.isObject(paramType)) {
419
+ return `{ ${apiParamToTsCode(paramType.props, injectImportKeys)} }`;
420
+ } else if (ApiParamType.isStringLiteral(paramType)) {
421
+ return `"${paramType.value}"`;
422
+ } else if (ApiParamType.isNumericLiteral(paramType)) {
423
+ return String(paramType.value);
424
+ } else if (ApiParamType.isUnion(paramType)) {
425
+ return paramType.types
426
+ .map((type) => apiParamTypeToTsType(type, injectImportKeys))
427
+ .join(" | ");
428
+ } else if (ApiParamType.isIntersection(paramType)) {
429
+ return paramType.types
430
+ .map((type) => apiParamTypeToTsType(type, injectImportKeys))
431
+ .join(" & ");
432
+ } else if (ApiParamType.isArray(paramType)) {
433
+ return (
434
+ apiParamTypeToTsType(paramType.elementsType, injectImportKeys) + "[]"
435
+ );
436
+ } else if (ApiParamType.isRef(paramType)) {
437
+ if (
438
+ ["Pick", "Omit", "Promise", "Partial"].includes(paramType.id) === false
439
+ ) {
440
+ // importKeys 인젝션
441
+ injectImportKeys.push(paramType.id);
442
+ }
443
+ if (paramType.args === undefined || paramType.args.length === 0) {
444
+ return paramType.id;
445
+ } else {
446
+ return `${paramType.id}<${paramType.args
447
+ .map((arg) => apiParamTypeToTsType(arg, injectImportKeys))
448
+ .join(",")}>`;
449
+ }
450
+ } else if (ApiParamType.isIndexedAccess(paramType)) {
451
+ return `${apiParamTypeToTsType(
452
+ paramType.object,
453
+ injectImportKeys
454
+ )}[${apiParamTypeToTsType(paramType.index, injectImportKeys)}]`;
455
+ } else if (ApiParamType.isTupleType(paramType)) {
456
+ return `[ ${paramType.elements.map((elem) =>
457
+ apiParamTypeToTsType(elem, injectImportKeys)
458
+ )} ]`;
459
+ } else if (ApiParamType.isTypeParam(paramType)) {
460
+ return `<${paramType.id}${
461
+ paramType.constraint
462
+ ? ` extends ${apiParamTypeToTsType(
463
+ paramType.constraint,
464
+ injectImportKeys
465
+ )}`
466
+ : ""
467
+ }>`;
468
+ } else {
469
+ throw new Error(`resolve 불가 ApiParamType ${paramType}`);
470
+ }
471
+ }
472
+
473
+ export function unwrapPromiseOnce(paramType: ApiParamType) {
474
+ if (ApiParamType.isPromise(paramType)) {
475
+ return paramType.args![0];
476
+ } else {
477
+ return paramType;
478
+ }
479
+ }
480
+
481
+ export function serializeZodType(zt: z.ZodTypeAny): any {
482
+ switch (zt._def.typeName) {
483
+ case "ZodObject":
484
+ return {
485
+ type: "object",
486
+ shape: Object.keys((zt as z.ZodObject<any>).shape).reduce(
487
+ (result, key) => {
488
+ return {
489
+ ...result,
490
+ [key]: serializeZodType((zt as z.ZodObject<any>).shape[key]),
491
+ };
492
+ },
493
+ {}
494
+ ),
495
+ };
496
+ case "ZodArray":
497
+ return {
498
+ type: "array",
499
+ element: serializeZodType(zt._def.type),
500
+ };
501
+ case "ZodEnum":
502
+ return {
503
+ type: "enum",
504
+ values: zt._def.values,
505
+ };
506
+ case "ZodString":
507
+ return {
508
+ type: "string",
509
+ checks: zt._def.checks,
510
+ };
511
+ case "ZodNumber":
512
+ return {
513
+ type: "number",
514
+ checks: zt._def.checks,
515
+ };
516
+ case "ZodBoolean":
517
+ return {
518
+ type: "boolean",
519
+ };
520
+ case "ZodNullable":
521
+ return {
522
+ ...serializeZodType(zt._def.innerType),
523
+ nullable: true,
524
+ };
525
+ case "ZodOptional":
526
+ return {
527
+ ...serializeZodType(zt._def.innerType),
528
+ optional: true,
529
+ };
530
+ case "ZodAny":
531
+ return {
532
+ type: "any",
533
+ };
534
+ case "ZodRecord":
535
+ return {
536
+ type: "record",
537
+ keyType: serializeZodType((zt as ZodRecord)._def.keyType),
538
+ valueType: serializeZodType((zt as ZodRecord)._def.valueType),
539
+ };
540
+ case "ZodUnion":
541
+ return {
542
+ type: "union",
543
+ options: (zt._def as z.ZodUnionDef).options.map((option) =>
544
+ serializeZodType(option)
545
+ ),
546
+ };
547
+ default:
548
+ throw new Error(
549
+ `Serialize 로직이 정의되지 않은 ZodType: ${zt._def.typeName}`
550
+ );
551
+ }
552
+ }
@@ -0,0 +1,20 @@
1
+ import { FastifyReply } from "fastify";
2
+ import { RouteGenericInterface } from "fastify/types/route";
3
+ import {
4
+ Server,
5
+ IncomingMessage,
6
+ ServerResponse,
7
+ IncomingHttpHeaders,
8
+ } from "http";
9
+
10
+ export interface ContextExtend {}
11
+ export type Context = {
12
+ reply: FastifyReply<
13
+ Server,
14
+ IncomingMessage,
15
+ ServerResponse,
16
+ RouteGenericInterface,
17
+ unknown
18
+ >;
19
+ headers: IncomingHttpHeaders;
20
+ } & ContextExtend;
@@ -0,0 +1,63 @@
1
+ import { HTTPMethods } from "fastify";
2
+ import { camelize } from "inflection";
3
+ import { ApiParam, ApiParamType } from "../types/types";
4
+
5
+ export type ServiceClient =
6
+ | "axios"
7
+ | "axios-multipart"
8
+ | "swr"
9
+ | "socketio"
10
+ | "window-fetch";
11
+ export type ApiDecoratorOptions = {
12
+ httpMethod?: HTTPMethods;
13
+ contentType?:
14
+ | "text/plain"
15
+ | "text/html"
16
+ | "text/xml"
17
+ | "application/json"
18
+ | "application/octet-stream";
19
+ clients?: ServiceClient[];
20
+ path?: string;
21
+ resourceName?: string;
22
+ };
23
+ export const registeredApis: {
24
+ modelName: string;
25
+ methodName: string;
26
+ path: string;
27
+ options: ApiDecoratorOptions;
28
+ }[] = [];
29
+ export type ExtendedApi = {
30
+ modelName: string;
31
+ methodName: string;
32
+ path: string;
33
+ options: ApiDecoratorOptions;
34
+ typeParameters: ApiParamType.TypeParam[];
35
+ parameters: ApiParam[];
36
+ returnType: ApiParamType;
37
+ };
38
+
39
+ export function api(options: ApiDecoratorOptions = {}) {
40
+ options = {
41
+ httpMethod: "GET",
42
+ contentType: "application/json",
43
+ clients: ["axios"],
44
+ ...options,
45
+ };
46
+
47
+ return function (target: Object, propertyKey: string) {
48
+ const modelName = target.constructor.name.match(/(.+)Class/)![1];
49
+ const methodName = propertyKey;
50
+ const defaultPath = `/${camelize(
51
+ modelName.replace("Model", ""),
52
+ true
53
+ )}/${camelize(propertyKey, true)}`;
54
+
55
+ const api = {
56
+ modelName,
57
+ methodName,
58
+ path: options.path ?? defaultPath,
59
+ options,
60
+ };
61
+ registeredApis.push(api);
62
+ };
63
+ }
@@ -0,0 +1,5 @@
1
+ export * from "./caster";
2
+ export * from "./code-converters";
3
+ export * from "./context";
4
+ export * from "./decorators";
5
+ export * from "./init";