Skip to content

Instantly share code, notes, and snippets.

@ottomata
Created June 23, 2020 16:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ottomata/66ecec333b32d4e21e8c1ea53c02e487 to your computer and use it in GitHub Desktop.
Save ottomata/66ecec333b32d4e21e8c1ea53c02e487 to your computer and use it in GitHub Desktop.
#!/usr/bin/env node
'use strict';
const fetch = require('node-fetch');
const jsTools = require('@wikimedia/jsonschema-tools');
/**
* Recurses through schema converting Draft 4 JSONSchema style
* required to Draft 7.
* @param {Object} schema
* @return {Object}
*/
function convertDraft4RequiredProperties( schema ) {
if ('properties' in schema) {
const required = [];
for (const [propertyName, property] of Object.entries(schema.properties)) {
if (property.type == 'object') {
schema.properties[propertyName] = convertDraft4RequiredProperties(property);
} else if ('required' in property) {
required.push(propertyName);
delete schema.properties[propertyName]['required'];
}
}
if (required.length > 0) {
schema.required = schema.required || [];
schema.required = schema.required.concat(required);
}
}
return schema;
}
function eventLoggingSchemaNameToMetaUrl(schemaName) {
return `https://meta.wikimedia.org/w/api.php?action=jsonschema&format=json&formatversion=2&title=${schemaName}`;
}
function eventLoggingSchemaNameToTitle(schemaName) {
return `analytics/legacy/${schemaName.toLowerCase()}`;
}
function eventLoggingSchemaNameToRelativePath(schemaName) {
return '/' + eventLoggingSchemaNameToTitle(schemaName);
}
function eventLoggingSchemaNameToFileUri(schemaName, filename) {
return eventLoggingSchemaNameToRelativePath(schemaName) + `/${filename}`;
}
function eventLoggingSchemaNameToCurrentFile(schemaName) {
return eventLoggingSchemaNameToCurrentFile(schemaName, 'current.yaml');
}
async function getEventLoggingSchema(schemaName) {
const schemaUrl = eventLoggingSchemaNameToMetaUrl(schemaName);
const response = await fetch(schemaUrl);
if (response.ok) {
return response.json();
} else {
throw new Error(response.statusText + "\n" + await response.text());
}
}
const legacySchemaTemplate = {
"$schema": "https://json-schema.org/draft-07/schema#",
"type": "object",
"allOf": [
{
"$ref": "/fragment/analytics/legacy/eventcapsule/1.1.0#"
},
],
"examples": []
}
const exampleTemplate = {"event":{"key1": "val1"},"meta":{"dt":"2020-04-02T19:11:20.942Z","id":"b0caf18d-6c7f-4403-947d-2712bbe28610","request_id":"bd54dd80-7515-11ea-98e5-fd72443e8b45"},"dt":"2020-04-02T19:11:20.942Z","client_dt":"2020-04-02T19:11:20.942Z","http":{"client_ip":"10.0.2.2","request_headers":{"user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"}}}
const capsuleSchemaUri = '/fragment/analytics/legacy/eventcapsule/1.1.0';
let capsuleSchema;
async function convertEventLoggingSchema(schemaName) {
const eventSubSchema = await getEventLoggingSchema(schemaName);
const newSchema = Object.assign({}, legacySchemaTemplate);
newSchema.description = eventSubSchema.description;
newSchema.title = eventLoggingSchemaNameToTitle(schemaName);
newSchema.$id = eventLoggingSchemaNameToFileUri(schemaName, '1.0.0');
eventSubSchema.type = 'object';
delete eventSubSchema.title;
delete eventSubSchema.description;
const eventSubProperties = convertDraft4RequiredProperties({
required: ['event'],
properties: {
event: eventSubSchema
}
});
newSchema.allOf.push(eventSubProperties)
const example = Object.assign({}, exampleTemplate);
example.$schema = newSchema.$id;
example.meta.stream = `eventlogging_${schemaName}`;
newSchema.examples.push(example);
return newSchema;
}
const scriptName = process.argv[1].substr(process.argv[1].lastIndexOf('/') + 1);
const usage = `${scriptName} <SchemaName>`;
async function main(args) {
if (args.length <= 0 || args[0] == 'help' || args[0].includes('--')) {
console.error(`Must provide SchemaName\n${usage}\n`);
process.exit(1);
}
const schemaName = args[0];
try {
const s = await convertEventLoggingSchema(schemaName);
console.log(jsTools.serialize(s, 'yaml'));
} catch(err) {
console.error(err);
process.exit(1);
}
}
main(process.argv.slice(2));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment