rollup-plugin-websqz 1.0.6 → 1.1.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/README.md CHANGED
@@ -1,4 +1,6 @@
1
1
  # rollup-plugin-websqz
2
+ ![NPM Version](https://img.shields.io/npm/v/rollup-plugin-websqz)
3
+
2
4
  Rollup / Vite plugin for using [websqz](https://github.com/r00tkids/websqz) to compress and bundle code and assets into one HTML file. This is intented for intros in the [demoscene](https://en.wikipedia.org/wiki/Demoscene) or size restricted JS challenges.
3
5
 
4
6
  ## Install
package/dist/index.js CHANGED
@@ -1,12 +1,10 @@
1
- Object.defineProperty(exports, "__esModule", { value: true });
2
- exports.default = default_1;
3
- const tslib_1 = require("tslib");
4
- const node_querystring_1 = tslib_1.__importDefault(require("node:querystring"));
5
- const promises_1 = tslib_1.__importDefault(require("node:fs/promises"));
6
- const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
7
- const node_path_1 = tslib_1.__importDefault(require("node:path"));
8
- const node_child_process_1 = tslib_1.__importDefault(require("node:child_process"));
9
- const pluginutils_1 = require("@rollup/pluginutils");
1
+ import querystring from 'node:querystring';
2
+ import fs from 'node:fs/promises';
3
+ import fsSync from 'node:fs';
4
+ import path from 'node:path';
5
+ import child_process from 'node:child_process';
6
+ import { createFilter } from '@rollup/pluginutils';
7
+
10
8
  class WebSqzExe {
11
9
  websqzPath;
12
10
  constructor(websqzPath) {
@@ -22,7 +20,7 @@ class WebSqzExe {
22
20
  args.push("--pre-compressed-files", preCompressedFile);
23
21
  }
24
22
  args.push("--output-directory", cliOptions.output);
25
- const spawn = await node_child_process_1.default.spawn(this.websqzPath, args, {
23
+ const spawn = await child_process.spawn(this.websqzPath, args, {
26
24
  stdio: "inherit",
27
25
  });
28
26
  return new Promise((resolve, reject) => {
@@ -44,14 +42,14 @@ function websqzExecutablePath(executablePath) {
44
42
  if (!executablePath) {
45
43
  const path = __dirname + "/bin/websqz";
46
44
  const extension = process.platform == "win32" ? ".exe" : "";
47
- if (node_fs_1.default.existsSync(path + extension)) {
45
+ if (fsSync.existsSync(path + extension)) {
48
46
  return path + extension;
49
47
  }
50
48
  return "websqz" + extension;
51
49
  }
52
50
  return executablePath;
53
51
  }
54
- function default_1(options = {}) {
52
+ function index (options = {}) {
55
53
  const isBuild = process.env.NODE_ENV === "production";
56
54
  const websqzExePath = websqzExecutablePath(options.websqzPath);
57
55
  const websqzExe = new WebSqzExe(websqzExePath);
@@ -60,7 +58,7 @@ function default_1(options = {}) {
60
58
  : undefined;
61
59
  const exclude = transform.exclude ? (Array.isArray(transform.exclude) ? transform.exclude : [transform.exclude])
62
60
  : undefined;
63
- const filter = (0, pluginutils_1.createFilter)(include, exclude);
61
+ const filter = createFilter(include, exclude);
64
62
  return {
65
63
  transform: transform.transform,
66
64
  filter,
@@ -88,7 +86,7 @@ function default_1(options = {}) {
88
86
  fileName,
89
87
  content: hookRes.content,
90
88
  isCompressed: hookRes.isCompressed,
91
- fileExt: hookRes.fileExt ?? node_path_1.default.extname(id),
89
+ fileExt: hookRes.fileExt ?? path.extname(id),
92
90
  isText: hookRes.isText,
93
91
  });
94
92
  return {
@@ -117,14 +115,14 @@ function default_1(options = {}) {
117
115
  const qIdx = id.indexOf("?");
118
116
  const beforeParams = id.slice(0, qIdx === -1 ? id.length : qIdx);
119
117
  const afterParams = id.slice(id.indexOf("?") + 1);
120
- const parsed = node_querystring_1.default.parse(afterParams);
118
+ const parsed = querystring.parse(afterParams);
121
119
  const cleanedUpId = beforeParams;
122
120
  let cachedFile = null;
123
121
  const loadFromDisk = async () => {
124
122
  if (cachedFile != null) {
125
123
  return cachedFile;
126
124
  }
127
- cachedFile = await promises_1.default.readFile(cleanedUpId);
125
+ cachedFile = await fs.readFile(cleanedUpId);
128
126
  return cachedFile;
129
127
  };
130
128
  if (fileTransforms) {
@@ -150,7 +148,7 @@ function default_1(options = {}) {
150
148
  content,
151
149
  isCompressed,
152
150
  isText: isWebSqzTxt,
153
- fileExt: node_path_1.default.extname(cleanedUpId),
151
+ fileExt: path.extname(cleanedUpId),
154
152
  };
155
153
  return await loadAndTransform(id, hookRes);
156
154
  }
@@ -167,37 +165,39 @@ function default_1(options = {}) {
167
165
  }
168
166
  const [jsFileName, jsChunk] = jsFiles[0];
169
167
  if (isBuild) {
170
- const outDir = node_path_1.default.resolve(outputOptions.dir || "", "websqz-tmp");
171
- if (await promises_1.default.stat(outDir).catch(() => false)) {
172
- await promises_1.default.rmdir(outDir, { recursive: true });
168
+ const outDir = path.resolve(outputOptions.dir || "", "websqz-tmp");
169
+ if (await fs.stat(outDir).catch(() => false)) {
170
+ await fs.rm(outDir, { recursive: true, force: true });
173
171
  }
174
172
  const filesToCompress = [];
175
173
  const preCompressedFiles = [];
176
174
  for (const [id, file] of files) {
177
175
  this.debug(`Copying '${id}' for websqz...`);
178
- const outPath = node_path_1.default.resolve(outputOptions.dir || "", "websqz-tmp", file.fileName);
179
- await promises_1.default.mkdir(node_path_1.default.dirname(outPath), { recursive: true });
180
- await promises_1.default.writeFile(outPath, file.content);
176
+ const outPath = path.resolve(outputOptions.dir || "", "websqz-tmp", file.fileName);
177
+ await fs.mkdir(path.dirname(outPath), { recursive: true });
178
+ await fs.writeFile(outPath, file.content);
181
179
  if (file.isCompressed) {
182
- preCompressedFiles.push(node_path_1.default.relative(".", outPath));
180
+ preCompressedFiles.push(path.relative(".", outPath));
183
181
  }
184
182
  else {
185
- filesToCompress.push({ isText: file.isText, fileExt: file.fileExt, path: node_path_1.default.relative(".", outPath) });
183
+ filesToCompress.push({ isText: file.isText, fileExt: file.fileExt, path: path.relative(".", outPath) });
186
184
  }
187
185
  }
188
186
  // Sort by file extension for better compression ratios in websqz
189
187
  filesToCompress.sort((a, b) => Math.sign(a.fileExt.localeCompare(b.fileExt)) + 2 * (a.isText === b.isText ? 0 : a.isText ? -1 : 1));
190
188
  this.info(`Using websqz executable at '${websqzExe.websqzPath}'`);
191
189
  await websqzExe.run({
192
- jsMain: node_path_1.default.resolve(outputOptions.dir || "", jsFileName),
190
+ jsMain: path.resolve(outputOptions.dir || "", jsFileName),
193
191
  files: filesToCompress.map(f => f.path),
194
192
  preCompressedFiles: preCompressedFiles,
195
- output: node_path_1.default.resolve(outputOptions.dir || "", "websqz-output"),
193
+ output: path.resolve(outputOptions.dir || "", "websqz-output"),
196
194
  });
197
- const relOutPath = node_path_1.default.relative(".", node_path_1.default.resolve(outputOptions.dir || "", "websqz-output"));
195
+ const relOutPath = path.relative(".", path.resolve(outputOptions.dir || "", "websqz-output"));
198
196
  this.info(`Websqz completed, output at '${relOutPath}'.\nRun 'python -m http.server -d ${relOutPath}' to serve the output.`);
199
197
  }
200
198
  },
201
199
  };
202
200
  }
201
+
202
+ export { index as default };
203
203
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { PluginContext, rollup, type OutputAsset, type OutputChunk, type OutputOptions, type Plugin } from \"rollup\";\nimport querystring from \"node:querystring\";\nimport fs from \"node:fs/promises\";\nimport fsSync from \"node:fs\";\nimport path from \"node:path\";\nimport child_process from \"node:child_process\";\nimport { createFilter, FilterPattern } from \"@rollup/pluginutils\";\n\ntype WebSqzFile = {\n fileName: string;\n content: Buffer;\n isCompressed: boolean;\n fileExt: string;\n isText: boolean;\n};\n\nexport type WebsqzFileTransformRes = {\n /**\n * The result of processing\n */\n content: Buffer;\n\n /**\n * Is already compressed and should not be compressed again by websqz\n */\n isCompressed: boolean;\n\n /**\n * Is it text? The plugin orders files by type for better compression ratios\n */\n isText: boolean;\n\n /**\n * File extension including the dot, e.g. .txt.\n * This is used to order files for better compression ratios.\n * Same type of content should share same file extension.\n * \n * By default it is extracted from the original file path.\n */\n fileExt?: string;\n};\n\ntype WebSqzOptions = {\n websqzPath?: string;\n\n /**\n * File transform hooks to process files before they are imported in code or compressed by websqz\n */\n fileTransforms?: [\n {\n include?: FilterPattern,\n exclude?: FilterPattern,\n transform: (ctx: PluginContext, id: string, content: Buffer) => Promise<WebsqzFileTransformRes>;\n }\n ]\n};\n\ntype WebSqzCliOptions = {\n jsMain: string;\n files: string[];\n preCompressedFiles: string[];\n output: string;\n}\n\nclass WebSqzExe {\n websqzPath: string;\n constructor(websqzPath: string) {\n this.websqzPath = websqzPath;\n }\n\n async run(cliOptions: WebSqzCliOptions): Promise<void> {\n const args: string[] = [];\n\n args.push(\"--js-main\", cliOptions.jsMain);\n\n for (const file of cliOptions.files) {\n args.push(\"--files\", file);\n }\n for (const preCompressedFile of cliOptions.preCompressedFiles) {\n args.push(\"--pre-compressed-files\", preCompressedFile);\n }\n\n args.push(\"--output-directory\", cliOptions.output);\n\n const spawn = await child_process.spawn(this.websqzPath, args, {\n stdio: \"inherit\",\n });\n\n return new Promise<void>((resolve, reject) => {\n spawn.once(\"error\", (err) => {\n reject(err);\n });\n\n spawn.once(\"close\", (code) => {\n if (code !== 0) {\n reject(new Error(`websqz process exited with code ${code}`));\n } else {\n resolve();\n }\n });\n });\n }\n}\n\nfunction websqzExecutablePath(executablePath: string | undefined): string {\n if (!executablePath) {\n const path = __dirname + \"/bin/websqz\";\n const extension = process.platform == \"win32\" ? \".exe\" : \"\";\n\n if (fsSync.existsSync(path + extension)) {\n return path + extension;\n }\n\n return \"websqz\" + extension;\n }\n\n return executablePath;\n}\n\nexport default function (options: WebSqzOptions = {}): Plugin {\n const isBuild = process.env.NODE_ENV === \"production\";\n const websqzExePath = websqzExecutablePath(options.websqzPath);\n const websqzExe = new WebSqzExe(websqzExePath);\n\n const fileTransforms = options.fileTransforms?.map(transform => {\n const include = transform.include ? (Array.isArray(transform.include) ? transform.include : [transform.include]) \n : undefined;\n const exclude = transform.exclude ? (Array.isArray(transform.exclude) ? transform.exclude : [transform.exclude]) \n : undefined;\n\n const filter = createFilter(include, exclude);\n return {\n transform: transform.transform,\n filter,\n }\n });\n\n const files = new Map<string, WebSqzFile>();\n let fileNameIdx = 0;\n\n const findNextAvailableFileName = () => {\n const startChar = 97; // a\n const endChar = 122; // z\n const alphabetSize= endChar - startChar;\n\n let numChars = fileNameIdx === 0 ? 1 : Math.floor(Math.log(fileNameIdx) / Math.log(alphabetSize)) + 1;\n let candidateName = \"\";\n \n for (let i = 0; i < numChars; i++) {\n const charCode = startChar + ((Math.floor(fileNameIdx / Math.pow(alphabetSize, i))) % alphabetSize);\n candidateName = String.fromCharCode(charCode) + candidateName;\n }\n\n fileNameIdx++;\n\n return candidateName;\n }\n\n const loadAndTransform = async function (id: string, hookRes: WebsqzFileTransformRes) {\n if (isBuild) {\n const fileName = findNextAvailableFileName();\n files.set(id, {\n fileName,\n content: hookRes.content,\n isCompressed: hookRes.isCompressed,\n fileExt: hookRes.fileExt ?? path.extname(id),\n isText: hookRes.isText,\n });\n\n return {\n code: hookRes.isText \n ? `export default new TextDecoder().decode(wsqz.files[\"${fileName}\"]);` \n : `export default wsqz.files[\"${fileName}\"];`,\n moduleSideEffects: false,\n moduleType: 'js',\n };\n } else {\n return {\n code: hookRes.isText \n ? `export default ${JSON.stringify(hookRes.content.toString(\"utf-8\"))};` \n : `export default Uint8Array.fromBase64(\"${hookRes.content.toString(\"base64\")}\");`,\n moduleSideEffects: false,\n moduleType: 'js',\n };\n }\n };\n\n return {\n name: \"rollup-plugin-websqz\",\n\n load: {\n order: \"pre\",\n async handler(id: string) {\n const qIdx = id.indexOf(\"?\");\n const beforeParams = id.slice(0, qIdx === -1 ? id.length : qIdx);\n const afterParams = id.slice(id.indexOf(\"?\") + 1);\n const parsed = querystring.parse(afterParams);\n const cleanedUpId = beforeParams;\n\n let cachedFile: Buffer | null = null;\n const loadFromDisk = async () => {\n if (cachedFile != null) {\n return cachedFile;\n }\n cachedFile = await fs.readFile(cleanedUpId);\n return cachedFile;\n };\n\n if (fileTransforms) {\n for (const transform of fileTransforms) {\n if (transform.filter(id)) {\n let hookRes = await transform.transform(this, id, await loadFromDisk());\n if (hookRes == null) {\n continue;\n }\n return await loadAndTransform(id, hookRes);\n }\n }\n }\n\n const isWebSqzTxt = parsed[\"websqz-txt\"] != null;\n const isWebSqzBin = parsed[\"websqz-bin\"] != null;\n\n if (isWebSqzTxt && isWebSqzBin) {\n throw new Error(\n `Cannot use both websqz-txt and websqz-bin on the same import: ${id}`,\n );\n }\n\n const isCompressed = parsed[\"compressed\"] != null;\n\n if (isWebSqzTxt || isWebSqzBin) {\n const content = await loadFromDisk();\n \n let hookRes: WebsqzFileTransformRes = {\n content,\n isCompressed,\n isText: isWebSqzTxt,\n fileExt: path.extname(cleanedUpId),\n };\n return await loadAndTransform(id, hookRes);\n }\n }\n },\n\n writeBundle: async function (outputOptions: OutputOptions, bundle: { [fileName: string]: OutputAsset | OutputChunk }) {\n const jsFiles = Object.entries(bundle)\n .filter(([fileName, asset]) => fileName.endsWith('.js') && asset.type === 'chunk');\n\n if (jsFiles.length === 0) {\n throw new Error('No JavaScript file found in the bundle.');\n }\n if (jsFiles.length > 1) {\n throw new Error('Multiple JavaScript files found in the bundle. Make sure to bundle into a single file.\\nTry setting \"build.rollupOptions.output.inlineDynamicImports\" to true in Vite config.');\n }\n\n const [jsFileName, jsChunk] = jsFiles[0];\n\n if (isBuild) {\n const outDir = path.resolve(\n outputOptions.dir || \"\",\n \"websqz-tmp\");\n if (await fs.stat(outDir).catch(() => false)) {\n await fs.rmdir(outDir, { recursive: true });\n }\n\n const filesToCompress = [];\n const preCompressedFiles = [];\n\n for (const [id, file] of files) {\n this.debug(`Copying '${id}' for websqz...`);\n const outPath = path.resolve(\n outputOptions.dir || \"\",\n \"websqz-tmp\",\n file.fileName,\n );\n\n await fs.mkdir(path.dirname(outPath), { recursive: true });\n await fs.writeFile(outPath, file.content);\n\n if (file.isCompressed) {\n preCompressedFiles.push(path.relative(\".\", outPath));\n } else {\n filesToCompress.push({ isText: file.isText, fileExt: file.fileExt, path: path.relative(\".\", outPath) });\n }\n }\n\n // Sort by file extension for better compression ratios in websqz\n filesToCompress.sort((a, b) => Math.sign(a.fileExt.localeCompare(b.fileExt)) + 2 * (a.isText === b.isText ? 0 : a.isText ? -1 : 1));\n\n this.info(`Using websqz executable at '${websqzExe.websqzPath}'`);\n await websqzExe.run({\n jsMain: path.resolve(\n outputOptions.dir || \"\",\n jsFileName,\n ),\n files: filesToCompress.map(f => f.path),\n preCompressedFiles: preCompressedFiles,\n output: path.resolve(\n outputOptions.dir || \"\",\n \"websqz-output\",\n ),\n });\n\n const relOutPath = path.relative(\".\", path.resolve(outputOptions.dir || \"\", \"websqz-output\"));\n this.info(`Websqz completed, output at '${relOutPath}'.\\nRun 'python -m http.server -d ${relOutPath}' to serve the output.`);\n }\n },\n };\n}\n"],"names":[],"mappings":";AAuHA,OAAA,CAAA,OAAA,GAAA,SAAA;;AAtHA,MAAA,kBAAA,GAAA,OAAA,CAAA,eAAA,CAAA,OAAA,CAAA,kBAAA,CAAA,CAAA;AACA,MAAA,UAAA,GAAA,OAAA,CAAA,eAAA,CAAA,OAAA,CAAA,kBAAA,CAAA,CAAA;AACA,MAAA,SAAA,GAAA,OAAA,CAAA,eAAA,CAAA,OAAA,CAAA,SAAA,CAAA,CAAA;AACA,MAAA,WAAA,GAAA,OAAA,CAAA,eAAA,CAAA,OAAA,CAAA,WAAA,CAAA,CAAA;AACA,MAAA,oBAAA,GAAA,OAAA,CAAA,eAAA,CAAA,OAAA,CAAA,oBAAA,CAAA,CAAA;AACA,MAAA,aAAA,GAAA,OAAA,CAAA,qBAAA,CAAA;AA0DA,MAAM,SAAS,CAAA;AACb,IAAA,UAAU;AACV,IAAA,WAAA,CAAY,UAAkB,EAAA;AAC5B,QAAA,IAAI,CAAC,UAAU,GAAG,UAAU;IAC9B;IAEA,MAAM,GAAG,CAAC,UAA4B,EAAA;QACpC,MAAM,IAAI,GAAa,EAAE;QAEzB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,MAAM,CAAC;AAEzC,QAAA,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,KAAK,EAAE;AACnC,YAAA,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC;QAC5B;AACA,QAAA,KAAK,MAAM,iBAAiB,IAAI,UAAU,CAAC,kBAAkB,EAAE;AAC7D,YAAA,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE,iBAAiB,CAAC;QACxD;QAEA,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,UAAU,CAAC,MAAM,CAAC;AAElD,QAAA,MAAM,KAAK,GAAG,MAAM,oBAAA,CAAA,OAAa,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE;AAC7D,YAAA,KAAK,EAAE,SAAS;AACjB,SAAA,CAAC;QAEF,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,KAAI;YAC3C,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,KAAI;gBAC1B,MAAM,CAAC,GAAG,CAAC;AACb,YAAA,CAAC,CAAC;YAEF,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,KAAI;AAC3B,gBAAA,IAAI,IAAI,KAAK,CAAC,EAAE;oBACd,MAAM,CAAC,IAAI,KAAK,CAAC,mCAAmC,IAAI,CAAA,CAAE,CAAC,CAAC;gBAC9D;qBAAO;AACL,oBAAA,OAAO,EAAE;gBACX;AACF,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;AACD;AAED,SAAS,oBAAoB,CAAC,cAAkC,EAAA;IAC9D,IAAI,CAAC,cAAc,EAAE;AACnB,QAAA,MAAM,IAAI,GAAG,SAAS,GAAG,aAAa;AACtC,QAAA,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,GAAG,MAAM,GAAG,EAAE;QAE3D,IAAI,SAAA,CAAA,OAAM,CAAC,UAAU,CAAC,IAAI,GAAG,SAAS,CAAC,EAAE;YACvC,OAAO,IAAI,GAAG,SAAS;QACzB;QAEA,OAAO,QAAQ,GAAG,SAAS;IAC7B;AAEA,IAAA,OAAO,cAAc;AACvB;AAEA,SAAA,SAAA,CAAyB,UAAyB,EAAE,EAAA;IAClD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;IACrD,MAAM,aAAa,GAAG,oBAAoB,CAAC,OAAO,CAAC,UAAU,CAAC;AAC9D,IAAA,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,aAAa,CAAC;IAE9C,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,SAAS,IAAG;AAC7D,QAAA,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,OAAO,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC;cAC3G,SAAS;AACb,QAAA,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,OAAO,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC;cAC3G,SAAS;QAEb,MAAM,MAAM,GAAG,IAAA,aAAA,CAAA,YAAY,EAAC,OAAO,EAAE,OAAO,CAAC;QAC7C,OAAO;YACL,SAAS,EAAE,SAAS,CAAC,SAAS;YAC9B,MAAM;SACP;AACH,IAAA,CAAC,CAAC;AAEF,IAAA,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB;IAC3C,IAAI,WAAW,GAAG,CAAC;IAEnB,MAAM,yBAAyB,GAAG,MAAK;AACrC,QAAA,MAAM,SAAS,GAAG,EAAE,CAAC;AACrB,QAAA,MAAM,OAAO,GAAG,GAAG,CAAC;AACpB,QAAA,MAAM,YAAY,GAAE,OAAO,GAAG,SAAS;AAEvC,QAAA,IAAI,QAAQ,GAAG,WAAW,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC;QACrG,IAAI,aAAa,GAAG,EAAE;AAEtB,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE;YACjC,MAAM,QAAQ,GAAG,SAAS,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC;YACnG,aAAa,GAAG,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,aAAa;QAC/D;AAEA,QAAA,WAAW,EAAE;AAEb,QAAA,OAAO,aAAa;AACtB,IAAA,CAAC;AAED,IAAA,MAAM,gBAAgB,GAAG,gBAAgB,EAAU,EAAE,OAA+B,EAAA;QAClF,IAAI,OAAO,EAAE;AACX,YAAA,MAAM,QAAQ,GAAG,yBAAyB,EAAE;AAC5C,YAAA,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE;gBACZ,QAAQ;gBACR,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,YAAY,EAAE,OAAO,CAAC,YAAY;gBAClC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,mBAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC5C,MAAM,EAAE,OAAO,CAAC,MAAM;AACvB,aAAA,CAAC;YAEF,OAAO;gBACL,IAAI,EAAE,OAAO,CAAC;sBACV,CAAA,oDAAA,EAAuD,QAAQ,CAAA,IAAA;sBAC/D,CAAA,2BAAA,EAA8B,QAAQ,CAAA,GAAA,CAAK;AAC/C,gBAAA,iBAAiB,EAAE,KAAK;AACxB,gBAAA,UAAU,EAAE,IAAI;aACjB;QACH;aAAO;YACL,OAAO;gBACL,IAAI,EAAE,OAAO,CAAC;AACZ,sBAAE,CAAA,eAAA,EAAkB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA,CAAA;sBACnE,CAAA,sCAAA,EAAyC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA,GAAA,CAAK;AACpF,gBAAA,iBAAiB,EAAE,KAAK;AACxB,gBAAA,UAAU,EAAE,IAAI;aACjB;QACH;AACF,IAAA,CAAC;IAED,OAAO;AACL,QAAA,IAAI,EAAE,sBAAsB;AAE5B,QAAA,IAAI,EAAE;AACJ,YAAA,KAAK,EAAE,KAAK;YACZ,MAAM,OAAO,CAAC,EAAU,EAAA;gBACtB,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;gBAC5B,MAAM,YAAY,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC;AAChE,gBAAA,MAAM,WAAW,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACjD,MAAM,MAAM,GAAG,kBAAA,CAAA,OAAW,CAAC,KAAK,CAAC,WAAW,CAAC;gBAC7C,MAAM,WAAW,GAAG,YAAY;gBAEhC,IAAI,UAAU,GAAkB,IAAI;AACpC,gBAAA,MAAM,YAAY,GAAG,YAAW;AAC9B,oBAAA,IAAI,UAAU,IAAI,IAAI,EAAE;AACtB,wBAAA,OAAO,UAAU;oBACnB;oBACA,UAAU,GAAG,MAAM,UAAA,CAAA,OAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;AAC3C,oBAAA,OAAO,UAAU;AACnB,gBAAA,CAAC;gBAED,IAAI,cAAc,EAAE;AAClB,oBAAA,KAAK,MAAM,SAAS,IAAI,cAAc,EAAE;AACtC,wBAAA,IAAI,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;AACxB,4BAAA,IAAI,OAAO,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,YAAY,EAAE,CAAC;AACvE,4BAAA,IAAI,OAAO,IAAI,IAAI,EAAE;gCACnB;4BACF;AACA,4BAAA,OAAO,MAAM,gBAAgB,CAAC,EAAE,EAAE,OAAO,CAAC;wBAC5C;oBACF;gBACF;gBAEA,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,IAAI;gBAChD,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,IAAI;AAEhD,gBAAA,IAAI,WAAW,IAAI,WAAW,EAAE;AAC9B,oBAAA,MAAM,IAAI,KAAK,CACb,iEAAiE,EAAE,CAAA,CAAE,CACtE;gBACH;gBAEA,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,IAAI;AAEjD,gBAAA,IAAI,WAAW,IAAI,WAAW,EAAE;AAC9B,oBAAA,MAAM,OAAO,GAAG,MAAM,YAAY,EAAE;AAEpC,oBAAA,IAAI,OAAO,GAA2B;wBACpC,OAAO;wBACP,YAAY;AACZ,wBAAA,MAAM,EAAE,WAAW;AACnB,wBAAA,OAAO,EAAE,WAAA,CAAA,OAAI,CAAC,OAAO,CAAC,WAAW,CAAC;qBACnC;AACD,oBAAA,OAAO,MAAM,gBAAgB,CAAC,EAAE,EAAE,OAAO,CAAC;gBAC5C;YACF;AACD,SAAA;AAED,QAAA,WAAW,EAAE,gBAAgB,aAA4B,EAAE,MAAyD,EAAA;AAClH,YAAA,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM;iBAClC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC;AAEpF,YAAA,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;AACxB,gBAAA,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC;YAC5D;AACA,YAAA,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;AACtB,gBAAA,MAAM,IAAI,KAAK,CAAC,+KAA+K,CAAC;YAClM;YAEA,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;YAExC,IAAI,OAAO,EAAE;AACX,gBAAA,MAAM,MAAM,GAAG,WAAA,CAAA,OAAI,CAAC,OAAO,CACvB,aAAa,CAAC,GAAG,IAAI,EAAE,EACvB,YAAY,CAAC;AACjB,gBAAA,IAAI,MAAM,UAAA,CAAA,OAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;AAC5C,oBAAA,MAAM,UAAA,CAAA,OAAE,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;gBAC7C;gBAEA,MAAM,eAAe,GAAG,EAAE;gBAC1B,MAAM,kBAAkB,GAAG,EAAE;gBAE7B,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,KAAK,EAAE;AAC9B,oBAAA,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAA,eAAA,CAAiB,CAAC;AAC3C,oBAAA,MAAM,OAAO,GAAG,WAAA,CAAA,OAAI,CAAC,OAAO,CAC1B,aAAa,CAAC,GAAG,IAAI,EAAE,EACvB,YAAY,EACZ,IAAI,CAAC,QAAQ,CACd;AAED,oBAAA,MAAM,kBAAE,CAAC,KAAK,CAAC,WAAA,CAAA,OAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;oBAC1D,MAAM,UAAA,CAAA,OAAE,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC;AAEzC,oBAAA,IAAI,IAAI,CAAC,YAAY,EAAE;AACrB,wBAAA,kBAAkB,CAAC,IAAI,CAAC,WAAA,CAAA,OAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;oBACtD;yBAAO;AACL,wBAAA,eAAe,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,WAAA,CAAA,OAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,CAAC;oBACzG;gBACF;;gBAGA,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;gBAEnI,IAAI,CAAC,IAAI,CAAC,CAAA,4BAAA,EAA+B,SAAS,CAAC,UAAU,CAAA,CAAA,CAAG,CAAC;gBACjE,MAAM,SAAS,CAAC,GAAG,CAAC;AAClB,oBAAA,MAAM,EAAE,WAAA,CAAA,OAAI,CAAC,OAAO,CAClB,aAAa,CAAC,GAAG,IAAI,EAAE,EACvB,UAAU,CACX;AACD,oBAAA,KAAK,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;AACvC,oBAAA,kBAAkB,EAAE,kBAAkB;AACtC,oBAAA,MAAM,EAAE,WAAA,CAAA,OAAI,CAAC,OAAO,CAClB,aAAa,CAAC,GAAG,IAAI,EAAE,EACvB,eAAe,CAChB;AACF,iBAAA,CAAC;gBAEF,MAAM,UAAU,GAAG,WAAA,CAAA,OAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAA,CAAA,OAAI,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,EAAE,EAAE,eAAe,CAAC,CAAC;gBAC7F,IAAI,CAAC,IAAI,CAAC,CAAA,6BAAA,EAAgC,UAAU,CAAA,kCAAA,EAAqC,UAAU,CAAA,sBAAA,CAAwB,CAAC;YAC9H;QACF,CAAC;KACF;AACH"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { PluginContext, rollup, type OutputAsset, type OutputChunk, type OutputOptions, type Plugin } from \"rollup\";\nimport querystring from \"node:querystring\";\nimport fs from \"node:fs/promises\";\nimport fsSync from \"node:fs\";\nimport path from \"node:path\";\nimport child_process from \"node:child_process\";\nimport { createFilter, FilterPattern } from \"@rollup/pluginutils\";\n\ntype WebSqzFile = {\n fileName: string;\n content: Buffer;\n isCompressed: boolean;\n fileExt: string;\n isText: boolean;\n};\n\nexport type WebsqzFileTransformRes = {\n /**\n * The result of processing\n */\n content: Buffer;\n\n /**\n * Is already compressed and should not be compressed again by websqz\n */\n isCompressed: boolean;\n\n /**\n * Is it text? The plugin orders files by type for better compression ratios\n */\n isText: boolean;\n\n /**\n * File extension including the dot, e.g. .txt.\n * This is used to order files for better compression ratios.\n * Same type of content should share same file extension.\n * \n * By default it is extracted from the original file path.\n */\n fileExt?: string;\n};\n\ntype WebSqzOptions = {\n websqzPath?: string;\n\n /**\n * File transform hooks to process files before they are imported in code or compressed by websqz\n */\n fileTransforms?: [\n {\n include?: FilterPattern,\n exclude?: FilterPattern,\n transform: (ctx: PluginContext, id: string, content: Buffer) => Promise<WebsqzFileTransformRes>;\n }\n ]\n};\n\ntype WebSqzCliOptions = {\n jsMain: string;\n files: string[];\n preCompressedFiles: string[];\n output: string;\n}\n\nclass WebSqzExe {\n websqzPath: string;\n constructor(websqzPath: string) {\n this.websqzPath = websqzPath;\n }\n\n async run(cliOptions: WebSqzCliOptions): Promise<void> {\n const args: string[] = [];\n\n args.push(\"--js-main\", cliOptions.jsMain);\n\n for (const file of cliOptions.files) {\n args.push(\"--files\", file);\n }\n for (const preCompressedFile of cliOptions.preCompressedFiles) {\n args.push(\"--pre-compressed-files\", preCompressedFile);\n }\n\n args.push(\"--output-directory\", cliOptions.output);\n\n const spawn = await child_process.spawn(this.websqzPath, args, {\n stdio: \"inherit\",\n });\n\n return new Promise<void>((resolve, reject) => {\n spawn.once(\"error\", (err) => {\n reject(err);\n });\n\n spawn.once(\"close\", (code) => {\n if (code !== 0) {\n reject(new Error(`websqz process exited with code ${code}`));\n } else {\n resolve();\n }\n });\n });\n }\n}\n\nfunction websqzExecutablePath(executablePath: string | undefined): string {\n if (!executablePath) {\n const path = __dirname + \"/bin/websqz\";\n const extension = process.platform == \"win32\" ? \".exe\" : \"\";\n\n if (fsSync.existsSync(path + extension)) {\n return path + extension;\n }\n\n return \"websqz\" + extension;\n }\n\n return executablePath;\n}\n\nexport default function (options: WebSqzOptions = {}): Plugin {\n const isBuild = process.env.NODE_ENV === \"production\";\n const websqzExePath = websqzExecutablePath(options.websqzPath);\n const websqzExe = new WebSqzExe(websqzExePath);\n\n const fileTransforms = options.fileTransforms?.map(transform => {\n const include = transform.include ? (Array.isArray(transform.include) ? transform.include : [transform.include]) \n : undefined;\n const exclude = transform.exclude ? (Array.isArray(transform.exclude) ? transform.exclude : [transform.exclude]) \n : undefined;\n\n const filter = createFilter(include, exclude);\n return {\n transform: transform.transform,\n filter,\n }\n });\n\n const files = new Map<string, WebSqzFile>();\n let fileNameIdx = 0;\n\n const findNextAvailableFileName = () => {\n const startChar = 97; // a\n const endChar = 122; // z\n const alphabetSize= endChar - startChar;\n\n let numChars = fileNameIdx === 0 ? 1 : Math.floor(Math.log(fileNameIdx) / Math.log(alphabetSize)) + 1;\n let candidateName = \"\";\n \n for (let i = 0; i < numChars; i++) {\n const charCode = startChar + ((Math.floor(fileNameIdx / Math.pow(alphabetSize, i))) % alphabetSize);\n candidateName = String.fromCharCode(charCode) + candidateName;\n }\n\n fileNameIdx++;\n\n return candidateName;\n }\n\n const loadAndTransform = async function (id: string, hookRes: WebsqzFileTransformRes) {\n if (isBuild) {\n const fileName = findNextAvailableFileName();\n files.set(id, {\n fileName,\n content: hookRes.content,\n isCompressed: hookRes.isCompressed,\n fileExt: hookRes.fileExt ?? path.extname(id),\n isText: hookRes.isText,\n });\n\n return {\n code: hookRes.isText \n ? `export default new TextDecoder().decode(wsqz.files[\"${fileName}\"]);` \n : `export default wsqz.files[\"${fileName}\"];`,\n moduleSideEffects: false,\n moduleType: 'js',\n };\n } else {\n return {\n code: hookRes.isText \n ? `export default ${JSON.stringify(hookRes.content.toString(\"utf-8\"))};` \n : `export default Uint8Array.fromBase64(\"${hookRes.content.toString(\"base64\")}\");`,\n moduleSideEffects: false,\n moduleType: 'js',\n };\n }\n };\n\n return {\n name: \"rollup-plugin-websqz\",\n\n load: {\n order: \"pre\",\n async handler(id: string) {\n const qIdx = id.indexOf(\"?\");\n const beforeParams = id.slice(0, qIdx === -1 ? id.length : qIdx);\n const afterParams = id.slice(id.indexOf(\"?\") + 1);\n const parsed = querystring.parse(afterParams);\n const cleanedUpId = beforeParams;\n\n let cachedFile: Buffer | null = null;\n const loadFromDisk = async () => {\n if (cachedFile != null) {\n return cachedFile;\n }\n cachedFile = await fs.readFile(cleanedUpId);\n return cachedFile;\n };\n\n if (fileTransforms) {\n for (const transform of fileTransforms) {\n if (transform.filter(id)) {\n let hookRes = await transform.transform(this, id, await loadFromDisk());\n if (hookRes == null) {\n continue;\n }\n return await loadAndTransform(id, hookRes);\n }\n }\n }\n\n const isWebSqzTxt = parsed[\"websqz-txt\"] != null;\n const isWebSqzBin = parsed[\"websqz-bin\"] != null;\n\n if (isWebSqzTxt && isWebSqzBin) {\n throw new Error(\n `Cannot use both websqz-txt and websqz-bin on the same import: ${id}`,\n );\n }\n\n const isCompressed = parsed[\"compressed\"] != null;\n\n if (isWebSqzTxt || isWebSqzBin) {\n const content = await loadFromDisk();\n \n let hookRes: WebsqzFileTransformRes = {\n content,\n isCompressed,\n isText: isWebSqzTxt,\n fileExt: path.extname(cleanedUpId),\n };\n return await loadAndTransform(id, hookRes);\n }\n }\n },\n\n writeBundle: async function (outputOptions: OutputOptions, bundle: { [fileName: string]: OutputAsset | OutputChunk }) {\n const jsFiles = Object.entries(bundle)\n .filter(([fileName, asset]) => fileName.endsWith('.js') && asset.type === 'chunk');\n\n if (jsFiles.length === 0) {\n throw new Error('No JavaScript file found in the bundle.');\n }\n if (jsFiles.length > 1) {\n throw new Error('Multiple JavaScript files found in the bundle. Make sure to bundle into a single file.\\nTry setting \"build.rollupOptions.output.inlineDynamicImports\" to true in Vite config.');\n }\n\n const [jsFileName, jsChunk] = jsFiles[0];\n\n if (isBuild) {\n const outDir = path.resolve(\n outputOptions.dir || \"\",\n \"websqz-tmp\");\n if (await fs.stat(outDir).catch(() => false)) {\n await fs.rm(outDir, { recursive: true, force: true });\n }\n\n const filesToCompress = [];\n const preCompressedFiles = [];\n\n for (const [id, file] of files) {\n this.debug(`Copying '${id}' for websqz...`);\n const outPath = path.resolve(\n outputOptions.dir || \"\",\n \"websqz-tmp\",\n file.fileName,\n );\n\n await fs.mkdir(path.dirname(outPath), { recursive: true });\n await fs.writeFile(outPath, file.content);\n\n if (file.isCompressed) {\n preCompressedFiles.push(path.relative(\".\", outPath));\n } else {\n filesToCompress.push({ isText: file.isText, fileExt: file.fileExt, path: path.relative(\".\", outPath) });\n }\n }\n\n // Sort by file extension for better compression ratios in websqz\n filesToCompress.sort((a, b) => Math.sign(a.fileExt.localeCompare(b.fileExt)) + 2 * (a.isText === b.isText ? 0 : a.isText ? -1 : 1));\n\n this.info(`Using websqz executable at '${websqzExe.websqzPath}'`);\n await websqzExe.run({\n jsMain: path.resolve(\n outputOptions.dir || \"\",\n jsFileName,\n ),\n files: filesToCompress.map(f => f.path),\n preCompressedFiles: preCompressedFiles,\n output: path.resolve(\n outputOptions.dir || \"\",\n \"websqz-output\",\n ),\n });\n\n const relOutPath = path.relative(\".\", path.resolve(outputOptions.dir || \"\", \"websqz-output\"));\n this.info(`Websqz completed, output at '${relOutPath}'.\\nRun 'python -m http.server -d ${relOutPath}' to serve the output.`);\n }\n },\n };\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "rollup-plugin-websqz",
3
- "version": "1.0.6",
3
+ "version": "1.1.0",
4
+ "type": "module",
4
5
  "description": "",
5
6
  "main": "./dist/index.js",
6
7
  "types": "./dist/index.d.ts",
7
8
  "exports": "./dist/index.js",
8
9
  "files": [
9
- "scripts/install.js",
10
+ "scripts/install.cj",
10
11
  "dist/index.js",
11
12
  "dist/index.js.map",
12
13
  "dist/index.d.ts"
@@ -30,6 +31,7 @@
30
31
  "devDependencies": {
31
32
  "@rollup/plugin-typescript": "^12.3.0",
32
33
  "@tsconfig/node22": "^22.0.5",
34
+ "@types/node": "^26.0.0",
33
35
  "rollup": "^4.55.3",
34
36
  "typescript": "^5.9.3"
35
37
  },
@@ -1,180 +0,0 @@
1
- const fs = require("fs");
2
- const https = require("https");
3
- const http = require("http");
4
- const path = require("path");
5
- const os = require("os");
6
-
7
- const RELEASE_BASE_URL = "https://github.com/r00tkids/websqz/releases/download";
8
- const VERSION = "0.4";
9
- const TOOL_NAME = "websqz";
10
- const BIN_DIR = path.resolve(__dirname, "../dist/bin");
11
-
12
- function getRustTarget() {
13
- const platform = process.platform;
14
- const arch = process.arch;
15
-
16
- let triple;
17
- let ext = "";
18
-
19
- if (platform === "win32") {
20
- ext = ".exe";
21
- if (arch === "x64") triple = "x86_64-pc-windows-msvc";
22
- else if (arch === "arm64") triple = "aarch64-pc-windows-msvc";
23
- else triple = `${arch}-pc-windows-msvc`;
24
- } else if (platform === "darwin") {
25
- if (arch === "x64") triple = "x86_64-apple-darwin";
26
- else if (arch === "arm64") triple = "aarch64-apple-darwin";
27
- else triple = `${arch}-apple-darwin`;
28
- } else if (platform === "linux") {
29
- if (arch === "x64") triple = "x86_64-unknown-linux-gnu";
30
- else if (arch === "arm64") triple = "aarch64-unknown-linux-gnu";
31
- else triple = `${arch}-unknown-linux-gnu`;
32
- } else {
33
- throw new Error(`Unsupported platform: ${platform}`);
34
- }
35
-
36
- return { triple, ext };
37
- }
38
-
39
- function buildAssetName(triple, ext) {
40
- return `${TOOL_NAME}-${triple}${ext}`;
41
- }
42
-
43
- function getDownloadUrl(assetName) {
44
- return `${RELEASE_BASE_URL}/v${VERSION}/${assetName}`;
45
- }
46
-
47
- function httpRequest(url, opts, callback) {
48
- const client = url.startsWith("https://") ? https : http;
49
- return client.get(url, opts, callback);
50
- }
51
-
52
- function downloadToFile(url, destPath) {
53
- return new Promise((resolve, reject) => {
54
- const maxRedirects = 5;
55
- let redirects = 0;
56
-
57
- function get(urlToGet) {
58
- const req = httpRequest(urlToGet, {}, (res) => {
59
- // Follow redirects
60
- if (
61
- res.statusCode >= 300 &&
62
- res.statusCode < 400 &&
63
- res.headers.location
64
- ) {
65
- if (redirects++ >= maxRedirects) {
66
- reject(new Error("Too many redirects"));
67
- return;
68
- }
69
- const next = new URL(res.headers.location, urlToGet).toString();
70
- res.resume();
71
- get(next);
72
- return;
73
- }
74
-
75
- if (res.statusCode !== 200) {
76
- reject(
77
- new Error(
78
- `Download failed: ${res.statusCode} ${res.statusMessage}`,
79
- ),
80
- );
81
- res.resume();
82
- return;
83
- }
84
-
85
- const total = parseInt(res.headers["content-length"] || "0", 10);
86
- let downloaded = 0;
87
-
88
- const fileStream = fs.createWriteStream(destPath, { mode: 0o755 });
89
- res.on("data", (chunk) => {
90
- downloaded += chunk.length;
91
- if (total) {
92
- const pct = ((downloaded / total) * 100).toFixed(1);
93
- process.stdout.write(
94
- `\rDownloading ${path.basename(destPath)} ${pct}% (${(downloaded / 1024).toFixed(1)} KB)`,
95
- );
96
- }
97
- });
98
-
99
- res.pipe(fileStream);
100
-
101
- fileStream.on("finish", () => {
102
- fileStream.close(() => {
103
- process.stdout.write("\n");
104
- resolve();
105
- });
106
- });
107
-
108
- fileStream.on("error", (err) => {
109
- fs.unlink(destPath, () => reject(err));
110
- });
111
- });
112
-
113
- req.on("error", (err) => reject(err));
114
- }
115
-
116
- get(url);
117
- });
118
- }
119
-
120
- async function ensureBinDir() {
121
- await fs.promises.mkdir(BIN_DIR, { recursive: true });
122
- }
123
-
124
- async function makeExecutable(filePath) {
125
- if (process.platform === "win32") {
126
- // Windows uses .exe; no chmod needed generally
127
- return;
128
- }
129
- try {
130
- await fs.promises.chmod(filePath, 0o755);
131
- } catch (err) {
132
- // Best-effort, not fatal
133
- console.warn(
134
- `Warning: could not set executable permissions on ${filePath}: ${err.message}`,
135
- );
136
- }
137
- }
138
-
139
- async function main() {
140
- try {
141
- const { triple, ext } = getRustTarget();
142
- const assetName = buildAssetName(triple, ext);
143
- const url = getDownloadUrl(assetName);
144
-
145
- console.log(`Detected platform: ${process.platform} ${process.arch}`);
146
- console.log(`Downloading asset: ${assetName}`);
147
- console.log(`From: ${url}`);
148
-
149
- if (fs.existsSync(BIN_DIR + "/" + TOOL_NAME + ext)) {
150
- console.log(`WebSQZ binary already exists at ${BIN_DIR}/${TOOL_NAME}${ext}, skipping download.`);
151
- return;
152
- }
153
-
154
- await ensureBinDir();
155
-
156
- const destFileName = `${TOOL_NAME}${ext}`; // place binary in bin with consistent name
157
- const destPath = path.join(BIN_DIR, destFileName);
158
-
159
- // Remove existing file if present (optional)
160
- try {
161
- await fs.promises.unlink(destPath);
162
- } catch (err) {
163
- // ignore if not exists
164
- }
165
-
166
- await downloadToFile(url, destPath);
167
-
168
- await makeExecutable(destPath);
169
-
170
- console.log(`Downloaded and saved to: ${destPath}`);
171
- console.log("Done.");
172
- } catch (err) {
173
- console.error(`Error: ${err.message}`);
174
- process.exitCode = 1;
175
- }
176
- }
177
-
178
- if (require.main === module) {
179
- main();
180
- }