@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.
Files changed (284) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +673 -0
  3. package/dictionary/angular-bridge.js +3 -0
  4. package/dictionary/any-promise.js +3 -0
  5. package/dictionary/async.js +3 -0
  6. package/dictionary/aws-sdk.js +7 -0
  7. package/dictionary/babel-core.js +3 -0
  8. package/dictionary/batch.js +3 -0
  9. package/dictionary/bcrypt.js +3 -0
  10. package/dictionary/better-sqlite3.js +3 -0
  11. package/dictionary/bignum.js +3 -0
  12. package/dictionary/bindings.js +3 -0
  13. package/dictionary/blessed.js +8 -0
  14. package/dictionary/body-parser.js +9 -0
  15. package/dictionary/browserify.js +7 -0
  16. package/dictionary/bson.js +3 -0
  17. package/dictionary/buffermaker.js +7 -0
  18. package/dictionary/bunyan.js +9 -0
  19. package/dictionary/busboy.js +7 -0
  20. package/dictionary/bytes.js +3 -0
  21. package/dictionary/callsites.js +3 -0
  22. package/dictionary/chokidar.js +3 -0
  23. package/dictionary/coffee-script.js +7 -0
  24. package/dictionary/colors.js +3 -0
  25. package/dictionary/compression.js +3 -0
  26. package/dictionary/compressjs.js +7 -0
  27. package/dictionary/connect-mongo.js +3 -0
  28. package/dictionary/connect-mongodb.js +3 -0
  29. package/dictionary/connect-redis.js +3 -0
  30. package/dictionary/connect.js +10 -0
  31. package/dictionary/consolidate.js +3 -0
  32. package/dictionary/cookie-parser.js +3 -0
  33. package/dictionary/cookie.js +3 -0
  34. package/dictionary/cors.js +3 -0
  35. package/dictionary/cron.js +3 -0
  36. package/dictionary/cross-env.js +11 -0
  37. package/dictionary/cross-spawn-async.js +3 -0
  38. package/dictionary/curve25519.js +3 -0
  39. package/dictionary/data-preflight.js +7 -0
  40. package/dictionary/debug.js +3 -0
  41. package/dictionary/denymount.js +3 -0
  42. package/dictionary/diff.js +3 -0
  43. package/dictionary/drivelist.js +22 -0
  44. package/dictionary/ed25519.js +3 -0
  45. package/dictionary/ejs.js +3 -0
  46. package/dictionary/elasticsearch.js +3 -0
  47. package/dictionary/electron.js +17 -0
  48. package/dictionary/emailjs.js +3 -0
  49. package/dictionary/engine.io.js +3 -0
  50. package/dictionary/epoll.js +3 -0
  51. package/dictionary/errorhandler.js +7 -0
  52. package/dictionary/errors.js +7 -0
  53. package/dictionary/eslint.js +7 -0
  54. package/dictionary/etcher-image-write.js +3 -0
  55. package/dictionary/exceljs.js +21 -0
  56. package/dictionary/exiftool.exe.js +13 -0
  57. package/dictionary/exiftool.pl.js +13 -0
  58. package/dictionary/express-load.js +12 -0
  59. package/dictionary/express-session.js +3 -0
  60. package/dictionary/express.js +14 -0
  61. package/dictionary/extender.js +11 -0
  62. package/dictionary/extsprintf.js +3 -0
  63. package/dictionary/faye-websocket.js +3 -0
  64. package/dictionary/feathers.js +3 -0
  65. package/dictionary/findup-sync.js +3 -0
  66. package/dictionary/floordate.js +3 -0
  67. package/dictionary/fmt.js +3 -0
  68. package/dictionary/formidable.js +3 -0
  69. package/dictionary/fs-extra.js +3 -0
  70. package/dictionary/fsevents.js +3 -0
  71. package/dictionary/geoip-lite.js +7 -0
  72. package/dictionary/github.js +7 -0
  73. package/dictionary/gm.js +3 -0
  74. package/dictionary/google-closure-compiler-java.js +13 -0
  75. package/dictionary/google-closure-compiler.js +13 -0
  76. package/dictionary/googleapis.js +7 -0
  77. package/dictionary/got.js +3 -0
  78. package/dictionary/graceful-fs.js +19 -0
  79. package/dictionary/grpc.js +11 -0
  80. package/dictionary/gulp.js +3 -0
  81. package/dictionary/hap-nodejs.js +3 -0
  82. package/dictionary/heapdump.js +3 -0
  83. package/dictionary/hoek.js +3 -0
  84. package/dictionary/homebridge.js +3 -0
  85. package/dictionary/http-proxy.js +3 -0
  86. package/dictionary/http-server.js +3 -0
  87. package/dictionary/image-size.js +3 -0
  88. package/dictionary/indexof.js +3 -0
  89. package/dictionary/inquirer.js +3 -0
  90. package/dictionary/j.js +16 -0
  91. package/dictionary/jade.js +3 -0
  92. package/dictionary/jsdom.js +3 -0
  93. package/dictionary/json-stringify-date.js +3 -0
  94. package/dictionary/json-stringify-safe.js +3 -0
  95. package/dictionary/jsonwebtoken.js +3 -0
  96. package/dictionary/kerberos.js +3 -0
  97. package/dictionary/knex.js +7 -0
  98. package/dictionary/later.js +7 -0
  99. package/dictionary/level.js +3 -0
  100. package/dictionary/leveldown.js +10 -0
  101. package/dictionary/levelup.js +3 -0
  102. package/dictionary/liftoff.js +12 -0
  103. package/dictionary/lodash.js +3 -0
  104. package/dictionary/log4js.js +7 -0
  105. package/dictionary/logform.js +7 -0
  106. package/dictionary/machinepack-urls.js +7 -0
  107. package/dictionary/markdown.js +3 -0
  108. package/dictionary/mdns.js +6 -0
  109. package/dictionary/method-override.js +3 -0
  110. package/dictionary/microjob.js +16 -0
  111. package/dictionary/mime-types.js +3 -0
  112. package/dictionary/mime.js +3 -0
  113. package/dictionary/minimatch.js +3 -0
  114. package/dictionary/minstache.js +3 -0
  115. package/dictionary/module-deps.js +3 -0
  116. package/dictionary/moment-timezone.js +3 -0
  117. package/dictionary/moment.js +7 -0
  118. package/dictionary/mongodb-core.js +22 -0
  119. package/dictionary/mongodb.js +7 -0
  120. package/dictionary/mongoose.js +7 -0
  121. package/dictionary/mongoskin.js +7 -0
  122. package/dictionary/ms.js +3 -0
  123. package/dictionary/msgpack.js +3 -0
  124. package/dictionary/multer.js +3 -0
  125. package/dictionary/muri.js +3 -0
  126. package/dictionary/native-or-bluebird.js +3 -0
  127. package/dictionary/natives.js +3 -0
  128. package/dictionary/nconf.js +7 -0
  129. package/dictionary/nedb.js +3 -0
  130. package/dictionary/negotiator.js +7 -0
  131. package/dictionary/newrelic.js +3 -0
  132. package/dictionary/nib.js +3 -0
  133. package/dictionary/nightmare.js +18 -0
  134. package/dictionary/node-forge.js +7 -0
  135. package/dictionary/node-libcurl.js +3 -0
  136. package/dictionary/node-notifier.js +30 -0
  137. package/dictionary/node-pre-gyp.js +7 -0
  138. package/dictionary/node-redis-pubsub.js +3 -0
  139. package/dictionary/node-sass.js +3 -0
  140. package/dictionary/node-uuid.js +3 -0
  141. package/dictionary/node-xlsx.js +3 -0
  142. package/dictionary/node-zookeeper-client.js +7 -0
  143. package/dictionary/nodegit.js +7 -0
  144. package/dictionary/nodemailer-sendmail-transport.js +3 -0
  145. package/dictionary/nodemailer.js +3 -0
  146. package/dictionary/npm-registry-client.js +7 -0
  147. package/dictionary/npm.js +7 -0
  148. package/dictionary/nssocket.js +3 -0
  149. package/dictionary/oauth2orize.js +7 -0
  150. package/dictionary/octobat.js +3 -0
  151. package/dictionary/open.js +13 -0
  152. package/dictionary/opn.js +4 -0
  153. package/dictionary/optimist.js +3 -0
  154. package/dictionary/passport-local.js +3 -0
  155. package/dictionary/passport.js +3 -0
  156. package/dictionary/pg-cursor.js +3 -0
  157. package/dictionary/pg-query-stream.js +3 -0
  158. package/dictionary/pg-types.js +7 -0
  159. package/dictionary/pg.js +7 -0
  160. package/dictionary/pg.js.js +7 -0
  161. package/dictionary/pgpass.js +7 -0
  162. package/dictionary/phantom.js +19 -0
  163. package/dictionary/phantomjs-prebuilt.js +16 -0
  164. package/dictionary/pkginfo.js +3 -0
  165. package/dictionary/pm2.js +7 -0
  166. package/dictionary/pmx.js +3 -0
  167. package/dictionary/pouchdb.js +3 -0
  168. package/dictionary/primus-emitter.js +3 -0
  169. package/dictionary/primus-spark-latency.js +3 -0
  170. package/dictionary/primus.js +3 -0
  171. package/dictionary/publicsuffixlist.js +15 -0
  172. package/dictionary/pug.js +3 -0
  173. package/dictionary/punt.js +3 -0
  174. package/dictionary/puppeteer.js +13 -0
  175. package/dictionary/pwd.js +3 -0
  176. package/dictionary/q.js +3 -0
  177. package/dictionary/raven.js +3 -0
  178. package/dictionary/rc.js +12 -0
  179. package/dictionary/readable-stream.js +3 -0
  180. package/dictionary/rechoir.js +3 -0
  181. package/dictionary/redis-parser.js +3 -0
  182. package/dictionary/redis.js +3 -0
  183. package/dictionary/regression.js +3 -0
  184. package/dictionary/reload.js +7 -0
  185. package/dictionary/request.js +3 -0
  186. package/dictionary/require-uncached.js +3 -0
  187. package/dictionary/require_optional.js +3 -0
  188. package/dictionary/s3.js +3 -0
  189. package/dictionary/safe_datejs.js +3 -0
  190. package/dictionary/sails.js +33 -0
  191. package/dictionary/sax.js +3 -0
  192. package/dictionary/scrypt.js +3 -0
  193. package/dictionary/semver.js +3 -0
  194. package/dictionary/sequelize.js +7 -0
  195. package/dictionary/serialport.js +3 -0
  196. package/dictionary/sha3.js +3 -0
  197. package/dictionary/sharp.js +11 -0
  198. package/dictionary/shelljs.js +7 -0
  199. package/dictionary/sinon.js +3 -0
  200. package/dictionary/socket.io-client.js +13 -0
  201. package/dictionary/socket.io.js +12 -0
  202. package/dictionary/sqip.js +7 -0
  203. package/dictionary/sqlite3.js +7 -0
  204. package/dictionary/steam-crypto.js +7 -0
  205. package/dictionary/steam-resources.js +19 -0
  206. package/dictionary/steam.js +3 -0
  207. package/dictionary/stripe-webhook-middleware.js +3 -0
  208. package/dictionary/stripe.js +3 -0
  209. package/dictionary/strong-globalize.js +3 -0
  210. package/dictionary/stylus.js +14 -0
  211. package/dictionary/supervisor.js +3 -0
  212. package/dictionary/svgo.js +8 -0
  213. package/dictionary/tabtab.js +3 -0
  214. package/dictionary/tesseract.js.js +7 -0
  215. package/dictionary/thread-stream.js +7 -0
  216. package/dictionary/throng.js +3 -0
  217. package/dictionary/time.js +3 -0
  218. package/dictionary/tinify.js +7 -0
  219. package/dictionary/tiny-worker.js +7 -0
  220. package/dictionary/tmp.js +3 -0
  221. package/dictionary/transformers.js +3 -0
  222. package/dictionary/uglify-js.js +9 -0
  223. package/dictionary/umd.js +19 -0
  224. package/dictionary/underscore.js +3 -0
  225. package/dictionary/union.js +3 -0
  226. package/dictionary/update-notifier.js +3 -0
  227. package/dictionary/usage.js +7 -0
  228. package/dictionary/v8flags.js +13 -0
  229. package/dictionary/verror.js +3 -0
  230. package/dictionary/voc.js +3 -0
  231. package/dictionary/webdriverio.js +7 -0
  232. package/dictionary/winston-uber.js +7 -0
  233. package/dictionary/winston.js +7 -0
  234. package/dictionary/ws.js +3 -0
  235. package/dictionary/xlsx.js +16 -0
  236. package/dictionary/xml2js.js +3 -0
  237. package/dictionary/yargs.js +3 -0
  238. package/dictionary/zeromq.js +13 -0
  239. package/lib-es5/addon-extract.js +164 -0
  240. package/lib-es5/analyzer.js +687 -0
  241. package/lib-es5/app-bundle.js +133 -0
  242. package/lib-es5/appdir.js +265 -0
  243. package/lib-es5/bin.js +304 -0
  244. package/lib-es5/bootstrap.js +179 -0
  245. package/lib-es5/bundler.js +496 -0
  246. package/lib-es5/chmod.js +15 -0
  247. package/lib-es5/colors.js +12 -0
  248. package/lib-es5/commands.js +376 -0
  249. package/lib-es5/common.js +328 -0
  250. package/lib-es5/compress_type.js +10 -0
  251. package/lib-es5/config.js +291 -0
  252. package/lib-es5/detector.js +421 -0
  253. package/lib-es5/esm-hooks.js +366 -0
  254. package/lib-es5/esm-resolver.js +292 -0
  255. package/lib-es5/esm-transformer.js +378 -0
  256. package/lib-es5/exports-resolver.js +184 -0
  257. package/lib-es5/external-artifacts.js +170 -0
  258. package/lib-es5/fabricator.js +137 -0
  259. package/lib-es5/follow.js +190 -0
  260. package/lib-es5/help.js +52 -0
  261. package/lib-es5/index.d.ts +2 -0
  262. package/lib-es5/index.js +552 -0
  263. package/lib-es5/log.js +7 -0
  264. package/lib-es5/mach-o.js +262 -0
  265. package/lib-es5/manifest.js +21 -0
  266. package/lib-es5/options.js +19 -0
  267. package/lib-es5/packager.js +1036 -0
  268. package/lib-es5/packer.js +137 -0
  269. package/lib-es5/pe-metadata.js +130 -0
  270. package/lib-es5/producer.js +378 -0
  271. package/lib-es5/refiner.js +87 -0
  272. package/lib-es5/resolver.js +142 -0
  273. package/lib-es5/runtime-diagnostics.js +172 -0
  274. package/lib-es5/sea.js +307 -0
  275. package/lib-es5/snapshot-fs-patch.js +396 -0
  276. package/lib-es5/snapshot-fs.js +255 -0
  277. package/lib-es5/snapshot-index.js +135 -0
  278. package/lib-es5/snapshot-path.js +168 -0
  279. package/lib-es5/types.js +9 -0
  280. package/lib-es5/walker.js +1019 -0
  281. package/lib-es5/windows-sign.js +139 -0
  282. package/package.json +99 -0
  283. package/prelude/bootstrap.js +2263 -0
  284. package/prelude/diagnostic.js +147 -0
@@ -0,0 +1,376 @@
1
+ "use strict";
2
+ /**
3
+ * Hakobu diagnostic and inspection commands.
4
+ *
5
+ * These answer the questions developers ask before, during, and after packaging:
6
+ * - targets: What can I build for? What base binaries are cached?
7
+ * - inspect: What does Hakobu see in my project?
8
+ * - doctor: Is my project ready to package? What's wrong?
9
+ */
10
+ var __importDefault = (this && this.__importDefault) || function (mod) {
11
+ return (mod && mod.__esModule) ? mod : { "default": mod };
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.commandDoctor = exports.commandInspect = exports.commandTargets = void 0;
15
+ const fs_1 = __importDefault(require("fs"));
16
+ const path_1 = __importDefault(require("path"));
17
+ const promises_1 = require("fs/promises");
18
+ const hakobu_fetch_1 = require("@hakobu/hakobu-fetch");
19
+ // These are internal to hakobu-fetch but we import the compiled JS
20
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
21
+ const { EXPECTED_HASHES } = require('@hakobu/hakobu-fetch/lib-es5/expected');
22
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
23
+ const { localPlace } = require('@hakobu/hakobu-fetch/lib-es5/places');
24
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
25
+ const fetchPkg = require('@hakobu/hakobu-fetch/package.json');
26
+ const analyzer_1 = require("./analyzer");
27
+ const { hostArch, hostPlatform, knownArchs, knownPlatforms, } = hakobu_fetch_1.system;
28
+ // ─────────────────────────────────────────────────────────────────────
29
+ // Shared formatting
30
+ // ─────────────────────────────────────────────────────────────────────
31
+ function bold(s) { return `\x1b[1m${s}\x1b[0m`; }
32
+ function green(s) { return `\x1b[32m${s}\x1b[0m`; }
33
+ function yellow(s) { return `\x1b[33m${s}\x1b[0m`; }
34
+ function red(s) { return `\x1b[31m${s}\x1b[0m`; }
35
+ function dim(s) { return `\x1b[2m${s}\x1b[0m`; }
36
+ function severityIcon(s) {
37
+ if (s === 'error')
38
+ return red('x');
39
+ if (s === 'warning')
40
+ return yellow('!');
41
+ return dim('i');
42
+ }
43
+ // ─────────────────────────────────────────────────────────────────────
44
+ // hakobu targets
45
+ // ─────────────────────────────────────────────────────────────────────
46
+ async function commandTargets() {
47
+ const nodeVersion = (0, hakobu_fetch_1.getNodeVersion)('node24');
48
+ const fetchVersion = fetchPkg.version;
49
+ console.log(bold('Hakobu Targets'));
50
+ console.log();
51
+ // Host
52
+ console.log(` Host: ${bold(`${hostPlatform}-${hostArch}`)} (Node ${process.version})`);
53
+ console.log(` Base: Node ${nodeVersion}`);
54
+ console.log();
55
+ // Published targets from expected-shas.json
56
+ const published = [];
57
+ for (const name of Object.keys(EXPECTED_HASHES)) {
58
+ // name format: hakobu-base-v24.14.0-linux-x64
59
+ const match = name.match(/^hakobu-base-(v[\d.]+)-([a-z]+)-([a-z0-9]+)$/);
60
+ if (!match)
61
+ continue;
62
+ const [, , platform, arch] = match;
63
+ // Check cache
64
+ const cachedPath = localPlace({
65
+ from: 'fetched',
66
+ arch,
67
+ nodeVersion,
68
+ platform,
69
+ version: fetchVersion,
70
+ });
71
+ let cached = false;
72
+ try {
73
+ const s = await (0, promises_1.stat)(cachedPath);
74
+ cached = s.size > 0;
75
+ }
76
+ catch { /* not cached */ }
77
+ published.push({ platform, arch, name, cached });
78
+ }
79
+ // Sort: host target first, then alphabetical
80
+ published.sort((a, b) => {
81
+ const aIsHost = a.platform === hostPlatform && a.arch === hostArch;
82
+ const bIsHost = b.platform === hostPlatform && b.arch === hostArch;
83
+ if (aIsHost && !bIsHost)
84
+ return -1;
85
+ if (!aIsHost && bIsHost)
86
+ return 1;
87
+ return `${a.platform}-${a.arch}`.localeCompare(`${b.platform}-${b.arch}`);
88
+ });
89
+ console.log(' Published base binaries:');
90
+ console.log();
91
+ for (const t of published) {
92
+ const isHost = t.platform === hostPlatform && t.arch === hostArch;
93
+ const label = `${t.platform}-${t.arch}`;
94
+ const hostTag = isHost ? dim(' (host)') : '';
95
+ const cacheTag = t.cached ? green(' cached') : dim(' remote');
96
+ console.log(` ${t.cached ? green('*') : ' '} ${label}${hostTag}${cacheTag}`);
97
+ }
98
+ console.log();
99
+ console.log(dim(' * = locally cached base binary'));
100
+ console.log(dim(` Cache: ${localPlace({ from: 'fetched', arch: 'x64', nodeVersion, platform: 'linux', version: fetchVersion }).replace(/fetched-.*$/, '')}`));
101
+ }
102
+ exports.commandTargets = commandTargets;
103
+ // ─────────────────────────────────────────────────────────────────────
104
+ // hakobu inspect <projectRoot>
105
+ // ─────────────────────────────────────────────────────────────────────
106
+ async function commandInspect(projectRoot) {
107
+ if (!projectRoot) {
108
+ console.error(red('Usage: hakobu inspect <project-root>'));
109
+ process.exit(1);
110
+ }
111
+ const resolved = path_1.default.resolve(projectRoot);
112
+ if (!fs_1.default.existsSync(resolved)) {
113
+ console.error(red(`Project root not found: ${resolved}`));
114
+ process.exit(1);
115
+ }
116
+ console.log(bold('Hakobu Project Inspection'));
117
+ console.log();
118
+ console.log(` Project: ${resolved}`);
119
+ let manifest;
120
+ try {
121
+ manifest = await (0, analyzer_1.analyze)({ projectRoot: resolved });
122
+ }
123
+ catch (err) {
124
+ console.log();
125
+ console.log(red(` Analysis failed: ${err.message}`));
126
+ if (err.remediation) {
127
+ console.log(` Remediation: ${err.remediation}`);
128
+ }
129
+ process.exit(1);
130
+ }
131
+ // Entry
132
+ console.log();
133
+ console.log(` ${bold('Entry')}`);
134
+ console.log(` Path: ${manifest.entry.snapshotPath}`);
135
+ console.log(` Format: ${manifest.entry.format === 'esm' ? green('ESM') : 'CJS'}`);
136
+ console.log(` Detected: ${manifest.entry.formatSource}`);
137
+ // Files summary
138
+ const files = Object.values(manifest.files);
139
+ const byKind = {};
140
+ for (const f of files) {
141
+ byKind[f.kind] = (byKind[f.kind] || 0) + 1;
142
+ }
143
+ console.log();
144
+ console.log(` ${bold('Files')} (${files.length} total)`);
145
+ for (const [kind, count] of Object.entries(byKind).sort((a, b) => b[1] - a[1])) {
146
+ console.log(` ${kind}: ${count}`);
147
+ }
148
+ // Packages
149
+ const pkgs = Object.values(manifest.packages);
150
+ if (pkgs.length > 0) {
151
+ console.log();
152
+ console.log(` ${bold('Packages')} (${pkgs.length})`);
153
+ for (const pkg of pkgs.slice(0, 20)) {
154
+ const name = pkg.name || dim('(unnamed)');
155
+ const ver = pkg.version || '';
156
+ const type = pkg.type === 'module' ? green('ESM') : 'CJS';
157
+ console.log(` ${name}${ver ? `@${ver}` : ''} ${dim(type)}`);
158
+ }
159
+ if (pkgs.length > 20) {
160
+ console.log(dim(` ... and ${pkgs.length - 20} more`));
161
+ }
162
+ }
163
+ // Native addons
164
+ if (manifest.nativeAddons.length > 0) {
165
+ console.log();
166
+ console.log(` ${bold('Native Addons')} (${manifest.nativeAddons.length})`);
167
+ for (const addon of manifest.nativeAddons) {
168
+ console.log(` ${addon.snapshotPath}`);
169
+ }
170
+ }
171
+ // Externals
172
+ if (manifest.externals.length > 0) {
173
+ console.log();
174
+ console.log(` ${bold('External Artifacts')} (${manifest.externals.length})`);
175
+ for (const ext of manifest.externals) {
176
+ console.log(` ${ext.name} ${ext.required ? red('required') : dim('optional')}`);
177
+ }
178
+ }
179
+ // Warnings
180
+ printWarnings(manifest.warnings);
181
+ console.log();
182
+ }
183
+ exports.commandInspect = commandInspect;
184
+ // ─────────────────────────────────────────────────────────────────────
185
+ // hakobu doctor <projectRoot>
186
+ // ─────────────────────────────────────────────────────────────────────
187
+ async function commandDoctor(projectRoot, targetSpec) {
188
+ if (!projectRoot) {
189
+ console.error(red('Usage: hakobu doctor <project-root> [--target node24-macos-arm64]'));
190
+ process.exit(1);
191
+ }
192
+ const resolved = path_1.default.resolve(projectRoot);
193
+ if (!fs_1.default.existsSync(resolved)) {
194
+ console.error(red(`Project root not found: ${resolved}`));
195
+ process.exit(1);
196
+ }
197
+ console.log(bold('Hakobu Doctor'));
198
+ console.log();
199
+ const checks = [];
200
+ // Check 1: Project root has package.json
201
+ const pkgJsonPath = path_1.default.join(resolved, 'package.json');
202
+ if (fs_1.default.existsSync(pkgJsonPath)) {
203
+ const pkg = JSON.parse(fs_1.default.readFileSync(pkgJsonPath, 'utf8'));
204
+ checks.push({
205
+ name: 'package.json',
206
+ status: 'ok',
207
+ detail: `${pkg.name || '(unnamed)'}@${pkg.version || '0.0.0'}`,
208
+ });
209
+ }
210
+ else {
211
+ checks.push({
212
+ name: 'package.json',
213
+ status: 'fail',
214
+ detail: 'Not found. Hakobu needs a package.json to determine the project name and entry.',
215
+ });
216
+ }
217
+ // Check 2: Entrypoint exists
218
+ let manifest = null;
219
+ try {
220
+ manifest = await (0, analyzer_1.analyze)({ projectRoot: resolved });
221
+ checks.push({
222
+ name: 'Entrypoint',
223
+ status: 'ok',
224
+ detail: `${manifest.entry.snapshotPath} (${manifest.entry.format})`,
225
+ });
226
+ }
227
+ catch (err) {
228
+ checks.push({
229
+ name: 'Entrypoint',
230
+ status: 'fail',
231
+ detail: err.message,
232
+ });
233
+ }
234
+ // Check 3: Analysis warnings
235
+ if (manifest) {
236
+ const errors = manifest.warnings.filter(w => w.severity === 'error');
237
+ const warns = manifest.warnings.filter(w => w.severity === 'warning');
238
+ if (errors.length > 0) {
239
+ checks.push({
240
+ name: 'Analysis',
241
+ status: 'fail',
242
+ detail: `${errors.length} error(s): ${errors[0].message}`,
243
+ });
244
+ }
245
+ else if (warns.length > 0) {
246
+ checks.push({
247
+ name: 'Analysis',
248
+ status: 'warn',
249
+ detail: `${warns.length} warning(s)`,
250
+ });
251
+ }
252
+ else {
253
+ checks.push({
254
+ name: 'Analysis',
255
+ status: 'ok',
256
+ detail: `${Object.keys(manifest.files).length} files, no issues`,
257
+ });
258
+ }
259
+ }
260
+ // Check 4: Target base binary
261
+ const target = parseTargetForDoctor(targetSpec);
262
+ const nodeVersion = (0, hakobu_fetch_1.getNodeVersion)('node24');
263
+ const fetchVersion = fetchPkg.version;
264
+ // Check if base is published
265
+ const expectedName = `hakobu-base-${nodeVersion}-${target.platform}-${target.arch}`;
266
+ const isPublished = !!EXPECTED_HASHES[expectedName];
267
+ if (isPublished) {
268
+ // Check if cached
269
+ const cachedPath = localPlace({
270
+ from: 'fetched',
271
+ arch: target.arch,
272
+ nodeVersion,
273
+ platform: target.platform,
274
+ version: fetchVersion,
275
+ });
276
+ let isCached = false;
277
+ try {
278
+ const s = await (0, promises_1.stat)(cachedPath);
279
+ isCached = s.size > 0;
280
+ }
281
+ catch { /* not cached */ }
282
+ if (isCached) {
283
+ checks.push({
284
+ name: `Base binary (${target.platform}-${target.arch})`,
285
+ status: 'ok',
286
+ detail: `Cached at ${cachedPath}`,
287
+ });
288
+ }
289
+ else {
290
+ checks.push({
291
+ name: `Base binary (${target.platform}-${target.arch})`,
292
+ status: 'ok',
293
+ detail: 'Available remotely (will be fetched during packaging)',
294
+ });
295
+ }
296
+ }
297
+ else {
298
+ checks.push({
299
+ name: `Base binary (${target.platform}-${target.arch})`,
300
+ status: 'fail',
301
+ detail: `No published base for ${target.platform}-${target.arch}. Available: ${Object.keys(EXPECTED_HASHES).map(n => n.replace(/^hakobu-base-v[\d.]+-/, '')).join(', ')}`,
302
+ });
303
+ }
304
+ // Check 5: Native addons (if any)
305
+ if (manifest && manifest.nativeAddons.length > 0) {
306
+ if (target.platform !== hostPlatform || target.arch !== hostArch) {
307
+ checks.push({
308
+ name: 'Native addons',
309
+ status: 'warn',
310
+ detail: `${manifest.nativeAddons.length} native addon(s) detected. Cross-platform packaging of native addons requires rebuilding for the target.`,
311
+ });
312
+ }
313
+ else {
314
+ checks.push({
315
+ name: 'Native addons',
316
+ status: 'ok',
317
+ detail: `${manifest.nativeAddons.length} addon(s) — host-target match`,
318
+ });
319
+ }
320
+ }
321
+ // Print results
322
+ let hasFailure = false;
323
+ for (const check of checks) {
324
+ const icon = check.status === 'ok' ? green('OK') : check.status === 'warn' ? yellow('!!') : red('XX');
325
+ console.log(` ${icon} ${check.name}`);
326
+ console.log(` ${check.detail}`);
327
+ if (check.status === 'fail')
328
+ hasFailure = true;
329
+ }
330
+ // Print manifest warnings if available
331
+ if (manifest && manifest.warnings.length > 0) {
332
+ printWarnings(manifest.warnings);
333
+ }
334
+ console.log();
335
+ if (hasFailure) {
336
+ console.log(red(' Some checks failed. Fix the issues above before packaging.'));
337
+ }
338
+ else {
339
+ console.log(green(' All checks passed. Ready to package.'));
340
+ }
341
+ }
342
+ exports.commandDoctor = commandDoctor;
343
+ // ─────────────────────────────────────────────────────────────────────
344
+ // Shared helpers
345
+ // ─────────────────────────────────────────────────────────────────────
346
+ function printWarnings(warnings) {
347
+ if (warnings.length === 0)
348
+ return;
349
+ console.log();
350
+ console.log(` ${bold('Warnings')} (${warnings.length})`);
351
+ for (const w of warnings) {
352
+ console.log(` ${severityIcon(w.severity)} [${w.category}] ${w.message}`);
353
+ if (w.file)
354
+ console.log(dim(` in ${w.file}`));
355
+ if (w.suggestion)
356
+ console.log(dim(` fix: ${w.suggestion}`));
357
+ }
358
+ }
359
+ function parseTargetForDoctor(spec) {
360
+ if (!spec) {
361
+ return { platform: hostPlatform, arch: hostArch };
362
+ }
363
+ const parts = spec.split('-');
364
+ let platform = hostPlatform;
365
+ let arch = hostArch;
366
+ for (const part of parts) {
367
+ if (part.startsWith('node'))
368
+ continue;
369
+ if (knownPlatforms.includes(part))
370
+ platform = part;
371
+ else if (knownArchs.includes(part))
372
+ arch = part;
373
+ }
374
+ return { platform, arch };
375
+ }
376
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1,328 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isESMFile = exports.isESMPackage = exports.toNormalizedRealPath = exports.removeUplevels = exports.stripSnapshot = exports.insideSnapshot = exports.snapshotify = exports.substituteDenominator = exports.retrieveDenominator = exports.unlikelyJavascript = exports.isDotNODE = exports.isDotJSON = exports.isDotJS = exports.isPackageJson = exports.normalizePath = exports.isRootPath = exports.ALIAS_AS_RESOLVABLE = exports.ALIAS_AS_RELATIVE = exports.STORE_STAT = exports.STORE_LINKS = exports.STORE_CONTENT = exports.STORE_BLOB = void 0;
7
+ const assert_1 = __importDefault(require("assert"));
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const path_1 = __importDefault(require("path"));
10
+ exports.STORE_BLOB = 0;
11
+ exports.STORE_CONTENT = 1;
12
+ exports.STORE_LINKS = 2;
13
+ exports.STORE_STAT = 3;
14
+ exports.ALIAS_AS_RELATIVE = 0; // require("./file.js") // file or directory
15
+ exports.ALIAS_AS_RESOLVABLE = 1; // require("package")
16
+ const win32 = process.platform === 'win32';
17
+ const hasURL = typeof URL !== 'undefined';
18
+ function uppercaseDriveLetter(f) {
19
+ if (f.slice(1, 3) !== ':\\')
20
+ return f;
21
+ return f[0].toUpperCase() + f.slice(1);
22
+ }
23
+ function removeTrailingSlashes(f) {
24
+ if (f === '/') {
25
+ return f; // dont remove from "/"
26
+ }
27
+ if (f.slice(1) === ':\\') {
28
+ return f; // dont remove from "D:\"
29
+ }
30
+ let last = f.length - 1;
31
+ while (true) {
32
+ const char = f.charAt(last);
33
+ if (char === '\\') {
34
+ f = f.slice(0, -1);
35
+ last -= 1;
36
+ }
37
+ else if (char === '/') {
38
+ f = f.slice(0, -1);
39
+ last -= 1;
40
+ }
41
+ else {
42
+ break;
43
+ }
44
+ }
45
+ return f;
46
+ }
47
+ const isUrl = (p) => hasURL && p instanceof URL;
48
+ function pathToString(p, win) {
49
+ let result;
50
+ if (Buffer.isBuffer(p)) {
51
+ result = p.toString();
52
+ }
53
+ else if (isUrl(p)) {
54
+ result = win ? p.pathname.replace(/^\//, '') : p.pathname;
55
+ }
56
+ else {
57
+ result = p;
58
+ }
59
+ return result;
60
+ }
61
+ function isRootPath(p) {
62
+ let file = pathToString(p, false);
63
+ if (file === '.') {
64
+ file = path_1.default.resolve(file);
65
+ }
66
+ return path_1.default.dirname(file) === p;
67
+ }
68
+ exports.isRootPath = isRootPath;
69
+ function normalizePath(f) {
70
+ let file = pathToString(f, win32);
71
+ if (!/^.:$/.test(file)) {
72
+ file = path_1.default.normalize(file);
73
+ } // 'c:' -> 'c:.'
74
+ if (win32) {
75
+ file = uppercaseDriveLetter(file);
76
+ }
77
+ return removeTrailingSlashes(file);
78
+ }
79
+ exports.normalizePath = normalizePath;
80
+ function isPackageJson(file) {
81
+ return path_1.default.basename(file) === 'package.json';
82
+ }
83
+ exports.isPackageJson = isPackageJson;
84
+ function isDotJS(file) {
85
+ return ['.js', '.cjs'].includes(path_1.default.extname(file));
86
+ }
87
+ exports.isDotJS = isDotJS;
88
+ function isDotJSON(file) {
89
+ return path_1.default.extname(file) === '.json';
90
+ }
91
+ exports.isDotJSON = isDotJSON;
92
+ function isDotNODE(file) {
93
+ return path_1.default.extname(file) === '.node';
94
+ }
95
+ exports.isDotNODE = isDotNODE;
96
+ function unlikelyJavascript(file) {
97
+ const ext = path_1.default.extname(file);
98
+ // Check single extensions
99
+ if (['.css', '.html', '.json', '.vue'].includes(ext)) {
100
+ return true;
101
+ }
102
+ // Check for .d.ts files (compound extension)
103
+ if (file.endsWith('.d.ts')) {
104
+ return true;
105
+ }
106
+ return false;
107
+ }
108
+ exports.unlikelyJavascript = unlikelyJavascript;
109
+ function replaceSlashes(file, slash) {
110
+ if (/^.:\\/.test(file)) {
111
+ if (slash === '/') {
112
+ return file.slice(2).replace(/\\/g, '/');
113
+ }
114
+ }
115
+ else if (/^\//.test(file)) {
116
+ if (slash === '\\') {
117
+ return `C:${file.replace(/\//g, '\\')}`;
118
+ }
119
+ }
120
+ return file;
121
+ }
122
+ function injectSnapshot(file) {
123
+ if (/^.:\\/.test(file)) {
124
+ // C:\path\to
125
+ if (file.length === 3) {
126
+ // C:\
127
+ file = file.slice(0, -1);
128
+ }
129
+ // by convention, on windows we use C:\\snapshot
130
+ return `C:\\snapshot${file.slice(2)}`;
131
+ }
132
+ if (/^\//.test(file)) {
133
+ // /home/user/project
134
+ if (file.length === 1) {
135
+ // /
136
+ file = file.slice(0, -1);
137
+ }
138
+ return `/snapshot${file}`;
139
+ }
140
+ return file;
141
+ }
142
+ function longestCommonLength(s1, s2) {
143
+ const length = Math.min(s1.length, s2.length);
144
+ for (let i = 0; i < length; i += 1) {
145
+ if (s1.charCodeAt(i) !== s2.charCodeAt(i)) {
146
+ return i;
147
+ }
148
+ }
149
+ return length;
150
+ }
151
+ function withoutNodeModules(file) {
152
+ return file.split(`${path_1.default.sep}node_modules${path_1.default.sep}`)[0];
153
+ }
154
+ function retrieveDenominator(files) {
155
+ (0, assert_1.default)(files.length > 0);
156
+ let s1 = withoutNodeModules(files[0]) + path_1.default.sep;
157
+ for (let i = 1; i < files.length; i += 1) {
158
+ const s2 = withoutNodeModules(files[i]) + path_1.default.sep;
159
+ s1 = s1.slice(0, longestCommonLength(s1, s2));
160
+ }
161
+ if (s1 === '') {
162
+ return win32 ? 2 : 0;
163
+ }
164
+ return s1.lastIndexOf(path_1.default.sep);
165
+ }
166
+ exports.retrieveDenominator = retrieveDenominator;
167
+ function substituteDenominator(f, denominator) {
168
+ const rootLength = win32 ? 2 : 0;
169
+ return f.slice(0, rootLength) + f.slice(denominator);
170
+ }
171
+ exports.substituteDenominator = substituteDenominator;
172
+ function snapshotify(file, slash) {
173
+ return injectSnapshot(replaceSlashes(file, slash));
174
+ }
175
+ exports.snapshotify = snapshotify;
176
+ function insideSnapshot(f) {
177
+ f = pathToString(f, win32);
178
+ if (typeof f !== 'string') {
179
+ return false;
180
+ }
181
+ if (win32) {
182
+ const slice112 = f.slice(1, 12);
183
+ return (slice112 === ':\\snapshot\\' ||
184
+ slice112 === ':/snapshot\\' ||
185
+ slice112 === ':\\snapshot/' ||
186
+ slice112 === ':/snapshot/' ||
187
+ slice112 === ':\\snapshot' ||
188
+ slice112 === ':/snapshot');
189
+ }
190
+ const slice010 = f.slice(0, 10);
191
+ return slice010 === '/snapshot/' || slice010 === '/snapshot';
192
+ }
193
+ exports.insideSnapshot = insideSnapshot;
194
+ function stripSnapshot(f) {
195
+ const file = normalizePath(f);
196
+ if (/^.:\\snapshot$/.test(file)) {
197
+ return `${file[0]}:\\**\\`;
198
+ }
199
+ if (/^.:\\snapshot\\/.test(file)) {
200
+ return `${file[0]}:\\**${file.slice(11)}`;
201
+ }
202
+ if (/^\/snapshot$/.test(file)) {
203
+ return '/**/';
204
+ }
205
+ if (/^\/snapshot\//.test(file)) {
206
+ return `/**${file.slice(9)}`;
207
+ }
208
+ return f; // not inside
209
+ }
210
+ exports.stripSnapshot = stripSnapshot;
211
+ function removeUplevels(f) {
212
+ if (win32) {
213
+ while (true) {
214
+ if (f.slice(0, 3) === '..\\') {
215
+ f = f.slice(3);
216
+ }
217
+ else if (f === '..') {
218
+ f = '.';
219
+ }
220
+ else {
221
+ break;
222
+ }
223
+ }
224
+ return f;
225
+ }
226
+ while (true) {
227
+ if (f.slice(0, 3) === '../') {
228
+ f = f.slice(3);
229
+ }
230
+ else if (f === '..') {
231
+ f = '.';
232
+ }
233
+ else {
234
+ break;
235
+ }
236
+ }
237
+ return f;
238
+ }
239
+ exports.removeUplevels = removeUplevels;
240
+ function toNormalizedRealPath(requestPath) {
241
+ const file = normalizePath(requestPath);
242
+ if (fs_1.default.existsSync(file)) {
243
+ return fs_1.default.realpathSync(file);
244
+ }
245
+ return file;
246
+ }
247
+ exports.toNormalizedRealPath = toNormalizedRealPath;
248
+ /**
249
+ * Find the nearest package.json file by walking up the directory tree
250
+ * @param filePath - Starting file path
251
+ * @returns Path to package.json or null if not found
252
+ */
253
+ function findNearestPackageJson(filePath) {
254
+ let dir = path_1.default.dirname(filePath);
255
+ const { root } = path_1.default.parse(dir);
256
+ while (dir !== root) {
257
+ const packageJsonPath = path_1.default.join(dir, 'package.json');
258
+ if (fs_1.default.existsSync(packageJsonPath)) {
259
+ return packageJsonPath;
260
+ }
261
+ dir = path_1.default.dirname(dir);
262
+ }
263
+ return null;
264
+ }
265
+ // Caches for ESM detection performance optimization
266
+ const packageJsonCache = new Map();
267
+ const esmPackageCache = new Map();
268
+ /**
269
+ * Check if a package.json indicates an ESM package
270
+ * @param packageJsonPath - Path to package.json
271
+ * @returns true if "type": "module" is set
272
+ */
273
+ function isESMPackage(packageJsonPath) {
274
+ // Check cache first
275
+ if (esmPackageCache.has(packageJsonPath)) {
276
+ return esmPackageCache.get(packageJsonPath);
277
+ }
278
+ try {
279
+ const content = fs_1.default.readFileSync(packageJsonPath, 'utf8');
280
+ const pkg = JSON.parse(content);
281
+ const result = pkg.type === 'module';
282
+ esmPackageCache.set(packageJsonPath, result);
283
+ return result;
284
+ }
285
+ catch {
286
+ esmPackageCache.set(packageJsonPath, false);
287
+ return false;
288
+ }
289
+ }
290
+ exports.isESMPackage = isESMPackage;
291
+ /**
292
+ * Determine if a file should be treated as ESM
293
+ * Based on file extension and nearest package.json "type" field
294
+ *
295
+ * @param filePath - The file path to check
296
+ * @returns true if file should be treated as ESM
297
+ */
298
+ function isESMFile(filePath) {
299
+ // .mjs files are always ESM
300
+ if (filePath.endsWith('.mjs')) {
301
+ return true;
302
+ }
303
+ // .cjs files are never ESM
304
+ if (filePath.endsWith('.cjs')) {
305
+ return false;
306
+ }
307
+ // For .js files, check nearest package.json for "type": "module"
308
+ if (filePath.endsWith('.js')) {
309
+ const dir = path_1.default.dirname(filePath);
310
+ // Check cache first
311
+ if (packageJsonCache.has(dir)) {
312
+ const cached = packageJsonCache.get(dir);
313
+ if (cached) {
314
+ return isESMPackage(cached);
315
+ }
316
+ return false;
317
+ }
318
+ // Compute and cache
319
+ const packageJsonPath = findNearestPackageJson(filePath);
320
+ packageJsonCache.set(dir, packageJsonPath);
321
+ if (packageJsonPath) {
322
+ return isESMPackage(packageJsonPath);
323
+ }
324
+ }
325
+ return false;
326
+ }
327
+ exports.isESMFile = isESMFile;
328
+ //# sourceMappingURL=common.js.map