@atom-js-org/cli 0.4.1-alpha.0 → 0.4.3-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/build.cjs +38 -13
- package/src/doctor.cjs +1 -1
- package/src/init.cjs +3 -3
- package/src/run.cjs +6 -0
package/package.json
CHANGED
package/src/build.cjs
CHANGED
|
@@ -70,6 +70,7 @@ async function localBuild(project, target, options = {}) {
|
|
|
70
70
|
appDir,
|
|
71
71
|
target,
|
|
72
72
|
productName,
|
|
73
|
+
appId: project.config.appId,
|
|
73
74
|
payloadPath
|
|
74
75
|
});
|
|
75
76
|
|
|
@@ -106,7 +107,7 @@ async function localBuild(project, target, options = {}) {
|
|
|
106
107
|
}
|
|
107
108
|
|
|
108
109
|
const manifest = {
|
|
109
|
-
atomjsVersion: '0.3
|
|
110
|
+
atomjsVersion: '0.4.3-alpha.0',
|
|
110
111
|
target,
|
|
111
112
|
productName,
|
|
112
113
|
appId: project.config.appId,
|
|
@@ -287,7 +288,7 @@ async function createApplicationPayload(appDir, outputPath) {
|
|
|
287
288
|
await fs.promises.writeFile(outputPath, compressed);
|
|
288
289
|
}
|
|
289
290
|
|
|
290
|
-
async function createSeaLauncher({ executablePath, appDir, target, productName, payloadPath = null }) {
|
|
291
|
+
async function createSeaLauncher({ executablePath, appDir, target, productName, appId, payloadPath = null }) {
|
|
291
292
|
const work = path.join(path.dirname(executablePath), '.sea-' + crypto.randomBytes(5).toString('hex'));
|
|
292
293
|
await fse.ensureDir(work);
|
|
293
294
|
const launcherPath = path.join(work, 'launcher.cjs');
|
|
@@ -295,7 +296,7 @@ async function createSeaLauncher({ executablePath, appDir, target, productName,
|
|
|
295
296
|
const configPath = path.join(work, 'sea-config.json');
|
|
296
297
|
|
|
297
298
|
if (!payloadPath) throw new Error('AtomJS SEA payload is required.');
|
|
298
|
-
const launcher = createEmbeddedLauncherSource(productName);
|
|
299
|
+
const launcher = createEmbeddedLauncherSource(productName, appId);
|
|
299
300
|
await fs.promises.writeFile(launcherPath, launcher, 'utf8');
|
|
300
301
|
|
|
301
302
|
const seaConfig = {
|
|
@@ -314,8 +315,8 @@ async function createSeaLauncher({ executablePath, appDir, target, productName,
|
|
|
314
315
|
if (target === 'windows') {
|
|
315
316
|
await prepareWindowsExecutableForInjection(executablePath);
|
|
316
317
|
}
|
|
317
|
-
if (target === 'macos' &&
|
|
318
|
-
spawnSync('codesign', ['--remove-signature', executablePath], { stdio: 'ignore' });
|
|
318
|
+
if (target === 'macos' && hasMacCodeSigningTool()) {
|
|
319
|
+
spawnSync('/usr/bin/codesign', ['--remove-signature', executablePath], { stdio: 'ignore' });
|
|
319
320
|
}
|
|
320
321
|
|
|
321
322
|
await inject(executablePath, 'NODE_SEA_BLOB', await fs.promises.readFile(blobPath), {
|
|
@@ -328,8 +329,8 @@ async function createSeaLauncher({ executablePath, appDir, target, productName,
|
|
|
328
329
|
} else {
|
|
329
330
|
await fs.promises.chmod(executablePath, 0o755);
|
|
330
331
|
}
|
|
331
|
-
if (target === 'macos' &&
|
|
332
|
-
await run('codesign', ['--force', '--sign', '-', executablePath]);
|
|
332
|
+
if (target === 'macos' && hasMacCodeSigningTool()) {
|
|
333
|
+
await run('/usr/bin/codesign', ['--force', '--sign', '-', executablePath]);
|
|
333
334
|
}
|
|
334
335
|
await fse.remove(work);
|
|
335
336
|
}
|
|
@@ -367,23 +368,36 @@ function readPortableExecutableLayout(image) {
|
|
|
367
368
|
}
|
|
368
369
|
|
|
369
370
|
const peOffset = image.readUInt32LE(0x3c);
|
|
370
|
-
|
|
371
|
+
const coffHeaderSize = 24;
|
|
372
|
+
if (peOffset < 0x40 || peOffset + coffHeaderSize > image.length || image.readUInt32LE(peOffset) !== 0x00004550) {
|
|
371
373
|
throw new Error('AtomJS expected a Windows PE executable but the PE header is invalid.');
|
|
372
374
|
}
|
|
373
375
|
|
|
374
|
-
const
|
|
376
|
+
const optionalHeaderSize = image.readUInt16LE(peOffset + 20);
|
|
377
|
+
const optionalHeaderOffset = peOffset + coffHeaderSize;
|
|
378
|
+
const optionalHeaderEnd = optionalHeaderOffset + optionalHeaderSize;
|
|
379
|
+
if (optionalHeaderSize < 2 || optionalHeaderEnd > image.length) {
|
|
380
|
+
throw new Error('AtomJS expected a complete Windows PE optional header.');
|
|
381
|
+
}
|
|
382
|
+
|
|
375
383
|
const magic = image.readUInt16LE(optionalHeaderOffset);
|
|
376
384
|
if (magic !== 0x10b && magic !== 0x20b) {
|
|
377
385
|
throw new Error(`AtomJS does not support Windows PE optional-header magic 0x${magic.toString(16)}.`);
|
|
378
386
|
}
|
|
379
387
|
|
|
388
|
+
const dataDirectoryOffset = optionalHeaderOffset + (magic === 0x20b ? 112 : 96);
|
|
389
|
+
const certificateDirectoryEnd = dataDirectoryOffset + (8 * 5);
|
|
390
|
+
if (certificateDirectoryEnd > optionalHeaderEnd) {
|
|
391
|
+
throw new Error('AtomJS expected the Windows PE certificate data directory.');
|
|
392
|
+
}
|
|
393
|
+
|
|
380
394
|
return {
|
|
381
395
|
optionalHeaderOffset,
|
|
382
|
-
dataDirectoryOffset
|
|
396
|
+
dataDirectoryOffset
|
|
383
397
|
};
|
|
384
398
|
}
|
|
385
399
|
|
|
386
|
-
function createEmbeddedLauncherSource(productName) {
|
|
400
|
+
function createEmbeddedLauncherSource(productName, appId) {
|
|
387
401
|
return `
|
|
388
402
|
'use strict';
|
|
389
403
|
const path = require('node:path');
|
|
@@ -396,6 +410,7 @@ const { pathToFileURL } = require('node:url');
|
|
|
396
410
|
const { getAsset } = require('node:sea');
|
|
397
411
|
|
|
398
412
|
const productName = ${JSON.stringify(productName)};
|
|
413
|
+
const appId = ${JSON.stringify(appId || 'com.atomjs.app')};
|
|
399
414
|
const payload = Buffer.from(getAsset('atom-app'));
|
|
400
415
|
const payloadHash = crypto.createHash('sha256').update(payload).digest('hex').slice(0, 24);
|
|
401
416
|
const dataRoot = process.platform === 'darwin'
|
|
@@ -435,10 +450,16 @@ if (!fs.existsSync(packagePath)) throw new Error('AtomJS could not materialize t
|
|
|
435
450
|
const executableDir = path.dirname(process.execPath);
|
|
436
451
|
process.chdir(appDir);
|
|
437
452
|
process.env.ATOM_PROJECT_ROOT = appDir;
|
|
453
|
+
process.env.ATOM_APP_NAME = productName;
|
|
454
|
+
process.env.ATOM_APP_ID = appId;
|
|
438
455
|
process.env.ATOM_BUILD = '1';
|
|
439
456
|
process.env.ATOM_EMBEDDED_RUNTIME = '1';
|
|
440
457
|
process.env.ATOM_WINDOW_HOST_ENTRY = path.join(appDir, 'vendor', 'atomjs', 'src', 'runtime', 'window-host.mjs');
|
|
441
458
|
process.env.ATOM_MACOS_HOST_EXECUTABLE = path.join(executableDir, 'AtomJSWindowHost');
|
|
459
|
+
const bundledMacIcon = path.join(executableDir, '..', 'Resources', 'AppIcon.icns');
|
|
460
|
+
if (process.platform === 'darwin' && fs.existsSync(bundledMacIcon)) {
|
|
461
|
+
process.env.ATOM_APP_ICON = bundledMacIcon;
|
|
462
|
+
}
|
|
442
463
|
const hostModeIndex = process.argv.indexOf('--atomjs-window-host');
|
|
443
464
|
if (hostModeIndex !== -1) {
|
|
444
465
|
const hostEntry = process.env.ATOM_WINDOW_HOST_ENTRY;
|
|
@@ -545,6 +566,10 @@ function resolveNsisExecutable() {
|
|
|
545
566
|
return candidates.find((candidate) => fs.existsSync(candidate)) || null;
|
|
546
567
|
}
|
|
547
568
|
|
|
569
|
+
function hasMacCodeSigningTool() {
|
|
570
|
+
return process.platform === 'darwin' && fs.existsSync('/usr/bin/codesign');
|
|
571
|
+
}
|
|
572
|
+
|
|
548
573
|
async function packageMacOS({ project, buildRoot, unpacked, executableName, productName, hostSource }) {
|
|
549
574
|
const outputs = [];
|
|
550
575
|
const appBundle = path.join(buildRoot, `${productName}.app`);
|
|
@@ -609,7 +634,7 @@ ${iconEntry}
|
|
|
609
634
|
await run('/usr/bin/plutil', ['-lint', plistPath]);
|
|
610
635
|
}
|
|
611
636
|
|
|
612
|
-
if (
|
|
637
|
+
if (hasMacCodeSigningTool()) {
|
|
613
638
|
await run('/usr/bin/codesign', ['--force', '--sign', '-', nativeHost]);
|
|
614
639
|
await run('/usr/bin/codesign', ['--force', '--sign', '-', mainExecutable]);
|
|
615
640
|
await run('/usr/bin/codesign', ['--force', '--deep', '--sign', '-', appBundle]);
|
|
@@ -783,4 +808,4 @@ function xml(value) {
|
|
|
783
808
|
return String(value).replace(/[<>&'\"]/g, (char) => ({ '<': '<', '>': '>', '&': '&', "'": ''', '"': '"' })[char]);
|
|
784
809
|
}
|
|
785
810
|
|
|
786
|
-
module.exports = { buildCommand, localBuild, createApplicationPayload };
|
|
811
|
+
module.exports = { buildCommand, localBuild, createApplicationPayload, readPortableExecutableLayout };
|
package/src/doctor.cjs
CHANGED
|
@@ -19,7 +19,7 @@ async function doctorCommand(options = {}) {
|
|
|
19
19
|
rows.push(check('Xcode Command Line Tools', commandExists('/usr/bin/xcrun', ['--version']), 'required to compile the native Cocoa host'));
|
|
20
20
|
rows.push(check('Clang', commandExists('/usr/bin/xcrun', ['clang', '--version'])));
|
|
21
21
|
rows.push(check('WebKit framework', fs.existsSync('/System/Library/Frameworks/WebKit.framework')));
|
|
22
|
-
rows.push(check('codesign',
|
|
22
|
+
rows.push(check('codesign', fs.existsSync('/usr/bin/codesign'), '/usr/bin/codesign'));
|
|
23
23
|
rows.push(check('hdiutil', commandExists('hdiutil', ['help'])));
|
|
24
24
|
} else {
|
|
25
25
|
rows.push(check('pkg-config', commandExists('pkg-config', ['--version'])));
|
package/src/init.cjs
CHANGED
|
@@ -30,14 +30,14 @@ async function initCommand(directory, options = {}) {
|
|
|
30
30
|
start: 'atom run build'
|
|
31
31
|
},
|
|
32
32
|
dependencies: {
|
|
33
|
-
'@atom-js-org/runtime': '0.3
|
|
34
|
-
electron: 'npm:@atom-js-org/electron@0.3
|
|
33
|
+
'@atom-js-org/runtime': '0.4.3-alpha.0',
|
|
34
|
+
electron: 'npm:@atom-js-org/electron@0.4.3-alpha.0'
|
|
35
35
|
},
|
|
36
36
|
optionalDependencies: {
|
|
37
37
|
'webview-nodejs': '0.5.0'
|
|
38
38
|
},
|
|
39
39
|
devDependencies: {
|
|
40
|
-
'@atom-js-org/cli': '0.3
|
|
40
|
+
'@atom-js-org/cli': '0.4.3-alpha.0'
|
|
41
41
|
},
|
|
42
42
|
overrides: {
|
|
43
43
|
tar: '7.5.20'
|
package/src/run.cjs
CHANGED
|
@@ -23,11 +23,17 @@ async function runDev(options) {
|
|
|
23
23
|
|
|
24
24
|
await ensureElectronCompatibility(project.root);
|
|
25
25
|
|
|
26
|
+
const iconPath = project.config.icon
|
|
27
|
+
? path.resolve(project.root, project.config.icon)
|
|
28
|
+
: null;
|
|
26
29
|
const child = spawn(process.execPath, [mainPath], {
|
|
27
30
|
cwd: project.root,
|
|
28
31
|
env: {
|
|
29
32
|
...process.env,
|
|
30
33
|
ATOM_PROJECT_ROOT: project.root,
|
|
34
|
+
ATOM_APP_NAME: project.config.productName,
|
|
35
|
+
ATOM_APP_ID: project.config.appId,
|
|
36
|
+
...(iconPath && fs.existsSync(iconPath) ? { ATOM_APP_ICON: iconPath } : {}),
|
|
31
37
|
ATOM_DEV: '1'
|
|
32
38
|
},
|
|
33
39
|
stdio: 'inherit'
|