chore(nx): update Nx to 22.7.1 (#923)

* chore(nx): update Nx to 22.7.1
Entire-Checkpoint: f957cd9849e0

* fix(ci): patch nx-electron package metadata copy
Entire-Checkpoint: f957cd9849e0

* fix(packaging): preserve electron package metadata
Entire-Checkpoint: f957cd9849e0

* fix(packaging): address package verifier review
Entire-Checkpoint: f957cd9849e0
This commit is contained in:
4gray authored and GitHub committed 2026-05-10 22:01:25 +02:00
1 parent 6305dcf00e
commit 1ca291d35c
13 files changed
+2614 -1981

No files matched your search

+1
View File
@@ -78,6 +78,7 @@ Thumbs.db
# Native Electron addons
apps/electron-backend/native/build/
apps/electron-backend/src/app/options/electron-builder.metadata.generated.json
vendor/embedded-mpv/darwin-*/include/
vendor/embedded-mpv/darwin-*/lib/
vendor/embedded-mpv/darwin-*/runtime-manifest.json
+2
View File
@@ -4,3 +4,5 @@ build
coverage
release
.angular
.nx/self-healing
+26 -2
View File
@@ -125,7 +125,10 @@
}
},
"package": {
"dependsOn": ["electron-backend:build"],
"dependsOn": [
"electron-backend:build",
"electron-backend:generate-builder-metadata"
],
"executor": "nx-electron:package",
"options": {
"name": "electron-backend",
@@ -136,7 +139,10 @@
}
},
"make": {
"dependsOn": ["electron-backend:build"],
"dependsOn": [
"electron-backend:build",
"electron-backend:generate-builder-metadata"
],
"executor": "nx-electron:make",
"options": {
"name": "electron-backend",
@@ -145,6 +151,24 @@
"outputPath": "dist/executables"
}
},
"generate-builder-metadata": {
"dependsOn": ["electron-backend:build"],
"executor": "nx:run-commands",
"cache": true,
"inputs": [
"{workspaceRoot}/package.json",
"{workspaceRoot}/electron-builder.json",
"{workspaceRoot}/tools/packaging/generate-electron-builder-metadata.mjs"
],
"outputs": [
"{workspaceRoot}/apps/electron-backend/src/app/options/electron-builder.metadata.generated.json",
"{workspaceRoot}/dist/apps/electron-backend/package.json"
],
"options": {
"command": "node tools/packaging/generate-electron-builder-metadata.mjs",
"cwd": "{workspaceRoot}"
}
},
"lint": {
"command": "eslint apps/electron-backend/**/*.ts"
},
@@ -1,3 +1,4 @@
{
"$schema": "../../../../../node_modules/nx-electron/src/validation/maker.schema.json"
"$schema": "../../../../../node_modules/nx-electron/src/validation/maker.schema.json",
"extends": "apps/electron-backend/src/app/options/electron-builder.metadata.generated.json"
}
+2 -2
View File
@@ -526,9 +526,9 @@ export async function initDatabase(
sqlite = new Database(filePath, {
readonly,
verbose: isSqlTraceEnabled()
? (sql: string) => {
? (message?: unknown) => {
traceSql('sql-main', 'query', {
sql: compactSqlForTrace(sql),
sql: compactSqlForTrace(String(message ?? '')),
});
}
: undefined,
+3 -1
View File
@@ -24,9 +24,11 @@
"cache": true,
"inputs": [
"default",
"^default",
"{workspaceRoot}/.eslintrc.json",
"{workspaceRoot}/.eslintignore",
"{workspaceRoot}/eslint.config.mjs"
"{workspaceRoot}/eslint.config.mjs",
"{workspaceRoot}/tools/eslint-rules/**/*"
]
},
"@nx/jest:jest": {
+47 -42
View File
@@ -58,16 +58,16 @@
"private": true,
"packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319",
"dependencies": {
"@angular/animations": "21.1.5",
"@angular/cdk": "^21.1.5",
"@angular/common": "~21.1.5",
"@angular/compiler": "~21.1.5",
"@angular/core": "~21.1.5",
"@angular/forms": "~21.1.5",
"@angular/material": "^21.1.5",
"@angular/platform-browser": "~21.1.5",
"@angular/platform-browser-dynamic": "~21.1.5",
"@angular/router": "~21.1.5",
"@angular/animations": "21.2.9",
"@angular/cdk": "21.2.9",
"@angular/common": "21.2.9",
"@angular/compiler": "21.2.9",
"@angular/core": "21.2.9",
"@angular/forms": "21.2.9",
"@angular/material": "21.2.9",
"@angular/platform-browser": "21.2.9",
"@angular/platform-browser-dynamic": "21.2.9",
"@angular/router": "21.2.9",
"@ngrx/component-store": "21.0.1",
"@ngrx/effects": "21.0.1",
"@ngrx/entity": "21.0.1",
@@ -103,28 +103,29 @@
"zone.js": "~0.15.1"
},
"devDependencies": {
"@angular-devkit/core": "~21.1.4",
"@angular-devkit/schematics": "~21.1.4",
"@angular-eslint/builder": "21.2.0",
"@angular-eslint/eslint-plugin": "21.2.0",
"@angular-eslint/eslint-plugin-template": "21.2.0",
"@angular-eslint/schematics": "21.2.0",
"@angular-eslint/template-parser": "21.2.0",
"@angular/build": "~21.1.4",
"@angular/cli": "~21.1.4",
"@angular/common": "21.1.5",
"@angular/compiler": "21.1.5",
"@angular/compiler-cli": "21.1.5",
"@angular/core": "21.1.5",
"@angular/forms": "21.1.5",
"@angular/language-service": "21.1.5",
"@angular/platform-browser": "21.1.5",
"@angular/platform-browser-dynamic": "21.1.5",
"@angular/router": "21.1.5",
"@angular/service-worker": "21.1.5",
"@angular-devkit/core": "21.2.9",
"@angular-devkit/schematics": "21.2.9",
"@angular-eslint/builder": "21.3.1",
"@angular-eslint/eslint-plugin": "21.3.1",
"@angular-eslint/eslint-plugin-template": "21.3.1",
"@angular-eslint/schematics": "21.3.1",
"@angular-eslint/template-parser": "21.3.1",
"@angular/build": "21.2.9",
"@angular/cli": "21.2.10",
"@angular/common": "21.2.9",
"@angular/compiler": "21.2.9",
"@angular/compiler-cli": "21.2.9",
"@angular/core": "21.2.9",
"@angular/forms": "21.2.9",
"@angular/language-service": "21.2.9",
"@angular/platform-browser": "21.2.9",
"@angular/platform-browser-dynamic": "21.2.9",
"@angular/router": "21.2.9",
"@angular/service-worker": "21.2.9",
"@astrojs/mdx": "4.3.13",
"@astrojs/sitemap": "3.7.0",
"@astrojs/tailwind": "6.0.2",
"@electron/asar": "3.4.1",
"@eslint/eslintrc": "3.3.1",
"@eslint/js": "^9.38.0",
"@faker-js/faker": "10.3.0",
@@ -135,17 +136,18 @@
"@ngrx/eslint-plugin": "^21.0.1",
"@ngx-translate/core": "16.0.4",
"@ngx-translate/http-loader": "16.0.1",
"@nx/angular": "22.5.1",
"@nx/devkit": "22.5.1",
"@nx/eslint": "22.5.1",
"@nx/eslint-plugin": "22.5.1",
"@nx/jest": "22.5.1",
"@nx/js": "22.5.1",
"@nx/playwright": "22.5.1",
"@nx/web": "22.5.1",
"@nx/workspace": "22.5.1",
"@nx/angular": "22.7.1",
"@nx/devkit": "22.7.1",
"@nx/esbuild": "22.7.1",
"@nx/eslint": "22.7.1",
"@nx/eslint-plugin": "22.7.1",
"@nx/jest": "22.7.1",
"@nx/js": "22.7.1",
"@nx/playwright": "22.7.1",
"@nx/web": "22.7.1",
"@nx/workspace": "22.7.1",
"@playwright/test": "^1.36.0",
"@schematics/angular": "~21.1.4",
"@schematics/angular": "21.2.9",
"@semantic-release/changelog": "6.0.3",
"@semantic-release/git": "10.0.1",
"@semantic-release/npm": "12.0.1",
@@ -165,7 +167,7 @@
"@typescript-eslint/eslint-plugin": "^8.46.2",
"@typescript-eslint/parser": "^8.46.2",
"@typescript-eslint/utils": "^8.46.2",
"angular-eslint": "20.5.2",
"angular-eslint": "21.3.1",
"astro": "5.18.1",
"conventional-changelog-cli": "5.0.0",
"cors": "2.8.6",
@@ -188,8 +190,8 @@
"jsonc-eslint-parser": "^2.1.0",
"material-design-icons-iconfont": "6.7.0",
"ng-mocks": "14.15.1",
"nx": "22.5.1",
"nx-electron": "^21.0.1",
"nx": "22.7.1",
"nx-electron": "22.0.0",
"prettier": "^3.8.1",
"semantic-release": "24.2.9",
"sharp": "0.34.5",
@@ -222,6 +224,9 @@
"smol-toml@1.6.0": "1.6.1",
"svgo@3.3.2": "3.3.3",
"yaml@1.10.2": "1.10.3"
},
"patchedDependencies": {
"nx-electron@22.0.0": "patches/nx-electron@22.0.0.patch"
}
}
}
+12
View File
@@ -0,0 +1,12 @@
diff --git a/src/executors/package/executor.js b/src/executors/package/executor.js
index e36f61a825a280c26ec5064f1ba086ac170fb1b6..17a351dd4b91bf3b72743036f79c8300aba7f79e 100644
--- a/src/executors/package/executor.js
+++ b/src/executors/package/executor.js
@@ -111,7 +111,6 @@ function _createBaseConfig(options, context) {
return {
directories: Object.assign(Object.assign({}, options.directories), { output: (0, path_1.join)(context.root, outputPath) }),
files: files.concat([
- './package.json',
{
from: (0, path_1.resolve)(options.sourcePath, options.name),
to: options.name,
+2114 -1908
View File
File diff suppressed because it is too large. Load diff
@@ -1,16 +1,49 @@
import assert from 'node:assert/strict';
import fs from 'node:fs';
import { createRequire } from 'node:module';
import { dirname, join } from 'node:path';
import test from 'node:test';
import { fileURLToPath } from 'node:url';
const currentDir = dirname(fileURLToPath(import.meta.url));
const require = createRequire(import.meta.url);
const packageMetadata = JSON.parse(
fs.readFileSync(join(currentDir, '..', '..', 'package.json'), 'utf8')
);
const electronBuilderConfig = JSON.parse(
fs.readFileSync(
join(currentDir, '..', '..', 'electron-builder.json'),
'utf8'
)
);
const electronProjectConfig = JSON.parse(
fs.readFileSync(
join(currentDir, '..', '..', 'apps', 'electron-backend', 'project.json'),
'utf8'
)
);
const makerOptions = JSON.parse(
fs.readFileSync(
join(
currentDir,
'..',
'..',
'apps',
'electron-backend',
'src',
'app',
'options',
'maker.options.json'
),
'utf8'
)
);
const generatedMetadataConfigPath =
'apps/electron-backend/src/app/options/electron-builder.metadata.generated.json';
const packageLayoutVerifier = fs.readFileSync(
join(currentDir, 'verify-electron-package-layout.mjs'),
'utf8'
);
test('Linux package identity does not expose the internal Electron backend project name', () => {
assert.equal(electronBuilderConfig.productName, 'IPTVnator');
@@ -22,3 +55,110 @@ test('Linux package identity does not expose the internal Electron backend proje
'iptvnator'
);
});
test('generated Electron package metadata mirrors the root package identity', async () => {
const {
buildElectronBuilderMetadata,
buildElectronPackageMetadata,
} = await import(
'./generate-electron-builder-metadata.mjs'
);
const generatedElectronPackage = buildElectronPackageMetadata(
packageMetadata,
electronBuilderConfig,
{
name: 'electron-backend',
version: '0.0.1',
dependencies: {
'better-sqlite3': '12.5.0',
},
}
);
assert.deepEqual(
buildElectronBuilderMetadata(packageMetadata, electronBuilderConfig)
.extraMetadata,
{
name: packageMetadata.name,
productName: electronBuilderConfig.productName,
version: packageMetadata.version,
description: packageMetadata.description,
author: packageMetadata.author,
homepage: packageMetadata.homepage,
license: packageMetadata.license,
main: electronBuilderConfig.extraMetadata.main,
}
);
assert.deepEqual(generatedElectronPackage, {
name: packageMetadata.name,
productName: electronBuilderConfig.productName,
version: packageMetadata.version,
description: packageMetadata.description,
author: packageMetadata.author,
homepage: packageMetadata.homepage,
license: packageMetadata.license,
main: electronBuilderConfig.extraMetadata.main,
dependencies: {
'better-sqlite3': '12.5.0',
},
});
});
test('nx-electron packaging prepares metadata before make/package', () => {
assert.equal(makerOptions.extends, generatedMetadataConfigPath);
assert.deepEqual(
electronProjectConfig.targets['generate-builder-metadata'].dependsOn,
['electron-backend:build']
);
assert.deepEqual(
electronProjectConfig.targets['generate-builder-metadata'].outputs,
[
`{workspaceRoot}/${generatedMetadataConfigPath}`,
'{workspaceRoot}/dist/apps/electron-backend/package.json',
]
);
assert.ok(
electronProjectConfig.targets.make.dependsOn.includes(
'electron-backend:generate-builder-metadata'
)
);
assert.ok(
electronProjectConfig.targets.package.dependsOn.includes(
'electron-backend:generate-builder-metadata'
)
);
});
test('package layout verifier uses canonical helpers and direct dependencies', () => {
assert.ok(packageMetadata.devDependencies?.['@electron/asar']);
assert.match(packageLayoutVerifier, /require\(['"]@electron\/asar['"]\)/);
assert.doesNotMatch(packageLayoutVerifier, /electronBuilderRequire/);
assert.match(
packageLayoutVerifier,
/buildElectronBuilderMetadata\(\s*packageMetadata,\s*electronBuilderConfig\s*\)\.extraMetadata/s
);
assert.doesNotMatch(
packageLayoutVerifier,
/const packagedPackageMetadata = \{\s*name:/s
);
assert.doesNotMatch(
packageLayoutVerifier,
/builderEffectiveConfigPath && fileExists\(builderEffectiveConfigPath\)/
);
});
test('nx-electron packaging does not copy duplicate root package metadata', () => {
const nxElectronExecutorPath = require.resolve(
'nx-electron/src/executors/package/executor.js'
);
const nxElectronExecutor = fs.readFileSync(
nxElectronExecutorPath,
'utf8'
);
assert.doesNotMatch(nxElectronExecutor, /['"]\.\/package\.json['"]/);
assert.match(
nxElectronExecutor,
/filter:\s*\[['"]index\.js['"],\s*['"]package\.json['"]\]/
);
});
@@ -0,0 +1,156 @@
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
export const generatedMetadataConfigPath = path.join(
'apps',
'electron-backend',
'src',
'app',
'options',
'electron-builder.metadata.generated.json'
);
export const electronBackendPackageJsonPath = path.join(
'dist',
'apps',
'electron-backend',
'package.json'
);
function readJson(filePath) {
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
}
function removeUndefinedValues(value) {
return Object.fromEntries(
Object.entries(value).filter(([, entryValue]) => entryValue !== undefined)
);
}
function requirePackageField(packageMetadata, fieldName) {
const value = packageMetadata[fieldName];
if (typeof value !== 'string' || value.length === 0) {
throw new Error(`Root package.json must define a non-empty ${fieldName}.`);
}
return value;
}
export function buildElectronBuilderMetadata(
packageMetadata,
electronBuilderConfig = {}
) {
const extraMetadata = removeUndefinedValues({
name: requirePackageField(packageMetadata, 'name'),
productName:
electronBuilderConfig.productName ??
electronBuilderConfig.extraMetadata?.productName,
version: requirePackageField(packageMetadata, 'version'),
description: packageMetadata.description,
author: packageMetadata.author,
homepage: packageMetadata.homepage,
license: packageMetadata.license,
main:
electronBuilderConfig.extraMetadata?.main ??
'electron-backend/main.js',
});
return {
extends: 'electron-builder.json',
extraMetadata,
};
}
export function buildElectronPackageMetadata(
packageMetadata,
electronBuilderConfig = {},
currentElectronPackageMetadata = {}
) {
return removeUndefinedValues({
...currentElectronPackageMetadata,
...buildElectronBuilderMetadata(packageMetadata, electronBuilderConfig)
.extraMetadata,
});
}
export function writeElectronPackageMetadata({
workspaceRoot = process.cwd(),
packageMetadata,
electronBuilderConfig,
packageJsonPath = electronBackendPackageJsonPath,
} = {}) {
const absolutePackageJsonPath = path.join(workspaceRoot, packageJsonPath);
if (!fs.existsSync(absolutePackageJsonPath)) {
return {
outputPath: absolutePackageJsonPath,
updated: false,
};
}
const currentElectronPackageMetadata = readJson(absolutePackageJsonPath);
const nextElectronPackageMetadata = buildElectronPackageMetadata(
packageMetadata,
electronBuilderConfig,
currentElectronPackageMetadata
);
fs.writeFileSync(
absolutePackageJsonPath,
`${JSON.stringify(nextElectronPackageMetadata, null, 2)}\n`
);
return {
outputPath: absolutePackageJsonPath,
updated: true,
};
}
export function writeElectronBuilderMetadata({
workspaceRoot = process.cwd(),
outputPath = generatedMetadataConfigPath,
} = {}) {
const packageMetadata = readJson(path.join(workspaceRoot, 'package.json'));
const electronBuilderConfig = readJson(
path.join(workspaceRoot, 'electron-builder.json')
);
const metadataConfig = buildElectronBuilderMetadata(
packageMetadata,
electronBuilderConfig
);
const absoluteOutputPath = path.join(workspaceRoot, outputPath);
const packageMetadataResult = writeElectronPackageMetadata({
workspaceRoot,
packageMetadata,
electronBuilderConfig,
});
fs.mkdirSync(path.dirname(absoluteOutputPath), { recursive: true });
fs.writeFileSync(
absoluteOutputPath,
`${JSON.stringify(metadataConfig, null, 4)}\n`
);
return {
outputPath: absoluteOutputPath,
metadataConfig,
packageMetadataResult,
};
}
const currentFilePath = fileURLToPath(import.meta.url);
if (process.argv[1] && path.resolve(process.argv[1]) === currentFilePath) {
const { outputPath, packageMetadataResult } = writeElectronBuilderMetadata();
console.log(`Wrote Electron builder metadata: ${outputPath}`);
if (packageMetadataResult.updated) {
console.log(
`Wrote Electron package metadata: ${packageMetadataResult.outputPath}`
);
} else {
console.log(
`Skipped Electron package metadata because ${packageMetadataResult.outputPath} does not exist yet.`
);
}
}
+8 -1
View File
@@ -7,7 +7,14 @@
"test": {
"executor": "nx:run-commands",
"cache": true,
"inputs": ["default", "{workspaceRoot}/electron-builder.json"],
"inputs": [
"default",
"{workspaceRoot}/package.json",
"{workspaceRoot}/electron-builder.json",
"{workspaceRoot}/apps/electron-backend/project.json",
"{workspaceRoot}/apps/electron-backend/src/app/options/maker.options.json",
"{workspaceRoot}/tools/packaging/generate-electron-builder-metadata.mjs"
],
"options": {
"command": "node --test tools/packaging/electron-package-identity.test.mjs",
"cwd": "{workspaceRoot}"
@@ -2,7 +2,10 @@ import fs from 'fs';
import { createRequire } from 'module';
import path from 'path';
import { buildElectronBuilderMetadata } from './generate-electron-builder-metadata.mjs';
const require = createRequire(import.meta.url);
const { extractFile } = require('@electron/asar');
const { validatePackagedEmbeddedMpv } = require('./embedded-mpv-macos.cjs');
const args = process.argv.slice(2);
const normalizedArgs = args[0] === '--' ? args.slice(1) : args;
@@ -16,15 +19,17 @@ if (!platform) {
}
const workspaceRoot = process.cwd();
const executablesRoot = path.join(workspaceRoot, 'dist', 'executables');
const packageOutputRoots = [
path.join(workspaceRoot, 'dist', 'executables'),
path.join(workspaceRoot, 'dist', 'packages'),
];
const packageJsonPath = path.join(workspaceRoot, 'package.json');
const electronBuilderConfigPath = path.join(
workspaceRoot,
'electron-builder.json'
);
const builderEffectiveConfigPath = path.join(
executablesRoot,
'builder-effective-config.yaml'
const builderEffectiveConfigPaths = packageOutputRoots.map((outputRoot) =>
path.join(outputRoot, 'builder-effective-config.yaml')
);
const flatpakMetainfoPath = path.join(
workspaceRoot,
@@ -47,6 +52,10 @@ const workerRelativeDir = path.join(
'workers'
);
const workerFiles = ['epg-parser.worker.js', 'database.worker.js'];
const packagedPackageMetadata = buildElectronBuilderMetadata(
packageMetadata,
electronBuilderConfig
).extraMetadata;
const nativeModuleRelativeDirs = [
path.join('app.asar.unpacked', 'node_modules'),
path.join('app.asar.unpacked', 'electron-backend', 'node_modules'),
@@ -79,11 +88,11 @@ function isTruthy(value) {
}
function getMacResourceDirs() {
const candidates = [
const candidates = packageOutputRoots.flatMap((outputRoot) => [
{
arch: 'x64',
directory: path.join(
executablesRoot,
outputRoot,
'mac',
'IPTVnator.app',
'Contents',
@@ -93,14 +102,14 @@ function getMacResourceDirs() {
{
arch: 'arm64',
directory: path.join(
executablesRoot,
outputRoot,
'mac-arm64',
'IPTVnator.app',
'Contents',
'Resources'
),
},
];
]);
return candidates
.filter((candidate) => !arch || candidate.arch === arch)
@@ -109,20 +118,20 @@ function getMacResourceDirs() {
}
function getUnpackedResourceDirs(prefix) {
if (!directoryExists(executablesRoot)) {
return [];
}
return fs
.readdirSync(executablesRoot, { withFileTypes: true })
.filter(
(entry) =>
entry.isDirectory() &&
entry.name.startsWith(prefix) &&
entry.name.endsWith('-unpacked')
)
.map((entry) => path.join(executablesRoot, entry.name, 'resources'))
.filter(directoryExists);
return packageOutputRoots
.filter(directoryExists)
.flatMap((outputRoot) =>
fs
.readdirSync(outputRoot, { withFileTypes: true })
.filter(
(entry) =>
entry.isDirectory() &&
entry.name.startsWith(prefix) &&
entry.name.endsWith('-unpacked')
)
.map((entry) => path.join(outputRoot, entry.name, 'resources'))
.filter(directoryExists)
);
}
function getResourceDirs() {
@@ -140,7 +149,15 @@ function getResourceDirs() {
}
function sanitizeExecutableName(value) {
return value.replace(/[<>:"/\\|?*\u0000-\u001f]/g, '');
const invalidCharacters = new Set(['<', '>', ':', '"', '/', '\\', '|', '?', '*']);
return [...value]
.filter(
(character) =>
character.charCodeAt(0) >= 32 &&
!invalidCharacters.has(character)
)
.join('');
}
function getLinuxExecutableName() {
@@ -345,7 +362,9 @@ function parseEffectiveSnapConfig(yamlContent) {
}
function loadSnapConfigInspection() {
if (fileExists(builderEffectiveConfigPath)) {
const builderEffectiveConfigPath = builderEffectiveConfigPaths.find(fileExists);
if (builderEffectiveConfigPath) {
const effectiveConfigContent = fs.readFileSync(
builderEffectiveConfigPath,
'utf8'
@@ -368,6 +387,62 @@ function loadSnapConfigInspection() {
};
}
function formatJsonValue(value) {
return JSON.stringify(value);
}
function packageMetadataMatches(actualValue, expectedValue) {
return formatJsonValue(actualValue) === formatJsonValue(expectedValue);
}
function readAsarPackageMetadata(asarPath) {
return JSON.parse(extractFile(asarPath, 'package.json').toString('utf8'));
}
function verifyPackagedPackageMetadata(resourceDir, errors) {
const asarPath = path.join(resourceDir, 'app.asar');
if (!fileExists(asarPath)) {
errors.push(`Missing packaged app archive: ${asarPath}`);
return;
}
let appPackageMetadata;
try {
appPackageMetadata = readAsarPackageMetadata(asarPath);
} catch (error) {
errors.push(
`Unable to read package.json from ${asarPath}: ${error.message}`
);
return;
}
const mismatches = Object.entries(packagedPackageMetadata)
.filter(([, expectedValue]) => expectedValue !== undefined)
.filter(
([fieldName, expectedValue]) =>
!packageMetadataMatches(
appPackageMetadata[fieldName],
expectedValue
)
)
.map(([fieldName, expectedValue]) => {
const actualValue = appPackageMetadata[fieldName];
return `- ${fieldName}: expected ${formatJsonValue(expectedValue)}, received ${formatJsonValue(actualValue)}`;
});
if (mismatches.length > 0) {
errors.push(
[
`Packaged app package.json metadata does not match root package identity in ${asarPath}.`,
...mismatches,
].join('\n')
);
}
}
function verifyLinuxLauncher(resourceDir, errors) {
const appDir = path.dirname(resourceDir);
const launcherPath = path.join(appDir, linuxExecutableName);
@@ -462,6 +537,8 @@ function verifyResourceDir(resourceDir) {
const errors = [];
verifyPackagedPackageMetadata(resourceDir, errors);
if (missingWorkers.length > 0) {
errors.push(
`Missing worker artifacts in ${resourceDir}: ${missingWorkers.join(', ')}`