File size: 2,400 Bytes
2070f43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#!/usr/bin/env node

import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import Ajv2020 from 'ajv/dist/2020.js';
import standaloneCode from 'ajv/dist/standalone/index.js';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const root = path.resolve(__dirname, '..');
const schemasDir = path.join(root, 'schemas');
const output = path.join(root, 'renderers/shared/generated-validators.mjs');
const diagramTypes = ['workflow', 'sequence', 'dataflow', 'lifecycle', 'architecture'];

const ajv = new Ajv2020({
  allErrors: true,
  strict: true,
  code: { source: true, esm: true },
});
ajv.addSchema(JSON.parse(fs.readFileSync(path.join(schemasDir, 'common.schema.json'), 'utf8')));

const schemaIds = {};
for (const type of diagramTypes) {
  const schema = JSON.parse(fs.readFileSync(path.join(schemasDir, `${type}.schema.json`), 'utf8'));
  ajv.addSchema(schema);
  schemaIds[type] = schema.$id;
}

const banner = '// Generated by scripts/generate-validators.mjs. Do not edit by hand.\n';
const ajvUcs2Import = 'require("ajv/dist/runtime/ucs2length").default';
const inlineUcs2Length = `function ucs2length(str) {
  const len = str.length;
  let length = 0;
  let pos = 0;
  while (pos < len) {
    length += 1;
    const value = str.charCodeAt(pos++);
    if (value >= 0xd800 && value <= 0xdbff && pos < len
      && (str.charCodeAt(pos) & 0xfc00) === 0xdc00) pos += 1;
  }
  return length;
}`;
let validatorCode = standaloneCode(ajv, schemaIds);
if (!validatorCode.includes(ajvUcs2Import)) {
  throw new Error('AJV standalone output no longer contains the expected ucs2length helper');
}
validatorCode = validatorCode.replaceAll(ajvUcs2Import, inlineUcs2Length);
if (validatorCode.includes('require(')) {
  throw new Error('AJV standalone output contains an unexpected runtime dependency');
}
const generated = `${banner}${validatorCode}\n`;

if (process.argv.includes('--check')) {
  const current = fs.existsSync(output)
    ? fs.readFileSync(output, 'utf8').replace(/\r\n?/g, '\n')
    : '';
  if (current !== generated) {
    console.error('generated validators are stale — run npm run generate:validators');
    process.exit(1);
  }
} else {
  const temporary = `${output}.${process.pid}.tmp`;
  fs.writeFileSync(temporary, generated);
  fs.renameSync(temporary, output);
  console.log(`generated ${path.relative(root, output)}`);
}