'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 _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n["default"] = e; return Object.freeze(n); } var fs__default = /*#__PURE__*/_interopDefaultLegacy(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) { var _a, _b, _c, _d; 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 == null ? void 0 : versions.has(pkg.version)) { return; } if (!versions) { versions = /* @__PURE__ */ new Set(); visitedPackageVersions.set(pkg.name, versions); } versions.add(pkg.version); const depNames = [ ...Object.keys((_a = pkg.dependencies) != null ? _a : {}), ...Object.keys((_b = pkg.devDependencies) != null ? _b : {}), ...Object.keys((_c = pkg.optionalDependencies) != null ? _c : {}), ...Object.keys((_d = pkg.peerDependencies) != null ? _d : {}) ]; 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 Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('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) => { var _a; 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 == null ? void 0 : generator.getSchemaForSymbol("Config"); const userSymbols = new Set(generator == null ? void 0 : 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((_a = generator == null ? void 0 : generator.ReffedDefinitions) != null ? _a : {}); 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-c99ee3f5.cjs.js.map