@e22m4u/js-openapi 0.0.5

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 (84) hide show
  1. package/.c8rc +9 -0
  2. package/.commitlintrc +5 -0
  3. package/.editorconfig +13 -0
  4. package/.husky/commit-msg +1 -0
  5. package/.husky/pre-commit +6 -0
  6. package/.mocharc.json +4 -0
  7. package/.prettierrc +7 -0
  8. package/LICENSE +21 -0
  9. package/README.md +510 -0
  10. package/build-cjs.js +16 -0
  11. package/dist/cjs/index.cjs +2695 -0
  12. package/eslint.config.js +41 -0
  13. package/package.json +64 -0
  14. package/src/data-type/index.d.ts +1 -0
  15. package/src/data-type/index.js +1 -0
  16. package/src/data-type/infer-openapi-data-type.d.ts +30 -0
  17. package/src/data-type/infer-openapi-data-type.js +38 -0
  18. package/src/data-validation/data-format-validator-map.d.ts +13 -0
  19. package/src/data-validation/data-format-validator-map.js +36 -0
  20. package/src/data-validation/data-format-validator-map.spec.js +39 -0
  21. package/src/data-validation/data-format-validators.d.ts +84 -0
  22. package/src/data-validation/data-format-validators.js +217 -0
  23. package/src/data-validation/index.d.ts +3 -0
  24. package/src/data-validation/index.js +3 -0
  25. package/src/data-validation/validate-data-with-openapi-schema.d.ts +46 -0
  26. package/src/data-validation/validate-data-with-openapi-schema.js +1913 -0
  27. package/src/data-validation/validate-data-with-openapi-schema.spec.js +6953 -0
  28. package/src/errors/index.d.ts +1 -0
  29. package/src/errors/index.js +1 -0
  30. package/src/errors/oa-data-validation-error.d.ts +6 -0
  31. package/src/errors/oa-data-validation-error.js +6 -0
  32. package/src/errors/oa-data-validation-error.spec.js +17 -0
  33. package/src/index.d.ts +9 -0
  34. package/src/index.js +9 -0
  35. package/src/json-pointer/escape-json-pointer.d.ts +7 -0
  36. package/src/json-pointer/escape-json-pointer.js +18 -0
  37. package/src/json-pointer/escape-json-pointer.spec.js +36 -0
  38. package/src/json-pointer/index.d.ts +3 -0
  39. package/src/json-pointer/index.js +3 -0
  40. package/src/json-pointer/resolve-json-pointer.d.ts +10 -0
  41. package/src/json-pointer/resolve-json-pointer.js +83 -0
  42. package/src/json-pointer/resolve-json-pointer.spec.js +103 -0
  43. package/src/json-pointer/unescape-json-pointer.d.ts +8 -0
  44. package/src/json-pointer/unescape-json-pointer.js +18 -0
  45. package/src/json-pointer/unescape-json-pointer.spec.js +32 -0
  46. package/src/oa-document-builder.d.ts +312 -0
  47. package/src/oa-document-builder.js +450 -0
  48. package/src/oa-document-object/index.d.ts +1 -0
  49. package/src/oa-document-object/index.js +1 -0
  50. package/src/oa-document-object/validate-shallow-oa-document.d.ts +10 -0
  51. package/src/oa-document-object/validate-shallow-oa-document.js +209 -0
  52. package/src/oa-document-object/validate-shallow-oa-document.spec.js +362 -0
  53. package/src/oa-document-scope.d.ts +52 -0
  54. package/src/oa-document-scope.js +228 -0
  55. package/src/oa-reference-object/index.d.ts +3 -0
  56. package/src/oa-reference-object/index.js +3 -0
  57. package/src/oa-reference-object/is-oa-reference-object.d.ts +9 -0
  58. package/src/oa-reference-object/is-oa-reference-object.js +14 -0
  59. package/src/oa-reference-object/is-oa-reference-object.spec.js +19 -0
  60. package/src/oa-reference-object/oa-ref.d.ts +11 -0
  61. package/src/oa-reference-object/oa-ref.js +31 -0
  62. package/src/oa-reference-object/oa-ref.spec.js +56 -0
  63. package/src/oa-reference-object/resolve-oa-reference-object.d.ts +18 -0
  64. package/src/oa-reference-object/resolve-oa-reference-object.js +113 -0
  65. package/src/oa-reference-object/resolve-oa-reference-object.spec.js +233 -0
  66. package/src/oa-specification.d.ts +767 -0
  67. package/src/oa-specification.js +153 -0
  68. package/src/types.d.ts +4 -0
  69. package/src/utils/count-unicode.d.ts +11 -0
  70. package/src/utils/count-unicode.js +15 -0
  71. package/src/utils/index.d.ts +5 -0
  72. package/src/utils/index.js +5 -0
  73. package/src/utils/join-path.d.ts +6 -0
  74. package/src/utils/join-path.js +36 -0
  75. package/src/utils/join-path.spec.js +104 -0
  76. package/src/utils/normalize-path.d.ts +12 -0
  77. package/src/utils/normalize-path.js +22 -0
  78. package/src/utils/normalize-path.spec.js +56 -0
  79. package/src/utils/to-pascal-case.d.ts +6 -0
  80. package/src/utils/to-pascal-case.js +26 -0
  81. package/src/utils/to-pascal-case.spec.js +15 -0
  82. package/src/utils/to-spaced-json.d.ts +17 -0
  83. package/src/utils/to-spaced-json.js +27 -0
  84. package/tsconfig.json +14 -0
@@ -0,0 +1,41 @@
1
+ import globals from 'globals';
2
+ import eslintJs from '@eslint/js';
3
+ import eslintJsdocPlugin from 'eslint-plugin-jsdoc';
4
+ import eslintMochaPlugin from 'eslint-plugin-mocha';
5
+ import eslintImportPlugin from 'eslint-plugin-import';
6
+ import eslintPrettierConfig from 'eslint-config-prettier';
7
+ import eslintChaiExpectPlugin from 'eslint-plugin-chai-expect';
8
+
9
+ export default [{
10
+ languageOptions: {
11
+ globals: {
12
+ ...globals.node,
13
+ ...globals.es2021,
14
+ ...globals.mocha,
15
+ },
16
+ },
17
+ plugins: {
18
+ 'jsdoc': eslintJsdocPlugin,
19
+ 'mocha': eslintMochaPlugin,
20
+ 'import': eslintImportPlugin,
21
+ 'chai-expect': eslintChaiExpectPlugin,
22
+ },
23
+ rules: {
24
+ ...eslintJs.configs.recommended.rules,
25
+ ...eslintPrettierConfig.rules,
26
+ ...eslintImportPlugin.flatConfigs.recommended.rules,
27
+ ...eslintMochaPlugin.configs.recommended.rules,
28
+ ...eslintChaiExpectPlugin.configs['recommended-flat'].rules,
29
+ ...eslintJsdocPlugin.configs['flat/recommended-error'].rules,
30
+ 'curly': 'error',
31
+ 'no-duplicate-imports': 'error',
32
+ 'import/export': 0,
33
+ 'jsdoc/reject-any-type': 0,
34
+ 'jsdoc/reject-function-type': 0,
35
+ 'jsdoc/require-param-description': 0,
36
+ 'jsdoc/require-returns-description': 0,
37
+ 'jsdoc/require-property-description': 0,
38
+ 'jsdoc/tag-lines': ['error', 'any', {startLines: 1}],
39
+ },
40
+ files: ['src/**/*.js'],
41
+ }];
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@e22m4u/js-openapi",
3
+ "version": "0.0.5",
4
+ "description": "JavaScript модуль для создания OpenAPI Документа",
5
+ "author": "Mikhail Evstropov <e22m4u@yandex.ru>",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "schema",
9
+ "openapi",
10
+ "generator"
11
+ ],
12
+ "homepage": "https://gitrepos.ru/e22m4u/js-openapi",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://gitrepos.ru/e22m4u/js-openapi.git"
16
+ },
17
+ "type": "module",
18
+ "types": "./src/index.d.ts",
19
+ "module": "./src/index.js",
20
+ "main": "./dist/cjs/index.cjs",
21
+ "exports": {
22
+ "types": "./src/index.d.ts",
23
+ "import": "./src/index.js",
24
+ "require": "./dist/cjs/index.cjs"
25
+ },
26
+ "engines": {
27
+ "node": ">=18"
28
+ },
29
+ "scripts": {
30
+ "lint": "tsc && eslint ./src",
31
+ "lint:fix": "tsc && eslint ./src --fix",
32
+ "format": "prettier --write \"./src/**/*.{js,ts}\"",
33
+ "test": "npm run lint && c8 --reporter=text-summary mocha --bail",
34
+ "test:coverage": "npm run lint && c8 --reporter=text mocha --bail",
35
+ "build:cjs": "rimraf ./dist/cjs && node build-cjs.js",
36
+ "prepare": "husky"
37
+ },
38
+ "dependencies": {
39
+ "@e22m4u/js-format": "~0.3.2",
40
+ "@e22m4u/js-service": "~0.5.1"
41
+ },
42
+ "devDependencies": {
43
+ "@commitlint/cli": "~20.3.1",
44
+ "@commitlint/config-conventional": "~20.3.1",
45
+ "@eslint/js": "~9.39.2",
46
+ "@types/chai": "~5.2.3",
47
+ "@types/mocha": "~10.0.10",
48
+ "c8": "~10.1.3",
49
+ "chai": "~6.2.2",
50
+ "esbuild": "~0.27.2",
51
+ "eslint": "~9.39.2",
52
+ "eslint-config-prettier": "~10.1.8",
53
+ "eslint-plugin-chai-expect": "~3.1.0",
54
+ "eslint-plugin-import": "~2.32.0",
55
+ "eslint-plugin-jsdoc": "~62.0.0",
56
+ "eslint-plugin-mocha": "~11.2.0",
57
+ "globals": "~17.0.0",
58
+ "husky": "~9.1.7",
59
+ "mocha": "~11.7.5",
60
+ "prettier": "~3.8.0",
61
+ "rimraf": "~6.1.2",
62
+ "typescript": "~5.9.3"
63
+ }
64
+ }
@@ -0,0 +1 @@
1
+ export * from './infer-openapi-data-type.js';
@@ -0,0 +1 @@
1
+ export * from './infer-openapi-data-type.js';
@@ -0,0 +1,30 @@
1
+ import {OADataType} from '../oa-specification.js';
2
+
3
+ /**
4
+ * Infer OpenAPI data type.
5
+ *
6
+ * @param data
7
+ */
8
+ export function inferOpenApiDataType(data: unknown): OADataType;
9
+
10
+ /**
11
+ * Infer OpenAPI data type.
12
+ *
13
+ * @param data
14
+ * @param returnJsTypeOnFail
15
+ */
16
+ export function inferOpenApiDataType(
17
+ data: unknown,
18
+ returnJsTypeOnFail: true,
19
+ ): OADataType | string;
20
+
21
+ /**
22
+ * Infer OpenAPI data type.
23
+ *
24
+ * @param data
25
+ * @param returnJsTypeOnFail
26
+ */
27
+ export function inferOpenApiDataType(
28
+ data: unknown,
29
+ returnJsTypeOnFail?: boolean,
30
+ ): OADataType | string;
@@ -0,0 +1,38 @@
1
+ import {InvalidArgumentError} from '@e22m4u/js-format';
2
+ import {OADataType} from '../oa-specification.js';
3
+
4
+ /**
5
+ * Infer OpenAPI data type.
6
+ *
7
+ * @param {*} data
8
+ * @param {boolean} [returnJsTypeOnFail]
9
+ * @returns {OADataType}
10
+ */
11
+ export function inferOpenApiDataType(data, returnJsTypeOnFail = false) {
12
+ if (data === null) {
13
+ return OADataType.NULL;
14
+ }
15
+ if (Array.isArray(data)) {
16
+ return OADataType.ARRAY;
17
+ }
18
+ const jsType = typeof data;
19
+ switch (jsType) {
20
+ case 'string':
21
+ return OADataType.STRING;
22
+ case 'boolean':
23
+ return OADataType.BOOLEAN;
24
+ case 'number':
25
+ return Number.isInteger(data) ? OADataType.INTEGER : OADataType.NUMBER;
26
+ case 'bigint':
27
+ return OADataType.INTEGER;
28
+ case 'object':
29
+ return OADataType.OBJECT;
30
+ }
31
+ if (returnJsTypeOnFail === true) {
32
+ return jsType;
33
+ }
34
+ throw new InvalidArgumentError(
35
+ 'Unable to infer the data type from %v value.',
36
+ data,
37
+ );
38
+ }
@@ -0,0 +1,13 @@
1
+ import {OADataFormatValidator} from './data-format-validators.js';
2
+
3
+ /**
4
+ * Data format validator map.
5
+ */
6
+ export type OADataFormatValidatorMap = {
7
+ [format: string]: OADataFormatValidator | undefined;
8
+ };
9
+
10
+ /**
11
+ * Built-in data format validator map.
12
+ */
13
+ export declare const OA_BUILT_IN_DATA_FORMAT_VALIDATOR_MAP: OADataFormatValidatorMap;
@@ -0,0 +1,36 @@
1
+ import {OADataFormat} from '../oa-specification.js';
2
+
3
+ import {
4
+ validateUriFormat,
5
+ validateIpv4Format,
6
+ validateIpv6Format,
7
+ validateUuidFormat,
8
+ validateByteFormat,
9
+ validateDateFormat,
10
+ validateInt32Format,
11
+ validateFloatFormat,
12
+ validateInt64Format,
13
+ validateEmailFormat,
14
+ validateDoubleFormat,
15
+ validateDateTimeFormat,
16
+ validateHostnameFormat,
17
+ } from './data-format-validators.js';
18
+
19
+ /**
20
+ * Built-in data format validator map.
21
+ */
22
+ export const OA_BUILT_IN_DATA_FORMAT_VALIDATOR_MAP = {
23
+ [OADataFormat.INT32]: validateInt32Format,
24
+ [OADataFormat.INT64]: validateInt64Format,
25
+ [OADataFormat.FLOAT]: validateFloatFormat,
26
+ [OADataFormat.DOUBLE]: validateDoubleFormat,
27
+ [OADataFormat.DATE]: validateDateFormat,
28
+ [OADataFormat.DATE_TIME]: validateDateTimeFormat,
29
+ [OADataFormat.BYTE]: validateByteFormat,
30
+ [OADataFormat.EMAIL]: validateEmailFormat,
31
+ [OADataFormat.UUID]: validateUuidFormat,
32
+ [OADataFormat.HOSTNAME]: validateHostnameFormat,
33
+ [OADataFormat.IPV4]: validateIpv4Format,
34
+ [OADataFormat.IPV6]: validateIpv6Format,
35
+ [OADataFormat.URI]: validateUriFormat,
36
+ };
@@ -0,0 +1,39 @@
1
+ import {expect} from 'chai';
2
+ import {OADataFormat} from '../oa-specification.js';
3
+ import {OA_BUILT_IN_DATA_FORMAT_VALIDATOR_MAP} from './data-format-validator-map.js';
4
+
5
+ import {
6
+ validateUriFormat,
7
+ validateIpv4Format,
8
+ validateIpv6Format,
9
+ validateUuidFormat,
10
+ validateByteFormat,
11
+ validateDateFormat,
12
+ validateInt32Format,
13
+ validateFloatFormat,
14
+ validateInt64Format,
15
+ validateEmailFormat,
16
+ validateDoubleFormat,
17
+ validateDateTimeFormat,
18
+ validateHostnameFormat,
19
+ } from './data-format-validators.js';
20
+
21
+ describe('OA_BUILT_IN_DATA_FORMAT_VALIDATOR_MAP', function () {
22
+ it('should map data formats to its corresponding validator function', function () {
23
+ expect(OA_BUILT_IN_DATA_FORMAT_VALIDATOR_MAP).to.be.eql({
24
+ [OADataFormat.INT32]: validateInt32Format,
25
+ [OADataFormat.INT64]: validateInt64Format,
26
+ [OADataFormat.FLOAT]: validateFloatFormat,
27
+ [OADataFormat.DOUBLE]: validateDoubleFormat,
28
+ [OADataFormat.DATE]: validateDateFormat,
29
+ [OADataFormat.DATE_TIME]: validateDateTimeFormat,
30
+ [OADataFormat.BYTE]: validateByteFormat,
31
+ [OADataFormat.EMAIL]: validateEmailFormat,
32
+ [OADataFormat.UUID]: validateUuidFormat,
33
+ [OADataFormat.HOSTNAME]: validateHostnameFormat,
34
+ [OADataFormat.IPV4]: validateIpv4Format,
35
+ [OADataFormat.IPV6]: validateIpv6Format,
36
+ [OADataFormat.URI]: validateUriFormat,
37
+ });
38
+ });
39
+ });
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Data format validator.
3
+ */
4
+ export type OADataFormatValidator = (value: unknown) => boolean;
5
+
6
+ /**
7
+ * Validate int32 format.
8
+ * Signed 32-bit integer.
9
+ * Range: [-2,147,483,648 to 2,147,483,647]
10
+ */
11
+ export declare const validateInt32Format: OADataFormatValidator;
12
+
13
+ /**
14
+ * Validate int64 format.
15
+ * Signed 64-bit integer.
16
+ * Note: JS Numbers lose precision beyond 2^53.
17
+ * This checks if it's a safe integer in JS context.
18
+ */
19
+ export declare const validateInt64Format: OADataFormatValidator;
20
+
21
+ /**
22
+ * Validate float (32-bit) format.
23
+ * Standard IEEE 754 single-precision binary floating-point.
24
+ * Range approx: ±3.4e38.
25
+ */
26
+ export declare const validateFloatFormat: OADataFormatValidator;
27
+
28
+ /**
29
+ * Validate double (64-bit) format.
30
+ */
31
+ export declare const validateDoubleFormat: OADataFormatValidator;
32
+
33
+ /**
34
+ * Validate byte format.
35
+ * Base64 encoded characters.
36
+ */
37
+ export declare const validateByteFormat: OADataFormatValidator;
38
+
39
+ /**
40
+ * Validate date format.
41
+ * Full-date notation as defined by RFC 3339, section 5.6 (YYYY-MM-DD).
42
+ */
43
+ export declare const validateDateFormat: OADataFormatValidator;
44
+
45
+ /**
46
+ * Validate date-time format.
47
+ * The date-time notation as defined by RFC 3339, section 5.6.
48
+ */
49
+ export declare const validateDateTimeFormat: OADataFormatValidator;
50
+
51
+ /**
52
+ * Validate email format.
53
+ */
54
+ export declare const validateEmailFormat: OADataFormatValidator;
55
+
56
+ /**
57
+ * Validate uuid format.
58
+ */
59
+ export declare const validateUuidFormat: OADataFormatValidator;
60
+
61
+ /**
62
+ * Validate ipv4 format.
63
+ */
64
+ export declare const validateIpv4Format: OADataFormatValidator;
65
+
66
+ /**
67
+ * Validate ipv6 format.
68
+ */
69
+ export declare const validateIpv6Format: OADataFormatValidator;
70
+
71
+ /**
72
+ * Validate hostname format.
73
+ */
74
+ export declare const validateHostnameFormat: OADataFormatValidator;
75
+
76
+ /**
77
+ * Validate uri format.
78
+ */
79
+ export declare const validateUriFormat: OADataFormatValidator;
80
+
81
+ /**
82
+ * Validate password format.
83
+ */
84
+ export declare const validatePasswordFormat: OADataFormatValidator;
@@ -0,0 +1,217 @@
1
+ /////////////////////////////////////////////////
2
+ ////////////// Regular Expressions //////////////
3
+ /////////////////////////////////////////////////
4
+ const RX_UUID =
5
+ /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
6
+ const RX_DATE = /^\d{4}-\d{2}-\d{2}$/;
7
+ const RX_DATE_TIME =
8
+ /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|([+-]\d{2}:?\d{2}))$/i;
9
+ const RX_IPV4 =
10
+ /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
11
+ const RX_IPV6 =
12
+ /^((([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])))$/;
13
+ const RX_HOSTNAME =
14
+ /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])$/;
15
+ const RX_EMAIL =
16
+ /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
17
+ const RX_BASE64 =
18
+ /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
19
+
20
+ /**
21
+ * Validate int32 format.
22
+ * Signed 32-bit integer.
23
+ * Range: [-2,147,483,648 to 2,147,483,647]
24
+ *
25
+ * @param {*} v
26
+ * @returns {boolean}
27
+ */
28
+ export const validateInt32Format = v => {
29
+ if (typeof v !== 'number') {
30
+ return true;
31
+ }
32
+ return Number.isInteger(v) && v >= -2147483648 && v <= 2147483647;
33
+ };
34
+
35
+ /**
36
+ * Validate int64 format.
37
+ * Signed 64-bit integer.
38
+ * This checks if it's a safe integer in JS context.
39
+ *
40
+ * @param {*} v
41
+ * @returns {boolean}
42
+ */
43
+ export const validateInt64Format = v => {
44
+ if (typeof v !== 'number') {
45
+ return true;
46
+ }
47
+ return Number.isSafeInteger(v);
48
+ };
49
+
50
+ /**
51
+ * Validate float (32-bit) format.
52
+ * Standard IEEE 754 single-precision binary floating-point.
53
+ * Range approx: ±3.4e38.
54
+ *
55
+ * @param {*} v
56
+ * @returns {boolean}
57
+ */
58
+ export const validateFloatFormat = v => {
59
+ if (typeof v !== 'number') {
60
+ return true;
61
+ }
62
+ return (
63
+ !Number.isNaN(v) &&
64
+ Number.isFinite(v) &&
65
+ // Math.fround приводит число к 32-битному float,
66
+ // если результат бесконечен, значит число не влазит в float
67
+ Number.isFinite(Math.fround(v))
68
+ );
69
+ };
70
+
71
+ /**
72
+ * Validate double (64-bit) format.
73
+ *
74
+ * @param {*} v
75
+ * @returns {boolean}
76
+ */
77
+ export const validateDoubleFormat = v => {
78
+ if (typeof v !== 'number') {
79
+ return true;
80
+ }
81
+ return !Number.isNaN(v) && Number.isFinite(v);
82
+ };
83
+
84
+ /**
85
+ * Validate byte format.
86
+ * Base64 encoded characters.
87
+ *
88
+ * @param {*} v
89
+ * @returns {boolean}
90
+ */
91
+ export const validateByteFormat = v => {
92
+ if (typeof v !== 'string') {
93
+ return true;
94
+ }
95
+ return v.length % 4 === 0 && RX_BASE64.test(v);
96
+ };
97
+
98
+ /**
99
+ * Validate date format.
100
+ * Full-date notation as defined by RFC 3339, section 5.6 (YYYY-MM-DD).
101
+ *
102
+ * @param {*} v
103
+ * @returns {boolean}
104
+ */
105
+ export const validateDateFormat = v => {
106
+ if (typeof v !== 'string') {
107
+ return true;
108
+ }
109
+ if (!RX_DATE.test(v)) {
110
+ return false;
111
+ }
112
+ // проверка на переполнение дней
113
+ const [y, m, d] = v.split('-').map(Number);
114
+ const date = new Date(Date.UTC(y, m - 1, d));
115
+ return (
116
+ date.getUTCFullYear() === y &&
117
+ date.getUTCMonth() === m - 1 &&
118
+ date.getUTCDate() === d
119
+ );
120
+ };
121
+
122
+ /**
123
+ * Validate date-time format.
124
+ * The date-time notation as defined by RFC 3339, section 5.6.
125
+ *
126
+ * @param {*} v
127
+ * @returns {boolean}
128
+ */
129
+ export const validateDateTimeFormat = v => {
130
+ if (typeof v !== 'string') {
131
+ return true;
132
+ }
133
+ return RX_DATE_TIME.test(v) && !isNaN(Date.parse(v));
134
+ };
135
+
136
+ /**
137
+ * Validate email format.
138
+ *
139
+ * @param {*} v
140
+ * @returns {boolean}
141
+ */
142
+ export const validateEmailFormat = v => {
143
+ if (typeof v !== 'string') {
144
+ return true;
145
+ }
146
+ return RX_EMAIL.test(v);
147
+ };
148
+
149
+ /**
150
+ * Validate uuid format.
151
+ *
152
+ * @param {*} v
153
+ * @returns {boolean}
154
+ */
155
+ export const validateUuidFormat = v => {
156
+ if (typeof v !== 'string') {
157
+ return true;
158
+ }
159
+ return RX_UUID.test(v);
160
+ };
161
+
162
+ /**
163
+ * Validate ipv4 format.
164
+ *
165
+ * @param {*} v
166
+ * @returns {boolean}
167
+ */
168
+ export const validateIpv4Format = v => {
169
+ if (typeof v !== 'string') {
170
+ return true;
171
+ }
172
+ return RX_IPV4.test(v);
173
+ };
174
+
175
+ /**
176
+ * Validate ipv6 format.
177
+ *
178
+ * @param {*} v
179
+ * @returns {boolean}
180
+ */
181
+ export const validateIpv6Format = v => {
182
+ if (typeof v !== 'string') {
183
+ return true;
184
+ }
185
+ return RX_IPV6.test(v);
186
+ };
187
+
188
+ /**
189
+ * Validate hostname format.
190
+ *
191
+ * @param {*} v
192
+ * @returns {boolean}
193
+ */
194
+ export const validateHostnameFormat = v => {
195
+ if (typeof v !== 'string') {
196
+ return true;
197
+ }
198
+ return v.length <= 255 && RX_HOSTNAME.test(v);
199
+ };
200
+
201
+ /**
202
+ * Validate uri format.
203
+ *
204
+ * @param {*} v
205
+ * @returns {boolean}
206
+ */
207
+ export const validateUriFormat = v => {
208
+ if (typeof v !== 'string') {
209
+ return true;
210
+ }
211
+ try {
212
+ new URL(v);
213
+ return true;
214
+ } catch {
215
+ return false;
216
+ }
217
+ };
@@ -0,0 +1,3 @@
1
+ export * from './data-format-validators.js';
2
+ export * from './data-format-validator-map.js';
3
+ export * from './validate-data-with-openapi-schema.js';
@@ -0,0 +1,3 @@
1
+ export * from './data-format-validators.js';
2
+ export * from './data-format-validator-map.js';
3
+ export * from './validate-data-with-openapi-schema.js';
@@ -0,0 +1,46 @@
1
+ import {OADataFormatValidatorMap} from './data-format-validator-map.js';
2
+
3
+ import {
4
+ OAAccessMode,
5
+ OASchemaObject,
6
+ OABooleanSchema,
7
+ } from '../oa-specification.js';
8
+
9
+ /**
10
+ * Data validation options.
11
+ */
12
+ export type OADataValidationOptions = {
13
+ rootDocument?: object | unknown[];
14
+ required?: boolean;
15
+ coerceTypes?: boolean;
16
+ applyDefaults?: boolean;
17
+ stripUnknown?: boolean;
18
+ dataSourceUri?: string;
19
+ schemaSourceUri?: string;
20
+ silent?: boolean;
21
+ accessMode?: OAAccessMode;
22
+ formatValidators?: OADataFormatValidatorMap;
23
+ parseJson?: boolean;
24
+ };
25
+
26
+ /**
27
+ * Data validation result.
28
+ */
29
+ export type OADataValidationResult<T> = {
30
+ isValid: boolean;
31
+ reason: string;
32
+ value?: T;
33
+ };
34
+
35
+ /**
36
+ * Validate data with OpenAPI Schema.
37
+ *
38
+ * @param data
39
+ * @param schema
40
+ * @param options
41
+ */
42
+ export function validateDataWithOpenApiSchema<T = any>(
43
+ data: unknown,
44
+ schema: OABooleanSchema | OASchemaObject,
45
+ options?: OADataValidationOptions,
46
+ ): OADataValidationResult<T>;