@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,396 @@
1
+ "use strict";
2
+ /**
3
+ * Hakobu Snapshot Filesystem Patch
4
+ *
5
+ * Monkey-patches Node's `fs` module to intercept snapshot-owned paths
6
+ * and route them to SnapshotFS. Non-snapshot paths pass through to the
7
+ * real OS filesystem unchanged.
8
+ *
9
+ * This is the runtime integration layer. It follows the same pattern as
10
+ * the inherited pkg bootstrap.js but delegates to the clean SnapshotFS
11
+ * abstraction instead of the legacy VIRTUAL_FILESYSTEM.
12
+ *
13
+ * Usage (in the runtime bootstrap):
14
+ * const { patchFS, unpatchFS } = require('./snapshot-fs-patch');
15
+ * const sfs = new SnapshotFS(index, blob);
16
+ * const restore = patchFS(sfs);
17
+ * // ... app runs with patched fs ...
18
+ * restore(); // optional cleanup
19
+ *
20
+ * Only sync operations are patched in this first slice.
21
+ * Async variants will be added when needed for the ESM loader.
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.patchFS = void 0;
28
+ const fs_1 = __importDefault(require("fs"));
29
+ const module_1 = __importDefault(require("module"));
30
+ const snapshot_fs_1 = require("./snapshot-fs");
31
+ const snapshot_path_1 = require("./snapshot-path");
32
+ const addon_extract_1 = require("./addon-extract");
33
+ // ─────────────────────────────────────────────────────────────────────
34
+ // Path coercion (Node passes string | Buffer | URL)
35
+ // ─────────────────────────────────────────────────────────────────────
36
+ function coercePath(p) {
37
+ if (typeof p === 'string')
38
+ return p;
39
+ if (Buffer.isBuffer(p))
40
+ return p.toString();
41
+ if (p instanceof URL) {
42
+ if (p.protocol === 'file:') {
43
+ // file:///snapshot/app/... → /snapshot/app/...
44
+ return process.platform === 'win32'
45
+ ? p.pathname.replace(/^\//, '')
46
+ : p.pathname;
47
+ }
48
+ return null; // non-file URL, let Node handle it
49
+ }
50
+ return null;
51
+ }
52
+ function isSnapshotArg(arg) {
53
+ const p = coercePath(arg);
54
+ return p !== null && (0, snapshot_fs_1.isSnapshotPath)(p);
55
+ }
56
+ // ─────────────────────────────────────────────────────────────────────
57
+ // EROFS error for write operations
58
+ // ─────────────────────────────────────────────────────────────────────
59
+ function throwEROFS(syscall, arg) {
60
+ const p = coercePath(arg) ?? String(arg);
61
+ const err = new Error(`${syscall} EROFS: read-only file system, '${p}'`);
62
+ err.code = 'EROFS';
63
+ err.errno = -30;
64
+ err.syscall = syscall;
65
+ err.path = p;
66
+ throw err;
67
+ }
68
+ // ─────────────────────────────────────────────────────────────────────
69
+ // Patch entry point
70
+ // ─────────────────────────────────────────────────────────────────────
71
+ /**
72
+ * Patch Node's `fs` module to route snapshot paths to the given
73
+ * SnapshotFS instance. Returns a restore function that undoes the patch.
74
+ */
75
+ function patchFS(sfs) {
76
+ // Save originals
77
+ const orig = {
78
+ existsSync: fs_1.default.existsSync,
79
+ statSync: fs_1.default.statSync,
80
+ lstatSync: fs_1.default.lstatSync,
81
+ readFileSync: fs_1.default.readFileSync,
82
+ readdirSync: fs_1.default.readdirSync,
83
+ realpathSync: fs_1.default.realpathSync,
84
+ accessSync: fs_1.default.accessSync,
85
+ writeFileSync: fs_1.default.writeFileSync,
86
+ mkdirSync: fs_1.default.mkdirSync,
87
+ unlinkSync: fs_1.default.unlinkSync,
88
+ rmdirSync: fs_1.default.rmdirSync,
89
+ renameSync: fs_1.default.renameSync,
90
+ chmodSync: fs_1.default.chmodSync,
91
+ copyFileSync: fs_1.default.copyFileSync,
92
+ };
93
+ const origRealpathNative = fs_1.default.realpathSync.native;
94
+ // ── existsSync ──
95
+ fs_1.default.existsSync = function existsSync(path_) {
96
+ if (isSnapshotArg(path_)) {
97
+ return sfs.existsSync(coercePath(path_));
98
+ }
99
+ return orig.existsSync.call(fs_1.default, path_);
100
+ };
101
+ // ── statSync ──
102
+ fs_1.default.statSync = function statSync(path_, options) {
103
+ if (isSnapshotArg(path_)) {
104
+ try {
105
+ return sfs.statSync(coercePath(path_));
106
+ }
107
+ catch (e) {
108
+ if (options?.throwIfNoEntry === false && e.code === 'ENOENT') {
109
+ return undefined;
110
+ }
111
+ throw e;
112
+ }
113
+ }
114
+ return orig.statSync.call(fs_1.default, path_, options);
115
+ };
116
+ // ── lstatSync ──
117
+ fs_1.default.lstatSync = function lstatSync(path_, options) {
118
+ if (isSnapshotArg(path_)) {
119
+ try {
120
+ return sfs.lstatSync(coercePath(path_));
121
+ }
122
+ catch (e) {
123
+ if (options?.throwIfNoEntry === false && e.code === 'ENOENT') {
124
+ return undefined;
125
+ }
126
+ throw e;
127
+ }
128
+ }
129
+ return orig.lstatSync.call(fs_1.default, path_, options);
130
+ };
131
+ // ── readFileSync ──
132
+ fs_1.default.readFileSync = function readFileSync(path_, options_) {
133
+ if (isSnapshotArg(path_)) {
134
+ const p = coercePath(path_);
135
+ const buffer = sfs.readFileSync(p);
136
+ // Handle encoding option
137
+ const encoding = typeof options_ === 'string'
138
+ ? options_
139
+ : options_?.encoding ?? null;
140
+ if (encoding) {
141
+ return buffer.toString(encoding);
142
+ }
143
+ return buffer;
144
+ }
145
+ return orig.readFileSync.call(fs_1.default, path_, options_);
146
+ };
147
+ // ── readdirSync ──
148
+ fs_1.default.readdirSync = function readdirSync(path_, options_) {
149
+ if (isSnapshotArg(path_)) {
150
+ const entries = sfs.readdirSync(coercePath(path_));
151
+ // Handle withFileTypes option
152
+ if (options_?.withFileTypes) {
153
+ const p = coercePath(path_);
154
+ return entries.map((name) => {
155
+ const fullPath = p.endsWith('/') ? p + name : p + '/' + name;
156
+ const stat = sfs.existsSync(fullPath) ? sfs.statSync(fullPath) : null;
157
+ return {
158
+ name,
159
+ isFile: () => stat?.isFile() ?? false,
160
+ isDirectory: () => stat?.isDirectory() ?? false,
161
+ isSymbolicLink: () => false,
162
+ isBlockDevice: () => false,
163
+ isCharacterDevice: () => false,
164
+ isFIFO: () => false,
165
+ isSocket: () => false,
166
+ };
167
+ });
168
+ }
169
+ return entries;
170
+ }
171
+ return orig.readdirSync.call(fs_1.default, path_, options_);
172
+ };
173
+ // ── realpathSync ──
174
+ fs_1.default.realpathSync = function realpathSync(path_, options) {
175
+ if (isSnapshotArg(path_)) {
176
+ return sfs.realpathSync(coercePath(path_));
177
+ }
178
+ return orig.realpathSync.call(fs_1.default, path_, options);
179
+ };
180
+ // Preserve realpathSync.native
181
+ fs_1.default.realpathSync.native = function realpathSyncNative(path_, options) {
182
+ if (isSnapshotArg(path_)) {
183
+ return sfs.realpathSync(coercePath(path_));
184
+ }
185
+ return origRealpathNative.call(fs_1.default, path_, options);
186
+ };
187
+ // ── accessSync ──
188
+ fs_1.default.accessSync = function accessSync(path_, mode_) {
189
+ if (isSnapshotArg(path_)) {
190
+ const p = coercePath(path_);
191
+ // Read access always succeeds if the path exists
192
+ if (!sfs.existsSync(p)) {
193
+ const err = new Error(`ENOENT: no such file or directory, access '${p}'`);
194
+ err.code = 'ENOENT';
195
+ err.errno = -2;
196
+ err.syscall = 'access';
197
+ err.path = p;
198
+ throw err;
199
+ }
200
+ // Write access on snapshot paths fails
201
+ const W_OK = 2;
202
+ if (mode_ !== undefined && (mode_ & W_OK)) {
203
+ const err = new Error(`EROFS: read-only file system, access '${p}'`);
204
+ err.code = 'EROFS';
205
+ err.errno = -30;
206
+ err.syscall = 'access';
207
+ err.path = p;
208
+ throw err;
209
+ }
210
+ return; // read-only access OK
211
+ }
212
+ return orig.accessSync.call(fs_1.default, path_, mode_);
213
+ };
214
+ // ── Write operations → EROFS ──
215
+ fs_1.default.writeFileSync = function writeFileSync(path_, ...rest) {
216
+ if (isSnapshotArg(path_))
217
+ throwEROFS('write', path_);
218
+ return orig.writeFileSync.call(fs_1.default, path_, ...rest);
219
+ };
220
+ fs_1.default.mkdirSync = function mkdirSync(path_, ...rest) {
221
+ if (isSnapshotArg(path_))
222
+ throwEROFS('mkdir', path_);
223
+ return orig.mkdirSync.call(fs_1.default, path_, ...rest);
224
+ };
225
+ fs_1.default.unlinkSync = function unlinkSync(path_) {
226
+ if (isSnapshotArg(path_))
227
+ throwEROFS('unlink', path_);
228
+ return orig.unlinkSync.call(fs_1.default, path_);
229
+ };
230
+ fs_1.default.rmdirSync = function rmdirSync(path_, ...rest) {
231
+ if (isSnapshotArg(path_))
232
+ throwEROFS('rmdir', path_);
233
+ return orig.rmdirSync.call(fs_1.default, path_, ...rest);
234
+ };
235
+ fs_1.default.renameSync = function renameSync(oldPath, newPath) {
236
+ if (isSnapshotArg(oldPath) || isSnapshotArg(newPath)) {
237
+ throwEROFS('rename', isSnapshotArg(oldPath) ? oldPath : newPath);
238
+ }
239
+ return orig.renameSync.call(fs_1.default, oldPath, newPath);
240
+ };
241
+ fs_1.default.chmodSync = function chmodSync(path_, mode) {
242
+ if (isSnapshotArg(path_))
243
+ throwEROFS('chmod', path_);
244
+ return orig.chmodSync.call(fs_1.default, path_, mode);
245
+ };
246
+ fs_1.default.copyFileSync = function copyFileSync(src, dest, ...rest) {
247
+ if (isSnapshotArg(dest))
248
+ throwEROFS('copyfile', dest);
249
+ // Reading from snapshot is OK — write the data through host FS
250
+ if (isSnapshotArg(src)) {
251
+ const content = sfs.readFileSync(coercePath(src));
252
+ return orig.writeFileSync.call(fs_1.default, dest, content);
253
+ }
254
+ return orig.copyFileSync.call(fs_1.default, src, dest, ...rest);
255
+ };
256
+ // ── CJS Module resolution patch ──
257
+ // Node's require() uses Module._resolveFilename which calls internal
258
+ // C++ file operations that bypass our fs patches. We patch
259
+ // _resolveFilename to recognize snapshot paths directly.
260
+ const origResolveFilename = module_1.default._resolveFilename;
261
+ module_1.default._resolveFilename = function _resolveFilename(request, parent, isMain, options) {
262
+ let resolved = null;
263
+ // Absolute snapshot path
264
+ if (isSnapshotArg(request)) {
265
+ const p = coercePath(request);
266
+ if (sfs.existsSync(p))
267
+ resolved = p;
268
+ }
269
+ // Relative require from within snapshot (./foo, ../bar)
270
+ if (!resolved && (request.startsWith('.') || request.startsWith('/')) && parent?.filename && isSnapshotArg(parent.filename)) {
271
+ const parentDir = parent.filename.substring(0, parent.filename.lastIndexOf('/'));
272
+ const candidate = (0, snapshot_path_1.toCanonical)(parentDir + '/' + request);
273
+ resolved = tryResolveInSnapshot(candidate, sfs);
274
+ }
275
+ // Bare specifier from within snapshot (package name)
276
+ if (!resolved && parent?.filename && isSnapshotArg(parent.filename) && !request.startsWith('.') && !request.startsWith('/')) {
277
+ resolved = tryResolveBareInSnapshot(request, parent.filename, sfs);
278
+ }
279
+ if (resolved) {
280
+ // Native addons (.node) cannot be loaded from the snapshot via
281
+ // dlopen() — they must exist as real files. Extract to the
282
+ // deterministic cache and return the extracted path.
283
+ if (resolved.endsWith('.node') && (0, snapshot_fs_1.isSnapshotPath)(resolved)) {
284
+ const extracted = (0, addon_extract_1.extractAddon)(resolved, sfs);
285
+ return extracted.extractedPath;
286
+ }
287
+ return resolved;
288
+ }
289
+ return origResolveFilename.call(this, request, parent, isMain, options);
290
+ };
291
+ // (ensureSnapshotModuleCached removed — preloading is handled by bootstrap)
292
+ // Patch Module._compile to read snapshot source via SnapshotFS
293
+ // when the filename is a snapshot path.
294
+ const origCompile = module_1.default.prototype._compile;
295
+ module_1.default.prototype._compile = function _compile(content, filename) {
296
+ if (isSnapshotArg(filename)) {
297
+ // Read the real content from snapshot (the CJS loader may have
298
+ // passed empty or wrong content since the file doesn't exist
299
+ // on the real filesystem).
300
+ const p = coercePath(filename);
301
+ if (sfs.existsSync(p) && sfs.statSync(p).isFile()) {
302
+ content = sfs.readFileSync(p).toString('utf8');
303
+ }
304
+ }
305
+ return origCompile.call(this, content, filename);
306
+ };
307
+ // ── CJS resolution helpers ──
308
+ function tryResolveInSnapshot(candidate, sfsInst) {
309
+ const EXTS = ['.js', '.cjs', '.mjs', '.json', '.node'];
310
+ // Exact file
311
+ if (sfsInst.existsSync(candidate) && sfsInst.statSync(candidate).isFile())
312
+ return candidate;
313
+ // With extensions
314
+ for (const ext of EXTS) {
315
+ const withExt = candidate + ext;
316
+ if (sfsInst.existsSync(withExt) && sfsInst.statSync(withExt).isFile())
317
+ return withExt;
318
+ }
319
+ // Directory with index
320
+ if (sfsInst.existsSync(candidate) && sfsInst.statSync(candidate).isDirectory()) {
321
+ const pjPath = candidate + '/package.json';
322
+ if (sfsInst.existsSync(pjPath)) {
323
+ const pkg = sfsInst.getPackage(pjPath);
324
+ if (pkg?.main) {
325
+ const mainPath = (0, snapshot_path_1.toCanonical)(candidate + '/' + pkg.main);
326
+ const resolved = tryResolveInSnapshot(mainPath, sfsInst);
327
+ if (resolved)
328
+ return resolved;
329
+ }
330
+ }
331
+ for (const ext of EXTS) {
332
+ const indexPath = candidate + '/index' + ext;
333
+ if (sfsInst.existsSync(indexPath))
334
+ return indexPath;
335
+ }
336
+ }
337
+ return null;
338
+ }
339
+ function tryResolveBareInSnapshot(specifier, parentFilename, sfsInst) {
340
+ const pkgName = specifier.startsWith('@')
341
+ ? specifier.split('/').slice(0, 2).join('/')
342
+ : specifier.split('/')[0];
343
+ const subpath = specifier.slice(pkgName.length);
344
+ const appId = sfsInst.getAppId();
345
+ const snapRoot = '/snapshot/' + appId;
346
+ let searchDir = parentFilename.substring(0, parentFilename.lastIndexOf('/'));
347
+ while (searchDir.startsWith(snapRoot)) {
348
+ const nmDir = searchDir + '/node_modules/' + pkgName;
349
+ if (sfsInst.existsSync(nmDir)) {
350
+ if (!subpath) {
351
+ // Root import — check exports, then main, then index
352
+ const pkgJsonPath = nmDir + '/package.json';
353
+ const pkg = sfsInst.existsSync(pkgJsonPath) ? sfsInst.getPackage(pkgJsonPath) : null;
354
+ if (pkg?.main) {
355
+ const resolved = tryResolveInSnapshot((0, snapshot_path_1.toCanonical)(nmDir + '/' + pkg.main), sfsInst);
356
+ if (resolved)
357
+ return resolved;
358
+ }
359
+ const resolved = tryResolveInSnapshot(nmDir + '/index', sfsInst);
360
+ if (resolved)
361
+ return resolved;
362
+ }
363
+ else {
364
+ const resolved = tryResolveInSnapshot((0, snapshot_path_1.toCanonical)(nmDir + subpath), sfsInst);
365
+ if (resolved)
366
+ return resolved;
367
+ }
368
+ return null;
369
+ }
370
+ searchDir = searchDir.substring(0, searchDir.lastIndexOf('/'));
371
+ }
372
+ return null;
373
+ }
374
+ // ── Restore function ──
375
+ return function unpatchFS() {
376
+ fs_1.default.existsSync = orig.existsSync;
377
+ fs_1.default.statSync = orig.statSync;
378
+ fs_1.default.lstatSync = orig.lstatSync;
379
+ fs_1.default.readFileSync = orig.readFileSync;
380
+ fs_1.default.readdirSync = orig.readdirSync;
381
+ fs_1.default.realpathSync = orig.realpathSync;
382
+ fs_1.default.realpathSync.native = origRealpathNative;
383
+ fs_1.default.accessSync = orig.accessSync;
384
+ fs_1.default.writeFileSync = orig.writeFileSync;
385
+ fs_1.default.mkdirSync = orig.mkdirSync;
386
+ fs_1.default.unlinkSync = orig.unlinkSync;
387
+ fs_1.default.rmdirSync = orig.rmdirSync;
388
+ fs_1.default.renameSync = orig.renameSync;
389
+ fs_1.default.chmodSync = orig.chmodSync;
390
+ fs_1.default.copyFileSync = orig.copyFileSync;
391
+ module_1.default._resolveFilename = origResolveFilename;
392
+ module_1.default.prototype._compile = origCompile;
393
+ };
394
+ }
395
+ exports.patchFS = patchFS;
396
+ //# sourceMappingURL=snapshot-fs-patch.js.map
@@ -0,0 +1,255 @@
1
+ "use strict";
2
+ /**
3
+ * Hakobu Snapshot Filesystem
4
+ *
5
+ * A read-only virtual filesystem backed by a SnapshotIndex and a flat
6
+ * content blob. This is the runtime abstraction that sits between the
7
+ * Node fs patches and the actual snapshot data.
8
+ *
9
+ * The SnapshotFS:
10
+ * - serves file content from the blob
11
+ * - provides stat/lstat metadata
12
+ * - supports readdir for snapshot directories
13
+ * - resolves canonical (real) paths within the snapshot
14
+ * - detects whether a path is inside the snapshot
15
+ * - rejects all write operations with EROFS
16
+ *
17
+ * It does NOT:
18
+ * - monkey-patch Node's fs module (that's the runtime bootstrap's job)
19
+ * - implement ESM/CJS loading (that's Task 6)
20
+ * - handle native addon extraction (that's Task 9)
21
+ *
22
+ * All paths passed to this layer must be in the platform-native form
23
+ * that the runtime receives from Node (e.g., /snapshot/app/... on POSIX,
24
+ * C:\snapshot\app\... on Windows). The layer normalizes to POSIX
25
+ * internally for index lookup.
26
+ */
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.SnapshotFS = exports.toFileUrl = exports.toCanonical = exports.toNative = exports.isSnapshotPath = void 0;
29
+ // Re-export path utilities from the canonical module
30
+ var snapshot_path_1 = require("./snapshot-path");
31
+ Object.defineProperty(exports, "isSnapshotPath", { enumerable: true, get: function () { return snapshot_path_1.isSnapshotPath; } });
32
+ Object.defineProperty(exports, "toNative", { enumerable: true, get: function () { return snapshot_path_1.toNative; } });
33
+ Object.defineProperty(exports, "toCanonical", { enumerable: true, get: function () { return snapshot_path_1.toCanonical; } });
34
+ Object.defineProperty(exports, "toFileUrl", { enumerable: true, get: function () { return snapshot_path_1.toFileUrl; } });
35
+ const snapshot_path_2 = require("./snapshot-path");
36
+ // ─────────────────────────────────────────────────────────────────────
37
+ // Error factories (match Node's error codes)
38
+ // ─────────────────────────────────────────────────────────────────────
39
+ function enoent(syscall, path) {
40
+ const err = new Error(`${syscall} ENOENT: no such file or directory, '${path}'`);
41
+ err.code = 'ENOENT';
42
+ err.errno = -2;
43
+ err.syscall = syscall;
44
+ err.path = path;
45
+ return err;
46
+ }
47
+ function enotdir(syscall, path) {
48
+ const err = new Error(`${syscall} ENOTDIR: not a directory, '${path}'`);
49
+ err.code = 'ENOTDIR';
50
+ err.errno = -20;
51
+ err.syscall = syscall;
52
+ err.path = path;
53
+ return err;
54
+ }
55
+ function erofs(syscall, path) {
56
+ const err = new Error(`${syscall} EROFS: read-only file system, '${path}'`);
57
+ err.code = 'EROFS';
58
+ err.errno = -30;
59
+ err.syscall = syscall;
60
+ err.path = path;
61
+ return err;
62
+ }
63
+ function eisdir(syscall, path) {
64
+ const err = new Error(`${syscall} EISDIR: illegal operation on a directory, '${path}'`);
65
+ err.code = 'EISDIR';
66
+ err.errno = -21;
67
+ err.syscall = syscall;
68
+ err.path = path;
69
+ return err;
70
+ }
71
+ // Fixed epoch for deterministic stat timestamps
72
+ const EPOCH = new Date('2026-01-01T00:00:00Z');
73
+ const EPOCH_MS = EPOCH.getTime();
74
+ function fileStat(size) {
75
+ return {
76
+ isFile: () => true,
77
+ isDirectory: () => false,
78
+ isSymbolicLink: () => false,
79
+ size,
80
+ mode: 0o100644,
81
+ mtime: EPOCH, mtimeMs: EPOCH_MS,
82
+ atime: EPOCH, atimeMs: EPOCH_MS,
83
+ ctime: EPOCH, ctimeMs: EPOCH_MS,
84
+ birthtime: EPOCH, birthtimeMs: EPOCH_MS,
85
+ };
86
+ }
87
+ function dirStat() {
88
+ return {
89
+ isFile: () => false,
90
+ isDirectory: () => true,
91
+ isSymbolicLink: () => false,
92
+ size: 0,
93
+ mode: 0o40755,
94
+ mtime: EPOCH, mtimeMs: EPOCH_MS,
95
+ atime: EPOCH, atimeMs: EPOCH_MS,
96
+ ctime: EPOCH, ctimeMs: EPOCH_MS,
97
+ birthtime: EPOCH, birthtimeMs: EPOCH_MS,
98
+ };
99
+ }
100
+ // ─────────────────────────────────────────────────────────────────────
101
+ // SnapshotFS
102
+ // ─────────────────────────────────────────────────────────────────────
103
+ class SnapshotFS {
104
+ index;
105
+ blob;
106
+ /** Entries keyed by POSIX snapshot path for O(1) lookup. */
107
+ entryMap;
108
+ constructor(index, blob) {
109
+ this.index = index;
110
+ this.blob = blob;
111
+ // Build O(1) entry map from the sorted array
112
+ this.entryMap = new Map();
113
+ for (const entry of index.entries) {
114
+ this.entryMap.set(entry.path, entry);
115
+ }
116
+ }
117
+ // ── Path classification ──
118
+ /** Check if a platform-native path is inside the snapshot. */
119
+ isSnapshot(nativePath) {
120
+ return (0, snapshot_path_2.isSnapshotPath)(nativePath);
121
+ }
122
+ // ── Existence ──
123
+ /** Check if a path exists in the snapshot (file or directory). */
124
+ existsSync(nativePath) {
125
+ const p = (0, snapshot_path_2.toCanonical)(nativePath);
126
+ return this.entryMap.has(p) || p in this.index.directories;
127
+ }
128
+ // ── Stat ──
129
+ /** Get file/directory metadata. Throws ENOENT if not found. */
130
+ statSync(nativePath) {
131
+ const p = (0, snapshot_path_2.toCanonical)(nativePath);
132
+ const entry = this.entryMap.get(p);
133
+ if (entry)
134
+ return fileStat(entry.size);
135
+ if (p in this.index.directories)
136
+ return dirStat();
137
+ throw enoent('stat', nativePath);
138
+ }
139
+ /** lstat is identical to stat — the snapshot has no symlinks. */
140
+ lstatSync(nativePath) {
141
+ return this.statSync(nativePath);
142
+ }
143
+ // ── Read file ──
144
+ /**
145
+ * Read file content from the blob.
146
+ * Returns a Buffer. Throws ENOENT or EISDIR.
147
+ */
148
+ readFileSync(nativePath) {
149
+ const p = (0, snapshot_path_2.toCanonical)(nativePath);
150
+ if (p in this.index.directories) {
151
+ throw eisdir('read', nativePath);
152
+ }
153
+ const entry = this.entryMap.get(p);
154
+ if (!entry)
155
+ throw enoent('open', nativePath);
156
+ return this.blob.subarray(entry.offset, entry.offset + entry.size);
157
+ }
158
+ // ── Read directory ──
159
+ /**
160
+ * List directory contents. Returns file and directory names (not paths).
161
+ * Throws ENOENT or ENOTDIR.
162
+ */
163
+ readdirSync(nativePath) {
164
+ const p = (0, snapshot_path_2.toCanonical)(nativePath);
165
+ // Check if it's a file, not a directory
166
+ if (this.entryMap.has(p)) {
167
+ throw enotdir('scandir', nativePath);
168
+ }
169
+ const dir = this.index.directories[p];
170
+ if (!dir)
171
+ throw enoent('scandir', nativePath);
172
+ return [...dir.files, ...dir.directories].sort();
173
+ }
174
+ // ── Realpath ──
175
+ /**
176
+ * Resolve canonical path within the snapshot.
177
+ * The snapshot has no symlinks, so this is just normalization.
178
+ * Returns the platform-native normalized path.
179
+ */
180
+ realpathSync(nativePath) {
181
+ const p = (0, snapshot_path_2.toCanonical)(nativePath);
182
+ if (!this.entryMap.has(p) && !(p in this.index.directories)) {
183
+ throw enoent('realpath', nativePath);
184
+ }
185
+ return (0, snapshot_path_2.toNative)(p);
186
+ }
187
+ // ── Write rejection ──
188
+ /** All write operations throw EROFS. */
189
+ writeFileSync(nativePath) {
190
+ throw erofs('write', nativePath);
191
+ }
192
+ mkdirSync(nativePath) {
193
+ throw erofs('mkdir', nativePath);
194
+ }
195
+ unlinkSync(nativePath) {
196
+ throw erofs('unlink', nativePath);
197
+ }
198
+ // ── Module metadata (for ESM/CJS loader integration) ──
199
+ /**
200
+ * Get the module format of a snapshot file.
201
+ * Returns null if the file is not a script or not found.
202
+ */
203
+ getModuleFormat(nativePath) {
204
+ const p = (0, snapshot_path_2.toCanonical)(nativePath);
205
+ const entry = this.entryMap.get(p);
206
+ return entry?.format ?? null;
207
+ }
208
+ /**
209
+ * Get the file kind of a snapshot file.
210
+ * Returns null if not found.
211
+ */
212
+ getFileKind(nativePath) {
213
+ const p = (0, snapshot_path_2.toCanonical)(nativePath);
214
+ const entry = this.entryMap.get(p);
215
+ return entry?.kind ?? null;
216
+ }
217
+ /**
218
+ * Get the package boundary (package.json) that governs a file.
219
+ * Returns the SnapshotPackageBoundary or null.
220
+ */
221
+ getPackageBoundary(nativePath) {
222
+ const p = (0, snapshot_path_2.toCanonical)(nativePath);
223
+ const entry = this.entryMap.get(p);
224
+ if (!entry?.packageBoundary)
225
+ return null;
226
+ return this.index.packages[entry.packageBoundary] ?? null;
227
+ }
228
+ /**
229
+ * Look up a package boundary by its package.json snapshot path.
230
+ */
231
+ getPackage(packageJsonPath) {
232
+ const p = (0, snapshot_path_2.toCanonical)(packageJsonPath);
233
+ return this.index.packages[p] ?? null;
234
+ }
235
+ // ── Index access ──
236
+ /** Get the snapshot entry for a path. */
237
+ getEntry(nativePath) {
238
+ const p = (0, snapshot_path_2.toCanonical)(nativePath);
239
+ return this.entryMap.get(p) ?? null;
240
+ }
241
+ /** Get the entrypoint path in platform-native form. */
242
+ getEntrypoint() {
243
+ return (0, snapshot_path_2.toNative)(this.index.entrypoint);
244
+ }
245
+ /** Get the entrypoint module format. */
246
+ getEntrypointFormat() {
247
+ return this.index.entrypointFormat;
248
+ }
249
+ /** Get the application ID. */
250
+ getAppId() {
251
+ return this.index.appId;
252
+ }
253
+ }
254
+ exports.SnapshotFS = SnapshotFS;
255
+ //# sourceMappingURL=snapshot-fs.js.map