import { readFile } from 'node:fs/promises'; import { spawnSync } from 'node:child_process'; import Ajv from 'ajv/dist/2020.js'; const manifest = JSON.parse(await readFile('module.json', 'utf8')); const packageManifest = JSON.parse(await readFile('package.json', 'utf8')); const openapiSource = await readFile('api/openapi.yaml', 'utf8'); const runtimeVersionSource = await readFile('src/version.ts', 'utf8'); const openapi = (await import('yaml')).default.parse(openapiSource); const settings = JSON.parse(await readFile('settings.schema.json', 'utf8')); const moduleSchema = JSON.parse(await readFile('schemas/module.schema.json', 'utf8')); const settingsSchema = JSON.parse(await readFile('schemas/settings.schema.schema.json', 'utf8')); const ajv = new Ajv({ allErrors: true }); for (const [name, value, schema] of [ ['module.json', manifest, moduleSchema], ['settings.schema.json', settings, settingsSchema], ]) { const validate = ajv.compile(schema); if (!validate(value)) throw new Error(`${name}: ${ajv.errorsText(validate.errors)}`); } if (manifest.configurable_entities.some((entity) => !manifest.entities.includes(entity))) throw new Error('Configurable entity must be declared'); const runtimeVersion = runtimeVersionSource.match(/SERVICE_VERSION\s*=\s*'([^']+)'/)?.[1]; const versions = new Set([ packageManifest.version, manifest.version, openapi.info.version, runtimeVersion, ]); if (versions.size !== 1 || versions.has(undefined)) throw new Error('Version mismatch between package, module, OpenAPI and runtime'); const lint = spawnSync( process.execPath, ['node_modules/@redocly/cli/bin/cli.js', 'lint', 'api/openapi.yaml'], { stdio: 'inherit' }, ); if (lint.error) throw lint.error; if (lint.status !== 0) process.exit(lint.status ?? 1); console.log('module manifest, settings schema and OpenAPI contract validated');