Giter Site home page Giter Site logo

ajv-formats's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ajv-formats's Issues

TypeScript error: Type 'FormatsPlugin' has no call signatures.

Following the doc and simply trying to validate with the date format, I receive the following error:

src/scripts/simple-validation.ts:5:1 - error TS2349: This expression is not callable.
  Type 'FormatsPlugin' has no call signatures.

5 addFormats(ajv);
  ~~~~~~~~~~

The source file is here:

import Ajv from 'ajv';
import addFormats from 'ajv-formats';

const ajv = new Ajv();
addFormats(ajv);

const schema = {
  type: 'string',
  format: 'date',
};

const validate = ajv.compile(schema);
const isValid = validate('1-1-1');
console.log(isValid);

date-time accept timestamp without time zone

According to ajv-formats documentation, "date-time" format specify that time-zone is mandatory. Unfortunately since full validation mode format has been added, it seems that time-zone is not mandatory anymore:

import ajvFormats from "ajv-formats"

const dateWithoutTimeZone = '2022-07-06T13:12:43';
const dateWithTimeZone = '2022-07-06T13:12:43Z';

// validation with new full format mode does not work as expected
console.log(ajvFormats.get("date-time").validate(dateWithoutTimeZone)) // true => should return false
console.log(ajvFormats.get("date-time").validate(dateWithTimeZone)) // true => ok

// validation with fast format mode is ok
console.log(new RegExp(ajvFormats.get("date-time", "fast").validate).test(dateWithoutTimeZone)) // false => ok
console.log(new RegExp(ajvFormats.get("date-time", "fast").validate).test(dateWithTimeZone)) // true => ok

Documentation incorrect, unable to se AJV formats

Using the example code results in errors and simply does not work.

const Ajv = require("ajv")
const addFormats = require("ajv-formats")

const ajv = new Ajv()
addFormats(ajv)

The above code, from the documentation, does not work.

Both const ajv = new Ajv() and addFormats(ajv) produce an error "This expression is not constructable."

Package versions:

    "ajv": "^8.2.0",
    "ajv-formats": "^2.0.2"

NB - I can get rid of one error, from const ajv = new Ajv() by add .default to the require statement, but addFormats(ajv) still errors.

“compare is not a function” when using formatMinimum with date format

This is my schema (with unrelated properties removed):

export const employeeSchema = {
	items: {
		properties: {
			launchDate: {
				errorMessage: {
					format: 'must be a date in YYYY-MM-DD format (e.g. _1973-05-11_)',
					type: 'required, and must be a date in YYYY-MM-DD format (e.g. _1973-05-11_)',
				},
				examples: ['1973-05-11'],
				format: 'date',
				type: 'string',
			},
		},
		required: [
			'launchDate',
		],
		type: 'object',
	},
	minItems: 1,
	type: 'array',
};

As-is, everything works and validates correctly. But when I add formatMinimum to launchDate:

export const employeeSchema = {
	items: {
		properties: {
			launchDate: {
				errorMessage: {
					format: 'must be a date in YYYY-MM-DD format (e.g. _1973-05-11_)',
					type: 'required, and must be a date in YYYY-MM-DD format (e.g. _1973-05-11_)',
				},
				examples: ['1973-05-11'],
				format: 'date',
				formatMinimum: '2022-03-30',
				type: 'string',
			},
		},
		required: [
			'launchDate',
		],
		type: 'object',
	},
	minItems: 1,
	type: 'array',
};

… I get the following console error:

Uncaught TypeError: {(intermediate value)(intermediate value)(intermediate value)(intermediate value)}.compare is not a function
    at validate14 (eval at compileSchema (index.jss:89:1), <anonymous>:3:2858)
    at index.jss:149:1
    at mountMemo (react-dom.development.jss:15846:1)
    at Object.useMemo (react-dom.development.jss:16219:1)
    at useMemo (react.development.jss:1532:1)
    at UseMemo (whyDidYouRender.jss:1461:1)
    at ModalImportReview (index.jss:132:1)
    at renderWithHooks (react-dom.development.jss:14985:1)
    at mountIndeterminateComponent (react-dom.development.jss:17811:1)
    at beginWork (react-dom.development.jss:19049:1)

Update:

RunKit example: https://runkit.com/brandondurham/compare-is-not-a-function-when-using-formatminimum-with-date-format

strict mode: unknown keyword: "format"

Hello, I'm using [email protected] and [email protected] in an AWS Lambda (Node.js 14) and I'm getting this error:

{
    "errorType": "Error",
    "errorMessage": "strict mode: unknown keyword: \"format\"",
    "stack": [
        "Error: strict mode: unknown keyword: \"format\"",
        "    at null.Gq (/node_modules/.pnpm/[email protected]/node_modules/ajv/lib/compile/util.ts:211:28)",
        "    at null.$q (/node_modules/.pnpm/[email protected]/node_modules/ajv/lib/compile/util.ts:27:22)",
        "    at null.Wfe (/node_modules/.pnpm/[email protected]/node_modules/ajv/lib/compile/util.ts:17:3)",
        "    at Object.code (/node_modules/.pnpm/[email protected]/node_modules/ajv/lib/vocabularies/jtd/metadata.ts:11:9)",
        "    at null.UN (/node_modules/.pnpm/[email protected]/node_modules/ajv/lib/compile/validate/index.ts:523:9)",
        "    at null.<anonymous> (/node_modules/.pnpm/[email protected]/node_modules/ajv/lib/compile/validate/index.ts:265:9)",
        "    at Nq.code (/node_modules/.pnpm/[email protected]/node_modules/ajv/lib/compile/codegen/index.ts:525:33)",
        "    at Nq.block (/node_modules/.pnpm/[email protected]/node_modules/ajv/lib/compile/codegen/index.ts:680:20)",
        "    at null.RN (/node_modules/.pnpm/[email protected]/node_modules/ajv/lib/compile/validate/index.ts:262:7)",
        "    at null.v (/node_modules/.pnpm/[email protected]/node_modules/ajv/lib/compile/validate/index.ts:248:7)"
    ]
}

Here is the function:

import {
  CognitoIdentityProviderClient,
  AdminCreateUserCommand,
  AdminAddUserToGroupCommand,
} from "@aws-sdk/client-cognito-identity-provider";
import { AppSyncResolverEvent } from "aws-lambda";
import Ajv, { JTDDataType } from "ajv/dist/jtd";
import format from "ajv/dist/vocabularies/format/format";
import addFormats from "ajv-formats";
import { transformUser } from "./user";
import { groupNames } from "./group";

// validation
const ajv = new Ajv();
ajv.addKeyword(format);
addFormats(ajv, ["email"]);
const schema = {
  properties: {
    email: { type: "string", metadata: { format: "email" } },
    family_name: { type: "string" },
    given_name: { type: "string" },
    groups: {
      elements: { enum: groupNames },
    },
    username: { type: "string" },
  },
} as const;
const validate = ajv.compile(schema);

// params
interface CreateUserGqlArgs {
  input: JTDDataType<typeof schema>;
}
interface CreateUserParams {
  cognitoClient: CognitoIdentityProviderClient;
  event: AppSyncResolverEvent<CreateUserGqlArgs>;
  userPoolId: string;
}

export async function createUser(props: CreateUserParams): Promise<unknown> {
  const { cognitoClient, event, userPoolId } = props;
  if (!validate(event.arguments.input)) {
    throw new Error(validate.errors?.toString());
  }
  const { username, groups, ...inputUserAttributes } = event.arguments.input;
  const userAttributes = Object.entries(inputUserAttributes).map(([k, v]) => ({
    Name: k,
    Value: v,
  }));
  const res = await cognitoClient.send(
    new AdminCreateUserCommand({
      UserPoolId: userPoolId,
      Username: username,
      UserAttributes: userAttributes,
    })
  );
  await Promise.all(
    groups.map((g) =>
      cognitoClient.send(
        new AdminAddUserToGroupCommand({
          GroupName: g,
          Username: username,
          UserPoolId: userPoolId,
        })
      )
    )
  );
  if (!res.User) throw new Error("Error while creating user");
  const user = transformUser(res.User);
  return user;
}

Does anyone know what's going on? Thank you!

Difficulty troubleshooting formatExclusiveMinimum error.

Hi!, I'm trying to use formatExclusiveMinimum with $data to compare two date fields and validate that endDate > startDate, but I'm having trouble tracking down an error.

package.json ajv version snippet:

    "ajv": "8.6.0",
    "ajv-formats": "^2.1.0",
    "ajv-keywords": "^5.0.0",
    "ajv-merge-patch": "4.1.0"

ajv setup:

    parameterAjv = new Ajv({
      schemas,
      strict: 'log',
      $data: true,
      removeAdditional: 'all',
      useDefaults: false,
      code: {
        lines: true,
        optimize: false
      }
    })

    require('ajv-merge-patch/keywords/merge')(parameterAjv)

    const addFormats = require('ajv-formats')
    addFormats(parameterAjv, {
      formats: ['date', 'time', 'date-time', 'uri', 'regex'],
      keywords: true
    })
    schema = parameterAjv.getSchema(schemaPath)

An example from my schema:

{
  "query": {
    "type": "object",
    "properties": {
      "propertyId": {
        "description": "The property you are querying",
        "$ref": "Common.schema.json#/definitions/propertyId"
      },
      "startDate": {
        "description": "The date check-in availability.  In the property's local timezone.",
        "type": "string",
        "format": "date"
      },
      "endDate": {
        "description": "The date check-out availability.  In the property's local timezone.",
        "type": "string",
        "format": "date",
        "formatExclusiveMinimum": {
          "$data": "1/startDate"
        }
      }
    },
    "required": ["startDate", "endDate"]
  }
}

When I pass in any combination of valid date strings for startDate and endDate I get the following error:

{
  "instancePath": "/query/endDate",
  "schemaPath": "#/properties/query/properties/endDate/formatExclusiveMinimum",
  "keyword": "formatExclusiveMinimum",
  "params": {
    "_items": [
      "{comparison: ",
      "\">\"",
      ", limit: ",
      "{\"str\":\"vSchema0\"}",
      "}"
    ]
  },
  "message": {
    "_items": ["\"should be > \"", "+", "{\"str\":\"vSchema0\"}"]
  }
}

Is this error format correct?

I've been trying to track this down in the code generated by ajv to validate this field and I'm having trouble understanding one of the condition checks.

Here is a snippet of the generated code that deals with the endDate comparison to startDate:

if (valid1) {
    if (data0.endDate !== undefined) {
      let data8 = data0.endDate;
      const _errs23 = errors;
      if (errors === _errs23) {
        if (errors === _errs23) {
          if (typeof data8 === "string") {
            if (!formats6.validate(data8)) {
              validate242.errors = [
                {
                  instancePath:
                    instancePath + "/query/endDate",
                  schemaPath:
                    "#/properties/query/properties/endDate/format",
                  keyword: "format",
                  params: { format: "date" },
                  message:
                    'must match format "' +
                    "date" +
                    '"',
                },
              ];
              return false;
            } else {
              const vSchema0 =
                data0 && data0.startDate;
              if (
                vSchema0 !== undefined &&
                (typeof vSchema0 !== "string" || { // Everything makes sense up until here
                  _items: [
                    "",
                    '{"str":"formats6","prefix":"formats","value":{"key":"date","ref":{},"code":{"_items":["","{\\"_items\\":[\\"require(\\\\\\"ajv-formats/dist/formats\\\\\\").\\",{\\"str\\":\\"fullFormats\\"},\\"\\"]}","",".date",""]}},"scopePath":{"_items":[".",{"str":"formats"},"[",1,"]"]}}',
                    ".compare(",
                    '{"str":"data8"}',
                    ", ",
                    '{"str":"vSchema0"}',
                    ") ",
                    "<=",
                    " 0",
                  ],
                })
              ) {
                validate242.errors = [
                  {
                    instancePath:
                      instancePath + "/query/endDate",
                    schemaPath:
                      "#/properties/query/properties/endDate/formatExclusiveMinimum",
                    keyword: "formatExclusiveMinimum",
                    params: {
                      _items: [
                        "{comparison: ",
                        '">"',
                        ", limit: ",
                        '{"str":"vSchema0"}',
                        "}",
                      ],
                    },
                    message: {
                      _items: [
                        '"should be > "',
                        "+",
                        '{"str":"vSchema0"}',
                      ],
                    },
                  },
                ];
                return false;
              }
            }
          } else {
            validate242.errors = [
              {
                instancePath:
                  instancePath + "/query/endDate",
                schemaPath:
                  "#/properties/query/properties/endDate/type",
                keyword: "type",
                params: { type: "string" },
                message: "must be string",
              },
            ];
            return false;
          }
        }
      }
      var valid1 = _errs23 === errors;
    } else {
      var valid1 = true;
    }

Can anyone point me in the right direction? I've been back and forth over the configuration of ajv with ajv-formats but can't seem to make any progress.

Doesnt work with [email protected]+

Currently the highest ajv version we can use is 8.6.3 any higher version breaks the addFormats that do not accept the Ajv instance anymore.

Do you plan an upgrade to support newest versions of AJV?

Use 're2' package to prevent ReDoS?

According to the Ajv documentation:

some formats that ajv-formats package implements use regular expressions that can be vulnerable to ReDoS attack

Having you considered using the re2 package to eliminate this risk? According to its documentation:

RE2 was designed and implemented with an explicit goal of being able to handle regular expressions from untrusted users without risk. One of its primary guarantees is that the match time is linear in the length of the input string.

Unknown format "iso-date-time"

Hi, I'm trying to use the "iso-date-time" format with [email protected] and [email protected] but it's throwing the following error:

Error: unknown format "iso-date-time" ignored in schema at path "#/properties/publishDate"

I'm using Node v16.13.1

Here's my code:

import Ajv from 'ajv';
import addFormats from 'ajv-formats';

const ajv = new Ajv();
addFormats(ajv);

const bookSchema = {
  type: 'object',
  properties: {
    title: { type: 'string' },
    numOfPages: { type: 'integer' },
    author: { type: 'string' },
    price: { type: 'number' },
    publishDate: { type: 'string', format: 'iso-date-time' },
  },
  required: ['title', 'numOfPages', 'author', 'price'],
  additionalProperties: false,
};

const validateBook = ajv.compile(bookSchema);

export default validateBook;

Error while building project on Github CI

the project is being built on my machine successfully, but an error occurs in Github when trying to build the project:

ERROR in ./src/server/app/create-app.ts 6:41-63
  Module not found: Error: Can't resolve 'ajv-formats' in '/home/runner/work/project/src/server/app'

set up dependencies in Github workflow

yarn install --frozen-lockfile

package.jso has the package in dependencies

{
    "dependencies": {
      ...
       "ajv": "8.10.0",
       "ajv-formats": "^2.1.1",
      ...
    }
}

module imports the package

import Ajv from 'ajv';
import addFormats from 'ajv-formats';

const ajv = new Ajv({
    strict: true,
    coerceTypes: false,
    formats: {
        semver: '^(0|[1-9][0-9]{0,5})\\.(0|[1-9][0-9]{0,5})\\.(0|[1-9][0-9]{0,5})$',
    },
});

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
addFormats(ajv);
...

invalid Unicode escape \.

In my React Native app the metro bundler fails with

error: node_modules/ajv-formats/dist/formats.js: /Users/mtroskot/Projects/app/node_modules/ajv-formats/dist/formats.js: invalid Unicode escape .

The issue is in the url regex.

url: /^(?:https?|ftp)://(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:.\d{1,3}){3})(?!(?:169.254|192.168)(?:.\d{1,3}){2})(?!172.(?:1[6-9]|2\d|3[0-1])(?:.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u{00a1}-\u{ffff}]+-)[a-z0-9\u{00a1}-\u{ffff}]+)(?:.(?:[a-z0-9\u{00a1}-\u{ffff}]+-)[a-z0-9\u{00a1}-\u{ffff}]+)(?:.(?:[a-z\u{00a1}-\u{ffff}]{2,})))(?::\d{2,5})?(?:/[^\s])?$/iu,

[question] Release v2.0.2 does not include new formats

Hi, @epoberezkin thanks for this package it is very useful.

I found that the version that was released yesterday v2.0.2 does not include new Formats like binary.

This is NPM README (Without binary format)

Screenshot 2021-04-03 at 18 06 58

And this is the code I found after downloading this version in my node_modules.

Screenshot 2021-04-03 at 18 07 16

I think this PR was not included in the release for any reason in the release to npm 😅

How can i use ajv-formats in JS ?

I'm using the minified version of ajv7 in Javascript, and i want to support other formats, which are in the ajv-formats package.
I want to import ajv-formats, which is written in typescript, to my Javascript project.
Is there a possibility to make it ?
Does a minified version of ajv-formats exist ?

url regex unsafe

Well. safe-Regex complains that the regex for url is considered "unsafe".

How can we implement it "safe" without deep digging in the regex?

something like this?

(url) => {
	try {
		const parsedUrl = new URL(url).toString();
		return url === parsedUrl;
	} catch (e) {
		return false;
	}
}

Using in the browser

I'm using the minified version of ajv7 in Javascript, and i want to support other formats, which are in the ajv-formats package.
I want to import ajv-formats, which is written in typescript, to my Javascript project.
Is there a possibility to make it ? Does a minified version of ajv-formats exist ?

URL error

This valid url wss://arbitrator.net/api does not pass url format validation.

expose formats in index.ts

Hi,

could you please expose the formats in index.ts? Currently I want to wrap all the formatters for typescript typeguards, but i cant do a
import { fastFormats } from "./ajv-formats";

[FR] Allow empty string

Summary

The following schema won't work:

createdAt: {
    type: 'string',
    format: 'iso-date-time',
    default: ''
}

as the default value will not pass validation if provided directly.
Are there any plans to support empty strings as the null value? it tends to keep the Javascript engine optimized more often and reduces the need to do a fuzzy falsy check.

Sandbox

https://stackblitz.com/edit/vitejs-vite-ggyjmk?file=src/main.ts

Workarounds

  • Use pattern matching and make your own formats, ie: /^()|([isodate])$/
  • Use the fact that undefined is not a valid JSON value to delete optional properties when needed, this seems tricky and implementation error prone, specially with patch calls and Datastore inconsistencies.
  • Use the awful "0000-01-01T00:00:00.000Z" date.

Documentation lists unsupported formats

Hello.

The readme lists the supported formats, including:

  • byte: base64 encoded data
  • int32: signed 32 bits integer
  • int64: signed 64 bits integer
  • float: float
  • double: double
  • password: password string
  • binary: binary string

These are specified in OpenAPI specification, but not really supported by ajv-formats. Tested with version 2.0.2.

Thanks.

How to use with JTDSchema?

All examples I see use JSONSchema.

This is the shape I want to validate:

interface MyData {
  name: string;
  email: string;
}
import Ajv, { JTDDataType } from 'ajv/dist/jtd';
import addFormats from 'ajv-formats';

const ajv = new Ajv();
addFormats(ajv, ['email']);

const schema = {
  properties: {
    name: { type: 'string' },
    email: { type: 'string', format: 'email' }
  },
} as const;

const validate = ajv.compile<MyData>(schema);

const data: MyData = {
  name: 'John Doe',
  email: '[email protected]',
};

if (validate(data)) {
  // success!
}

However, i cannot get it to work. I'm using TypeScript v4.3.4.

The error I get is:

Error: schema is invalid: data/properties must NOT have additional properties, data must have property 'ref', data must have property 'type', data must have property 'enum', data must have property 'elements', data/properties/email/type must NOT have additional properties, data/properties/email must have property 'ref', data/properties/email/type must be equal to one of the allowed values, data/properties/email must have property 'enum', data/properties/email must have property 'elements', data/properties/email must have property 'properties', data/properties/email must have property 'optionalProperties', data/properties/email must have property 'discriminator', data/properties/email must have property 'values', data/properties/email must match a schema in union, data/optionalProperties/age/type must NOT have additional properties, data/optionalProperties/age must have property 'ref', data/optionalProperties/age/type must be equal to one of the allowed values, data/optionalProperties/age must have property 'enum', data/optionalProperties/age must have property 'elements', data/optionalProperties/age must have property 'properties', data/optionalProperties/age must have property 'optionalProperties', data/optionalProperties/age must have property 'discriminator', data/optionalProperties/age must have property 'values', data/optionalProperties/age must match a schema in union, data must have property 'discriminator', data must have property 'values', data must match a schema in union

opts is undefined

ajv.opts.code.formats ??= _`require("ajv-formats/dist/formats").${exportName}`

[error] TypeError: Cannot read properties of undefined (reading 'code')
at addFormats (D:\repos\GPD Analys\GPDAnalys\Presentation\GPD.Web.UI.V2\node_modules\ajv-formats\dist\index.js:30:26)
at formatsPlugin (D:\repos\GPD Analys\GPDAnalys\Presentation\GPD.Web.UI.V2\node_modules\ajv-formats\dist\index.js:15:5)
at new CoreSchemaRegistry (D:\repos\GPD Analys\GPDAnalys\Presentation\GPD.Web.UI.V2\node_modules@angular-devkit\core\src\json\schema\registry.js:92:35)
at runCommand (D:\repos\GPD Analys\GPDAnalys\Presentation\GPD.Web.UI.V2\node_modules@angular\cli\models\command-runner.js:114:22)
at default_1 (D:\repos\GPD Analys\GPDAnalys\Presentation\GPD.Web.UI.V2\node_modules@angular\cli\lib\cli\index.js:70:69)

Project builds when adding a ?.

ajv.opts?.code.formats ??= _require("ajv-formats/dist/formats").${exportName}

"resolutions": { "path-parse": "1.0.7", "ws": "7.5.6", "ajv": "6.12.6", "ajv-keywords": "3.5.2" }, "private": true, "dependencies": { "@angular/animations": "~13.1.0", "@angular/cdk": "^13.1.0", "@angular/common": "~13.1.0", "@angular/compiler": "~13.1.0", "@angular/core": "~13.1.0", "@angular/flex-layout": "13.0.0-beta.36", "@angular/forms": "~13.1.0", "@angular/localize": "^13.1.0", "@angular/platform-browser": "~13.1.0", "@angular/platform-browser-dynamic": "~13.1.0", "@angular/router": "~13.1.0", "@fortawesome/angular-fontawesome": "^0.10.1", "@fortawesome/fontawesome-svg-core": "^1.2.36", "@fortawesome/free-regular-svg-icons": "^5.15.4", "@fortawesome/free-solid-svg-icons": "^5.15.4", "@ng-bootstrap/ng-bootstrap": "^10.0.0", "bootstrap": "^4.6.0", "dayjs": "^1.10.4", "details-polyfill": "^1.2.0", "font-awesome": "^4.7.0", "geojson": "^0.5.0", "moment": "^2.29.1", "ng2-date-picker": "^11.0.0", "ngx-moment": "^5.0.0", "ol": "6.5.0", "proj4": "^2.7.2", "rxjs": "~7.4.0", "tslib": "^2.2.0", "zone.js": "~0.11.4" }, "devDependencies": { "@angular-devkit/build-angular": "~13.1.0", "@angular/cli": "13.1", "@angular/compiler-cli": "^13.1.0", "@angular/language-service": "^13.1.0", "@istanbuljs/nyc-config-typescript": "^1.0.1", "@types/jasmine": "~3.7.4", "@types/jasminewd2": "^2.0.9", "@types/node": "~15.6.0", "ajv": "^8.8.2", "ajv-formats": "^2.1.1", "ajv-keywords": "^5.1.0", "codelyzer": "^6.0.2", "jasmine-core": "~3.7.1", "jasmine-spec-reporter": "~7.0.0", "karma": "~6.3.2", "karma-chrome-launcher": "~3.1.0", "karma-coverage-istanbul-reporter": "~3.0.3", "karma-jasmine": "~4.0.1", "karma-jasmine-html-reporter": "^1.6.0", "nyc": "^15.1.0", "postcss": "8.2.15", "source-map-support": "^0.5.19", "ts-node": "~10.0.0", "tslint": "^6.1.3", "typescript": "4.4.4" },

Export formats separately, without scoping

Related issues

By scoping formats into fullFormats and fastFormats:

  • it's harder to do code generation as it's impossible to import a format in a single line
  • it makes it more complicated not to have multiple imports of the same variable

As a breaking change proposal, let's export two modules instead:

  • formats-fast.js
  • formats-full.js

This way, when doing code generation, it'd be possible to have a single line import:

import { int32 } from "ajv-formats/dist/formats-full"

ES5 compatible export to dist required ("target": "es5")

Hi,

There is object shorthand syntax in node_modules/ajv-formats/dist/formats.js.

exports.fullFormats = {
    // date: http://tools.ietf.org/html/rfc3339#section-5.6
    date,
    // date-time: http://tools.ietf.org/html/rfc3339#section-5.6
    time,

Can you add compilerOptions: { "target": "es5" } in tsconfig.json, please?
Without this I can't use module in IE11.

I have also tried importing node_modules/ajv-formats/src/index.ts.
But webpack 5 reports an error because of module.exports are used

module.exports = formatsPlugin

URI format to restrictive

URIs should be allowed to have characters outside of a-zA-z, e.g. ñ and other non-ascii characters.

Take into account ajv `code.esm` option

What version of Ajv are you using? Does the issue happen if you use the latest version?

8.11.0 (currently latest)

Ajv options object

import Ajv from "ajv"
import standaloneCode from "ajv/dist/standalone"
import ajvFormats from "ajv-formats"

const ajv = new Ajv({
  code: { esm: true, source: true },
})
ajvFormats(ajv)

const output = standaloneCode(ajv, validate)

JSON Schema

{
  "type": "object",
  "properties": {
    "example": { "type": "number", "format": "int32" }
  },
  "$schema": "http://json-schema.org/draft-07/schema"
}

Output

// ...
const formats0 = require(`ajv-formats/dist/formats`).fullFormats.int32
// ...

What results did you expect?

// this is kinda awkward, but that's the only way to make it work as of now in pure ESM w/o post-processing
import { fullFormats } from "ajv-formats/dist/formats"
const { int32 } = fullFormats

Are you going to resolve the issue?
I've tried to look into it, but it seems to be coupled with many ajv packages, so please let me know your proposal.

I believe the resolution should be done in multiple steps:

  1. the import should be used instead of require (this issue)
  2. ajv-formats should export every function separately, not scoped within fullFormats, fastFormats, etc. (#65)

Webpack unable to compile due to type discrepancies between ajv and ajv-formats

Hello, I'm trying to compile a typescript project using Webpack 5, but I'm running in the following error:

TS2345: Argument of type 'import(".../node_modules/ajv/dist/ajv").default' is not assignable to parameter of type 'import(".../node_modules/ajv-formats/node_modules/ajv/dist/core").default'.
  Types of property 'opts' are incompatible.
    Type 'import(".../node_modules/ajv/dist/core").InstanceOptions' is not assignable to type 'import(".../node_modules/ajv-formats/node_modules/ajv/dist/core").InstanceOptions'.
      Type 'InstanceOptions' is not assignable to type 'CurrentOptions'.
        Types of property 'keywords' are incompatible.

I'm using ajv v7.2.1 and ajv-formats v1.5.1 with the default code example:

import Ajv from "ajv"
import addFormats from "ajv-formats"

const ajv = new Ajv()
addFormats(ajv)

If I remove the line addFormats(ajv) it compiles fine.

Here is my tsconfig.js

{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "jsx": "react",
    "lib": [
      "dom",
      "ES2019"
    ],
    "module": "commonjs",
    "target": "ES2019",
    "allowJs": true,
    "sourceMap": true,
    "moduleResolution": "node",
    "skipLibCheck": true,
    "resolveJsonModule": true,
    "experimentalDecorators": true,
    "noEmitOnError": true,
    "removeComments": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "importHelpers": true,
    "noEmitHelpers": true,
    "forceConsistentCasingInFileNames": true,
    "esModuleInterop": true,
    "strict": true
  }
}

Any help would be much appreciated

uri-reference ?

hi,

The current format for uri-reference declares a fragment like #/paths/~1{id}/get/responses/404 invalid.
The fragment is considered valid if the curly braces are percent encoded as %7B and %7D.

I use AJV to validate openApi specs, and out of about 2300 real world specs about 7 fail because they have uri-reference with curly braces.

RFC 3986 is not very strict on what to encode and what not.
The What-wg url spec is more formal and states:

The C0 control percent-encode set are the C0 controls and all code points greater than U+007E (~).

The fragment percent-encode set is the C0 control percent-encode set and U+0020 SPACE, U+0022 ("), U+003C (<), U+003E (>), and U+0060 (`).

This would allow curly braces as valid.

Should AJV-formats follow the What-wg spec?

Kind regards,
Hans

Stable 3.0.0

Thank you for the great work you do. Is there already a plan, when you release 3.0.0 as stable?

float and double are hardcoded to return true without validation

Howdy;
I'm assuming ignorance on my part, as I haven't dug into this far enough, but according to these lines: https://github.com/ajv-validator/ajv-formats/blob/master/src/formats.ts#L79-L82

  // C-type float
  float: {type: "number", validate: validateNumber},
  // C-type double
  double: {type: "number", validate: validateNumber},

Both float and double depend on the validateNumber() function which is here: https://github.com/ajv-validator/ajv-formats/blob/master/src/formats.ts#L206-L208

function validateNumber(): boolean {
  return true
}

Is this actually validating anything? Is something else responsible for validation and this is just a pass-through of some sort? Again I apologize if I'm missing something basic.

Thanks!

Date-time with formatMinimum throws TypeError on validate

const Ajv = require('ajv/dist/2019').default;
const AjvFormats = require('ajv-formats');

// Instance
const ajv = new Ajv();
AjvFormats(ajv);

const schema = { 
  type: 'string',
  format: 'date-time',
  formatMinimum: '2020-01-01T00:00:00.000Z'
};

const validate = ajv.compile(schema);
console.log(validate('2020-01-01T00:00:00.000Z')); // Throws TypeError

// Works fine without formatMinimum
const schema2 = { 
  type: 'string',
  format: 'date-time'
};
const validate2 = ajv.compile(schema2);
console.log(validate2('2020-01-01T00:00:00.000Z')); 

Cannot read properties of undefined (reading 'code')



Cannot read properties of undefined (reading 'code')

TypeError: Cannot read properties of undefined (reading 'code')
    at addFormats (/home/ettinger/src/avenasea.com/avenasea-ui/node_modules/ajv-formats/dist/index.js:30:26)
    at Proxy.formatsPlugin (/home/ettinger/src/avenasea.com/avenasea-ui/node_modules/ajv-formats/dist/index.js:15:5)
    at [email protected]:8:12
	import Ajv from 'ajv';
	import addFormats from 'ajv-formats';

	const ajv = new Ajv({ allErrors: true, strictSchema: false });
	addFormats(ajv);

Date-time with no timezone is considered valid

I'm using Ajv 8.10.0, latest version as of this writing.

const Ajv = require("ajv")
const addFormats = require('ajv-formats')
const ajv = new Ajv()

addFormats(ajv)

const validate = ajv.compile({
    type: "string",
    format: "date-time"
})

console.log(validate('2018-01-26T00:18:49.000')) // true

An RFC3339 date time string with no timezone is valid, but since Ajv website says the time-zone is mandatory for the "date-time" format, I expected the code above to raise an error. It outputs true.

What am I missing? Is it expected behavior? If so, maybe the website should be updated.

Please add ajv to peer dependencies

TypeScript projects that use ajv and ajv-formats may have compilation errors after every upgrade. This is because a different version of ajv is installed under node_modules/ajv-formats/node_modules, the only way to solve this problem is to add ajv to the peer dependency of ajv-formats.

date-time accepts timestamps without `"T"` separator between date and time

According to the JSON Schema Validation spec, section 7.3.1 and ajv-formats' documentation, the date-time format should validate a string against the date-time production of RFC 3339, section 5.6.
This production requires the date and time components to be separated by "T" or "t".

The validation regex used in ajv-formats 2.1.1 however also accepts strings like "2023-01-22 11:11:11.123" with a whitespace character separating the date and time components (note the [t\s] portion):

/^\d\d\d\d-[0-1]\d-[0-3]\d[t\s](?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)$/i

This issue will be addressed in version 3. I am posting this issue for troubleshooting/documentation.

A workaround for ajv-formats 2.1.1 is to add a pattern() to the schema, e.g. using a slight variation of the regular expression used in ajv-formats 3:

S.string().format('date-time').pattern(/^\d\d\d\d-[0-1]\d-[0-3]\d[tT](?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:[zZ]|[+-]\d\d(?::?\d\d)?)$/)

Type Error using ajv-formats with ajv v8.11.0

I have a typescript project and am following instructions to add "date-time" as follows:

let ajv = new Ajv({ allErrors: true});
addFormats(ajv, ["date-time"]);

but getting the following error for "ajv", the first argument to addFormats:
Type 'Ajv' is missing the following properties from type 'Ajv': opts, logger, scope, schemas, and 17 more.

My tsconfig is as follows:

{
  "compilerOptions": {
    "module": "CommonJS",
    "target": "ES2020",
    "noImplicitAny": true,
    "preserveConstEnums": true,
    "outDir": "./build",
    "sourceMap": true,
    "esModuleInterop": true,
    "resolveJsonModule": true,
    "moduleResolution": "node"
  },
  "exclude": ["node_modules"],
  "include": ["my-project/src/**/*", "docs/**/*.json"]
}

The only way I was able to get it working was by initializing ajv as 'any' type, which doesn't seem ideal. Any ideas as to what could be the issue?

Error: unknown format "iso-date-time"

In testing, I've run across the following error -

Error: unknown format "iso-date-time" ignored in schema at path "#/properties/schema/properties/created"

I am using the following code:

const Ajv = require("ajv")
var addFormats = require("ajv-formats")

const ajv = new Ajv({allErrors: true})
addFormats(ajv, ["iso-date-time","uri"])

const schema = {
  type: "object",
  properties: {
    foo: {type: "string", "format": "uri"},
    bar: {type: "string", "format": "iso-date-time"}
  },
  additionalProperties: false,
}

const validate = ajv.compile(schema)

test({foo:"https://google.com",bar: "2022-06-11T00:11:59.000Z"})

function test(data) {
  const valid = validate(data)
  if (valid) console.log("Valid!")
  else console.log("Invalid: " + ajv.errorsText(validate.errors))
}

The "format": "uri" validates correctly, but the "format": "iso-date-time" throws an error.

Any help appreciated!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.