Skip to content

Commit

Permalink
support uuid format validation (#101)
Browse files Browse the repository at this point in the history
- see #99

uuid format validation and sets up future format validation
  • Loading branch information
Elmer Bulthuis authored May 5, 2024
1 parent 097f107 commit f3d4f8f
Show file tree
Hide file tree
Showing 18 changed files with 144 additions and 154 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ node_modules/
target/
coverage/
transpiled/
types/
typed/
bundled/
out/
bin/
Expand Down
2 changes: 1 addition & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
transpiled/
types/
typed/
bundled/
4 changes: 0 additions & 4 deletions JsonSchema42.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@
"name": "fixtures",
"path": "fixtures",
},
{
"name": "schema-intermediate",
"path": "packages/oas/schema-intermediate",
},
{
"name": "npm/jns42-generator",
"path": "packages/npm/jns42-generator",
Expand Down
14 changes: 0 additions & 14 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ clean: \
rm -rf generated
rm -rf target


generated/npm: \
generated/npm/schema-intermediate \
generated/npm/schema-draft-04 \
generated/npm/schema-draft-2020-12 \
generated/npm/schema-oas-v3-1 \
Expand All @@ -27,18 +25,6 @@ generated/npm: \
# Link the generated code, but don't save those links to the package lock
npm install --no-package-lock

generated/cargo: \
generated/cargo/schema-intermediate \


generated/npm/schema-intermediate: packages/oas/schema-intermediate/src/schema.yaml
mkdir -p $(@D)

npx jns42-generator package $< \
--package-directory $@ \
--package-name @jns42/$(notdir $(basename $@)) \
--package-version $(shell npx jns42-generator --version) \

generated/npm/schema-draft-04:
mkdir -p $(@D)

Expand Down
1 change: 1 addition & 0 deletions cspell.config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
version: "0.2"
words:
- ABNF
- automagically
- bindgen
- Bulthuis
Expand Down
28 changes: 28 additions & 0 deletions fixtures/testing/uuid-or-handle.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
$schema: "./schema.json"

rootTypeName: UuidOrHandleYaml

schemas:
draft_2020-12:
$schema: "https://json-schema.org/draft/2020-12/schema"
oneOf:
- $ref: "#/$defs/uuid"
- $ref: "#/$defs/handle"
$defs:
uuid:
type: string
format: uuid
handle:
type: string
minLength: 5
pattern: ^[a-z0-9]+$
not:
format: uuid

valid:
uuid: 3e4666bf-d5e5-4aa7-b8ce-cefe41c7568a
handle: handle123

invalid:
not-uuid: 3e4666bf-d5e5-4aa7-b8ce-cefe41c7568x
not-handle: handle-123
6 changes: 3 additions & 3 deletions packages/npm/jns42-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@
"type": "module",
"main": "./bundled/main.cjs",
"module": "./bundled/main.js",
"types": "./types/main.d.ts",
"types": "./typed/main.d.ts",
"exports": {
".": {
"require": "./bundled/main.cjs",
"import": "./bundled/main.js",
"types": "./types/main.d.ts"
"types": "./typed/main.d.ts"
}
},
"files": [
"./types/**",
"./typed/**",
"./bundled/**",
"./bin/**"
],
Expand Down
4 changes: 2 additions & 2 deletions packages/npm/jns42-core/src/imports/schema-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ export type SchemaItemValue<K> = {
multipleOf?: number;
minimumLength?: number;
maximumLength?: number;
valuePattern?: string[];
valueFormat?: string[];
valuePattern?: string;
valueFormat?: string;
minimumItems?: number;
maximumItems?: number;
uniqueItems?: boolean;
Expand Down
2 changes: 1 addition & 1 deletion packages/npm/jns42-core/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"compilerOptions": {
"rootDir": "./src",
"outDir": "./transpiled",
"declarationDir": "./types",
"declarationDir": "./typed",
"sourceMap": true,
"declaration": true,
"composite": true,
Expand Down
6 changes: 3 additions & 3 deletions packages/npm/jns42-generator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@
"type": "module",
"main": "./bundled/main.cjs",
"module": "./bundled/main.js",
"types": "./types/main.d.ts",
"types": "./typed/main.d.ts",
"exports": {
".": {
"require": "./bundled/main.cjs",
"import": "./bundled/main.js",
"types": "./types/main.d.ts"
"types": "./typed/main.d.ts"
}
},
"files": [
"./types/**",
"./typed/**",
"./bundled/**"
],
"bin": {
Expand Down
2 changes: 1 addition & 1 deletion packages/npm/jns42-generator/src/generators/clean-js.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function* generateCleanJsCode() {

yield itt`
fs.rmSync(path.resolve("transpiled"), { recursive: true, force: true });
fs.rmSync(path.resolve("types"), { recursive: true, force: true });
fs.rmSync(path.resolve("typed"), { recursive: true, force: true });
fs.rmSync(path.resolve("bundled"), { recursive: true, force: true });
`;
}
6 changes: 3 additions & 3 deletions packages/npm/jns42-generator/src/generators/package-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ export function generatePackageJsonData(name: string, version: string) {
type: "module",
main: "./bundled/main.cjs",
module: "./bundled/main.js",
types: "./types/main.d.ts",
types: "./typed/main.d.ts",
exports: {
".": {
require: "./bundled/main.cjs",
import: "./bundled/main.js",
types: "./types/main.d.ts",
types: "./typed/main.d.ts",
},
},
files: ["./types/**", "./bundled/**"],
files: ["./typed/**", "./bundled/**"],
scripts: {
prepack: "node ./scripts/build.js",
pretest: "tsc",
Expand Down
2 changes: 1 addition & 1 deletion packages/npm/jns42-generator/src/generators/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export function generatePackage(
!.gitignore
*.tsbuildinfo
transpiled/
types/
typed/
bundled/
`;
const filePath = path.join(packageDirectoryPath, ".gitignore");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export function generateTsconfigJsonData() {
compilerOptions: {
rootDir: "./src",
outDir: "./transpiled",
declarationDir: "./types",
declarationDir: "./typed",
sourceMap: true,
declaration: true,
composite: true,
Expand Down
98 changes: 97 additions & 1 deletion packages/npm/jns42-generator/src/generators/validators-ts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,8 @@ export function* generateValidatorsTsCode(specification: models.Specification) {
if (
itemValue.minimumLength != null ||
itemValue.maximumLength != null ||
itemValue.valuePattern != null
itemValue.valuePattern != null ||
itemValue.valueFormat != null
) {
yield itt`
if(
Expand Down Expand Up @@ -351,6 +352,21 @@ export function* generateValidatorsTsCode(specification: models.Specification) {
}
`;
}

if (itemValue.valueFormat != null) {
const isValueFormatExpression = getValueFormatExpression(
itemValue.valueFormat,
valueExpression,
);
yield itt`
if(
!${isValueFormatExpression}
) {
recordError("valueFormat");
return false;
}
`;
}
}
}

Expand Down Expand Up @@ -788,3 +804,83 @@ export function* generateValidatorsTsCode(specification: models.Specification) {
`;
}
}

/**
* @see https://json-schema.org/understanding-json-schema/reference/string#built-in-formats
*/
function getValueFormatExpression(format: string, expression: string) {
switch (format) {
case "date-time": // Date and time together, for example, 2018-11-13T20:20:39+00:00.
return JSON.stringify(true);

case "time": // New in draft 7
// Time, for example, 20:20:39+00:00
return JSON.stringify(true);

case "date": // New in draft 7
// Date, for example, 2018-11-13.
return `/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/.test(${expression})`;

case "duration": // New in draft 2019-09
// A duration as defined by the ISO 8601 ABNF for "duration". For example, P3D expresses a duration of 3 days.
return JSON.stringify(true);

case "email": // Internet email address, see RFC 5321, section 4.1.2.
return JSON.stringify(true);

case "idn-email": // New in draft 7
// The internationalized form of an Internet email address, see RFC 6531.
return JSON.stringify(true);

case "hostname": // Internet host name, see RFC 1123, section 2.1.
return JSON.stringify(true);

case "idn-hostname": // New in draft 7
// An internationalized Internet host name, see RFC5890, section 2.3.2.3.
return JSON.stringify(true);

case "ipv4": // IPv4 address, according to dotted-quad ABNF syntax as defined in RFC 2673, section 3.2.
return JSON.stringify(true);

case "ipv6": // IPv6 address, as defined in RFC 2373, section 2.2.
return JSON.stringify(true);

case "uuid": // New in draft 2019-09
// A Universally Unique Identifier as defined by RFC 4122. Example: 3e4666bf-d5e5-4aa7-b8ce-cefe41c7568a
return `/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(${expression})`;

case "uri": // A universal resource identifier (URI), according to RFC3986.
return JSON.stringify(true);

case "uri-reference": // New in draft 6
// A URI Reference (either a URI or a relative-reference), according to RFC3986, section 4.1.
return JSON.stringify(true);

case "iri": // New in draft 7
// The internationalized equivalent of a "uri", according to RFC3987.
return JSON.stringify(true);

case "iri-reference": //New in draft 7
// The internationalized equivalent of a "uri-reference", according to RFC3987
return JSON.stringify(true);

case "uri-template": // New in draft 6
// A URI Template (of any level) according to RFC6570. If you don't already know what a URI Template is, you probably don't need this value.
return JSON.stringify(true);

case "json-pointer": // New in draft 6
// A JSON Pointer, according to RFC6901. There is more discussion on the use of JSON Pointer within JSON Schema in Structuring a complex schema. Note that this should be used only when the entire string contains only JSON Pointer content, e.g. /foo/bar. JSON Pointer URI fragments, e.g. #/foo/bar/ should use "uri-reference".
return JSON.stringify(true);

case "relative-json-pointer": // New in draft 7
// A relative JSON pointer.
return JSON.stringify(true);

case "regex": // New in draft 7
// A regular expression, which should be valid according to the ECMA 262 dialect.
return JSON.stringify(true);

default:
return JSON.stringify(true);
}
}
2 changes: 1 addition & 1 deletion packages/npm/jns42-generator/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"compilerOptions": {
"rootDir": "./src",
"outDir": "./transpiled",
"declarationDir": "./types",
"declarationDir": "./typed",
"sourceMap": true,
"declaration": true,
"composite": true,
Expand Down
4 changes: 0 additions & 4 deletions packages/oas/schema-intermediate/.vscode/extensions.json

This file was deleted.

Loading

0 comments on commit f3d4f8f

Please sign in to comment.