@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,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Hakobu Snapshot Index
|
|
4
|
+
*
|
|
5
|
+
* The snapshot index is the structural contract between the packaging
|
|
6
|
+
* pipeline and the runtime. It describes every file in the snapshot,
|
|
7
|
+
* every package boundary, and enough metadata for the runtime to:
|
|
8
|
+
*
|
|
9
|
+
* - serve fs operations (readFile, stat, readdir, realpath)
|
|
10
|
+
* - determine module format per-file (ESM vs CJS)
|
|
11
|
+
* - resolve imports through package.json exports/imports maps
|
|
12
|
+
* - construct canonical file: URLs for import.meta.url
|
|
13
|
+
* - extract native addons to the real filesystem
|
|
14
|
+
*
|
|
15
|
+
* Invariants:
|
|
16
|
+
* 1. DETERMINISTIC: identical manifest → identical index → identical blob.
|
|
17
|
+
* Entries are sorted by snapshot path (lexicographic, POSIX).
|
|
18
|
+
* 2. POSIX-NORMALIZED: all paths use '/' separators and are absolute
|
|
19
|
+
* within the snapshot root (/snapshot/{appId}/...). The runtime
|
|
20
|
+
* projects these to platform-native paths at execution time.
|
|
21
|
+
* 3. NO HOST PATHS: the index never contains host filesystem paths.
|
|
22
|
+
* The manifest's absolutePath is consumed during blob assembly
|
|
23
|
+
* and does not appear in the index.
|
|
24
|
+
* 4. SELF-CONTAINED for resolution: the index carries enough package
|
|
25
|
+
* metadata to resolve imports without re-reading package.json
|
|
26
|
+
* from the blob. This is critical for ESM loader performance.
|
|
27
|
+
*
|
|
28
|
+
* Lifecycle:
|
|
29
|
+
* PackagingManifest → buildSnapshotIndex() → SnapshotIndex
|
|
30
|
+
* ↓
|
|
31
|
+
* (Task 5.2) blob assembly + fs hooks
|
|
32
|
+
* ↓
|
|
33
|
+
* (Task 6) ESM loader reads the index
|
|
34
|
+
*/
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.buildSnapshotIndex = void 0;
|
|
37
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
38
|
+
// Builder: PackagingManifest → SnapshotIndex
|
|
39
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
40
|
+
/**
|
|
41
|
+
* Build a SnapshotIndex from a PackagingManifest.
|
|
42
|
+
*
|
|
43
|
+
* This function:
|
|
44
|
+
* 1. Sorts entries deterministically by snapshot path
|
|
45
|
+
* 2. Computes byte offsets (sequential, no gaps)
|
|
46
|
+
* 3. Converts package metadata to runtime-optimized boundaries
|
|
47
|
+
* 4. Builds the directory tree for readdir/stat
|
|
48
|
+
*
|
|
49
|
+
* Content hashes and sizes must be populated in the manifest files.
|
|
50
|
+
* If they are not (e.g., during dry-run analysis), the index is still
|
|
51
|
+
* structurally valid but offset/size/hash fields will be zero/empty.
|
|
52
|
+
*/
|
|
53
|
+
function buildSnapshotIndex(manifest, fileSizes) {
|
|
54
|
+
// ── Sort entries deterministically ──
|
|
55
|
+
const sortedPaths = Object.keys(manifest.files).sort();
|
|
56
|
+
// ── Build entries with sequential offsets ──
|
|
57
|
+
let currentOffset = 0;
|
|
58
|
+
const entries = [];
|
|
59
|
+
for (const snapshotPath of sortedPaths) {
|
|
60
|
+
const file = manifest.files[snapshotPath];
|
|
61
|
+
const sizeInfo = fileSizes.get(snapshotPath) ?? { size: 0, hash: '' };
|
|
62
|
+
entries.push({
|
|
63
|
+
path: snapshotPath,
|
|
64
|
+
kind: file.kind,
|
|
65
|
+
format: file.format,
|
|
66
|
+
packageBoundary: file.packageBoundary,
|
|
67
|
+
offset: currentOffset,
|
|
68
|
+
size: sizeInfo.size,
|
|
69
|
+
contentHash: sizeInfo.hash,
|
|
70
|
+
});
|
|
71
|
+
currentOffset += sizeInfo.size;
|
|
72
|
+
}
|
|
73
|
+
// ── Build package boundaries ──
|
|
74
|
+
const packages = {};
|
|
75
|
+
for (const [snapshotPath, meta] of Object.entries(manifest.packages)) {
|
|
76
|
+
const dir = snapshotPath.replace(/\/package\.json$/, '');
|
|
77
|
+
packages[snapshotPath] = {
|
|
78
|
+
path: snapshotPath,
|
|
79
|
+
name: meta.name,
|
|
80
|
+
version: meta.version,
|
|
81
|
+
type: meta.type,
|
|
82
|
+
main: meta.main,
|
|
83
|
+
exports: meta.exports,
|
|
84
|
+
imports: meta.imports,
|
|
85
|
+
directory: dir,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// ── Build directory tree ──
|
|
89
|
+
const directories = buildDirectoryTree(entries);
|
|
90
|
+
return {
|
|
91
|
+
appId: manifest.appId,
|
|
92
|
+
entrypoint: manifest.entry.snapshotPath,
|
|
93
|
+
entrypointFormat: manifest.entry.format,
|
|
94
|
+
entries,
|
|
95
|
+
packages,
|
|
96
|
+
directories,
|
|
97
|
+
blobSize: currentOffset,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
exports.buildSnapshotIndex = buildSnapshotIndex;
|
|
101
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
102
|
+
// Directory tree builder
|
|
103
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
104
|
+
function buildDirectoryTree(entries) {
|
|
105
|
+
const dirs = new Map();
|
|
106
|
+
function ensureDir(dirPath) {
|
|
107
|
+
if (!dirs.has(dirPath)) {
|
|
108
|
+
dirs.set(dirPath, { files: new Set(), directories: new Set() });
|
|
109
|
+
}
|
|
110
|
+
// Register this directory in its parent
|
|
111
|
+
const parent = dirPath.substring(0, dirPath.lastIndexOf('/')) || '/';
|
|
112
|
+
if (parent !== dirPath) {
|
|
113
|
+
ensureDir(parent);
|
|
114
|
+
const name = dirPath.substring(dirPath.lastIndexOf('/') + 1);
|
|
115
|
+
dirs.get(parent).directories.add(name);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
for (const entry of entries) {
|
|
119
|
+
const dirPath = entry.path.substring(0, entry.path.lastIndexOf('/'));
|
|
120
|
+
const fileName = entry.path.substring(entry.path.lastIndexOf('/') + 1);
|
|
121
|
+
ensureDir(dirPath);
|
|
122
|
+
dirs.get(dirPath).files.add(fileName);
|
|
123
|
+
}
|
|
124
|
+
// Convert to sorted arrays for determinism
|
|
125
|
+
const result = {};
|
|
126
|
+
for (const [dirPath, contents] of dirs) {
|
|
127
|
+
result[dirPath] = {
|
|
128
|
+
path: dirPath,
|
|
129
|
+
files: [...contents.files].sort(),
|
|
130
|
+
directories: [...contents.directories].sort(),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=snapshot-index.js.map
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Hakobu Snapshot Path Canonicalization
|
|
4
|
+
*
|
|
5
|
+
* Canonical rules:
|
|
6
|
+
*
|
|
7
|
+
* 1. INTERNAL FORM is always POSIX: /snapshot/{appId}/path/to/file.js
|
|
8
|
+
* - Forward slashes only
|
|
9
|
+
* - No drive letter
|
|
10
|
+
* - No trailing slash (except root "/")
|
|
11
|
+
* - No duplicate slashes
|
|
12
|
+
* - No . or .. segments (resolved)
|
|
13
|
+
* - Case-sensitive for all path segments
|
|
14
|
+
*
|
|
15
|
+
* 2. PLATFORM-NATIVE FORM is what Node's fs module sees:
|
|
16
|
+
* - POSIX: /snapshot/{appId}/path/to/file.js (same as internal)
|
|
17
|
+
* - Windows: C:\snapshot\{appId}\path\to\file.js
|
|
18
|
+
*
|
|
19
|
+
* 3. DETECTION accepts any platform variation:
|
|
20
|
+
* - /snapshot/...
|
|
21
|
+
* - C:\snapshot\... (any drive letter case)
|
|
22
|
+
* - C:/snapshot/... (mixed separators)
|
|
23
|
+
* - Paths with . and .. segments that resolve into /snapshot/
|
|
24
|
+
*
|
|
25
|
+
* 4. CASE SENSITIVITY:
|
|
26
|
+
* - The "snapshot" prefix is case-insensitive on Windows only
|
|
27
|
+
* - All path segments below /snapshot/ are case-sensitive on all
|
|
28
|
+
* platforms (Node module resolution is case-sensitive)
|
|
29
|
+
*
|
|
30
|
+
* These utilities are used by:
|
|
31
|
+
* - snapshot-fs.ts (SnapshotFS lookups)
|
|
32
|
+
* - snapshot-fs-patch.ts (routing decisions)
|
|
33
|
+
* - snapshot-index.ts (index key computation)
|
|
34
|
+
* - (future) ESM loader (import.meta.url construction)
|
|
35
|
+
*/
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.snapshotJoin = exports.snapshotRoot = exports.fromFileUrl = exports.toFileUrl = exports.toNative = exports.toCanonical = exports.isSnapshotPath = void 0;
|
|
38
|
+
const IS_WIN = process.platform === 'win32';
|
|
39
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
40
|
+
// Detection
|
|
41
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
42
|
+
/**
|
|
43
|
+
* Check if a path is inside the snapshot filesystem.
|
|
44
|
+
* Accepts any platform-native form, including mixed separators.
|
|
45
|
+
*/
|
|
46
|
+
function isSnapshotPath(p) {
|
|
47
|
+
// Normalize for detection: lowercase, forward slashes
|
|
48
|
+
const norm = p.replace(/\\/g, '/');
|
|
49
|
+
const lower = norm.toLowerCase();
|
|
50
|
+
// Strip drive letter for matching
|
|
51
|
+
const noPrefix = /^[a-z]:/.test(lower) ? lower.slice(2) : lower;
|
|
52
|
+
return noPrefix === '/snapshot' ||
|
|
53
|
+
noPrefix.startsWith('/snapshot/');
|
|
54
|
+
}
|
|
55
|
+
exports.isSnapshotPath = isSnapshotPath;
|
|
56
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
57
|
+
// Canonicalization
|
|
58
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
59
|
+
/**
|
|
60
|
+
* Convert any snapshot path form to canonical POSIX internal form.
|
|
61
|
+
*
|
|
62
|
+
* Input: any valid snapshot path (native or mixed)
|
|
63
|
+
* Output: /snapshot/{appId}/path/to/file (no trailing slash, no ./..)
|
|
64
|
+
*
|
|
65
|
+
* Throws if the input is not a snapshot path.
|
|
66
|
+
*/
|
|
67
|
+
function toCanonical(nativePath) {
|
|
68
|
+
// Replace all backslashes with forward slashes
|
|
69
|
+
let p = nativePath.replace(/\\/g, '/');
|
|
70
|
+
// Strip drive letter (e.g., C: or c:)
|
|
71
|
+
if (/^[A-Za-z]:/.test(p)) {
|
|
72
|
+
p = p.slice(2);
|
|
73
|
+
}
|
|
74
|
+
// Resolve . and .. segments, collapse duplicate slashes
|
|
75
|
+
const parts = p.split('/');
|
|
76
|
+
const resolved = [];
|
|
77
|
+
for (const part of parts) {
|
|
78
|
+
if (part === '' || part === '.')
|
|
79
|
+
continue;
|
|
80
|
+
if (part === '..') {
|
|
81
|
+
// Don't resolve above the root
|
|
82
|
+
if (resolved.length > 0 && resolved[resolved.length - 1] !== '') {
|
|
83
|
+
resolved.pop();
|
|
84
|
+
}
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
resolved.push(part);
|
|
88
|
+
}
|
|
89
|
+
const result = '/' + resolved.join('/');
|
|
90
|
+
// Remove trailing slash (except bare "/")
|
|
91
|
+
if (result.length > 1 && result.endsWith('/')) {
|
|
92
|
+
return result.slice(0, -1);
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
exports.toCanonical = toCanonical;
|
|
97
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
98
|
+
// Platform conversion
|
|
99
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
100
|
+
/**
|
|
101
|
+
* Convert a canonical POSIX path to platform-native form.
|
|
102
|
+
* - POSIX: returns the path unchanged
|
|
103
|
+
* - Windows: prepends C: and replaces / with \
|
|
104
|
+
*/
|
|
105
|
+
function toNative(posixPath) {
|
|
106
|
+
if (IS_WIN) {
|
|
107
|
+
return 'C:' + posixPath.replace(/\//g, '\\');
|
|
108
|
+
}
|
|
109
|
+
return posixPath;
|
|
110
|
+
}
|
|
111
|
+
exports.toNative = toNative;
|
|
112
|
+
/**
|
|
113
|
+
* Construct a file: URL from a canonical snapshot path.
|
|
114
|
+
* Used for import.meta.url in ESM modules.
|
|
115
|
+
*
|
|
116
|
+
* POSIX: file:///snapshot/app/src/index.js
|
|
117
|
+
* Windows: file:///C:/snapshot/app/src/index.js
|
|
118
|
+
*/
|
|
119
|
+
function toFileUrl(posixPath) {
|
|
120
|
+
if (IS_WIN) {
|
|
121
|
+
return 'file:///C:' + posixPath;
|
|
122
|
+
}
|
|
123
|
+
return 'file://' + posixPath;
|
|
124
|
+
}
|
|
125
|
+
exports.toFileUrl = toFileUrl;
|
|
126
|
+
/**
|
|
127
|
+
* Extract the canonical POSIX path from a file: URL.
|
|
128
|
+
* Returns null if the URL doesn't point into the snapshot.
|
|
129
|
+
*/
|
|
130
|
+
function fromFileUrl(url) {
|
|
131
|
+
if (!url.startsWith('file://'))
|
|
132
|
+
return null;
|
|
133
|
+
let p;
|
|
134
|
+
if (url.startsWith('file:///') && /^file:\/\/\/[A-Za-z]:/.test(url)) {
|
|
135
|
+
// file:///C:/snapshot/... → /snapshot/...
|
|
136
|
+
p = url.slice(8); // after file:///C:
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
// file:///snapshot/... → /snapshot/...
|
|
140
|
+
p = url.slice(7); // after file://
|
|
141
|
+
}
|
|
142
|
+
p = decodeURIComponent(p);
|
|
143
|
+
if (!p.startsWith('/snapshot'))
|
|
144
|
+
return null;
|
|
145
|
+
return toCanonical(p);
|
|
146
|
+
}
|
|
147
|
+
exports.fromFileUrl = fromFileUrl;
|
|
148
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
149
|
+
// Snapshot root and app ID extraction
|
|
150
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
151
|
+
/**
|
|
152
|
+
* Get the snapshot root for a given appId in platform-native form.
|
|
153
|
+
* POSIX: /snapshot/{appId}
|
|
154
|
+
* Windows: C:\snapshot\{appId}
|
|
155
|
+
*/
|
|
156
|
+
function snapshotRoot(appId) {
|
|
157
|
+
return toNative(`/snapshot/${appId}`);
|
|
158
|
+
}
|
|
159
|
+
exports.snapshotRoot = snapshotRoot;
|
|
160
|
+
/**
|
|
161
|
+
* Join a snapshot root with a relative path, returning canonical form.
|
|
162
|
+
*/
|
|
163
|
+
function snapshotJoin(appId, ...segments) {
|
|
164
|
+
const posix = '/snapshot/' + appId + '/' + segments.join('/');
|
|
165
|
+
return toCanonical(posix);
|
|
166
|
+
}
|
|
167
|
+
exports.snapshotJoin = snapshotJoin;
|
|
168
|
+
//# sourceMappingURL=snapshot-path.js.map
|