UNPKG

@equinor/fusion-framework-cli

Version:

--- title: Fusion Framework CLI ---

142 lines 4.95 kB
import deepMerge from 'deepmerge'; import { execSync } from 'node:child_process'; import { resolveAppKey, resolveEntryPoint, } from './app-package.js'; import { loadConfig, initiateConfig, resolveConfig, } from './utils/config.js'; import { AssertionError, assert, assertObject } from './utils/assert.js'; import { parse as parseSemver } from 'semver'; import { StandardIncludeAssetExtensions } from './plugins/app-assets/index.js'; /** base filename for configuration files */ export const manifestConfigFilename = 'app.manifest.config'; /** * Define a manifest for an application * * @example * ```ts * export default defineAppManifest(async() => { * return { * ...AppManifest_properties * } * }) * ``` * @param fnOrObj - defines the manifest as an object or callback */ export const defineAppManifest = (fn) => fn; export function assertAppManifest(value) { assert(value, 'expected manifest'); assert(value.build, 'expected build'); assert(parseSemver(value.build?.version), 'invalid version'); // TODO make assertions } // /** // * assert that the package version of the manifest is correct // * // * @TODO this should assert semver not .net syntax 🥺 // */ // export function assertPackageVersion(value: AppManifest['version']): asserts value { // assertObjectEntries(value, { // props: ['major', 'minor', 'patch'], // assertion: (v, k): asserts v => assertNumber(v, `invalid value for version.${k}`), // preMessage: 'expected package version', // }); // } /** * @example * ```ts * export default defineAppManifest(base) => mergeManifests(base, {prop: value}); * ``` * @param base base manifest to merge with * @param overrides target manifest to apply to base * @returns deep merged manifest */ export const mergeManifests = (base, overrides) => { const manifest = deepMerge(base, overrides); assertAppManifest(manifest); return manifest; }; /** loads manifestFn from file */ export const loadManifest = (filename) => loadConfig(filename ?? manifestConfigFilename); /** * tries to resolve manifest * @see {@link resolveConfig | resolving config} */ export const resolveManifest = async (options) => { if (options?.file) { const config = await loadManifest(options.file); return { config, path: options.file, }; } return resolveConfig(manifestConfigFilename, { find: options }); }; const resolveGithubRepo = (pkg) => { try { /* get reporurl from package.json */ if (pkg.repository) { return typeof pkg.repository === 'string' ? pkg.repository : pkg.repository.url; } else { /* get reporurl from git command */ return execSync('git remote get-url origin') .toString() .trim() .replace('git@github.com:', 'https://github.com/') .replace(/.git$/, ''); } } catch { return undefined; } }; const resolveGitCommitSha = () => { try { return execSync('git rev-parse HEAD').toString().trim(); } catch { return undefined; } }; export const createManifestFromPackage = (pkg) => { const { packageJson } = pkg; assertObject(packageJson, 'expected packageJson'); assert(packageJson.name, 'expected [name] in packageJson'); assert(packageJson.version, 'expected [version] in packageJson'); const entryPoint = resolveEntryPoint(packageJson); const manifest = { appKey: resolveAppKey(pkg.packageJson), displayName: packageJson.name, description: packageJson.description || '', keywords: packageJson.keywords, type: 'standalone', build: { entryPoint, version: packageJson.version, timestamp: new Date().toISOString(), githubRepo: resolveGithubRepo(packageJson), commitSha: resolveGitCommitSha(), annotations: packageJson.annotations, projectPage: packageJson.homepage, allowedExtensions: StandardIncludeAssetExtensions.map( // TODO: @jaysencpp, this is just 🫤, extensions should not require leading dot (ext) => `.${ext}`), }, }; return manifest; }; export const createManifest = async (env, base, options) => { const resolved = await resolveManifest(options); if (resolved) { const configuredManifest = await initiateConfig(resolved.config, env, { base }); const manifest = deepMerge(base, configuredManifest ?? {}); assertAppManifest(manifest); return { manifest, path: resolved.path }; } else if (options?.file) { throw new AssertionError({ message: `Expected to load manifest from ${options.file}`, expected: '<manifest>', }); } return { manifest: base }; }; //# sourceMappingURL=app-manifest.js.map