UNPKG

@red-hat-developer-hub/cli

Version:
183 lines (177 loc) 6.04 kB
'use strict'; var configLoader = require('@backstage/config-loader'); var errors = require('@backstage/errors'); var fs = require('fs-extra'); var os = require('os'); var path = require('path'); function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; } var fs__default = /*#__PURE__*/_interopDefaultCompat(fs); const filterPackages = (depName) => { if (depName.startsWith("@backstage/")) { if (depName.startsWith("@backstage/plugin-")) { if (depName.startsWith("@backstage/plugin-catalog-") || depName.startsWith("@backstage/plugin-permission-") || depName.startsWith("@backstage/plugin-search-") || depName.startsWith("@backstage/plugin-scaffolder-")) { return false; } return true; } return false; } else if (depName === "@janus-idp/cli") { return false; } return true; }; const req = typeof __non_webpack_require__ === "undefined" ? require : __non_webpack_require__; async function collectConfigSchemas(packageName) { const schemas = new Array(); const tsSchemaPaths = new Array(); const visitedPackageVersions = /* @__PURE__ */ new Map(); const currentDir = await fs__default.default.realpath(process.cwd()); async function processItem(item) { let pkgPath = item.packagePath; if (pkgPath) { const pkgExists = await fs__default.default.pathExists(pkgPath); if (!pkgExists) { return; } } else if (item.name) { const { name, parentPath } = item; try { pkgPath = req.resolve( `${name}/package.json`, parentPath && { paths: [parentPath] } ); } catch { } } if (!pkgPath) { return; } const pkg = await fs__default.default.readJson(pkgPath); let versions = visitedPackageVersions.get(pkg.name); if (versions?.has(pkg.version)) { return; } if (!versions) { versions = /* @__PURE__ */ new Set(); visitedPackageVersions.set(pkg.name, versions); } versions.add(pkg.version); const depNames = [ ...Object.keys(pkg.dependencies ?? {}), ...Object.keys(pkg.devDependencies ?? {}), ...Object.keys(pkg.optionalDependencies ?? {}), ...Object.keys(pkg.peerDependencies ?? {}) ]; const hasSchema = "configSchema" in pkg; if (hasSchema) { if (typeof pkg.configSchema === "string") { const isJson = pkg.configSchema.endsWith(".json"); const isDts = pkg.configSchema.endsWith(".d.ts"); if (!isJson && !isDts) { throw new Error( `Config schema files must be .json or .d.ts, got ${pkg.configSchema}` ); } if (isDts) { tsSchemaPaths.push( path.relative( currentDir, path.resolve(path.dirname(pkgPath), pkg.configSchema) ) ); } else { const path$1 = path.resolve(path.dirname(pkgPath), pkg.configSchema); const value = await fs__default.default.readJson(path$1); schemas.push({ value, path: path.relative(currentDir, path$1) }); } } else { schemas.push({ value: pkg.configSchema, path: path.relative(currentDir, pkgPath) }); } } await Promise.all( depNames.filter(filterPackages).map((depName) => processItem({ name: depName, parentPath: pkgPath })) ); } await processItem({ name: packageName, packagePath: `${currentDir}/package.json` }); const tsSchemas = await compileTsSchemas(tsSchemaPaths); return schemas.concat(tsSchemas); } async function compileTsSchemas(paths) { if (paths.length === 0) { return []; } const { getProgramFromFiles, buildGenerator } = await import('typescript-json-schema'); const program = getProgramFromFiles(paths, { incremental: false, isolatedModules: true, lib: ["ES5"], // Skipping most libs speeds processing up a lot, we just need the primitive types anyway noEmit: true, noResolve: true, skipLibCheck: true, // Skipping lib checks speeds things up skipDefaultLibCheck: true, strict: true, typeRoots: [], // Do not include any additional types types: [] }); const tsSchemas = paths.map((path$1) => { let value; try { const generator = buildGenerator( program, // This enables the use of these tags in TSDoc comments { required: true, validationKeywords: ["visibility", "deepVisibility", "deprecated"] }, [path$1.split(path.sep).join("/")] // Unix paths are expected for all OSes here ); value = generator?.getSchemaForSymbol("Config"); const userSymbols = new Set(generator?.getUserSymbols()); userSymbols.delete("Config"); if (userSymbols.size !== 0) { const names = Array.from(userSymbols).join("', '"); throw new Error( `Invalid configuration schema in ${path$1}, additional symbol definitions are not allowed, found '${names}'` ); } const reffedDefs = Object.keys(generator?.ReffedDefinitions ?? {}); if (reffedDefs.length !== 0) { const lines = reffedDefs.join(`${os.EOL} `); throw new Error( `Invalid configuration schema in ${path$1}, the following definitions are not supported:${os.EOL}${os.EOL} ${lines}` ); } } catch (error) { errors.assertError(error); if (error.message !== "type Config not found") { throw error; } } if (!value) { throw new Error(`Invalid schema in ${path$1}, missing Config export`); } return { path: path$1, value }; }); return tsSchemas; } const getConfigSchema = async (packageName) => { const schemas = await collectConfigSchemas(packageName); return configLoader.mergeConfigSchemas(schemas.map((_) => _.value)); }; exports.getConfigSchema = getConfigSchema; //# sourceMappingURL=collect.cjs.js.map