()
| 866 | // ============================================================ |
| 867 | |
| 868 | async function main() { |
| 869 | const { parseArgs } = await import('node:util') |
| 870 | const { readFileSync, writeFileSync } = await import('node:fs') |
| 871 | const { resolve } = await import('node:path') |
| 872 | |
| 873 | // Under Bazel the js_binary wrapper chdir's to BAZEL_BINDIR, but $(location) |
| 874 | // inputs are execroot-relative and already carry that prefix — strip it so the |
| 875 | // path is not doubled. Mirrors resolveInputPath() in generate_bidi.mjs. |
| 876 | const resolveInput = (p) => { |
| 877 | if (!process.env.BAZEL_BINDIR) return resolve(p) |
| 878 | const prefix = process.env.BAZEL_BINDIR.replaceAll('\\', '/') + '/' |
| 879 | const norm = p.replaceAll('\\', '/') |
| 880 | return resolve(norm.startsWith(prefix) ? norm.slice(prefix.length) : norm) |
| 881 | } |
| 882 | |
| 883 | const { values: args } = parseArgs({ |
| 884 | options: { |
| 885 | ast: { type: 'string' }, |
| 886 | model: { type: 'string' }, |
| 887 | 'dump-schema': { type: 'string' }, |
| 888 | // Repeatable: one webref dfns index per merged spec. Optional — omitting them |
| 889 | // (and --anchors) yields a schema with no specHref links (fully backward compatible). |
| 890 | dfns: { type: 'string', multiple: true }, |
| 891 | // The core spec's prose-anchor index (see extract_bidi_anchors.mjs). Optional; |
| 892 | // upgrades type links to prose sections and adds command/event/domain links. |
| 893 | anchors: { type: 'string' }, |
| 894 | }, |
| 895 | }) |
| 896 | if (!args.ast || !args.model || !args['dump-schema']) { |
| 897 | console.error( |
| 898 | 'Usage: project_bidi_schema.mjs --ast <ast.json> --model <model.json> --dump-schema <out.json>' + |
| 899 | ' [--dfns <dfns.json> ...] [--anchors <anchors.json>]', |
| 900 | ) |
| 901 | process.exit(1) |
| 902 | } |
| 903 | |
| 904 | const ast = JSON.parse(readFileSync(resolveInput(args.ast), 'utf8')) |
| 905 | const model = JSON.parse(readFileSync(resolveInput(args.model), 'utf8')) |
| 906 | const dfnsDocs = (args.dfns ?? []).map((p) => JSON.parse(readFileSync(resolveInput(p), 'utf8'))) |
| 907 | const anchors = args.anchors ? JSON.parse(readFileSync(resolveInput(args.anchors), 'utf8')) : {} |
| 908 | const schema = projectSchema(ast, model, buildSpecLinks(dfnsDocs, anchors)) |
| 909 | |
| 910 | // Generation is the gate: a broken or incomplete schema fails the build. |
| 911 | const errors = [...checkSchema(schema), ...checkCompleteness(ast, schema)] |
| 912 | if (errors.length) { |
| 913 | console.error('BiDi schema validation failed:') |
| 914 | errors.forEach((e) => console.error(` ${e}`)) |
| 915 | process.exit(1) |
| 916 | } |
| 917 | |
| 918 | writeFileSync(resolve(args['dump-schema']), JSON.stringify(schema, null, 2) + '\n', 'utf8') |
| 919 | const prose = (u) => (u && !u.includes('#cddl-') ? 1 : 0) |
| 920 | const linkedTypes = Object.values(schema.types).filter((t) => t.specHref) |
| 921 | const proseTypes = linkedTypes.filter((t) => prose(t.specHref)).length |
| 922 | console.log( |
| 923 | ` ${schema.commands.length} commands, ${schema.events.length} events, ${Object.keys(schema.types).length} types` + |
| 924 | ` (${linkedTypes.length} spec-linked, ${proseTypes} prose) → ${args['dump-schema']}`, |
| 925 | ) |
no test coverage detected