@gpc-cli/core 0.9.73 → 0.9.74

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/dist/index.js CHANGED
@@ -5132,7 +5132,8 @@ async function loadPreflightConfig(configPath) {
5132
5132
  }
5133
5133
 
5134
5134
  // src/preflight/aab-reader.ts
5135
- import { open as yauzlOpen } from "yauzl";
5135
+ import { readFile as readFile10 } from "fs/promises";
5136
+ import { fromBuffer } from "yauzl";
5136
5137
 
5137
5138
  // src/preflight/manifest-parser.ts
5138
5139
  import protobuf from "protobufjs";
@@ -5321,12 +5322,20 @@ var AAB_MANIFEST_PATH = "base/manifest/AndroidManifest.xml";
5321
5322
  var APK_MANIFEST_PATH = "AndroidManifest.xml";
5322
5323
  var SO_HEADER_BYTES = 4096;
5323
5324
  var SO_PATH_RE = /(?:^|\/)lib\/[^/]+\/[^/]+\.so$/;
5325
+ var SCAN_TIMEOUT_MS = 6e4;
5324
5326
  function detectManifestPath(filePath) {
5325
5327
  return filePath.toLowerCase().endsWith(".apk") ? APK_MANIFEST_PATH : AAB_MANIFEST_PATH;
5326
5328
  }
5327
5329
  async function readAab(aabPath) {
5328
5330
  const manifestPath = detectManifestPath(aabPath);
5329
- const { zipfile, entries, manifestBuf, soHeaders } = await openAndScan(aabPath, manifestPath);
5331
+ let buffer;
5332
+ try {
5333
+ buffer = await readFile10(aabPath);
5334
+ } catch (err) {
5335
+ const msg = err instanceof Error ? err.message : String(err);
5336
+ throw new Error(`Could not read ${aabPath}: ${msg}`);
5337
+ }
5338
+ const { zipfile, entries, manifestBuf, soHeaders } = await openAndScan(buffer, manifestPath);
5330
5339
  zipfile.close();
5331
5340
  if (!manifestBuf) {
5332
5341
  const fileType = aabPath.toLowerCase().endsWith(".apk") ? "APK" : "AAB";
@@ -5363,98 +5372,125 @@ function createFallbackManifest() {
5363
5372
  providers: []
5364
5373
  };
5365
5374
  }
5366
- function openAndScan(aabPath, manifestPath = AAB_MANIFEST_PATH) {
5375
+ function openAndScan(buffer, manifestPath = AAB_MANIFEST_PATH) {
5367
5376
  return new Promise((resolve2, reject) => {
5368
- yauzlOpen(aabPath, { lazyEntries: true, autoClose: false }, (err, zipfile) => {
5369
- if (err || !zipfile) {
5370
- reject(err ?? new Error("Failed to open AAB file"));
5371
- return;
5377
+ let settled = false;
5378
+ const timer = setTimeout(() => {
5379
+ if (!settled) {
5380
+ settled = true;
5381
+ reject(new Error("Timed out reading the archive. The file may be corrupt or truncated."));
5372
5382
  }
5373
- const entries = [];
5374
- const soHeaders = /* @__PURE__ */ new Map();
5375
- let manifestBuf = null;
5376
- let rejected = false;
5377
- let pendingStreams = 0;
5378
- let entrysDone = false;
5379
- function fail(error) {
5380
- if (!rejected) {
5381
- rejected = true;
5382
- zipfile.close();
5383
- reject(error);
5383
+ }, SCAN_TIMEOUT_MS);
5384
+ function settleResolve(value) {
5385
+ if (settled) return;
5386
+ settled = true;
5387
+ clearTimeout(timer);
5388
+ resolve2(value);
5389
+ }
5390
+ function settleReject(error) {
5391
+ if (settled) return;
5392
+ settled = true;
5393
+ clearTimeout(timer);
5394
+ reject(error);
5395
+ }
5396
+ try {
5397
+ fromBuffer(buffer, { lazyEntries: true }, (err, zipfile) => {
5398
+ if (err || !zipfile) {
5399
+ settleReject(err ?? new Error("Failed to open AAB file"));
5400
+ return;
5384
5401
  }
5385
- }
5386
- function maybeResolve() {
5387
- if (!rejected && entrysDone && pendingStreams === 0) {
5388
- resolve2({ zipfile, entries, manifestBuf, soHeaders });
5402
+ const entries = [];
5403
+ const soHeaders = /* @__PURE__ */ new Map();
5404
+ let manifestBuf = null;
5405
+ let pendingStreams = 0;
5406
+ let entrysDone = false;
5407
+ function fail(error) {
5408
+ if (settled) return;
5409
+ try {
5410
+ zipfile.close();
5411
+ } catch {
5412
+ }
5413
+ settleReject(error);
5389
5414
  }
5390
- }
5391
- function readEntryStream(entry, onData, maxBytes) {
5392
- pendingStreams++;
5393
- zipfile.openReadStream(entry, (streamErr, stream) => {
5394
- if (streamErr || !stream) {
5395
- fail(streamErr ?? new Error(`Failed to read ${entry.fileName}`));
5396
- return;
5415
+ function maybeResolve() {
5416
+ if (!settled && entrysDone && pendingStreams === 0) {
5417
+ settleResolve({ zipfile, entries, manifestBuf, soHeaders });
5397
5418
  }
5398
- const chunks = [];
5399
- let totalBytes = 0;
5400
- let done = false;
5401
- stream.on("data", (chunk) => {
5402
- chunks.push(chunk);
5403
- totalBytes += chunk.length;
5404
- if (maxBytes && totalBytes >= maxBytes) {
5405
- stream.destroy();
5406
- }
5407
- });
5408
- stream.on("error", (e) => {
5409
- if (maxBytes && totalBytes >= maxBytes) return;
5410
- fail(e);
5411
- });
5412
- const finish = () => {
5413
- if (done) return;
5414
- done = true;
5415
- const buf = Buffer.concat(chunks);
5416
- onData(maxBytes ? buf.subarray(0, maxBytes) : buf);
5417
- pendingStreams--;
5418
- maybeResolve();
5419
- };
5420
- stream.on("end", finish);
5421
- stream.on("close", () => {
5422
- if (totalBytes > 0 && maxBytes) finish();
5423
- });
5424
- });
5425
- }
5426
- zipfile.on("error", fail);
5427
- zipfile.on("entry", (entry) => {
5428
- if (rejected) return;
5429
- const path = entry.fileName;
5430
- if (!path.endsWith("/")) {
5431
- entries.push({
5432
- path,
5433
- compressedSize: entry.compressedSize,
5434
- uncompressedSize: entry.uncompressedSize
5435
- });
5436
5419
  }
5437
- if (path === manifestPath) {
5438
- readEntryStream(entry, (buf) => {
5439
- manifestBuf = buf;
5420
+ function readEntryStream(entry, onData, maxBytes) {
5421
+ pendingStreams++;
5422
+ zipfile.openReadStream(entry, (streamErr, stream) => {
5423
+ if (streamErr || !stream) {
5424
+ fail(streamErr ?? new Error(`Failed to read ${entry.fileName}`));
5425
+ return;
5426
+ }
5427
+ const chunks = [];
5428
+ let totalBytes = 0;
5429
+ let done = false;
5430
+ stream.on("data", (chunk) => {
5431
+ chunks.push(chunk);
5432
+ totalBytes += chunk.length;
5433
+ if (maxBytes && totalBytes >= maxBytes) {
5434
+ stream.destroy();
5435
+ }
5436
+ });
5437
+ stream.on("error", (e) => {
5438
+ if (maxBytes && totalBytes >= maxBytes) return;
5439
+ fail(e);
5440
+ });
5441
+ const finish = () => {
5442
+ if (done) return;
5443
+ done = true;
5444
+ const buf = Buffer.concat(chunks);
5445
+ onData(maxBytes ? buf.subarray(0, maxBytes) : buf);
5446
+ pendingStreams--;
5447
+ maybeResolve();
5448
+ };
5449
+ stream.on("end", finish);
5450
+ stream.on("close", () => {
5451
+ if (totalBytes > 0 && maxBytes) finish();
5452
+ });
5440
5453
  });
5441
- } else if (SO_PATH_RE.test(path)) {
5442
- readEntryStream(
5443
- entry,
5444
- (buf) => {
5445
- soHeaders.set(path, buf);
5446
- },
5447
- SO_HEADER_BYTES
5448
- );
5449
5454
  }
5455
+ zipfile.on("error", fail);
5456
+ zipfile.on("entry", (entry) => {
5457
+ if (settled) return;
5458
+ try {
5459
+ const path = entry.fileName;
5460
+ if (!path.endsWith("/")) {
5461
+ entries.push({
5462
+ path,
5463
+ compressedSize: entry.compressedSize,
5464
+ uncompressedSize: entry.uncompressedSize
5465
+ });
5466
+ }
5467
+ if (path === manifestPath) {
5468
+ readEntryStream(entry, (buf) => {
5469
+ manifestBuf = buf;
5470
+ });
5471
+ } else if (SO_PATH_RE.test(path)) {
5472
+ readEntryStream(
5473
+ entry,
5474
+ (buf) => {
5475
+ soHeaders.set(path, buf);
5476
+ },
5477
+ SO_HEADER_BYTES
5478
+ );
5479
+ }
5480
+ zipfile.readEntry();
5481
+ } catch (e) {
5482
+ fail(e instanceof Error ? e : new Error(String(e)));
5483
+ }
5484
+ });
5485
+ zipfile.on("end", () => {
5486
+ entrysDone = true;
5487
+ maybeResolve();
5488
+ });
5450
5489
  zipfile.readEntry();
5451
5490
  });
5452
- zipfile.on("end", () => {
5453
- entrysDone = true;
5454
- maybeResolve();
5455
- });
5456
- zipfile.readEntry();
5457
- });
5491
+ } catch (err) {
5492
+ settleReject(err instanceof Error ? err : new Error(String(err)));
5493
+ }
5458
5494
  });
5459
5495
  }
5460
5496
 
@@ -6018,7 +6054,7 @@ ${fileList}` + (hasPageSizeCompat ? "\nandroid:pageSizeCompat is set, so the app
6018
6054
  }
6019
6055
 
6020
6056
  // src/preflight/scanners/metadata-scanner.ts
6021
- import { readdir as readdir4, stat as stat6, readFile as readFile10 } from "fs/promises";
6057
+ import { readdir as readdir4, stat as stat6, readFile as readFile11 } from "fs/promises";
6022
6058
  import { join as join8 } from "path";
6023
6059
  var SAFE_LANG = /^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$/;
6024
6060
  var FILE_MAP2 = {
@@ -6077,7 +6113,7 @@ var metadataScanner = {
6077
6113
  for (const [fileName, field] of Object.entries(FILE_MAP2)) {
6078
6114
  const filePath = join8(langDir, fileName);
6079
6115
  try {
6080
- const content = await readFile10(filePath, "utf-8");
6116
+ const content = await readFile11(filePath, "utf-8");
6081
6117
  fields[field] = content.trimEnd();
6082
6118
  } catch {
6083
6119
  }
@@ -6150,7 +6186,7 @@ var metadataScanner = {
6150
6186
  const defaultLang = locales.includes("en-US") ? "en-US" : locales[0];
6151
6187
  const privacyPath = join8(dir, defaultLang, "privacy_policy_url.txt");
6152
6188
  try {
6153
- const url = await readFile10(privacyPath, "utf-8");
6189
+ const url = await readFile11(privacyPath, "utf-8");
6154
6190
  if (!url.trim()) throw new Error("empty");
6155
6191
  } catch {
6156
6192
  findings.push({
@@ -6175,7 +6211,7 @@ var metadataScanner = {
6175
6211
  };
6176
6212
 
6177
6213
  // src/preflight/scanners/secrets-scanner.ts
6178
- import { readFile as readFile11 } from "fs/promises";
6214
+ import { readFile as readFile12 } from "fs/promises";
6179
6215
 
6180
6216
  // src/preflight/scan-files.ts
6181
6217
  import { readdir as readdir5, stat as stat7 } from "fs/promises";
@@ -6295,7 +6331,7 @@ var secretsScanner = {
6295
6331
  for (const filePath of files) {
6296
6332
  let content;
6297
6333
  try {
6298
- content = await readFile11(filePath, "utf-8");
6334
+ content = await readFile12(filePath, "utf-8");
6299
6335
  } catch {
6300
6336
  continue;
6301
6337
  }
@@ -6323,7 +6359,7 @@ var secretsScanner = {
6323
6359
  };
6324
6360
 
6325
6361
  // src/preflight/scanners/billing-scanner.ts
6326
- import { readFile as readFile12 } from "fs/promises";
6362
+ import { readFile as readFile13 } from "fs/promises";
6327
6363
  var BILLING_PATTERNS = [
6328
6364
  {
6329
6365
  ruleId: "billing-stripe-sdk",
@@ -6384,7 +6420,7 @@ var billingScanner = {
6384
6420
  for (const filePath of files) {
6385
6421
  let content;
6386
6422
  try {
6387
- content = await readFile12(filePath, "utf-8");
6423
+ content = await readFile13(filePath, "utf-8");
6388
6424
  } catch {
6389
6425
  continue;
6390
6426
  }
@@ -6410,7 +6446,7 @@ var billingScanner = {
6410
6446
  };
6411
6447
 
6412
6448
  // src/preflight/scanners/privacy-scanner.ts
6413
- import { readFile as readFile13 } from "fs/promises";
6449
+ import { readFile as readFile14 } from "fs/promises";
6414
6450
  var TRACKING_SDKS = [
6415
6451
  {
6416
6452
  name: "Facebook SDK",
@@ -6450,7 +6486,7 @@ var privacyScanner = {
6450
6486
  for (const filePath of files) {
6451
6487
  let content;
6452
6488
  try {
6453
- content = await readFile13(filePath, "utf-8");
6489
+ content = await readFile14(filePath, "utf-8");
6454
6490
  } catch {
6455
6491
  continue;
6456
6492
  }
@@ -7150,7 +7186,7 @@ async function downloadGeneratedApk(client, packageName, versionCode, apkId, out
7150
7186
  }
7151
7187
 
7152
7188
  // src/commands/bundle-analysis.ts
7153
- import { readFile as readFile14, stat as stat8 } from "fs/promises";
7189
+ import { readFile as readFile15, stat as stat8 } from "fs/promises";
7154
7190
  var EOCD_SIGNATURE = 101010256;
7155
7191
  var CD_SIGNATURE = 33639248;
7156
7192
  var MODULE_SUBDIRS = /* @__PURE__ */ new Set(["dex", "manifest", "res", "assets", "lib", "resources.pb", "root"]);
@@ -7230,7 +7266,7 @@ async function analyzeBundle(filePath) {
7230
7266
  if (!fileInfo || !fileInfo.isFile()) {
7231
7267
  throw new Error(`File not found: ${filePath}`);
7232
7268
  }
7233
- const buf = await readFile14(filePath);
7269
+ const buf = await readFile15(filePath);
7234
7270
  const cdEntries = parseCentralDirectory(buf);
7235
7271
  const fileType = detectFileType2(filePath);
7236
7272
  const isAab = fileType === "aab";
@@ -7316,7 +7352,7 @@ function topFiles(analysis, n = 20) {
7316
7352
  async function checkBundleSize(analysis, configPath = ".bundlesize.json") {
7317
7353
  let config;
7318
7354
  try {
7319
- const raw = await readFile14(configPath, "utf-8");
7355
+ const raw = await readFile15(configPath, "utf-8");
7320
7356
  config = JSON.parse(raw);
7321
7357
  } catch {
7322
7358
  return { passed: true, violations: [] };