@futpib/parser 1.0.0 → 1.0.1

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 (171) hide show
  1. package/build/apk.d.ts +29 -3
  2. package/build/apkParser.d.ts +15 -2
  3. package/build/apkParser.js +70 -41
  4. package/build/apkParser.test.js +2 -2
  5. package/build/apkUnparser.d.ts +4 -0
  6. package/build/apkUnparser.js +90 -0
  7. package/build/apkUnparser.test.d.ts +1 -0
  8. package/build/apkUnparser.test.js +26 -0
  9. package/build/arbitraryFileSystemEntry.js +1 -1
  10. package/build/arbitraryZip.d.ts +1 -1
  11. package/build/arbitraryZip.js +13 -19
  12. package/build/arbitraryZipPermissions.d.ts +1 -8
  13. package/build/arbitraryZipPermissions.js +1 -16
  14. package/build/arbitraryZipStream.d.ts +1 -1
  15. package/build/arbitraryZipStream.js +3 -3
  16. package/build/arrayParser.d.ts +1 -1
  17. package/build/arrayParser.js +2 -2
  18. package/build/arrayParser.test.js +2 -2
  19. package/build/arrayUnparser.d.ts +2 -0
  20. package/build/arrayUnparser.js +8 -0
  21. package/build/bsonParser.test.js +2 -2
  22. package/build/customInvariant.d.ts +4 -0
  23. package/build/customInvariant.js +11 -0
  24. package/build/debugLogParser.d.ts +1 -1
  25. package/build/debugLogParser.js +1 -1
  26. package/build/elementParser.d.ts +2 -2
  27. package/build/elementParser.js +1 -1
  28. package/build/endOfInputParser.d.ts +2 -2
  29. package/build/exactElementParser.d.ts +1 -1
  30. package/build/exactSequenceParser.js +1 -1
  31. package/build/index.d.ts +5 -2
  32. package/build/index.js +3 -0
  33. package/build/inputReader.d.ts +3 -3
  34. package/build/inputReader.js +6 -6
  35. package/build/inputReader.test.js +7 -7
  36. package/build/javaKeyStore.d.ts +1 -0
  37. package/build/javaKeyStore.js +1 -0
  38. package/build/javaKeyStoreParser.d.ts +2 -0
  39. package/build/javaKeyStoreParser.js +67 -0
  40. package/build/javaKeyStoreParser.test.d.ts +1 -0
  41. package/build/javaKeyStoreParser.test.js +16 -0
  42. package/build/javaKeystoreParser.d.ts +2 -0
  43. package/build/javaKeystoreParser.js +7 -0
  44. package/build/jsonParser.js +3 -2
  45. package/build/jsonParser.test.js +2 -2
  46. package/build/listParser.d.ts +1 -1
  47. package/build/listParser.js +5 -5
  48. package/build/negativeLookahead.d.ts +1 -1
  49. package/build/negativeLookahead.js +16 -18
  50. package/build/negativeLookaheadParser.d.ts +2 -0
  51. package/build/negativeLookaheadParser.js +18 -0
  52. package/build/optionalParser.d.ts +1 -1
  53. package/build/optionalParser.js +2 -2
  54. package/build/parser.d.ts +3 -3
  55. package/build/parser.js +3 -3
  56. package/build/parser.test.js +16 -16
  57. package/build/parserAccessorParser.d.ts +1 -1
  58. package/build/parserConsumedSequenceParser.d.ts +2 -0
  59. package/build/parserConsumedSequenceParser.js +17 -0
  60. package/build/parserContext.d.ts +6 -6
  61. package/build/parserContext.js +15 -14
  62. package/build/parserContext.test.js +7 -7
  63. package/build/parserCreatorCompose.d.ts +3 -3
  64. package/build/parserCreatorCompose.js +2 -2
  65. package/build/parserImplementationInvariant.d.ts +1 -1
  66. package/build/parserImplementationInvariant.js +2 -2
  67. package/build/parserInputCompanion.d.ts +20 -0
  68. package/build/parserInputCompanion.js +30 -0
  69. package/build/parserInvariant.d.ts +1 -1
  70. package/build/parserInvariant.js +1 -1
  71. package/build/quantifierParser.d.ts +2 -0
  72. package/build/quantifierParser.js +17 -0
  73. package/build/sequenceBuffer.d.ts +3 -3
  74. package/build/sequenceBuffer.js +6 -6
  75. package/build/sequenceBuffer.test.js +2 -2
  76. package/build/sequenceUnparser.d.ts +2 -0
  77. package/build/sequenceUnparser.js +6 -0
  78. package/build/sliceBoundedParser.d.ts +1 -1
  79. package/build/sliceBoundedParser.js +1 -1
  80. package/build/sliceBoundedParser.test.js +2 -2
  81. package/build/terminatedArrayParser.d.ts +1 -1
  82. package/build/terminatedArrayParser.js +3 -3
  83. package/build/uint8Array.d.ts +1 -0
  84. package/build/uint8Array.js +7 -0
  85. package/build/unparser.d.ts +8 -0
  86. package/build/unparser.js +104 -0
  87. package/build/unparser.test.d.ts +1 -0
  88. package/build/unparser.test.js +150 -0
  89. package/build/unparserContext.d.ts +31 -0
  90. package/build/unparserContext.js +74 -0
  91. package/build/unparserError.d.ts +9 -0
  92. package/build/unparserError.js +9 -0
  93. package/build/unparserImplementationInvariant.d.ts +2 -0
  94. package/build/unparserImplementationInvariant.js +5 -0
  95. package/build/unparserInputCompanion.d.ts +15 -0
  96. package/build/unparserInputCompanion.js +13 -0
  97. package/build/unparserOutputCompanion.d.ts +15 -0
  98. package/build/unparserOutputCompanion.js +13 -0
  99. package/build/zip.d.ts +9 -17
  100. package/build/zipParser.d.ts +13 -10
  101. package/build/zipParser.js +48 -60
  102. package/build/zipParser.test.js +2 -7
  103. package/build/zipUnparser.d.ts +5 -0
  104. package/build/zipUnparser.js +171 -0
  105. package/build/zipUnparser.test.d.ts +1 -0
  106. package/build/zipUnparser.test.js +80 -0
  107. package/package.json +4 -2
  108. package/src/apk.ts +35 -3
  109. package/src/apkParser.test.ts +2 -2
  110. package/src/apkParser.test.ts.md +114 -111
  111. package/src/apkParser.test.ts.snap +0 -0
  112. package/src/apkParser.ts +150 -85
  113. package/src/apkUnparser.test.ts +37 -0
  114. package/src/apkUnparser.ts +120 -0
  115. package/src/arbitraryFileSystemEntry.ts +2 -4
  116. package/src/arbitraryZip.ts +20 -27
  117. package/src/arbitraryZipPermissions.ts +0 -25
  118. package/src/arbitraryZipStream.ts +4 -4
  119. package/src/arrayParser.test.ts +3 -3
  120. package/src/arrayParser.ts +3 -2
  121. package/src/arrayUnparser.ts +13 -0
  122. package/src/bsonParser.test.ts +2 -2
  123. package/src/bsonParser.ts +3 -3
  124. package/src/{parserInvariant.ts → customInvariant.ts} +1 -1
  125. package/src/debugLogParser.ts +1 -1
  126. package/src/elementParser.ts +3 -3
  127. package/src/endOfInputParser.ts +4 -4
  128. package/src/exactElementParser.ts +1 -1
  129. package/src/exactSequenceParser.ts +2 -2
  130. package/src/index.ts +15 -2
  131. package/src/inputReader.test.ts +7 -7
  132. package/src/inputReader.ts +5 -5
  133. package/src/javaKeyStore.ts +0 -0
  134. package/src/javaKeyStoreParser.test.ts +23 -0
  135. package/src/javaKeyStoreParser.test.ts.md +103 -0
  136. package/src/javaKeyStoreParser.test.ts.snap +0 -0
  137. package/src/javaKeyStoreParser.ts +136 -0
  138. package/src/jsonParser.test.ts +2 -2
  139. package/src/jsonParser.ts +13 -12
  140. package/src/listParser.ts +6 -6
  141. package/src/negativeLookaheadParser.ts +24 -0
  142. package/src/optionalParser.ts +3 -3
  143. package/src/parser.test.ts +19 -17
  144. package/src/parser.ts +7 -7
  145. package/src/parserAccessorParser.ts +1 -1
  146. package/src/parserConsumedSequenceParser.ts +20 -0
  147. package/src/parserContext.test.ts +7 -7
  148. package/src/parserContext.ts +18 -14
  149. package/src/parserCreatorCompose.ts +6 -6
  150. package/src/parserImplementationInvariant.ts +2 -2
  151. package/src/{inputCompanion.ts → parserInputCompanion.ts} +10 -6
  152. package/src/quantifierParser.ts +25 -0
  153. package/src/sequenceBuffer.test.ts +2 -2
  154. package/src/sequenceBuffer.ts +5 -5
  155. package/src/sequenceUnparser.ts +9 -0
  156. package/src/sliceBoundedParser.test.ts +2 -2
  157. package/src/sliceBoundedParser.ts +2 -2
  158. package/src/terminatedArrayParser.ts +3 -3
  159. package/src/uint8Array.ts +10 -0
  160. package/src/unparser.test.ts +221 -0
  161. package/src/unparser.ts +209 -0
  162. package/src/unparserContext.ts +127 -0
  163. package/src/unparserError.ts +12 -0
  164. package/src/unparserImplementationInvariant.ts +6 -0
  165. package/src/unparserOutputCompanion.ts +24 -0
  166. package/src/zip.ts +10 -22
  167. package/src/zipParser.test.ts +2 -8
  168. package/src/zipParser.ts +147 -129
  169. package/src/zipUnparser.test.ts +119 -0
  170. package/src/zipUnparser.ts +239 -0
  171. package/src/negativeLookahead.ts +0 -26
@@ -1,17 +1,12 @@
1
1
  import { testProp } from '@fast-check/ava';
2
2
  import { arbitraryZipStream } from './arbitraryZipStream.js';
3
3
  import { zipParser } from './zipParser.js';
4
- import { uint8ArrayInputCompanion } from './inputCompanion.js';
4
+ import { uint8ArrayParserInputCompanion } from './parserInputCompanion.js';
5
5
  import { runParser } from './parser.js';
6
- async function* readableStreamToUint8ArrayAsyncIterator(stream) {
7
- for await (const chunk of stream) {
8
- yield chunk;
9
- }
10
- }
11
6
  testProp('zip', [
12
7
  arbitraryZipStream,
13
8
  ], async (t, [zip, zipStream]) => {
14
- const actual = await runParser(zipParser, readableStreamToUint8ArrayAsyncIterator(zipStream), uint8ArrayInputCompanion, {
9
+ const actual = await runParser(zipParser, zipStream, uint8ArrayParserInputCompanion, {
15
10
  errorJoinMode: 'all',
16
11
  });
17
12
  actual.entries.sort((a, b) => a.path.localeCompare(b.path));
@@ -0,0 +1,5 @@
1
+ import { Unparser } from "./unparser.js";
2
+ import { Zip } from "./zip.js";
3
+ import { ZipEndOfCentralDirectoryRecord } from './zipParser.js';
4
+ export declare const zipEndOfCentralDirectoryRecordUnparser: Unparser<ZipEndOfCentralDirectoryRecord, Uint8Array>;
5
+ export declare const zipUnparser: Unparser<Zip, Uint8Array>;
@@ -0,0 +1,171 @@
1
+ import zlib from 'node:zlib';
2
+ import { Readable } from 'node:stream';
3
+ import { pipeline } from 'node:stream/promises';
4
+ import { uint8ArrayAsyncIterableToUint8Array } from './uint8Array.js';
5
+ const uint16LEUnparser = async function* (uint16LE) {
6
+ const buffer = Buffer.alloc(2);
7
+ buffer.writeUInt16LE(uint16LE);
8
+ yield buffer;
9
+ };
10
+ const uint32LEUnparser = async function* (uint32LE) {
11
+ const buffer = Buffer.alloc(4);
12
+ buffer.writeUInt32LE(uint32LE);
13
+ yield buffer;
14
+ };
15
+ const uint16LEPrefixedUint8ArrayUnparser = async function* (uint8Array, unparserContext) {
16
+ yield* uint16LEUnparser(uint8Array.length, unparserContext);
17
+ yield uint8Array;
18
+ };
19
+ const uint16LEPrefixedStringUnparser = async function* (string, unparserContext) {
20
+ yield* uint16LEPrefixedUint8ArrayUnparser(Buffer.from(string, 'utf8'), unparserContext);
21
+ };
22
+ const dosDateTimeUnparser = async function* (date, unparserContext) {
23
+ yield* uint16LEUnparser((date.getUTCSeconds() / 2
24
+ | date.getUTCMinutes() << 5
25
+ | date.getUTCHours() << 11), unparserContext);
26
+ yield* uint16LEUnparser((date.getUTCDate()
27
+ | (date.getUTCMonth() + 1) << 5
28
+ | (date.getUTCFullYear() - 1980) << 9), unparserContext);
29
+ };
30
+ const zipCompressionMethodUnparser = async function* (compressionMethod, unparserContext) {
31
+ if (compressionMethod === 'store') {
32
+ yield* uint16LEUnparser(0, unparserContext);
33
+ }
34
+ else {
35
+ yield* uint16LEUnparser(8, unparserContext);
36
+ }
37
+ };
38
+ export const zipEndOfCentralDirectoryRecordUnparser = async function* (zipEndOfCentralDirectoryRecord, unparserContext) {
39
+ yield Buffer.from('504b0506', 'hex');
40
+ yield* uint16LEUnparser(zipEndOfCentralDirectoryRecord.numberOfThisDisk, unparserContext);
41
+ yield* uint16LEUnparser(zipEndOfCentralDirectoryRecord.numberOfTheDiskWithTheStartOfTheCentralDirectory, unparserContext);
42
+ yield* uint16LEUnparser(zipEndOfCentralDirectoryRecord.totalNumberOfEntriesInTheCentralDirectoryOnThisDisk, unparserContext);
43
+ yield* uint16LEUnparser(zipEndOfCentralDirectoryRecord.totalNumberOfEntriesInTheCentralDirectory, unparserContext);
44
+ yield* uint32LEUnparser(zipEndOfCentralDirectoryRecord.sizeOfTheCentralDirectory, unparserContext);
45
+ yield* uint32LEUnparser(zipEndOfCentralDirectoryRecord.offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber, unparserContext);
46
+ yield* uint16LEPrefixedStringUnparser(zipEndOfCentralDirectoryRecord.zipFileComment, unparserContext);
47
+ };
48
+ export const zipUnparser = async function* (zip, unparserContext) {
49
+ const compressedContentByZipFileEntry = new Map(zip.entries.flatMap(zipEntry => {
50
+ if (zipEntry.type !== 'file') {
51
+ return [];
52
+ }
53
+ if (zipEntry.compression === 'store') {
54
+ return [[zipEntry, Promise.resolve(zipEntry.content)]];
55
+ }
56
+ const uncompressedContent = zipEntry.content;
57
+ const deflate = zlib.createDeflateRaw();
58
+ const input = Readable.from(Buffer.from(uncompressedContent));
59
+ const promise = Promise.all([
60
+ pipeline(input, deflate),
61
+ uint8ArrayAsyncIterableToUint8Array(deflate),
62
+ ]);
63
+ return [[zipEntry, promise.then(([, compressedContent]) => compressedContent)]];
64
+ }));
65
+ const filePathByZipEntry = new Map(zip.entries.map(zipEntry => [zipEntry, zipEntry.type === 'file' ? zipEntry.path : zipEntry.path + '/']));
66
+ const localHeaderPositionByZipEntry = new Map();
67
+ for (const zipEntry of zip.entries) {
68
+ localHeaderPositionByZipEntry.set(zipEntry, unparserContext.position);
69
+ yield Buffer.from('504b0304', 'hex');
70
+ yield* uint16LEUnparser(10, unparserContext); // version needed to extract
71
+ yield* uint16LEUnparser(0, unparserContext); // general purpose bit flag
72
+ if (zipEntry.type === 'file') {
73
+ yield* zipCompressionMethodUnparser(zipEntry.compression, unparserContext);
74
+ }
75
+ else {
76
+ yield* uint16LEUnparser(0, unparserContext);
77
+ }
78
+ yield* dosDateTimeUnparser(zipEntry.date, unparserContext);
79
+ if (zipEntry.type === 'file') {
80
+ const compressedContent = await compressedContentByZipFileEntry.get(zipEntry);
81
+ yield* uint32LEUnparser(0, unparserContext); // crc32 // TODO
82
+ yield* uint32LEUnparser(compressedContent.length, unparserContext);
83
+ yield* uint32LEUnparser(zipEntry.content.length, unparserContext);
84
+ }
85
+ else {
86
+ yield* uint32LEUnparser(0, unparserContext);
87
+ yield* uint32LEUnparser(0, unparserContext);
88
+ yield* uint32LEUnparser(0, unparserContext);
89
+ }
90
+ const filePath = filePathByZipEntry.get(zipEntry);
91
+ const filePathBuffer = Buffer.from(filePath, 'utf8');
92
+ const extraFieldBuffer = Buffer.alloc(0);
93
+ yield* uint16LEUnparser(filePathBuffer.length, unparserContext);
94
+ yield* uint16LEUnparser(extraFieldBuffer.length, unparserContext);
95
+ yield filePathBuffer;
96
+ yield extraFieldBuffer;
97
+ if (zipEntry.type === 'file') {
98
+ const compressedContent = await compressedContentByZipFileEntry.get(zipEntry);
99
+ yield compressedContent;
100
+ }
101
+ }
102
+ const startOfCentralDirectoryPosition = unparserContext.position;
103
+ for (const zipEntry of zip.entries) {
104
+ yield Buffer.from('504b0102', 'hex');
105
+ if (zipEntry.hostSystem === 'unix') {
106
+ yield 0; // zip specification version
107
+ yield 3; // host system
108
+ }
109
+ else {
110
+ yield 0;
111
+ yield 0;
112
+ }
113
+ yield* uint16LEUnparser(0, unparserContext); // version needed to extract
114
+ yield* uint16LEUnparser(0, unparserContext); // general purpose bit flag
115
+ if (zipEntry.type === 'file') {
116
+ yield* zipCompressionMethodUnparser(zipEntry.compression, unparserContext);
117
+ }
118
+ else {
119
+ yield* uint16LEUnparser(0, unparserContext);
120
+ }
121
+ yield* dosDateTimeUnparser(zipEntry.date, unparserContext);
122
+ if (zipEntry.type === 'file') {
123
+ const compressedContent = await compressedContentByZipFileEntry.get(zipEntry);
124
+ yield* uint32LEUnparser(0, unparserContext); // crc32 // TODO
125
+ yield* uint32LEUnparser(compressedContent.length, unparserContext);
126
+ yield* uint32LEUnparser(zipEntry.content.length, unparserContext);
127
+ }
128
+ else {
129
+ yield* uint32LEUnparser(0, unparserContext);
130
+ yield* uint32LEUnparser(0, unparserContext);
131
+ yield* uint32LEUnparser(0, unparserContext);
132
+ }
133
+ const filePath = filePathByZipEntry.get(zipEntry);
134
+ const filePathBuffer = Buffer.from(filePath, 'utf8');
135
+ yield* uint16LEUnparser(filePathBuffer.length, unparserContext);
136
+ const extraFieldBuffer = Buffer.alloc(0);
137
+ yield* uint16LEUnparser(extraFieldBuffer.length, unparserContext);
138
+ const fileCommentBuffer = Buffer.from(zipEntry.comment, 'utf8');
139
+ yield* uint16LEUnparser(fileCommentBuffer.length, unparserContext);
140
+ yield* uint16LEUnparser(0, unparserContext); // disk number start
141
+ yield* uint16LEUnparser(0, unparserContext); // internal file attributes
142
+ if (zipEntry.hostSystem === 'unix') {
143
+ yield* uint32LEUnparser((0
144
+ | (zipEntry.type === 'directory'
145
+ ? (0b0100_0000_0000_0000 << 16)
146
+ : (0b1000_0000_0000_0000 << 16))) >>> 0, unparserContext);
147
+ }
148
+ else {
149
+ yield* uint32LEUnparser((0
150
+ | (zipEntry.type === 'directory'
151
+ ? 0b0001_0000
152
+ : 0)), unparserContext);
153
+ }
154
+ const localHeaderPosition = localHeaderPositionByZipEntry.get(zipEntry);
155
+ yield* uint32LEUnparser(localHeaderPosition, unparserContext);
156
+ yield filePathBuffer;
157
+ yield extraFieldBuffer;
158
+ yield fileCommentBuffer;
159
+ }
160
+ const endOfCentralDirectoryPosition = unparserContext.position;
161
+ const sizeOfTheCentralDirectory = endOfCentralDirectoryPosition - startOfCentralDirectoryPosition;
162
+ yield* zipEndOfCentralDirectoryRecordUnparser({
163
+ numberOfThisDisk: 0,
164
+ numberOfTheDiskWithTheStartOfTheCentralDirectory: 0,
165
+ totalNumberOfEntriesInTheCentralDirectoryOnThisDisk: zip.entries.length,
166
+ totalNumberOfEntriesInTheCentralDirectory: zip.entries.length,
167
+ sizeOfTheCentralDirectory,
168
+ offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber: startOfCentralDirectoryPosition,
169
+ zipFileComment: zip.comment,
170
+ }, unparserContext);
171
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,80 @@
1
+ import { testProp } from '@fast-check/ava';
2
+ import { temporaryFile } from 'tempy';
3
+ import { execa } from 'execa';
4
+ import fsPromises from 'node:fs/promises';
5
+ import { runUnparser } from './unparser.js';
6
+ import { zipUnparser } from './zipUnparser.js';
7
+ import { uint8ArrayUnparserOutputCompanion } from './unparserOutputCompanion.js';
8
+ import { runParser } from './parser.js';
9
+ import { zipParser } from './zipParser.js';
10
+ import { uint8ArrayParserInputCompanion } from './parserInputCompanion.js';
11
+ import { arbitraryZip } from './arbitraryZip.js';
12
+ async function hasExecutable(executable) {
13
+ const hasExecutable = execa(executable).then(() => true, () => false);
14
+ if (!hasExecutable) {
15
+ console.warn(`Executable %o not found`, executable);
16
+ }
17
+ return hasExecutable;
18
+ }
19
+ const hasZipinfoPromise = hasExecutable('zipinfo');
20
+ const has7zPromise = hasExecutable('7z');
21
+ async function zipinfo(zipFilePath) {
22
+ const { stdout } = await execa('zipinfo', [
23
+ '-v',
24
+ zipFilePath,
25
+ ], {
26
+ reject: false,
27
+ });
28
+ return {
29
+ isEmptyZipfile: stdout.endsWith('Empty zipfile.'),
30
+ };
31
+ }
32
+ async function _7zList(zipFilePath) {
33
+ const { stdout } = await execa('7z', [
34
+ 'l',
35
+ zipFilePath,
36
+ ], {
37
+ reject: false,
38
+ });
39
+ if (/Errors: \d+$/.test(stdout)) {
40
+ throw new Error(`7z reports errors: ${stdout}`);
41
+ }
42
+ return {
43
+ isEmptyZipfile: false, // TODO
44
+ };
45
+ }
46
+ testProp('zip', [
47
+ arbitraryZip,
48
+ ], async (t, zip) => {
49
+ const actualStream = runUnparser(zipUnparser, zip, uint8ArrayUnparserOutputCompanion);
50
+ const actual = await runParser(zipParser, actualStream, uint8ArrayParserInputCompanion);
51
+ const isDeepEqual = t.deepEqual(actual, zip);
52
+ if (!isDeepEqual) {
53
+ return;
54
+ }
55
+ const hasZipinfo = await hasZipinfoPromise;
56
+ const has7z = await has7zPromise;
57
+ if (!hasZipinfo && !has7z) {
58
+ return;
59
+ }
60
+ const temporaryFilePath = temporaryFile({
61
+ extension: 'zip',
62
+ });
63
+ const zipStream = runUnparser(zipUnparser, zip, uint8ArrayUnparserOutputCompanion);
64
+ await fsPromises.writeFile(temporaryFilePath, zipStream);
65
+ if (has7z) {
66
+ const { isEmptyZipfile, } = await _7zList(temporaryFilePath);
67
+ if (isEmptyZipfile) {
68
+ t.deepEqual(actual.entries, [], '7z reports the zipfile as empty, but it has entries');
69
+ }
70
+ }
71
+ if (hasZipinfo) {
72
+ const { isEmptyZipfile, } = await zipinfo(temporaryFilePath);
73
+ if (isEmptyZipfile) {
74
+ t.deepEqual(actual.entries.filter(entry => entry.type === 'file'), [], 'zipinfo reports the zipfile as empty, but it has file entries');
75
+ }
76
+ }
77
+ await fsPromises.unlink(temporaryFilePath);
78
+ }, {
79
+ verbose: true,
80
+ });
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@futpib/parser",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "main": "build/index.js",
5
5
  "license": "GPL-3.0-only",
6
6
  "type": "module",
7
7
  "scripts": {
8
8
  "dev": "tsc --watch",
9
9
  "build": "tsc",
10
- "test": "xo && c8 ava",
10
+ "test": "c8 ava",
11
11
  "prepack": "yarn build"
12
12
  },
13
13
  "homepage": "https://github.com/futpib/parser",
@@ -30,9 +30,11 @@
30
30
  "c8": "^10.1.2",
31
31
  "coveralls": "^3.1.1",
32
32
  "eslint-config-xo-typescript-overrides": "^1.6.1",
33
+ "execa": "^9.5.2",
33
34
  "fast-check": "^3.23.1",
34
35
  "invariant": "^2.2.4",
35
36
  "jszip": "^3.10.1",
37
+ "tempy": "^3.1.0",
36
38
  "type-fest": "^4.29.0",
37
39
  "typescript": "^5.7.2",
38
40
  "xo": "^0.59.3"
package/src/apk.ts CHANGED
@@ -1,14 +1,46 @@
1
- import { Zip } from './zip.js';
1
+ import { type Zip } from './zip.js';
2
2
 
3
3
  export type ApkSigningBlockPair = {
4
4
  id: number;
5
5
  value: Uint8Array;
6
6
  };
7
7
 
8
- export type ApkSigningBlock = {
8
+ export type ApkSignatureV2Digest = {
9
+ signatureAlgorithmId: number;
10
+ digest: Uint8Array;
11
+ };
12
+
13
+ export type ApkSignatureV2AdditionalAttribute = {
14
+ id: number;
15
+ value: Uint8Array;
16
+ };
17
+
18
+ export type ApkSignatureV2SignedData = {
19
+ digests: ApkSignatureV2Digest[];
20
+ certificates: Uint8Array[];
21
+ additionalAttributes: ApkSignatureV2AdditionalAttribute[];
9
22
  zeroPaddingLength?: number;
10
- signatureV2?: unknown;
23
+ };
24
+
25
+ export type ApkSignatureV2Signature = {
26
+ signatureAlgorithmId: number;
27
+ signature: Uint8Array;
28
+ };
29
+
30
+ export type ApkSignatureV2Signer = {
31
+ signedData: ApkSignatureV2SignedData;
32
+ signatures: ApkSignatureV2Signature[];
33
+ publicKey: Uint8Array;
34
+ };
35
+
36
+ export type ApkSignatureV2 = {
37
+ signers: ApkSignatureV2Signer[];
38
+ };
39
+
40
+ export type ApkSigningBlock = {
11
41
  pairs: ApkSigningBlockPair[];
42
+ signatureV2?: ApkSignatureV2;
43
+ zeroPaddingLength?: number;
12
44
  };
13
45
 
14
46
  export type Apk = Zip & {
@@ -1,5 +1,5 @@
1
1
  import test from 'ava';
2
- import { uint8ArrayInputCompanion } from './inputCompanion.js';
2
+ import { uint8ArrayParserInputCompanion } from './parserInputCompanion.js';
3
3
  import { runParser } from './parser.js';
4
4
  import { apkParser } from './apkParser.js';
5
5
 
@@ -14,7 +14,7 @@ for (const apkCid of [
14
14
 
15
15
  const apkStream = apkResponse.body!;
16
16
 
17
- const actual = await runParser(apkParser, apkStream, uint8ArrayInputCompanion, {
17
+ const actual = await runParser(apkParser, apkStream, uint8ArrayParserInputCompanion, {
18
18
  errorJoinMode: 'all',
19
19
  });
20
20