Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(json-schema): support propertyNames for sample generation #9739

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -2,9 +2,9 @@
* @prettier
*/

import Registry from "../class/Registry"
import FormatRegistry from "../class/FormatRegistry"

const registry = new Registry()
const registry = new FormatRegistry()

const formatAPI = (format, generator) => {
if (typeof generator === "function") {
Expand All @@ -15,5 +15,6 @@ const formatAPI = (format, generator) => {

return registry.get(format)
}
formatAPI.getDefaults = () => registry.defaults

export default formatAPI
@@ -0,0 +1,65 @@
/**
* @prettier
*/
import Registry from "./Registry"
import int32Generator from "../generators/int32"
import int64Generator from "../generators/int64"
import floatGenerator from "../generators/float"
import doubleGenerator from "../generators/double"
import emailGenerator from "../generators/email"
import idnEmailGenerator from "../generators/idn-email"
import hostnameGenerator from "../generators/hostname"
import idnHostnameGenerator from "../generators/idn-hostname"
import ipv4Generator from "../generators/ipv4"
import ipv6Generator from "../generators/ipv6"
import uriGenerator from "../generators/uri"
import uriReferenceGenerator from "../generators/uri-reference"
import iriGenerator from "../generators/iri"
import iriReferenceGenerator from "../generators/iri-reference"
import uuidGenerator from "../generators/uuid"
import uriTemplateGenerator from "../generators/uri-template"
import jsonPointerGenerator from "../generators/json-pointer"
import relativeJsonPointerGenerator from "../generators/relative-json-pointer"
import dateTimeGenerator from "../generators/date-time"
import dateGenerator from "../generators/date"
import timeGenerator from "../generators/time"
import durationGenerator from "../generators/duration"
import passwordGenerator from "../generators/password"
import regexGenerator from "../generators/regex"

class FormatRegistry extends Registry {
#defaults = {
int32: int32Generator,
int64: int64Generator,
float: floatGenerator,
double: doubleGenerator,
email: emailGenerator,
"idn-email": idnEmailGenerator,
hostname: hostnameGenerator,
"idn-hostname": idnHostnameGenerator,
ipv4: ipv4Generator,
ipv6: ipv6Generator,
uri: uriGenerator,
"uri-reference": uriReferenceGenerator,
iri: iriGenerator,
"iri-reference": iriReferenceGenerator,
uuid: uuidGenerator,
"uri-template": uriTemplateGenerator,
"json-pointer": jsonPointerGenerator,
"relative-json-pointer": relativeJsonPointerGenerator,
"date-time": dateTimeGenerator,
date: dateGenerator,
time: timeGenerator,
duration: durationGenerator,
password: passwordGenerator,
regex: regexGenerator,
}

data = { ...this.#defaults }

get defaults() {
return { ...this.#defaults }
}
}

export default FormatRegistry
22 changes: 22 additions & 0 deletions src/core/plugins/json-schema-2020-12-samples/fn/core/example.js
Expand Up @@ -55,3 +55,25 @@ export const extractExample = (schema) => {

return undefined
}

export const extractExamples = (schema) => {
if (!isJSONSchemaObject(schema)) return []

const { examples, example, default: defaultVal } = schema

let allExamples = []

if (typeof defaultVal !== "undefined") {
allExamples.push(defaultVal)
}

if (Array.isArray(examples) && examples.length >= 1) {
allExamples.push(...examples)
}

if (typeof example !== "undefined") {
allExamples.push(example)
}

return allExamples
}
8 changes: 8 additions & 0 deletions src/core/plugins/json-schema-2020-12-samples/fn/core/utils.js
Expand Up @@ -21,3 +21,11 @@ export const typeCast = (schema) => {

return schema
}

export const padZeros = (number, targetLength) => {
let numString = "" + number
while (numString.length < targetLength) {
numString = "0" + numString
}
return numString
}
@@ -1,6 +1,9 @@
/**
* @prettier
*/
const dateTimeGenerator = () => new Date().toISOString()
import { padZeros } from "../core/utils"

const dateTimeGenerator = (_, {idx} = {}) =>
Number.isInteger(idx) ? `2${padZeros(idx, 3)}-10-04T20:20:39Z` : new Date().toISOString()

export default dateTimeGenerator
@@ -1,6 +1,9 @@
/**
* @prettier
*/
const dateGenerator = () => new Date().toISOString().substring(0, 10)
import { padZeros } from "../core/utils"

const dateGenerator = (_, {idx} = {}) =>
Number.isInteger(idx) ? `2${padZeros(idx, 3)}-10-04` : new Date().toISOString().substring(0, 10)

export default dateGenerator
@@ -1,6 +1,7 @@
/**
* @prettier
*/
const durationGenerator = () => "P3D" // expresses a duration of 3 days
const durationGenerator = (_, {idx} = {}) =>
Number.isInteger(idx) ? `P${idx}D` : "P3D" // expresses a duration of 3 days

export default durationGenerator
@@ -1,6 +1,7 @@
/**
* @prettier
*/
const emailGenerator = () => "user@example.com"
const emailGenerator = (_, {idx} = {}) =>
Number.isInteger(idx) ? `user${idx}@example.com` : "user@example.com"

export default emailGenerator
@@ -1,6 +1,7 @@
/**
* @prettier
*/
const hostnameGenerator = () => "example.com"
const hostnameGenerator = (_, {idx} = {}) =>
Number.isInteger(idx) ? `example${idx}.com` : "example.com"

export default hostnameGenerator
@@ -1,6 +1,7 @@
/**
* @prettier
*/
const idnEmailGenerator = () => "실례@example.com"
const idnEmailGenerator = (_, {idx} = {}) =>
Number.isInteger(idx) ? `실례${idx}@example.com` : "실례@example.com"

export default idnEmailGenerator
@@ -1,6 +1,7 @@
/**
* @prettier
*/
const idnHostnameGenerator = () => "실례.com"
const idnHostnameGenerator = (_, {idx} = {}) =>
Number.isInteger(idx) ? `실례${idx}.com` : "실례.com"

export default idnHostnameGenerator
@@ -1,6 +1,7 @@
/**
* @prettier
*/
const ipv4Generator = () => "198.51.100.42"
const ipv4Generator = (_, {idx} = {}) =>
Number.isInteger(idx) ? `198.51.${idx}.42` : "198.51.100.42"

export default ipv4Generator
@@ -1,6 +1,9 @@
/**
* @prettier
*/
const ipv6Generator = () => "2001:0db8:5b96:0000:0000:426f:8e17:642a"
import { padZeros } from "../core/utils"

const ipv6Generator = (_, {idx} = {}) =>
Number.isInteger(idx) ? `2${padZeros(idx, 3)}:0db8:5b96:0000:0000:426f:8e17:642a` : "2001:0db8:5b96:0000:0000:426f:8e17:642a"

export default ipv6Generator
@@ -1,6 +1,7 @@
/**
* @prettier
*/
const iriReferenceGenerator = () => "path/실례.html"
const iriReferenceGenerator = (_, {idx} = {}) =>
Number.isInteger(idx) ? `path${idx}/실례.html` : "path/실례.html"

export default iriReferenceGenerator
@@ -1,6 +1,7 @@
/**
* @prettier
*/
const iriGenerator = () => "https://실례.com/"
const iriGenerator = (_, {idx} = {}) =>
Number.isInteger(idx) ? `https://실례${idx}.com/` : "https://실례.com/"

export default iriGenerator
@@ -1,6 +1,7 @@
/**
* @prettier
*/
const jsonPointerGenerator = () => "/a/b/c"
const jsonPointerGenerator = (_, {idx} = {}) =>
Number.isInteger(idx) ? `/a${idx}/b/c` : "/a/b/c"

export default jsonPointerGenerator
Expand Up @@ -5,12 +5,12 @@ import { bytes } from "../../core/random"

// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
const applicationMediaTypesGenerators = {
"application/json": () => '{"key":"value"}',
"application/ld+json": () => '{"name": "John Doe"}',
"application/x-httpd-php": () => "<?php echo '<p>Hello World!</p>'; ?>",
"application/rtf": () => String.raw`{\rtf1\adeflang1025\ansi\ansicpg1252\uc1`,
"application/x-sh": () => 'echo "Hello World!"',
"application/xhtml+xml": () => "<p>content</p>",
"application/json": (_, {idx} = {}) => Number.isInteger(idx) ? `{"key${idx}":"value${idx}"}` : '{"key":"value"}',
"application/ld+json": (_, {idx} = {}) => Number.isInteger(idx) ? `{"name": "John Doe${idx}"}` : '{"name": "John Doe"}',
"application/x-httpd-php": (_, {idx} = {}) => Number.isInteger(idx) ? `<?php echo '<p>Hello World${idx}!</p>'; ?>` : "<?php echo '<p>Hello World!</p>'; ?>",
"application/rtf": (_, {idx} = {}) => Number.isInteger(idx) ? String.raw`{\rtf1\adeflang${idx}025\ansi\ansicpg1252\uc1` : String.raw`{\rtf1\adeflang1025\ansi\ansicpg1252\uc1`,
"application/x-sh": (_, {idx} = {}) => Number.isInteger(idx) ? `echo "Hello World${idx}!"` : 'echo "Hello World!"',
"application/xhtml+xml": (_, {idx} = {}) => Number.isInteger(idx) ? `<p>content${idx}</p>` : "<p>content</p>",
"application/*": () => bytes(25).toString("binary"),
}

Expand Down
Expand Up @@ -4,14 +4,14 @@

// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
const textMediaTypesGenerators = {
"text/plain": () => "string",
"text/css": () => ".selector { border: 1px solid red }",
"text/csv": () => "value1,value2,value3",
"text/html": () => "<p>content</p>",
"text/calendar": () => "BEGIN:VCALENDAR",
"text/javascript": () => "console.dir('Hello world!');",
"text/xml": () => '<person age="30">John Doe</person>',
"text/*": () => "string",
"text/plain": (_, {idx} = {}) => Number.isInteger(idx) ? `string${idx}` : "string",
"text/css": (_, {idx} = {}) => Number.isInteger(idx) ? `.selector { border: ${idx}px solid red }` : ".selector { border: 1px solid red }",
"text/csv": (_, {idx} = {}) => Number.isInteger(idx) ? `value${idx},value${idx+1},value${idx+2}` : "value1,value2,value3",
"text/html": (_, {idx} = {}) => Number.isInteger(idx) ? `<p>content${idx}</p>` : "<p>content</p>",
"text/calendar": (_, {idx} = {}) => Number.isInteger(idx) ? `BEGIN:VCALENDAR\nSEQUENCE:${idx}` : "BEGIN:VCALENDAR",
"text/javascript": (_, {idx} = {}) => Number.isInteger(idx) ? `console.dir('Hello world${idx}!');` : "console.dir('Hello world!');",
"text/xml": (_, {idx} = {}) => Number.isInteger(idx) ? `<person age="${idx}">John Doe</person>` : '<person age="30">John Doe</person>',
"text/*": (_, {idx} = {}) => Number.isInteger(idx) ? `string${idx}` : "string",
}

export default textMediaTypesGenerators
@@ -1,6 +1,7 @@
/**
* @prettier
*/
const regexGenerator = () => "^[a-z]+$"
const regexGenerator = (_, {idx} = {}) =>
Number.isInteger(idx) ? `^[a-z]{${idx}}$` : "^[a-z]+$"

export default regexGenerator
@@ -1,6 +1,7 @@
/**
* @prettier
*/
const relativeJsonPointerGenerator = () => "1/0"
const relativeJsonPointerGenerator = (_, {idx} = {}) =>
Number.isInteger(idx) ? idx + "/0" : "1/0"

export default relativeJsonPointerGenerator
@@ -1,6 +1,9 @@
/**
* @prettier
*/
const timeGenerator = () => new Date().toISOString().substring(11)
import { padZeros } from "../core/utils"

const timeGenerator = (_, {idx} = {}) =>
Number.isInteger(idx) ? `20:20:${padZeros(idx, 2)}Z` : new Date().toISOString().substring(11)

export default timeGenerator
@@ -1,6 +1,7 @@
/**
* @prettier
*/
const uriReferenceGenerator = () => "path/index.html"
const uriReferenceGenerator = (_, {idx} = {}) =>
Number.isInteger(idx) ? `path${idx}/index.html` : "path/index.html"

export default uriReferenceGenerator
@@ -1,7 +1,7 @@
/**
* @prettier
*/
const uriTemplateGenerator = () =>
"https://example.com/dictionary/{term:1}/{term}"
const uriTemplateGenerator = (_, {idx} = {}) =>
Number.isInteger(idx) ? `https://example${idx}.com/dictionary/{term:1}/{term}` : "https://example.com/dictionary/{term:1}/{term}"

export default uriTemplateGenerator
@@ -1,6 +1,7 @@
/**
* @prettier
*/
const uriGenerator = () => "https://example.com/"
const uriGenerator = (_, {idx} = {}) =>
Number.isInteger(idx) ? `https://example${idx}.com/` : "https://example.com/"

export default uriGenerator
@@ -1,6 +1,9 @@
/**
* @prettier
*/
const uuidGenerator = () => "3fa85f64-5717-4562-b3fc-2c963f66afa6"
import { padZeros } from "../core/utils"

const uuidGenerator = (_, {idx} = {}) =>
Number.isInteger(idx) ? padZeros(idx, 8) + "-5717-4562-b3fc-2c963f66afa6" : "3fa85f64-5717-4562-b3fc-2c963f66afa6"

export default uuidGenerator