vona-module-a-openapi 5.0.32 → 5.0.34

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/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { registerMappedClassMetadataKey, appMetadata, appResource, cast, deepExtend, BeanInfo, BeanBase, LocaleModuleNameSeparator, HttpStatus, BeanSimple, BeanScopeBase, useApp, beanFullNameFromOnionName } from 'vona';
2
2
  import * as ModuleInfo from '@cabloy/module-info';
3
- import { isClass, isEmptyObject, isNil } from '@cabloy/utils';
3
+ import { isEmptyObject, isClass, isNil } from '@cabloy/utils';
4
4
  import { toUpperCaseFirstChar } from '@cabloy/word-utils';
5
5
  import { getInnerTypeName, coerceWithNil } from '@cabloy/zod-query';
6
6
  import { OpenApiGeneratorV3, OpenApiGeneratorV31, OpenAPIRegistry } from '@cabloy/zod-to-openapi';
@@ -54,8 +54,6 @@ function getTargetDecoratorRuleColumnsMap(target) {
54
54
  return map;
55
55
  }
56
56
  function mergeFieldsOpenapiMetadata(target) {
57
- // rules
58
- const rules = getTargetDecoratorRules(target.prototype);
59
57
  // beanOptions
60
58
  const beanOptions = appResource.getBean(target);
61
59
  const fields = cast(beanOptions?.options)?.fields;
@@ -63,21 +61,40 @@ function mergeFieldsOpenapiMetadata(target) {
63
61
  for (const key in fields) {
64
62
  const field = fields[key];
65
63
  if (!field) continue;
66
- const schemaCurrent = rules[key];
67
- const metadataCurrent = schemaCurrent ? ZodMetadata.getOpenapiMetadata(schemaCurrent) : undefined;
68
- if (Object.prototype.hasOwnProperty.call(field, 'parseAsync')) {
69
- const schema = field;
64
+ mergeFieldOpenapiMetadata(target.prototype, key, field);
65
+ }
66
+ }
67
+
68
+ // fieldRule maybe undefined
69
+ function mergeFieldOpenapiMetadata(target, prop, fieldRule) {
70
+ // rules
71
+ const rules = getTargetDecoratorRules(target);
72
+ // rule
73
+ const schemaCurrent = rules[prop];
74
+ const metadataCurrent = schemaCurrent ? ZodMetadata.getOpenapiMetadata(schemaCurrent) : undefined;
75
+ // merge
76
+ if (Object.prototype.hasOwnProperty.call(fieldRule, 'parseAsync')) {
77
+ const schema = fieldRule;
78
+ if (isEmptyObject(metadataCurrent)) {
79
+ rules[prop] = schema;
80
+ } else {
70
81
  const metadataCustom = ZodMetadata.getOpenapiMetadata(schema);
71
- rules[key] = schema.openapi(deepExtend({}, metadataCurrent, metadataCustom));
82
+ rules[prop] = schema.openapi(deepExtend({}, metadataCurrent, metadataCustom));
83
+ }
84
+ } else {
85
+ if (schemaCurrent) {
86
+ if (!isEmptyObject(fieldRule)) {
87
+ rules[prop] = schemaCurrent.openapi(deepExtend({}, metadataCurrent, fieldRule));
88
+ }
72
89
  } else {
73
- // use deepExtend for sure strict
74
- if (schemaCurrent) {
75
- rules[key] = schemaCurrent.openapi(deepExtend({}, metadataCurrent, field));
90
+ if (isEmptyObject(fieldRule)) {
91
+ rules[prop] = z.any();
76
92
  } else {
77
- rules[key] = z.any().openapi(deepExtend({}, field));
93
+ rules[prop] = z.any().openapi(fieldRule);
78
94
  }
79
95
  }
80
96
  }
97
+ return rules;
81
98
  }
82
99
  function prepareClassType(classType) {
83
100
  return isClass(classType) ? classType : cast(classType)();
@@ -269,11 +286,15 @@ let ServiceOpenapi = (_dec$2 = Service(), _dec2$2 = BeanInfo({
269
286
  _translateSchema(schema, generateJsonScene) {
270
287
  if (!schema) return;
271
288
  if (schema.type === 'object' && schema.required === undefined) schema.required = [];
289
+ // serializerTransforms
290
+ delete schema.serializerTransforms;
291
+ // schema
272
292
  this._translateStrings(schema, ['title', 'description']);
273
293
  if (generateJsonScene === 'api' && !schema.description && schema.title) {
274
294
  schema.description = schema.title;
275
295
  delete schema.title;
276
296
  }
297
+ // properties
277
298
  const properties = cast(schema).properties;
278
299
  if (properties && typeof properties === 'object') {
279
300
  for (const prop in properties) {
@@ -281,6 +302,11 @@ let ServiceOpenapi = (_dec$2 = Service(), _dec2$2 = BeanInfo({
281
302
  this._translateSchema(propObj, generateJsonScene);
282
303
  }
283
304
  }
305
+ // items
306
+ const items = cast(schema).items;
307
+ if (items && typeof items === 'object') {
308
+ this._translateSchema(items, generateJsonScene);
309
+ }
284
310
  }
285
311
  _translateStrings(obj, keys) {
286
312
  for (const key of keys) {
@@ -453,7 +479,7 @@ let ServiceOpenapi = (_dec$2 = Service(), _dec2$2 = BeanInfo({
453
479
  if (argumentType === 'body') {
454
480
  // body
455
481
  request.body = {
456
- required: !schema.isOptional(),
482
+ required: !schema.safeParse(undefined).success,
457
483
  content: {
458
484
  'application/json': {
459
485
  schema
@@ -592,10 +618,7 @@ function _patchGenerator(generator) {
592
618
  const gen = Object.getPrototypeOf(cast(generator).generator);
593
619
  gen.generateSchemaWithRef = function (zodSchema) {
594
620
  // schema ref
595
- const lazySchema = ZodMetadata.getLazySchema(zodSchema);
596
- if (lazySchema) {
597
- zodSchema = lazySchema();
598
- }
621
+ zodSchema = ZodMetadata.resolveLazySchema(zodSchema);
599
622
  const refId = ZodMetadata.getRefId(zodSchema);
600
623
  if (!refId) {
601
624
  return this.generateSimpleSchema(zodSchema);
@@ -626,108 +649,6 @@ let ScopeModuleAOpenapi = (_dec = Scope(), _dec2 = BeanInfo({
626
649
 
627
650
  /** scope: end */
628
651
 
629
- function Field(...schemaLikes) {
630
- return function (target, prop) {
631
- // rules
632
- const rules = getTargetDecoratorRules(target);
633
- // rule
634
- const metaType = appMetadata.getDesignType(target, prop);
635
- rules[prop] = makeSchemaLikes(schemaLikes, metaType);
636
- };
637
- }
638
-
639
- function httpCode(httpCode) {
640
- return function (target, prop, descriptor) {
641
- const options = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target, prop);
642
- options.httpCode = httpCode;
643
- return descriptor;
644
- };
645
- }
646
- function contentType(contentType) {
647
- return function (target, prop, descriptor) {
648
- const options = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target, prop);
649
- options.contentType = contentType;
650
- return descriptor;
651
- };
652
- }
653
- function body(...schemaLikes) {
654
- return function (target, prop, descriptor) {
655
- // schema
656
- const metaType = appMetadata.getDesignReturntype(target, prop);
657
- const schema = makeSchemaLikes(schemaLikes, metaType);
658
- // options
659
- const options = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target, prop);
660
- options.bodySchema = schema;
661
- return descriptor;
662
- };
663
- }
664
- function bodyCustom(bodySchemaWrapper, ...schemaLikes) {
665
- return function (target, prop, descriptor) {
666
- // schema
667
- const metaType = appMetadata.getDesignReturntype(target, prop);
668
- const schema = makeSchemaLikes(schemaLikes, metaType);
669
- // options
670
- const options = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target, prop);
671
- options.bodySchema = schema;
672
- options.bodySchemaWrapper = bodySchemaWrapper;
673
- return descriptor;
674
- };
675
- }
676
- function exclude() {
677
- return function (target, prop, descriptor) {
678
- const options = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target, prop);
679
- options.exclude = true;
680
- return descriptor;
681
- };
682
- }
683
- function tags(tags) {
684
- return function (target, prop, descriptor) {
685
- const options = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target, prop);
686
- options.tags = tags;
687
- return descriptor;
688
- };
689
- }
690
- function header(header) {
691
- return function (target, prop, descriptor) {
692
- const options = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target, prop);
693
- if (!options.headers) options.headers = [];
694
- options.headers.push(header);
695
- return descriptor;
696
- };
697
- }
698
- function headers(headers) {
699
- return function (target, prop, descriptor) {
700
- const options = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target, prop);
701
- if (!options.headers) options.headers = [];
702
- options.headers.push(...headers);
703
- return descriptor;
704
- };
705
- }
706
- function setHeader(field, val) {
707
- return function (target, prop, descriptor) {
708
- const options = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target, prop);
709
- if (!options.setHeaders) options.setHeaders = {};
710
- if (typeof field === 'string') {
711
- options.setHeaders[field] = val;
712
- } else {
713
- Object.assign(options.setHeaders, field);
714
- }
715
- return descriptor;
716
- };
717
- }
718
- const Api = {
719
- field: Field,
720
- httpCode,
721
- contentType,
722
- body,
723
- bodyCustom,
724
- exclude,
725
- tags,
726
- header,
727
- headers,
728
- setHeader
729
- };
730
-
731
652
  function schemaEmail(params) {
732
653
  return function (_schema) {
733
654
  return z.email(params);
@@ -826,6 +747,42 @@ function schemaCaptcha(options) {
826
747
  });
827
748
  };
828
749
  }
750
+ function schemaSerializerExclude() {
751
+ return function (schema) {
752
+ return schema.openapi({
753
+ exclude: true
754
+ });
755
+ };
756
+ }
757
+ function schemaSerializerTransform(serializerTransformName, options) {
758
+ return function (schema) {
759
+ return schema.openapi({
760
+ serializerTransforms: {
761
+ [serializerTransformName]: options
762
+ }
763
+ });
764
+ };
765
+ }
766
+ function schemaSerializerSensitive(options) {
767
+ return function (schema) {
768
+ return schema.openapi({
769
+ serializerTransforms: {
770
+ 'a-serialization:sensitive': options
771
+ }
772
+ });
773
+ };
774
+ }
775
+ function schemaSerializerGetter(getter) {
776
+ return function (schema) {
777
+ return schema.openapi({
778
+ serializerTransforms: {
779
+ 'a-serialization:getter': {
780
+ getter
781
+ }
782
+ }
783
+ });
784
+ };
785
+ }
829
786
 
830
787
  function schemaOpenapi(refId, metadata) {
831
788
  return function (schema) {
@@ -954,6 +911,10 @@ const v = {
954
911
  tableIdentity: schemaTableIdentity,
955
912
  bigNumber: schemaBigNumber,
956
913
  captcha: schemaCaptcha,
914
+ serializerExclude: schemaSerializerExclude,
915
+ serializerTransform: schemaSerializerTransform,
916
+ serializerSensitive: schemaSerializerSensitive,
917
+ serializerGetter: schemaSerializerGetter,
957
918
  // openapi
958
919
  openapi: schemaOpenapi,
959
920
  title: schemaTitle,
@@ -964,9 +925,112 @@ const v = {
964
925
  transform: schemaZodTransform
965
926
  };
966
927
 
928
+ function Field(...schemaLikes) {
929
+ return function (target, prop, descriptor) {
930
+ const metaType = appMetadata.getDesignType(target, prop);
931
+ const schema = makeSchemaLikes(schemaLikes, metaType);
932
+ const rules = mergeFieldOpenapiMetadata(target, prop, schema);
933
+ if (descriptor?.get) {
934
+ rules[prop] = v.serializerGetter(descriptor.get)(rules[prop]);
935
+ }
936
+ };
937
+ }
938
+
939
+ function httpCode(httpCode) {
940
+ return function (target, prop, descriptor) {
941
+ const options = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target, prop);
942
+ options.httpCode = httpCode;
943
+ return descriptor;
944
+ };
945
+ }
946
+ function contentType(contentType) {
947
+ return function (target, prop, descriptor) {
948
+ const options = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target, prop);
949
+ options.contentType = contentType;
950
+ return descriptor;
951
+ };
952
+ }
953
+ function body(...schemaLikes) {
954
+ return function (target, prop, descriptor) {
955
+ // schema
956
+ const metaType = appMetadata.getDesignReturntype(target, prop);
957
+ const schema = makeSchemaLikes(schemaLikes, metaType);
958
+ // options
959
+ const options = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target, prop);
960
+ options.bodySchema = schema;
961
+ return descriptor;
962
+ };
963
+ }
964
+ function bodyCustom(bodySchemaWrapper, ...schemaLikes) {
965
+ return function (target, prop, descriptor) {
966
+ // schema
967
+ const metaType = appMetadata.getDesignReturntype(target, prop);
968
+ const schema = makeSchemaLikes(schemaLikes, metaType);
969
+ // options
970
+ const options = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target, prop);
971
+ options.bodySchema = schema;
972
+ options.bodySchemaWrapper = bodySchemaWrapper;
973
+ return descriptor;
974
+ };
975
+ }
976
+ function exclude() {
977
+ return function (target, prop, descriptor) {
978
+ const options = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target, prop);
979
+ options.exclude = true;
980
+ return descriptor;
981
+ };
982
+ }
983
+ function tags(tags) {
984
+ return function (target, prop, descriptor) {
985
+ const options = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target, prop);
986
+ options.tags = tags;
987
+ return descriptor;
988
+ };
989
+ }
990
+ function header(header) {
991
+ return function (target, prop, descriptor) {
992
+ const options = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target, prop);
993
+ if (!options.headers) options.headers = [];
994
+ options.headers.push(header);
995
+ return descriptor;
996
+ };
997
+ }
998
+ function headers(headers) {
999
+ return function (target, prop, descriptor) {
1000
+ const options = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target, prop);
1001
+ if (!options.headers) options.headers = [];
1002
+ options.headers.push(...headers);
1003
+ return descriptor;
1004
+ };
1005
+ }
1006
+ function setHeader(field, val) {
1007
+ return function (target, prop, descriptor) {
1008
+ const options = appMetadata.getOwnMetadataMap(false, SymbolOpenApiOptions, target, prop);
1009
+ if (!options.setHeaders) options.setHeaders = {};
1010
+ if (typeof field === 'string') {
1011
+ options.setHeaders[field] = val;
1012
+ } else {
1013
+ Object.assign(options.setHeaders, field);
1014
+ }
1015
+ return descriptor;
1016
+ };
1017
+ }
1018
+ const Api = {
1019
+ field: Field,
1020
+ httpCode,
1021
+ contentType,
1022
+ body,
1023
+ bodyCustom,
1024
+ exclude,
1025
+ tags,
1026
+ header,
1027
+ headers,
1028
+ setHeader
1029
+ };
1030
+
967
1031
  const OrderCoreBase = 100;
968
1032
  const OrderBusinessBase = 1000;
969
1033
  const OrderUnknownBase = 10000;
970
1034
  const OrderMaxBase = 100000;
971
1035
 
972
- export { $schema, $schemaLazy, Api, Main, OrderBusinessBase, OrderCoreBase, OrderMaxBase, OrderUnknownBase, ScopeModuleAOpenapi, ServiceOpenapi, SummerCacheJson, SymbolRouteHandlersArgumentsMeta, SymbolRouteHandlersArgumentsValue, SymbolSchemaDynamicRefId, addSchemaDynamic, bodySchemaWrapperDefault, config, getSchemaDynamic, getSchemasDynamic, getTargetDecoratorRuleColumns, getTargetDecoratorRuleColumnsMap, getTargetDecoratorRules, makeSchemaLike, makeSchemaLikes, mergeFieldsOpenapiMetadata, prepareClassType, schemaRefCustomAdapter, v };
1036
+ export { $schema, $schemaLazy, Api, Main, OrderBusinessBase, OrderCoreBase, OrderMaxBase, OrderUnknownBase, ScopeModuleAOpenapi, ServiceOpenapi, SummerCacheJson, SymbolRouteHandlersArgumentsMeta, SymbolRouteHandlersArgumentsValue, SymbolSchemaDynamicRefId, addSchemaDynamic, bodySchemaWrapperDefault, config, getSchemaDynamic, getSchemasDynamic, getTargetDecoratorRuleColumns, getTargetDecoratorRuleColumnsMap, getTargetDecoratorRules, makeSchemaLike, makeSchemaLikes, mergeFieldOpenapiMetadata, mergeFieldsOpenapiMetadata, prepareClassType, schemaRefCustomAdapter, v };
@@ -1,3 +1,4 @@
1
+ import type { ISerializerTransformRecord, TypeSerializerTransformGetter } from 'vona-module-a-serialization';
1
2
  import type { ISchemaObjectExtensionFieldCaptcha } from '../../../types/captcha.ts';
2
3
  import { z } from 'zod';
3
4
  export declare function schemaEmail(params?: string | z.core.$ZodEmailParams): (_schema: z.ZodString) => z.ZodEmail;
@@ -16,3 +17,7 @@ export declare function schemaRegex(regex: RegExp, params?: string | z.core.$Zod
16
17
  export declare function schemaTableIdentity(): (_schema?: any) => z.ZodString | z.ZodNumber;
17
18
  export declare function schemaBigNumber(): (_schema: any) => z.ZodType;
18
19
  export declare function schemaCaptcha(options: ISchemaObjectExtensionFieldCaptcha): (schema: z.ZodType) => z.ZodType;
20
+ export declare function schemaSerializerExclude(): (schema: z.ZodType) => z.ZodType;
21
+ export declare function schemaSerializerTransform<T extends keyof ISerializerTransformRecord>(serializerTransformName: T, options?: Partial<ISerializerTransformRecord[T]>): (schema: z.ZodType) => z.ZodType;
22
+ export declare function schemaSerializerSensitive(options: ISerializerTransformRecord['a-serialization:sensitive']): (schema: z.ZodType) => z.ZodType;
23
+ export declare function schemaSerializerGetter(getter: TypeSerializerTransformGetter): (schema: z.ZodType) => z.ZodType;
@@ -1,4 +1,4 @@
1
- import { schemaBigNumber, schemaCaptcha, schemaEmail, schemaIPv4, schemaIPv6, schemaLowercase, schemaMax, schemaMin, schemaRegex, schemaTableIdentity, schemaToLowerCase, schemaToUpperCase, schemaTrim, schemaUppercase, schemaUrl, schemaUuid } from './v/helpers.ts';
1
+ import { schemaBigNumber, schemaCaptcha, schemaEmail, schemaIPv4, schemaIPv6, schemaLowercase, schemaMax, schemaMin, schemaRegex, schemaSerializerExclude, schemaSerializerGetter, schemaSerializerSensitive, schemaSerializerTransform, schemaTableIdentity, schemaToLowerCase, schemaToUpperCase, schemaTrim, schemaUppercase, schemaUrl, schemaUuid } from './v/helpers.ts';
2
2
  import { schemaDescription, schemaExample, schemaOpenapi, schemaTitle } from './v/openapi.ts';
3
3
  import { schemaArray, schemaDefault, schemaLazy, schemaLooseObject, schemaObject, schemaOptional, schemaStrictObject } from './v/system.ts';
4
4
  import { schemaZodRefine, schemaZodTransform } from './v/zod.ts';
@@ -26,6 +26,10 @@ export declare const v: {
26
26
  tableIdentity: typeof schemaTableIdentity;
27
27
  bigNumber: typeof schemaBigNumber;
28
28
  captcha: typeof schemaCaptcha;
29
+ serializerExclude: typeof schemaSerializerExclude;
30
+ serializerTransform: typeof schemaSerializerTransform;
31
+ serializerSensitive: typeof schemaSerializerSensitive;
32
+ serializerGetter: typeof schemaSerializerGetter;
29
33
  openapi: typeof schemaOpenapi;
30
34
  title: typeof schemaTitle;
31
35
  description: typeof schemaDescription;
@@ -1,7 +1,10 @@
1
1
  import type { Constructable } from 'vona';
2
2
  import type { TypeDecoratorRules } from 'vona-module-a-openapiutils';
3
+ import type { TypeOpenapiMetadata } from '../types/rest.ts';
4
+ import { z } from 'zod';
3
5
  export declare function getTargetDecoratorRules(target: object, disableRegisterMetadata?: boolean): TypeDecoratorRules;
4
6
  export declare function getTargetDecoratorRuleColumns(target: object): string[];
5
7
  export declare function getTargetDecoratorRuleColumnsMap(target: object): Record<string, string>;
6
8
  export declare function mergeFieldsOpenapiMetadata(target: Constructable): void;
9
+ export declare function mergeFieldOpenapiMetadata(target: object, prop: string, fieldRule?: TypeOpenapiMetadata | z.ZodType): TypeDecoratorRules;
7
10
  export declare function prepareClassType<T>(classType: (() => Constructable<T>) | Constructable<T>): Constructable<T>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vona-module-a-openapi",
3
3
  "type": "module",
4
- "version": "5.0.32",
4
+ "version": "5.0.34",
5
5
  "title": "a-openapi",
6
6
  "vonaModule": {
7
7
  "capabilities": {
@@ -36,7 +36,7 @@
36
36
  ],
37
37
  "dependencies": {
38
38
  "@cabloy/zod-errors-custom": "^2.0.2",
39
- "@cabloy/zod-openapi": "^1.0.1",
39
+ "@cabloy/zod-openapi": "^1.0.2",
40
40
  "@cabloy/zod-query": "^2.0.1",
41
41
  "@cabloy/zod-to-openapi": "^8.1.1",
42
42
  "@zhennann/currency": "^2.0.0",