@hakobu/hakobu 1.0.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/LICENSE +21 -0
- package/README.md +673 -0
- package/dictionary/angular-bridge.js +3 -0
- package/dictionary/any-promise.js +3 -0
- package/dictionary/async.js +3 -0
- package/dictionary/aws-sdk.js +7 -0
- package/dictionary/babel-core.js +3 -0
- package/dictionary/batch.js +3 -0
- package/dictionary/bcrypt.js +3 -0
- package/dictionary/better-sqlite3.js +3 -0
- package/dictionary/bignum.js +3 -0
- package/dictionary/bindings.js +3 -0
- package/dictionary/blessed.js +8 -0
- package/dictionary/body-parser.js +9 -0
- package/dictionary/browserify.js +7 -0
- package/dictionary/bson.js +3 -0
- package/dictionary/buffermaker.js +7 -0
- package/dictionary/bunyan.js +9 -0
- package/dictionary/busboy.js +7 -0
- package/dictionary/bytes.js +3 -0
- package/dictionary/callsites.js +3 -0
- package/dictionary/chokidar.js +3 -0
- package/dictionary/coffee-script.js +7 -0
- package/dictionary/colors.js +3 -0
- package/dictionary/compression.js +3 -0
- package/dictionary/compressjs.js +7 -0
- package/dictionary/connect-mongo.js +3 -0
- package/dictionary/connect-mongodb.js +3 -0
- package/dictionary/connect-redis.js +3 -0
- package/dictionary/connect.js +10 -0
- package/dictionary/consolidate.js +3 -0
- package/dictionary/cookie-parser.js +3 -0
- package/dictionary/cookie.js +3 -0
- package/dictionary/cors.js +3 -0
- package/dictionary/cron.js +3 -0
- package/dictionary/cross-env.js +11 -0
- package/dictionary/cross-spawn-async.js +3 -0
- package/dictionary/curve25519.js +3 -0
- package/dictionary/data-preflight.js +7 -0
- package/dictionary/debug.js +3 -0
- package/dictionary/denymount.js +3 -0
- package/dictionary/diff.js +3 -0
- package/dictionary/drivelist.js +22 -0
- package/dictionary/ed25519.js +3 -0
- package/dictionary/ejs.js +3 -0
- package/dictionary/elasticsearch.js +3 -0
- package/dictionary/electron.js +17 -0
- package/dictionary/emailjs.js +3 -0
- package/dictionary/engine.io.js +3 -0
- package/dictionary/epoll.js +3 -0
- package/dictionary/errorhandler.js +7 -0
- package/dictionary/errors.js +7 -0
- package/dictionary/eslint.js +7 -0
- package/dictionary/etcher-image-write.js +3 -0
- package/dictionary/exceljs.js +21 -0
- package/dictionary/exiftool.exe.js +13 -0
- package/dictionary/exiftool.pl.js +13 -0
- package/dictionary/express-load.js +12 -0
- package/dictionary/express-session.js +3 -0
- package/dictionary/express.js +14 -0
- package/dictionary/extender.js +11 -0
- package/dictionary/extsprintf.js +3 -0
- package/dictionary/faye-websocket.js +3 -0
- package/dictionary/feathers.js +3 -0
- package/dictionary/findup-sync.js +3 -0
- package/dictionary/floordate.js +3 -0
- package/dictionary/fmt.js +3 -0
- package/dictionary/formidable.js +3 -0
- package/dictionary/fs-extra.js +3 -0
- package/dictionary/fsevents.js +3 -0
- package/dictionary/geoip-lite.js +7 -0
- package/dictionary/github.js +7 -0
- package/dictionary/gm.js +3 -0
- package/dictionary/google-closure-compiler-java.js +13 -0
- package/dictionary/google-closure-compiler.js +13 -0
- package/dictionary/googleapis.js +7 -0
- package/dictionary/got.js +3 -0
- package/dictionary/graceful-fs.js +19 -0
- package/dictionary/grpc.js +11 -0
- package/dictionary/gulp.js +3 -0
- package/dictionary/hap-nodejs.js +3 -0
- package/dictionary/heapdump.js +3 -0
- package/dictionary/hoek.js +3 -0
- package/dictionary/homebridge.js +3 -0
- package/dictionary/http-proxy.js +3 -0
- package/dictionary/http-server.js +3 -0
- package/dictionary/image-size.js +3 -0
- package/dictionary/indexof.js +3 -0
- package/dictionary/inquirer.js +3 -0
- package/dictionary/j.js +16 -0
- package/dictionary/jade.js +3 -0
- package/dictionary/jsdom.js +3 -0
- package/dictionary/json-stringify-date.js +3 -0
- package/dictionary/json-stringify-safe.js +3 -0
- package/dictionary/jsonwebtoken.js +3 -0
- package/dictionary/kerberos.js +3 -0
- package/dictionary/knex.js +7 -0
- package/dictionary/later.js +7 -0
- package/dictionary/level.js +3 -0
- package/dictionary/leveldown.js +10 -0
- package/dictionary/levelup.js +3 -0
- package/dictionary/liftoff.js +12 -0
- package/dictionary/lodash.js +3 -0
- package/dictionary/log4js.js +7 -0
- package/dictionary/logform.js +7 -0
- package/dictionary/machinepack-urls.js +7 -0
- package/dictionary/markdown.js +3 -0
- package/dictionary/mdns.js +6 -0
- package/dictionary/method-override.js +3 -0
- package/dictionary/microjob.js +16 -0
- package/dictionary/mime-types.js +3 -0
- package/dictionary/mime.js +3 -0
- package/dictionary/minimatch.js +3 -0
- package/dictionary/minstache.js +3 -0
- package/dictionary/module-deps.js +3 -0
- package/dictionary/moment-timezone.js +3 -0
- package/dictionary/moment.js +7 -0
- package/dictionary/mongodb-core.js +22 -0
- package/dictionary/mongodb.js +7 -0
- package/dictionary/mongoose.js +7 -0
- package/dictionary/mongoskin.js +7 -0
- package/dictionary/ms.js +3 -0
- package/dictionary/msgpack.js +3 -0
- package/dictionary/multer.js +3 -0
- package/dictionary/muri.js +3 -0
- package/dictionary/native-or-bluebird.js +3 -0
- package/dictionary/natives.js +3 -0
- package/dictionary/nconf.js +7 -0
- package/dictionary/nedb.js +3 -0
- package/dictionary/negotiator.js +7 -0
- package/dictionary/newrelic.js +3 -0
- package/dictionary/nib.js +3 -0
- package/dictionary/nightmare.js +18 -0
- package/dictionary/node-forge.js +7 -0
- package/dictionary/node-libcurl.js +3 -0
- package/dictionary/node-notifier.js +30 -0
- package/dictionary/node-pre-gyp.js +7 -0
- package/dictionary/node-redis-pubsub.js +3 -0
- package/dictionary/node-sass.js +3 -0
- package/dictionary/node-uuid.js +3 -0
- package/dictionary/node-xlsx.js +3 -0
- package/dictionary/node-zookeeper-client.js +7 -0
- package/dictionary/nodegit.js +7 -0
- package/dictionary/nodemailer-sendmail-transport.js +3 -0
- package/dictionary/nodemailer.js +3 -0
- package/dictionary/npm-registry-client.js +7 -0
- package/dictionary/npm.js +7 -0
- package/dictionary/nssocket.js +3 -0
- package/dictionary/oauth2orize.js +7 -0
- package/dictionary/octobat.js +3 -0
- package/dictionary/open.js +13 -0
- package/dictionary/opn.js +4 -0
- package/dictionary/optimist.js +3 -0
- package/dictionary/passport-local.js +3 -0
- package/dictionary/passport.js +3 -0
- package/dictionary/pg-cursor.js +3 -0
- package/dictionary/pg-query-stream.js +3 -0
- package/dictionary/pg-types.js +7 -0
- package/dictionary/pg.js +7 -0
- package/dictionary/pg.js.js +7 -0
- package/dictionary/pgpass.js +7 -0
- package/dictionary/phantom.js +19 -0
- package/dictionary/phantomjs-prebuilt.js +16 -0
- package/dictionary/pkginfo.js +3 -0
- package/dictionary/pm2.js +7 -0
- package/dictionary/pmx.js +3 -0
- package/dictionary/pouchdb.js +3 -0
- package/dictionary/primus-emitter.js +3 -0
- package/dictionary/primus-spark-latency.js +3 -0
- package/dictionary/primus.js +3 -0
- package/dictionary/publicsuffixlist.js +15 -0
- package/dictionary/pug.js +3 -0
- package/dictionary/punt.js +3 -0
- package/dictionary/puppeteer.js +13 -0
- package/dictionary/pwd.js +3 -0
- package/dictionary/q.js +3 -0
- package/dictionary/raven.js +3 -0
- package/dictionary/rc.js +12 -0
- package/dictionary/readable-stream.js +3 -0
- package/dictionary/rechoir.js +3 -0
- package/dictionary/redis-parser.js +3 -0
- package/dictionary/redis.js +3 -0
- package/dictionary/regression.js +3 -0
- package/dictionary/reload.js +7 -0
- package/dictionary/request.js +3 -0
- package/dictionary/require-uncached.js +3 -0
- package/dictionary/require_optional.js +3 -0
- package/dictionary/s3.js +3 -0
- package/dictionary/safe_datejs.js +3 -0
- package/dictionary/sails.js +33 -0
- package/dictionary/sax.js +3 -0
- package/dictionary/scrypt.js +3 -0
- package/dictionary/semver.js +3 -0
- package/dictionary/sequelize.js +7 -0
- package/dictionary/serialport.js +3 -0
- package/dictionary/sha3.js +3 -0
- package/dictionary/sharp.js +11 -0
- package/dictionary/shelljs.js +7 -0
- package/dictionary/sinon.js +3 -0
- package/dictionary/socket.io-client.js +13 -0
- package/dictionary/socket.io.js +12 -0
- package/dictionary/sqip.js +7 -0
- package/dictionary/sqlite3.js +7 -0
- package/dictionary/steam-crypto.js +7 -0
- package/dictionary/steam-resources.js +19 -0
- package/dictionary/steam.js +3 -0
- package/dictionary/stripe-webhook-middleware.js +3 -0
- package/dictionary/stripe.js +3 -0
- package/dictionary/strong-globalize.js +3 -0
- package/dictionary/stylus.js +14 -0
- package/dictionary/supervisor.js +3 -0
- package/dictionary/svgo.js +8 -0
- package/dictionary/tabtab.js +3 -0
- package/dictionary/tesseract.js.js +7 -0
- package/dictionary/thread-stream.js +7 -0
- package/dictionary/throng.js +3 -0
- package/dictionary/time.js +3 -0
- package/dictionary/tinify.js +7 -0
- package/dictionary/tiny-worker.js +7 -0
- package/dictionary/tmp.js +3 -0
- package/dictionary/transformers.js +3 -0
- package/dictionary/uglify-js.js +9 -0
- package/dictionary/umd.js +19 -0
- package/dictionary/underscore.js +3 -0
- package/dictionary/union.js +3 -0
- package/dictionary/update-notifier.js +3 -0
- package/dictionary/usage.js +7 -0
- package/dictionary/v8flags.js +13 -0
- package/dictionary/verror.js +3 -0
- package/dictionary/voc.js +3 -0
- package/dictionary/webdriverio.js +7 -0
- package/dictionary/winston-uber.js +7 -0
- package/dictionary/winston.js +7 -0
- package/dictionary/ws.js +3 -0
- package/dictionary/xlsx.js +16 -0
- package/dictionary/xml2js.js +3 -0
- package/dictionary/yargs.js +3 -0
- package/dictionary/zeromq.js +13 -0
- package/lib-es5/addon-extract.js +164 -0
- package/lib-es5/analyzer.js +687 -0
- package/lib-es5/app-bundle.js +133 -0
- package/lib-es5/appdir.js +265 -0
- package/lib-es5/bin.js +304 -0
- package/lib-es5/bootstrap.js +179 -0
- package/lib-es5/bundler.js +496 -0
- package/lib-es5/chmod.js +15 -0
- package/lib-es5/colors.js +12 -0
- package/lib-es5/commands.js +376 -0
- package/lib-es5/common.js +328 -0
- package/lib-es5/compress_type.js +10 -0
- package/lib-es5/config.js +291 -0
- package/lib-es5/detector.js +421 -0
- package/lib-es5/esm-hooks.js +366 -0
- package/lib-es5/esm-resolver.js +292 -0
- package/lib-es5/esm-transformer.js +378 -0
- package/lib-es5/exports-resolver.js +184 -0
- package/lib-es5/external-artifacts.js +170 -0
- package/lib-es5/fabricator.js +137 -0
- package/lib-es5/follow.js +190 -0
- package/lib-es5/help.js +52 -0
- package/lib-es5/index.d.ts +2 -0
- package/lib-es5/index.js +552 -0
- package/lib-es5/log.js +7 -0
- package/lib-es5/mach-o.js +262 -0
- package/lib-es5/manifest.js +21 -0
- package/lib-es5/options.js +19 -0
- package/lib-es5/packager.js +1036 -0
- package/lib-es5/packer.js +137 -0
- package/lib-es5/pe-metadata.js +130 -0
- package/lib-es5/producer.js +378 -0
- package/lib-es5/refiner.js +87 -0
- package/lib-es5/resolver.js +142 -0
- package/lib-es5/runtime-diagnostics.js +172 -0
- package/lib-es5/sea.js +307 -0
- package/lib-es5/snapshot-fs-patch.js +396 -0
- package/lib-es5/snapshot-fs.js +255 -0
- package/lib-es5/snapshot-index.js +135 -0
- package/lib-es5/snapshot-path.js +168 -0
- package/lib-es5/types.js +9 -0
- package/lib-es5/walker.js +1019 -0
- package/lib-es5/windows-sign.js +139 -0
- package/package.json +99 -0
- package/prelude/bootstrap.js +2263 -0
- package/prelude/diagnostic.js +147 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* macOS Application Bundle Generator
|
|
4
|
+
*
|
|
5
|
+
* Wraps a packaged Mach-O executable into a standard .app bundle:
|
|
6
|
+
*
|
|
7
|
+
* MyApp.app/
|
|
8
|
+
* └── Contents/
|
|
9
|
+
* ├── Info.plist
|
|
10
|
+
* ├── MacOS/
|
|
11
|
+
* │ └── <binary>
|
|
12
|
+
* └── Resources/ (icons added in Task 24.3)
|
|
13
|
+
*
|
|
14
|
+
* The .app bundle is the standard macOS application format. It allows
|
|
15
|
+
* the executable to appear as a native application in Finder, Dock,
|
|
16
|
+
* and Launchpad, and is required for full Info.plist metadata and
|
|
17
|
+
* .icns icon support.
|
|
18
|
+
*/
|
|
19
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
20
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.createAppBundle = void 0;
|
|
24
|
+
const fs_1 = __importDefault(require("fs"));
|
|
25
|
+
const path_1 = __importDefault(require("path"));
|
|
26
|
+
const log_1 = require("./log");
|
|
27
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
28
|
+
// Info.plist generation
|
|
29
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
30
|
+
function esc(s) {
|
|
31
|
+
return s
|
|
32
|
+
.replace(/&/g, '&')
|
|
33
|
+
.replace(/</g, '<')
|
|
34
|
+
.replace(/>/g, '>');
|
|
35
|
+
}
|
|
36
|
+
function plistEntry(key, value) {
|
|
37
|
+
return ` <key>${esc(key)}</key>\n <string>${esc(value)}</string>`;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Derive a reverse-DNS bundle identifier from an app name.
|
|
41
|
+
* Strips @scope/ prefixes and replaces non-alphanumeric chars with hyphens.
|
|
42
|
+
*/
|
|
43
|
+
function deriveBundleId(appName) {
|
|
44
|
+
const clean = appName
|
|
45
|
+
.replace(/^@[^/]+\//, '') // strip npm scope
|
|
46
|
+
.replace(/[^a-zA-Z0-9.-]/g, '-')
|
|
47
|
+
.replace(/-+/g, '-')
|
|
48
|
+
.replace(/^-|-$/g, '');
|
|
49
|
+
return `com.hakobu.${clean || 'app'}`;
|
|
50
|
+
}
|
|
51
|
+
function generatePlist(executableName, appName, meta, iconFileName) {
|
|
52
|
+
const entries = [];
|
|
53
|
+
// Required keys
|
|
54
|
+
entries.push(plistEntry('CFBundleExecutable', executableName));
|
|
55
|
+
entries.push(plistEntry('CFBundleName', appName));
|
|
56
|
+
entries.push(plistEntry('CFBundlePackageType', 'APPL'));
|
|
57
|
+
entries.push(plistEntry('CFBundleInfoDictionaryVersion', '6.0'));
|
|
58
|
+
// Metadata keys (with defaults)
|
|
59
|
+
const bundleId = meta?.bundleId || deriveBundleId(appName);
|
|
60
|
+
entries.push(plistEntry('CFBundleIdentifier', bundleId));
|
|
61
|
+
const bundleVersion = meta?.bundleVersion || '1.0.0';
|
|
62
|
+
entries.push(plistEntry('CFBundleVersion', bundleVersion));
|
|
63
|
+
const shortVersion = meta?.shortVersion || bundleVersion;
|
|
64
|
+
entries.push(plistEntry('CFBundleShortVersionString', shortVersion));
|
|
65
|
+
if (meta?.displayName) {
|
|
66
|
+
entries.push(plistEntry('CFBundleDisplayName', meta.displayName));
|
|
67
|
+
}
|
|
68
|
+
if (meta?.copyright) {
|
|
69
|
+
entries.push(plistEntry('NSHumanReadableCopyright', meta.copyright));
|
|
70
|
+
}
|
|
71
|
+
if (iconFileName) {
|
|
72
|
+
entries.push(plistEntry('CFBundleIconFile', iconFileName));
|
|
73
|
+
}
|
|
74
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
75
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
76
|
+
<plist version="1.0">
|
|
77
|
+
<dict>
|
|
78
|
+
${entries.join('\n')}
|
|
79
|
+
</dict>
|
|
80
|
+
</plist>
|
|
81
|
+
`;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Wrap a packaged Mach-O executable into a macOS .app bundle.
|
|
85
|
+
*
|
|
86
|
+
* The executable is moved (not copied) into the bundle to avoid
|
|
87
|
+
* doubling disk usage.
|
|
88
|
+
*
|
|
89
|
+
* @returns The absolute path to the generated .app bundle.
|
|
90
|
+
*/
|
|
91
|
+
function createAppBundle(opts) {
|
|
92
|
+
const { executablePath } = opts;
|
|
93
|
+
// Determine .app path
|
|
94
|
+
let appPath = opts.outputPath;
|
|
95
|
+
if (!appPath.endsWith('.app')) {
|
|
96
|
+
appPath += '.app';
|
|
97
|
+
}
|
|
98
|
+
appPath = path_1.default.resolve(appPath);
|
|
99
|
+
// Derive names
|
|
100
|
+
const execName = path_1.default.basename(executablePath);
|
|
101
|
+
const appName = opts.appName || execName;
|
|
102
|
+
// Create bundle directory structure
|
|
103
|
+
const contentsDir = path_1.default.join(appPath, 'Contents');
|
|
104
|
+
const macosDir = path_1.default.join(contentsDir, 'MacOS');
|
|
105
|
+
const resourcesDir = path_1.default.join(contentsDir, 'Resources');
|
|
106
|
+
fs_1.default.mkdirSync(macosDir, { recursive: true });
|
|
107
|
+
fs_1.default.mkdirSync(resourcesDir, { recursive: true });
|
|
108
|
+
// Move executable into bundle
|
|
109
|
+
const bundledExec = path_1.default.join(macosDir, execName);
|
|
110
|
+
fs_1.default.renameSync(executablePath, bundledExec);
|
|
111
|
+
// Copy .icns icon if configured
|
|
112
|
+
let iconFileName;
|
|
113
|
+
const iconPath = opts.macos?.icon;
|
|
114
|
+
if (iconPath) {
|
|
115
|
+
if (!fs_1.default.existsSync(iconPath)) {
|
|
116
|
+
throw new Error(`macOS icon file not found: ${iconPath}`);
|
|
117
|
+
}
|
|
118
|
+
if (!iconPath.endsWith('.icns')) {
|
|
119
|
+
throw new Error(`macOS icon must be a .icns file (got ${path_1.default.extname(iconPath) || 'no extension'}).\n` +
|
|
120
|
+
'Convert your icon to .icns using: iconutil -c icns <iconset>');
|
|
121
|
+
}
|
|
122
|
+
iconFileName = path_1.default.basename(iconPath);
|
|
123
|
+
fs_1.default.copyFileSync(iconPath, path_1.default.join(resourcesDir, iconFileName));
|
|
124
|
+
log_1.log.info(` icon: ${iconFileName}`);
|
|
125
|
+
}
|
|
126
|
+
// Write Info.plist
|
|
127
|
+
const plist = generatePlist(execName, appName, opts.macos, iconFileName);
|
|
128
|
+
fs_1.default.writeFileSync(path_1.default.join(contentsDir, 'Info.plist'), plist, 'utf8');
|
|
129
|
+
log_1.log.info(`Created macOS app bundle: ${appPath}`);
|
|
130
|
+
return appPath;
|
|
131
|
+
}
|
|
132
|
+
exports.createAppBundle = createAppBundle;
|
|
133
|
+
//# sourceMappingURL=app-bundle.js.map
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Linux AppDir Generator
|
|
4
|
+
*
|
|
5
|
+
* Wraps a packaged ELF executable into an AppDir-style directory:
|
|
6
|
+
*
|
|
7
|
+
* MyApp.AppDir/
|
|
8
|
+
* ├── AppRun (launcher script)
|
|
9
|
+
* └── usr/
|
|
10
|
+
* ├── bin/
|
|
11
|
+
* │ └── <binary>
|
|
12
|
+
* ├── share/
|
|
13
|
+
* │ ├── applications/ (for .desktop in Task 25.2)
|
|
14
|
+
* │ └── icons/
|
|
15
|
+
* │ └── hicolor/ (for icons in Task 25.3)
|
|
16
|
+
* └── share/
|
|
17
|
+
* └── metainfo/ (for AppStream in Task 25.4)
|
|
18
|
+
*
|
|
19
|
+
* AppDir is the standard input format for AppImage tools and a common
|
|
20
|
+
* Linux application directory layout. It can be distributed as-is or
|
|
21
|
+
* packaged into an AppImage (Task 25.5).
|
|
22
|
+
*/
|
|
23
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
24
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
25
|
+
};
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
exports.isLinuxPlatform = exports.createAppImage = exports.createAppDir = void 0;
|
|
28
|
+
const fs_1 = __importDefault(require("fs"));
|
|
29
|
+
const path_1 = __importDefault(require("path"));
|
|
30
|
+
const log_1 = require("./log");
|
|
31
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
32
|
+
// .desktop file generation
|
|
33
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
34
|
+
/**
|
|
35
|
+
* Generate a .desktop file conforming to the Desktop Entry Specification.
|
|
36
|
+
* https://specifications.freedesktop.org/desktop-entry-spec/latest/
|
|
37
|
+
*/
|
|
38
|
+
function generateDesktopFile(executableName, appName, meta) {
|
|
39
|
+
const name = meta?.name || appName;
|
|
40
|
+
const icon = meta?.icon || appName;
|
|
41
|
+
const categories = meta?.categories || 'Utility;';
|
|
42
|
+
// Ensure categories ends with semicolon (spec requirement)
|
|
43
|
+
const cats = categories.endsWith(';') ? categories : categories + ';';
|
|
44
|
+
const terminal = meta?.terminal !== undefined ? meta.terminal : true;
|
|
45
|
+
const lines = [
|
|
46
|
+
'[Desktop Entry]',
|
|
47
|
+
'Type=Application',
|
|
48
|
+
`Name=${name}`,
|
|
49
|
+
`Exec=${executableName}`,
|
|
50
|
+
`Icon=${icon}`,
|
|
51
|
+
`Categories=${cats}`,
|
|
52
|
+
`Terminal=${terminal ? 'true' : 'false'}`,
|
|
53
|
+
];
|
|
54
|
+
if (meta?.comment) {
|
|
55
|
+
lines.splice(3, 0, `Comment=${meta.comment}`);
|
|
56
|
+
}
|
|
57
|
+
return lines.join('\n') + '\n';
|
|
58
|
+
}
|
|
59
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
60
|
+
// AppStream metainfo generation
|
|
61
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
62
|
+
function xmlEsc(s) {
|
|
63
|
+
return s
|
|
64
|
+
.replace(/&/g, '&')
|
|
65
|
+
.replace(/</g, '<')
|
|
66
|
+
.replace(/>/g, '>')
|
|
67
|
+
.replace(/"/g, '"');
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Derive a reverse-DNS component ID from an app name.
|
|
71
|
+
*/
|
|
72
|
+
function deriveComponentId(appName) {
|
|
73
|
+
const clean = appName
|
|
74
|
+
.replace(/^@[^/]+\//, '')
|
|
75
|
+
.replace(/[^a-zA-Z0-9.-]/g, '-')
|
|
76
|
+
.replace(/-+/g, '-')
|
|
77
|
+
.replace(/^-|-$/g, '');
|
|
78
|
+
return `com.hakobu.${clean || 'app'}`;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Generate an AppStream metainfo XML file.
|
|
82
|
+
* https://www.freedesktop.org/software/appstream/docs/
|
|
83
|
+
*
|
|
84
|
+
* Produces a minimal valid <component type="desktop-application">
|
|
85
|
+
* with the fields available from config/package.json.
|
|
86
|
+
*/
|
|
87
|
+
function generateMetainfo(appName, meta) {
|
|
88
|
+
const id = deriveComponentId(appName);
|
|
89
|
+
const name = meta?.name || appName;
|
|
90
|
+
const summary = meta?.summary || meta?.comment || `${name} application`;
|
|
91
|
+
const metadataLicense = 'FSFAP'; // Free for all purposes — standard for metainfo files
|
|
92
|
+
const projectLicense = meta?.license || 'LicenseRef-Proprietary';
|
|
93
|
+
const desktopId = `${appName}.desktop`;
|
|
94
|
+
const lines = [
|
|
95
|
+
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
96
|
+
'<component type="desktop-application">',
|
|
97
|
+
` <id>${xmlEsc(id)}</id>`,
|
|
98
|
+
` <name>${xmlEsc(name)}</name>`,
|
|
99
|
+
` <summary>${xmlEsc(summary)}</summary>`,
|
|
100
|
+
` <metadata_license>${xmlEsc(metadataLicense)}</metadata_license>`,
|
|
101
|
+
` <project_license>${xmlEsc(projectLicense)}</project_license>`,
|
|
102
|
+
` <launchable type="desktop-id">${xmlEsc(desktopId)}</launchable>`,
|
|
103
|
+
];
|
|
104
|
+
if (meta?.description) {
|
|
105
|
+
lines.push(' <description>');
|
|
106
|
+
lines.push(` <p>${xmlEsc(meta.description)}</p>`);
|
|
107
|
+
lines.push(' </description>');
|
|
108
|
+
}
|
|
109
|
+
if (meta?.url) {
|
|
110
|
+
lines.push(` <url type="homepage">${xmlEsc(meta.url)}</url>`);
|
|
111
|
+
}
|
|
112
|
+
if (meta?.version) {
|
|
113
|
+
lines.push(' <releases>');
|
|
114
|
+
lines.push(` <release version="${xmlEsc(meta.version)}" />`);
|
|
115
|
+
lines.push(' </releases>');
|
|
116
|
+
}
|
|
117
|
+
lines.push('</component>');
|
|
118
|
+
lines.push('');
|
|
119
|
+
return lines.join('\n');
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Generate the AppRun launcher script.
|
|
123
|
+
*
|
|
124
|
+
* AppRun is the entry point when an AppDir (or AppImage) is executed.
|
|
125
|
+
* It sets up the environment and launches the actual binary.
|
|
126
|
+
*/
|
|
127
|
+
function generateAppRun(executableName) {
|
|
128
|
+
return `#!/bin/sh
|
|
129
|
+
# AppRun — launcher for AppDir/AppImage
|
|
130
|
+
# Generated by Hakobu
|
|
131
|
+
|
|
132
|
+
SELF="$(readlink -f "$0")"
|
|
133
|
+
HERE="$(dirname "$SELF")"
|
|
134
|
+
|
|
135
|
+
exec "$HERE/usr/bin/${executableName}" "$@"
|
|
136
|
+
`;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Wrap a packaged ELF executable into a Linux AppDir.
|
|
140
|
+
*
|
|
141
|
+
* The executable is moved (not copied) into the AppDir to avoid
|
|
142
|
+
* doubling disk usage.
|
|
143
|
+
*
|
|
144
|
+
* @returns The absolute path to the generated AppDir.
|
|
145
|
+
*/
|
|
146
|
+
function createAppDir(opts) {
|
|
147
|
+
const { executablePath } = opts;
|
|
148
|
+
// Determine AppDir path
|
|
149
|
+
let appDirPath = opts.outputPath;
|
|
150
|
+
if (!appDirPath.endsWith('.AppDir')) {
|
|
151
|
+
appDirPath += '.AppDir';
|
|
152
|
+
}
|
|
153
|
+
appDirPath = path_1.default.resolve(appDirPath);
|
|
154
|
+
// Derive names
|
|
155
|
+
const execName = path_1.default.basename(executablePath);
|
|
156
|
+
const appName = opts.appName || execName;
|
|
157
|
+
// Create directory structure
|
|
158
|
+
const binDir = path_1.default.join(appDirPath, 'usr', 'bin');
|
|
159
|
+
const applicationsDir = path_1.default.join(appDirPath, 'usr', 'share', 'applications');
|
|
160
|
+
const iconsDir = path_1.default.join(appDirPath, 'usr', 'share', 'icons', 'hicolor');
|
|
161
|
+
const metainfoDir = path_1.default.join(appDirPath, 'usr', 'share', 'metainfo');
|
|
162
|
+
fs_1.default.mkdirSync(binDir, { recursive: true });
|
|
163
|
+
fs_1.default.mkdirSync(applicationsDir, { recursive: true });
|
|
164
|
+
fs_1.default.mkdirSync(iconsDir, { recursive: true });
|
|
165
|
+
fs_1.default.mkdirSync(metainfoDir, { recursive: true });
|
|
166
|
+
// Move executable into AppDir
|
|
167
|
+
const destExec = path_1.default.join(binDir, execName);
|
|
168
|
+
fs_1.default.renameSync(executablePath, destExec);
|
|
169
|
+
// Write AppRun launcher
|
|
170
|
+
const appRunPath = path_1.default.join(appDirPath, 'AppRun');
|
|
171
|
+
fs_1.default.writeFileSync(appRunPath, generateAppRun(execName), { mode: 0o755 });
|
|
172
|
+
// Write .desktop file
|
|
173
|
+
const desktopContent = generateDesktopFile(execName, appName, opts.linux);
|
|
174
|
+
const desktopFileName = `${appName}.desktop`;
|
|
175
|
+
fs_1.default.writeFileSync(path_1.default.join(applicationsDir, desktopFileName), desktopContent);
|
|
176
|
+
// Place icon if configured
|
|
177
|
+
const iconPath = opts.linux?.iconPath;
|
|
178
|
+
if (iconPath) {
|
|
179
|
+
if (!fs_1.default.existsSync(iconPath)) {
|
|
180
|
+
throw new Error(`Linux icon file not found: ${iconPath}`);
|
|
181
|
+
}
|
|
182
|
+
if (!iconPath.endsWith('.png')) {
|
|
183
|
+
throw new Error(`Linux icon must be a .png file (got ${path_1.default.extname(iconPath) || 'no extension'}).`);
|
|
184
|
+
}
|
|
185
|
+
const iconName = (opts.linux?.icon || appName) + '.png';
|
|
186
|
+
// Place in hicolor/256x256/apps/ (standard freedesktop location)
|
|
187
|
+
const hicolor256 = path_1.default.join(iconsDir, '256x256', 'apps');
|
|
188
|
+
fs_1.default.mkdirSync(hicolor256, { recursive: true });
|
|
189
|
+
fs_1.default.copyFileSync(iconPath, path_1.default.join(hicolor256, iconName));
|
|
190
|
+
// Place at AppDir root (AppImage convention)
|
|
191
|
+
fs_1.default.copyFileSync(iconPath, path_1.default.join(appDirPath, iconName));
|
|
192
|
+
log_1.log.info(` icon: ${iconName}`);
|
|
193
|
+
}
|
|
194
|
+
// Write AppStream metainfo
|
|
195
|
+
const metainfoContent = generateMetainfo(appName, opts.linux);
|
|
196
|
+
fs_1.default.writeFileSync(path_1.default.join(metainfoDir, `${appName}.metainfo.xml`), metainfoContent);
|
|
197
|
+
log_1.log.info(`Created Linux AppDir: ${appDirPath}`);
|
|
198
|
+
return appDirPath;
|
|
199
|
+
}
|
|
200
|
+
exports.createAppDir = createAppDir;
|
|
201
|
+
/**
|
|
202
|
+
* Map Node.js arch names to AppImage arch names.
|
|
203
|
+
*/
|
|
204
|
+
function nodeArchToAppImage(arch) {
|
|
205
|
+
switch (arch) {
|
|
206
|
+
case 'x64': return 'x86_64';
|
|
207
|
+
case 'arm64': return 'aarch64';
|
|
208
|
+
case 'arm': return 'armhf';
|
|
209
|
+
default: return arch;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Build an AppImage from an AppDir using appimagetool.
|
|
214
|
+
*
|
|
215
|
+
* appimagetool is an external tool that must be in PATH.
|
|
216
|
+
* Download from: https://github.com/AppImage/appimagetool/releases
|
|
217
|
+
*
|
|
218
|
+
* @throws If appimagetool is not found or fails.
|
|
219
|
+
* @returns The absolute path to the generated .AppImage file.
|
|
220
|
+
*/
|
|
221
|
+
function createAppImage(opts) {
|
|
222
|
+
const { appDirPath } = opts;
|
|
223
|
+
let outputPath = opts.outputPath;
|
|
224
|
+
if (!outputPath.endsWith('.AppImage')) {
|
|
225
|
+
outputPath += '.AppImage';
|
|
226
|
+
}
|
|
227
|
+
outputPath = path_1.default.resolve(outputPath);
|
|
228
|
+
// Ensure output directory exists
|
|
229
|
+
fs_1.default.mkdirSync(path_1.default.dirname(outputPath), { recursive: true });
|
|
230
|
+
const arch = opts.arch || nodeArchToAppImage(process.arch);
|
|
231
|
+
// Check if appimagetool is available
|
|
232
|
+
const { execFileSync } = require('child_process');
|
|
233
|
+
try {
|
|
234
|
+
execFileSync('appimagetool', ['--version'], {
|
|
235
|
+
stdio: 'pipe',
|
|
236
|
+
timeout: 10000,
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
if (err.code === 'ENOENT') {
|
|
241
|
+
throw new Error('appimagetool is not installed or not in PATH.\n' +
|
|
242
|
+
'Download from: https://github.com/AppImage/appimagetool/releases\n' +
|
|
243
|
+
'On Ubuntu/Debian: download the AppImage, chmod +x, and move to /usr/local/bin/\n' +
|
|
244
|
+
'Or install via package manager if available.');
|
|
245
|
+
}
|
|
246
|
+
throw err;
|
|
247
|
+
}
|
|
248
|
+
log_1.log.info(`Building AppImage from ${path_1.default.basename(appDirPath)}...`);
|
|
249
|
+
execFileSync('appimagetool', [appDirPath, outputPath], {
|
|
250
|
+
stdio: 'inherit',
|
|
251
|
+
timeout: 300000,
|
|
252
|
+
env: { ...process.env, ARCH: arch },
|
|
253
|
+
});
|
|
254
|
+
log_1.log.info(`Created AppImage: ${outputPath}`);
|
|
255
|
+
return outputPath;
|
|
256
|
+
}
|
|
257
|
+
exports.createAppImage = createAppImage;
|
|
258
|
+
/**
|
|
259
|
+
* Check if a platform string represents a Linux target.
|
|
260
|
+
*/
|
|
261
|
+
function isLinuxPlatform(platform) {
|
|
262
|
+
return platform === 'linux' || platform === 'alpine' || platform === 'linuxstatic';
|
|
263
|
+
}
|
|
264
|
+
exports.isLinuxPlatform = isLinuxPlatform;
|
|
265
|
+
//# sourceMappingURL=appdir.js.map
|