sporades 0.9.23 → 0.9.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/CHANGES.md +145 -6
  2. package/bin/sporades-host-helper.js +88 -9
  3. package/bin/sporades.js +3317 -1205
  4. package/dist/acl-runtime.d.ts +17 -50
  5. package/dist/acl-runtime.d.ts.map +1 -1
  6. package/dist/acl-runtime.js +226 -67
  7. package/dist/acl-runtime.js.map +1 -1
  8. package/dist/auth-runtime.d.ts.map +1 -1
  9. package/dist/auth-runtime.js +33 -11
  10. package/dist/auth-runtime.js.map +1 -1
  11. package/dist/cli/cli-version.d.ts +1 -1
  12. package/dist/cli/cli-version.js +1 -1
  13. package/dist/cli/host-helper-archive.d.ts.map +1 -1
  14. package/dist/cli/host-helper-archive.js +62 -7
  15. package/dist/cli/host-helper-archive.js.map +1 -1
  16. package/dist/cli/sporades.js +19 -8
  17. package/dist/cli/sporades.js.map +1 -1
  18. package/dist/client.d.ts +1 -1
  19. package/dist/client.d.ts.map +1 -1
  20. package/dist/client.js.map +1 -1
  21. package/dist/database-runtime.d.ts +1 -1
  22. package/dist/database-runtime.d.ts.map +1 -1
  23. package/dist/database-runtime.js +596 -83
  24. package/dist/database-runtime.js.map +1 -1
  25. package/dist/file-storage-runtime.d.ts.map +1 -1
  26. package/dist/file-storage-runtime.js +213 -278
  27. package/dist/file-storage-runtime.js.map +1 -1
  28. package/dist/generated-source-manifest.json +22 -2
  29. package/dist/http-runtime.d.ts +9 -1
  30. package/dist/http-runtime.d.ts.map +1 -1
  31. package/dist/http-runtime.js +118 -42
  32. package/dist/http-runtime.js.map +1 -1
  33. package/dist/jobs-runtime.d.ts +3 -1
  34. package/dist/jobs-runtime.d.ts.map +1 -1
  35. package/dist/jobs-runtime.js +19 -2
  36. package/dist/jobs-runtime.js.map +1 -1
  37. package/dist/mail-runtime.d.ts +46 -2
  38. package/dist/mail-runtime.d.ts.map +1 -1
  39. package/dist/mail-runtime.js +171 -71
  40. package/dist/mail-runtime.js.map +1 -1
  41. package/dist/notification-intent-runtime.d.ts +52 -0
  42. package/dist/notification-intent-runtime.d.ts.map +1 -0
  43. package/dist/notification-intent-runtime.js +408 -0
  44. package/dist/notification-intent-runtime.js.map +1 -0
  45. package/dist/promise-coordinator.d.ts +17 -0
  46. package/dist/promise-coordinator.d.ts.map +1 -0
  47. package/dist/promise-coordinator.js +155 -0
  48. package/dist/promise-coordinator.js.map +1 -0
  49. package/dist/resource-runtime.d.ts +30 -0
  50. package/dist/resource-runtime.d.ts.map +1 -0
  51. package/dist/resource-runtime.js +764 -0
  52. package/dist/resource-runtime.js.map +1 -0
  53. package/dist/server-runtime-source.d.ts +2 -2
  54. package/dist/server-runtime-source.d.ts.map +1 -1
  55. package/dist/server-runtime-source.js +373 -47
  56. package/dist/server-runtime-source.js.map +1 -1
  57. package/dist/server.d.ts +1 -1
  58. package/dist/server.d.ts.map +1 -1
  59. package/dist/server.js.map +1 -1
  60. package/dist/stripe-payment-config.d.ts +1 -1
  61. package/dist/stripe-payment-config.js +1 -1
  62. package/dist/team-billing-convergence.d.ts.map +1 -1
  63. package/dist/team-billing-convergence.js +6 -1
  64. package/dist/team-billing-convergence.js.map +1 -1
  65. package/dist/team-billing-erasure.d.ts +1 -1
  66. package/dist/team-billing-erasure.d.ts.map +1 -1
  67. package/dist/team-billing-erasure.js +13 -11
  68. package/dist/team-billing-erasure.js.map +1 -1
  69. package/dist/team-billing-management.d.ts.map +1 -1
  70. package/dist/team-billing-management.js +23 -22
  71. package/dist/team-billing-management.js.map +1 -1
  72. package/dist/team-billing-quantity.d.ts +9 -0
  73. package/dist/team-billing-quantity.d.ts.map +1 -0
  74. package/dist/team-billing-quantity.js +9 -0
  75. package/dist/team-billing-quantity.js.map +1 -0
  76. package/dist/team-billing-runtime.d.ts.map +1 -1
  77. package/dist/team-billing-runtime.js +12 -10
  78. package/dist/team-billing-runtime.js.map +1 -1
  79. package/dist/templates/client-runtime-template.d.ts.map +1 -1
  80. package/dist/templates/client-runtime-template.js +32 -8
  81. package/dist/templates/client-runtime-template.js.map +1 -1
  82. package/dist/templates/server-bundle-entry.d.ts.map +1 -1
  83. package/dist/templates/server-bundle-entry.js +19 -6
  84. package/dist/templates/server-bundle-entry.js.map +1 -1
  85. package/package.json +2 -2
  86. package/src/types/client.d.ts +12 -2
  87. package/src/types/server.d.ts +61 -14
  88. package/src/types/stripe.d.ts +1 -1
package/CHANGES.md CHANGED
@@ -1,21 +1,159 @@
1
1
  # Changes
2
2
 
3
- ## Unreleased - 2026-09-17
3
+ ## Unreleased - 2026-09-21
4
4
 
5
- Changes since v0.9.22.
5
+ Changes since v0.9.25.
6
6
 
7
7
  ### 🚀 Features
8
8
 
9
- - Add user-scoped server file deletion (#46) (5629928f).
9
+ - Add durable notification intents (#75) (8885992b).
10
+ - Add PostgreSQL resource transaction locks (f52eb67e).
11
+ - Add outer resource watchdog regression coverage (447f186f).
12
+ - Implement SQLite Job resource transactions and durable replay receipts (d2553b24).
10
13
 
11
14
  ### 🐛 Bug Fixes
12
15
 
13
- - Fix stale runtime connection-token recovery (#48) (51193284).
14
- - Normalize subject whitespace (f7f2f6d9).
16
+ - Preserve URL health route contract (#88) (10db3e3d).
17
+ - Harden request target rejection (#84) (d7514796).
18
+ - Fix HTTP failure logging liveness (#82) (fa53a5d8).
19
+ - Fix issue #77 suite baseline failures (#78) (2f52fd41).
20
+ - Fix File URL locking and resource acquisition deadlines (4571679e).
21
+ - Fix postgres resource callback lock waits (f3f5374f).
22
+ - Fence ACL and resource schema races (16200025).
23
+ - Fix ACL Promise combinator tracking (4da46e89).
24
+ - Reject unsafe resource table identity (c9d6bda0).
25
+ - Harden ACL lineage and resource readiness (602a968e).
26
+ - Harden ACL promise settlement and reject rewrite rules (901f34ba).
27
+ - Reject all resource table triggers (e7546547).
28
+ - Lock resource ACL dependencies and reject mutating triggers (fbdb4b53).
29
+ - Support async postgres ACL helpers (cfa01f1f).
30
+ - Close four findings in PostgreSQL resource handling (b353f1cf).
31
+ - Retain lazy reconnect after an unknown COMMIT outcome (08188c67).
32
+ - Deny a missing locked anchor before authorization (010a1785).
33
+ - Isolate postgres resource error boundaries (91684477).
34
+ - Redact PostgreSQL outer resource storage errors (619e0ab5).
35
+ - Fix postgres resource failure settlement (6a049ac7).
36
+ - Harden PostgreSQL resource authorization (d2dc57cb).
37
+ - Make PostgreSQL Job claim locks nowait (0fdfea3d).
38
+ - Publish PostgreSQL resource bootstrap atomically (d4f2b435).
39
+ - Bound PostgreSQL resource bootstrap lock (cdcc950f).
40
+ - Serialize PostgreSQL resource bootstrap (d5afdd21).
41
+ - Fix PostgreSQL resource identifier casing (d2bcd317).
42
+ - Harden resource transaction adapter seam (be2fe86d).
43
+ - Lock PostgreSQL resource authorization (b5f45cfb).
44
+ - Settle cancelled PostgreSQL resource Jobs (d4810820).
45
+ - Correct PostgreSQL Job loss capability assertion (2958562d).
46
+ - Fix outer resource logging settlement (4afe9504).
47
+ - Fix outer watchdog mutation race regression (2f849575).
48
+ - Fix authentication provider labels and migrate corrupted user rows (63d2f16a).
49
+ - Fix stale page-token recovery and bound unstable reconnects (b601a9ab).
50
+ - Repair resource constructor typing and regenerate shipped CLI fixes (98e22936).
51
+ - Fix SQLite resource review findings and document invocation boundaries (b1c0fe4b).
52
+ - Correct ticket 06 dependency metadata for resource swarm (cdba60a9).
53
+
54
+ ### 🔧 Improvements
55
+
56
+ - Reconcile monolith HTTP import census (#87) (9c897f7a).
57
+ - Reconcile HTTP runtime module census (#85) (a9a66a68).
58
+ - Keep ACL race and any fail closed (84a8fc8e).
59
+ - Clarify PostgreSQL resource evidence boundaries (abcc32e3).
60
+ - Fail closed for noneligible resource adapters (c25db850).
61
+ - Race outer resource hooks with deadline (43a99c76).
62
+ - Guard endpoint files after resource binding (bb42a116).
63
+ - Mark ticket 02 done: merged as e31b4dfe (#61) (fa640cd1).
15
64
 
16
65
  ### 📝 Documentation
17
66
 
18
- - Support additional deployment files with preserve and replace policies (#45) (9cc5bdef).
67
+ - Track request admission research (#90) (1d5f27a1).
68
+ - Reconcile HTTP re-export census (#89) (1220e9f9).
69
+ - Complete HTTP runtime caller census (#86) (0955f7c3).
70
+ - Book ticket 07 completion (32759b21).
71
+ - Verify amended Grant workflow boundaries (#76) (14eda541).
72
+ - Book ticket 06 complete (f0d905e5).
73
+ - Book ticket 05 complete (PR #74) (45258174).
74
+ - Fail closed for libSQL resource scopes (#74) (d9f036d5).
75
+ - Unblock fence tickets 05/06 after 02/04 merged (687f58d1).
76
+ - Reject partitioned PostgreSQL resource tables (f198d2de).
77
+ - Reject unexpected resource indexes (fa474fd6).
78
+ - Await Team ACL helpers (82d8b4ef).
79
+ - Configure engineering skills for GitHub issues (831fc4bf).
80
+ - Prove PostgreSQL endpoint receipt recovery (be719200).
81
+ - Complete PostgreSQL resource receipt recovery (675120bd).
82
+ - Mark ticket 03 merged and update resource fence frontier (9229ea96).
83
+ - Reconcile outer resource commits and publish logs (d033d108).
84
+ - Regenerate resource API reference (be2c0dba).
85
+ - Document outer resource transaction joining (9851aba0).
86
+ - Track unsupported notification attempts through resource rollback (8b094c59).
87
+ - Map resource connection acquisition errors and retain durable planning links (869bb009).
88
+ - Align Stripe dependency and pinned API version on 22.6.2 (2b5cc9c6).
89
+ - Expose auth.sessionToken() for same-origin public endpoints (#62) (0a87a800).
90
+ - Carry approved M1 resource transaction plan from decision PR 57 (28e95c2e).
91
+
92
+ ### 🧪 Tests
93
+
94
+ - Preserve literal HTTP request-target semantics (#83) (9b4eb84b).
95
+ - Quarantine Postgres backend on deadline cancellation (61162981).
96
+ - Bound PostgreSQL cancellation delivery (1d97423f).
97
+ - Fence cancelled Postgres queries and nested ACL promises (70f09f18).
98
+ - Bind File deletion authorization to locked metadata (d1b497ca).
99
+ - Bound PostgreSQL resource callback lock waits (709d14f2).
100
+ - Normalize PostgreSQL ACL lock contention (6c8ed5f8).
101
+ - Bound PostgreSQL ACL dependency locks (59005492).
102
+ - Bound Job resource authorization contention (1d0a407c).
103
+ - Preserve resource callback SQLSTATE errors (6cdb5476).
104
+ - Reject generated Postgres resource columns (098753ad).
105
+ - Reject unsafe Postgres resource schemas (568c50e2).
106
+ - Prove PostgreSQL resource schema publication (91ce4717).
107
+ - Census carried resource and billing modules (85285957).
108
+ - Prove resource transaction seam boundary (656bddf3).
109
+ - Cover PostgreSQL Job claim conflicts (6cd34a7f).
110
+ - Prove PostgreSQL paused-owner recovery (ec9a17e0).
111
+ - Prove PostgreSQL resource process death recovery (846fb131).
112
+ - Reset PostgreSQL commit-loss fixture (67ed81b3).
113
+ - Prove PostgreSQL commit acknowledgement loss (6d6f0c31).
114
+ - Assert revoked PostgreSQL Job scope handles (1e543513).
115
+ - Fence PostgreSQL Job claims through commit admission (951c1fd6).
116
+ - Cover PostgreSQL Job resource receipts (bb614495).
117
+ - Prove PostgreSQL resource lock contention and backend loss (c50007ab).
118
+ - Harden outer resource admission and failures (205df5da).
119
+ - Prove outer resource dispatch causally (a9c750ff).
120
+ - Poison admitted outer resource failures (4b0c7a71).
121
+ - Quarantine SQLite root after uncertain outer commit (81322daa).
122
+ - Redact postcommit resource log publication failures (76a11538).
123
+ - Keep outer cleanup watchdog coverage runtime-owned (7fbc2e19).
124
+ - Prove outer notification rejection settlement (a246cb65).
125
+ - Fence outer resource settlement and parent logging (11ab4cfe).
126
+ - Cover outer resource uncertainty across endpoints (181ad213).
127
+ - Prove outer resource commit uncertainty outcomes (fd8af841).
128
+ - Classify outer resource commit uncertainty (c5990fa3).
129
+ - Quarantine uncertain outer resource connections (a21fa98d).
130
+ - Fence outer resource middleware and commit deadline (b07bfe1e).
131
+ - Track nested resource table operations (a6285359).
132
+ - Prove watchdog reaches pending log cleanup (177d08a4).
133
+ - Make outer hook watchdog proof self-contained (e79596a2).
134
+ - Cover watchdog during resource cleanup (5de7d131).
135
+ - Assert Grant state inside protected Jobs (56342516).
136
+ - Prove joined Grant mutations across runtimes (464e69fe).
137
+ - Cover real multipart endpoint resource file guards (ab61e05a).
138
+ - Cover endpoint resource file guards (e3c71ed0).
139
+ - Cover outer resource hook deadline (0cbe976e).
140
+ - Exercise the token route in Journey reconnect integration tests (5884446a).
141
+ - Abort outer cleanup after resource deadline (8fbcab4d).
142
+ - Cover outer resource log transactions (260a9270).
143
+ - Poison caught outer resource failures (6d00d514).
144
+ - Prove membership ACL ordering across runtimes (2da4cddd).
145
+ - Prove Grant resource ordering across workers (cda02216).
146
+ - Cover endpoint resource deadline parity (62160e8e).
147
+ - Prove outer resource transaction ordering (b7c9d4e4).
148
+ - Keep outer resource deadline through transaction settlement (7ae38c07).
149
+ - WIP: fence outer resource transaction deadline (34da2523).
150
+ - WIP: join mutation and endpoint resource scopes (1092d072).
151
+ - Reconcile resource cancellation from independent runtimes (93a1442b).
152
+ - Preserve cancelled Job settlement for resource abort errors (fa2b08c3).
153
+
154
+ ### 📦 Packaging
155
+
156
+ - Bound PostgreSQL quarantine lock release (bff3a21c).
19
157
 
20
158
  ## v0.9.11 - 2026-09-02
21
159
 
@@ -114,3 +252,4 @@ generated artifacts, and documentation.
114
252
 
115
253
 
116
254
 
255
+
@@ -26829,6 +26829,28 @@ function validatePublicTreeFileSet(files) {
26829
26829
  return { ok: true, fileCount: files.length, totalBytes };
26830
26830
  }
26831
26831
 
26832
+ // src/resource-runtime.ts
26833
+ var RESOURCE_ADAPTER_SUPPORT = Object.freeze({
26834
+ sqlite: "supported",
26835
+ postgres: "supported",
26836
+ libsql: "unsupported"
26837
+ });
26838
+ var resourceAbort = Symbol("resourceAbort");
26839
+ function resourceError(code) {
26840
+ return Object.assign(new Error(code === "RESOURCE_BUSY" ? "Resource transaction is busy." : "Resource operation could not complete."), {
26841
+ code,
26842
+ ...code === "RESOURCE_BUSY" ? { retryable: true } : {}
26843
+ });
26844
+ }
26845
+ var unsupportedResources = Object.freeze({
26846
+ async run() {
26847
+ throw resourceError("RESOURCE_CONTEXT_UNSUPPORTED");
26848
+ },
26849
+ async status() {
26850
+ throw resourceError("RESOURCE_CONTEXT_UNSUPPORTED");
26851
+ }
26852
+ });
26853
+
26832
26854
  // src/log-envelope.ts
26833
26855
  import { randomUUID as randomUUID2 } from "node:crypto";
26834
26856
  function uncappedLogEnvelope(input) {
@@ -26900,6 +26922,9 @@ function isSensitiveLogKey(key) {
26900
26922
  return /(^|[-_])(?:password|passwd|token|secret|authorization|cookie|client[-_]?secret|api[-_]?token|private[-_]?key|authorized[-_]?keys?|request[-_]?body|raw[-_]?body|stack(?:trace)?)([-_]|$)/i.test(String(key)) || /(?:password|passwd|token|secret|authorization|cookie|clientSecret|apiToken|privateKey|authorizedKeys|requestBody|rawRequestBody|stackTrace)/i.test(String(key));
26901
26923
  }
26902
26924
 
26925
+ // src/promise-coordinator.ts
26926
+ var nodePromiseHooks = process.getBuiltinModule("node:v8")?.promiseHooks;
26927
+
26903
26928
  // src/acl-runtime.ts
26904
26929
  var PRIVILEGED_AUDIT_SCHEMA = "sporades.privileged-audit.v1";
26905
26930
  var PRIVILEGED_AUDIT_ACTOR_KINDS = /* @__PURE__ */ new Set(["privileged-server-role", "captured-user", "platform", "unknown"]);
@@ -26975,7 +27000,6 @@ var ACL_HELPER_STATE = Symbol("sporades.aclHelperState");
26975
27000
 
26976
27001
  // src/file-storage-runtime.ts
26977
27002
  var nodeCryptoModule2 = process.getBuiltinModule("node:crypto");
26978
- var nodePromiseHooks = process.getBuiltinModule("node:v8")?.promiseHooks;
26979
27003
 
26980
27004
  // src/file-ingress-runtime.ts
26981
27005
  var import_pdf_lib = __toESM(require_cjs(), 1);
@@ -42853,6 +42877,11 @@ var nodeCryptoModule4 = process.getBuiltinModule("node:crypto");
42853
42877
  var nodeFsModule = process.getBuiltinModule("node:fs");
42854
42878
  var transactionOperations = Symbol.for("sporades.database.transactionOperations");
42855
42879
  var transactionBeforeCommitChecks2 = Symbol.for("sporades.database.transactionBeforeCommitChecks");
42880
+ var resourceTransactionMechanics = Symbol.for("sporades.database.resourceTransactionMechanics");
42881
+ var resourceBootstrapMechanics = Symbol.for("sporades.database.resourceBootstrapMechanics");
42882
+ var resourceConsumptionMechanics = Symbol.for("sporades.database.resourceConsumptionMechanics");
42883
+ var resourceSchemaPublished = Symbol.for("sporades.database.resourceSchemaPublished");
42884
+ var resourceCancelActiveQuery = Symbol.for("sporades.database.resourceCancelActiveQuery");
42856
42885
 
42857
42886
  // src/server-runtime-source.ts
42858
42887
  var trustedReadTransactionAdapter = Symbol("sporades.trustedReadTransactionAdapter");
@@ -42956,7 +42985,7 @@ var MutationExecutionStorage = process.getBuiltinModule("node:async_hooks").Asyn
42956
42985
  var mutationExecution = new MutationExecutionStorage();
42957
42986
 
42958
42987
  // src/cli/cli-version.ts
42959
- var CLI_VERSION = "0.9.23";
42988
+ var CLI_VERSION = "0.9.26";
42960
42989
 
42961
42990
  // src/cli/schedule-inspection-envelope.ts
42962
42991
  var SCHEDULE_DIAGNOSTIC_FIELDS = /* @__PURE__ */ new Set([
@@ -43033,6 +43062,8 @@ function sanitizeScheduleInspectionEnvelope(envelope, invalid) {
43033
43062
 
43034
43063
  // src/cli/host-helper-archive.ts
43035
43064
  import { spawnSync } from "node:child_process";
43065
+ import { readFileSync } from "node:fs";
43066
+ import { gunzipSync } from "node:zlib";
43036
43067
 
43037
43068
  // src/cli/host-helper-release-files.ts
43038
43069
  function expectedReleaseFiles(release) {
@@ -43122,27 +43153,75 @@ function validateReleaseArchive(request, archivePath = request.release.remoteArc
43122
43153
  };
43123
43154
  }
43124
43155
  function listArchiveEntries(archivePath) {
43156
+ const literalMetadataEntries = inspectLiteralArchiveMetadata(archivePath);
43157
+ if (literalMetadataEntries.length > 0) {
43158
+ validateArchiveBounds(literalMetadataEntries);
43159
+ throw helperError(
43160
+ "Hosted Capsule release archive contains unsupported metadata.",
43161
+ "Push again without __MACOSX or AppleDouble metadata entries."
43162
+ );
43163
+ }
43125
43164
  const namesResult = spawnSync("tar", ["-tzf", archivePath], { encoding: "utf8" });
43126
43165
  const verboseResult = spawnSync("tar", ["-tvzf", archivePath], { encoding: "utf8" });
43166
+ const names = namesResult.stdout.trim().split("\n").filter(Boolean);
43167
+ const verboseLines = verboseResult.stdout.trim().split("\n").filter(Boolean);
43168
+ const entries = names.length === verboseLines.length ? names.map((name2, index) => ({
43169
+ name: name2,
43170
+ type: verboseLines[index]?.[0],
43171
+ size: archiveEntrySize(verboseLines[index] ?? "")
43172
+ })) : [];
43127
43173
  if (namesResult.error || namesResult.status !== 0 || verboseResult.error || verboseResult.status !== 0) {
43174
+ if (entries.some((entry) => isDiscardableArchiveMetadata(entry.name))) {
43175
+ validateArchiveBounds(entries);
43176
+ throw helperError(
43177
+ "Hosted Capsule release archive contains unsupported metadata.",
43178
+ "Push again without __MACOSX or AppleDouble metadata entries."
43179
+ );
43180
+ }
43128
43181
  throw helperError(
43129
43182
  "Failed to inspect Hosted Capsule release archive.",
43130
43183
  "Upload the release again with `sporades host push` and check that tar is installed on the Host server."
43131
43184
  );
43132
43185
  }
43133
- const names = namesResult.stdout.trim().split("\n").filter(Boolean);
43134
- const verboseLines = verboseResult.stdout.trim().split("\n").filter(Boolean);
43135
43186
  if (names.length !== verboseLines.length) {
43136
43187
  throw helperError(
43137
43188
  "Hosted Capsule release archive could not be validated.",
43138
43189
  "Push again so Sporades can package a clean runtime archive."
43139
43190
  );
43140
43191
  }
43141
- return names.map((name2, index) => ({
43142
- name: name2,
43143
- type: verboseLines[index]?.[0],
43144
- size: archiveEntrySize(verboseLines[index] ?? "")
43145
- }));
43192
+ return entries;
43193
+ }
43194
+ function inspectLiteralArchiveMetadata(archivePath) {
43195
+ let archive;
43196
+ try {
43197
+ archive = gunzipSync(readFileSync(archivePath), {
43198
+ maxOutputLength: HOST_RELEASE_ARCHIVE_LIMITS.totalBytes + (HOST_RELEASE_ARCHIVE_LIMITS.entries + 1) * 1024
43199
+ });
43200
+ } catch (error) {
43201
+ if (error?.code === "ERR_BUFFER_TOO_LARGE") {
43202
+ throw helperError("Hosted Capsule release archive exceeds bounds.", "Reduce total release bytes and push again.");
43203
+ }
43204
+ return [];
43205
+ }
43206
+ const entries = [];
43207
+ let offset2 = 0;
43208
+ while (offset2 + 512 <= archive.length) {
43209
+ const header = archive.subarray(offset2, offset2 + 512);
43210
+ if (header.every((byte) => byte === 0)) break;
43211
+ const name2 = tarHeaderText(header, 0, 100);
43212
+ const prefix = tarHeaderText(header, 345, 155);
43213
+ const sizeText = tarHeaderText(header, 124, 12).trim();
43214
+ if (!/^[0-7]+$/.test(sizeText)) return [];
43215
+ const size = Number.parseInt(sizeText, 8);
43216
+ if (!Number.isSafeInteger(size) || size < 0) return [];
43217
+ entries.push({ name: prefix ? `${prefix}/${name2}` : name2, type: String.fromCharCode(header[156] || 48) === "0" ? "-" : String.fromCharCode(header[156]) || "-", size });
43218
+ offset2 += 512 + Math.ceil(size / 512) * 512;
43219
+ }
43220
+ return entries.some((entry) => isDiscardableArchiveMetadata(entry.name)) ? entries : [];
43221
+ }
43222
+ function tarHeaderText(header, offset2, length) {
43223
+ const end = header.indexOf(0, offset2);
43224
+ return header.toString("utf8", offset2, end >= offset2 && end < offset2 + length ? end : offset2 + length);
43146
43225
  }
43147
43226
  function archiveEntrySize(line) {
43148
43227
  const bsd = line.match(/^\S+\s+\d+\s+\S+\s+\S+\s+(\d+)\s+/);