-
Notifications
You must be signed in to change notification settings - Fork 91
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
Add extended JSON file build output #1407
Changes from all commits
33f243d
291bf4d
2bb0da7
bfaf30b
563381c
b3be4b1
054b219
c95aefd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,3 +21,4 @@ | |
!/scripts/find-troublesome-ancestors.ts | ||
!/scripts/release.ts | ||
!/scripts/update-drafts.ts | ||
!/scripts/validate.ts |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,21 @@ | ||
import { basename } from "node:path"; | ||
import { DefinedError } from "ajv"; | ||
import { getStatus } from "compute-baseline"; | ||
import stringify from "fast-json-stable-stringify"; | ||
import { execSync } from "node:child_process"; | ||
import fs from "node:fs"; | ||
import stringify from "fast-json-stable-stringify"; | ||
import { basename } from "node:path"; | ||
import winston from "winston"; | ||
import yargs from "yargs"; | ||
import * as data from "../index.js"; | ||
import { validate } from "./validate.js"; | ||
|
||
const logger = winston.createLogger({ | ||
format: winston.format.combine( | ||
winston.format.colorize(), | ||
winston.format.simple(), | ||
), | ||
transports: new winston.transports.Console(), | ||
}); | ||
|
||
const rootDir = new URL("..", import.meta.url); | ||
|
||
|
@@ -14,14 +26,23 @@ yargs(process.argv.slice(2)) | |
describe: "Generate the web-features npm package", | ||
handler: buildPackage, | ||
}) | ||
.command({ | ||
command: "extended-json", | ||
describe: "Generate a web-features JSON file with BCD per-key statuses", | ||
handler: buildExtendedJSON, | ||
}) | ||
.parseSync(); | ||
|
||
function buildPackage() { | ||
const packageDir = new URL("./packages/web-features/", rootDir); | ||
const filesToCopy = ["LICENSE.txt", "types.ts", "schemas/data.schema.json"]; | ||
|
||
if (!valid(data)) { | ||
logger.error("Data failed schema validation. No package built."); | ||
process.exit(1); | ||
} | ||
|
||
const json = stringify(data); | ||
// TODO: Validate the resulting JSON against a schema. | ||
Comment on lines
+40
to
-24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since I had to figure out how to validate the built JSON against the schema for the extended JSON, I did the same for the packaged one. |
||
const path = new URL("data.json", packageDir); | ||
fs.writeFileSync(path, json); | ||
for (const file of filesToCopy) { | ||
|
@@ -39,3 +60,42 @@ function buildPackage() { | |
encoding: "utf-8", | ||
}); | ||
} | ||
|
||
function buildExtendedJSON() { | ||
for (const [id, featureData] of Object.entries(data.features)) { | ||
if ( | ||
Array.isArray(featureData.compat_features) && | ||
featureData.compat_features.length && | ||
featureData.status | ||
) { | ||
featureData.status.by_compat_key = {}; | ||
for (const key of featureData.compat_features) { | ||
featureData.status.by_compat_key[key] = getStatus(id, key); | ||
} | ||
} | ||
} | ||
|
||
if (!valid(data)) { | ||
logger.error("Data failed schema validation. No JSON file written."); | ||
process.exit(1); | ||
} | ||
|
||
fs.writeFileSync( | ||
new URL("./web-features.extended.json", rootDir), | ||
stringify(data), | ||
); | ||
} | ||
|
||
function valid(data: any): boolean { | ||
const valid = validate(data); | ||
if (!valid) { | ||
// TODO: turn on strictNullChecks, fix all the errors, and replace this with: | ||
// const errors = validate.errors; | ||
const errors = (valid as any).errors as DefinedError[]; | ||
Comment on lines
+91
to
+94
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a bit ugly because ajv can't produce (useful) types without |
||
for (const error of errors) { | ||
logger.error(`${error.instancePath}: ${error.message}`); | ||
} | ||
return false; | ||
} | ||
return true; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import Ajv from "ajv"; | ||
import addFormats from "ajv-formats"; | ||
import assert from "node:assert/strict"; | ||
|
||
import * as schema from "../schemas/data.schema.json" with { type: "json" }; | ||
|
||
export function validate(data: any) { | ||
const ajv = new Ajv({ allErrors: true, allowUnionTypes: true }); | ||
Comment on lines
+7
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I consolidated compiling the schema here, so that we can have one place with settings (and to check that we don't do something foolish like validate nothing at all). |
||
addFormats(ajv); | ||
// TODO: turn on strictNullChecks, fix all the errors, and replace this with: | ||
// const validator = ajv.compile<WebFeaturesData>(schema); | ||
const validator = ajv.compile(schema); | ||
|
||
assert.equal( | ||
validator({}), | ||
false, | ||
"Failed confidence check: schema validates empty object", | ||
); | ||
|
||
return validator; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This bit is pretty serious:
I figured out what that top-level
$ref
was for. Without it, it was just a list of definitions without asserting anything using those definitions. Without this option, any object will pass validation against our schema. 🙄There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh... let's put it back!