@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,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
|