pack-crx 1.0.1 → 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
@@ -16,15 +16,15 @@ import { serve, type ServeOptions } from "bun";
16
16
  import { constants, writeFile } from "node:fs/promises";
17
17
 
18
18
  const {
19
- crx,
20
- id: crxId,
21
- manifest,
22
- rsa
19
+ crx,
20
+ id: crxId,
21
+ manifest,
22
+ rsa,
23
23
  } = await pack({
24
- contents: "./extension", // path to extension root
25
- privateKey: "./key.pem", // path to key (if it doesn't exist, that's fine)
26
- crx: null,
27
- id: null
24
+ contents: "./extension", // path to extension root
25
+ privateKey: "./key.pem", // path to key (if it doesn't exist, that's fine)
26
+ crx: null,
27
+ id: null,
28
28
  });
29
29
 
30
30
  // Write the CRX
@@ -32,25 +32,35 @@ await writeFile("./extension.crx", crx);
32
32
 
33
33
  // Write the private key unless it already exists
34
34
  try {
35
- await writeFile("./key.pem", rsa.exportKey("pkcs8-private-pem"), {flag: constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY});
35
+ await writeFile("./key.pem", rsa.exportKey("pkcs8-private-pem"), {
36
+ flag: constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY,
37
+ });
36
38
  } catch (e) {}
37
39
 
38
40
  let updateXML: string;
39
41
 
40
42
  // Serve the extension (optional)
41
43
  const server = serve({
42
- fetch(request, server) {
43
- const url = new URL(request.url);
44
- if (url.pathname.startsWith("/updates.xml")) {
45
- updateXML ??= generateUpdateXML(crxId, server.url.toString() + "extension.crx", manifest.version);
46
- return new Response(updateXML, {headers: {"Content-Type": "application/xml"}});
47
- } else if (url.pathname.startsWith("/extension.crx")) {
48
- return new Response(crx, {headers: {"Content-Type": "application/x-chrome-extension"}});
49
- }
50
- return new Response(undefined, {status: 404, statusText: "Not Found"});
51
- },
52
- port: 3000,
53
- hostname: "localhost"
44
+ fetch(request, server) {
45
+ const url = new URL(request.url);
46
+ if (url.pathname.startsWith("/updates.xml")) {
47
+ updateXML ??= generateUpdateXML(
48
+ crxId,
49
+ server.url.toString() + "extension.crx",
50
+ manifest.version,
51
+ );
52
+ return new Response(updateXML, {
53
+ headers: { "Content-Type": "application/xml" },
54
+ });
55
+ } else if (url.pathname.startsWith("/extension.crx")) {
56
+ return new Response(crx, {
57
+ headers: { "Content-Type": "application/x-chrome-extension" },
58
+ });
59
+ }
60
+ return new Response(undefined, { status: 404, statusText: "Not Found" });
61
+ },
62
+ port: 3000,
63
+ hostname: "localhost",
54
64
  } as ServeOptions);
55
65
 
56
66
  console.log(`Server opened at ${server.url}`);
@@ -69,7 +79,7 @@ The easiest way to use this package is through the default export, `pack`.
69
79
  <!-- It is highly recommended to turn off line wrapping while editing this table -->
70
80
 
71
81
  | Name | Type (also can be `undefined`) | Description | Auto-generation notes |
72
- |--------------------|----------------------------------|-------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------|
82
+ | ------------------ | -------------------------------- | ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
73
83
  | `contents` | `Uint8Array` or `string` | The ZIP archive of the contents of the extension, or a path to the folder containing the extension. | Cannot be auto-generated |
74
84
  | `privateKey` | `Uint8Array`, `string` or `null` | The private key for the extension, or a path to it. | If loading from a string, the contents should be in pkcs8-pem if the path ends in `.pem`. |
75
85
  | `keySize` | `number` | The size of key to generate, if needed. | No dependencies, defaults to 4096 |
@@ -92,12 +102,16 @@ If `privateKey` or `publicKey` are strings, `pack` will load the file at each pa
92
102
 
93
103
  `pack` always returns a `Promise`, even if all of the operations inside are synchronous.
94
104
 
95
- However, the return result is the same object as the input - just with the properties modified - so if you *really* want synchronous operations, you can keep a reference to the input object, call the function, and access the synchronous results from that object. Just make sure you don't set `privateKey` or `manifest` to `null` or `contents` to a string, otherwise some of your values might not arrive synchronously.
105
+ However, the return result is the same object as the input - just with the properties modified - so if you _really_ want synchronous operations, you can keep a reference to the input object, call the function, and access the synchronous results from that object. Just make sure you don't set `privateKey` or `manifest` to `null` or `contents` to a string, otherwise some of your values might not arrive synchronously.
96
106
 
97
107
  ### packCrx3
98
108
 
99
109
  ```ts
100
- function packCrx3(privateKey: Uint8Array, publicKey: Uint8Array, contents: Uint8Array): Uint8Array
110
+ function packCrx3(
111
+ privateKey: Uint8Array,
112
+ publicKey: Uint8Array,
113
+ contents: Uint8Array,
114
+ ): Uint8Array;
101
115
  ```
102
116
 
103
117
  Pack a CRX3 extension.
@@ -111,7 +125,11 @@ Pack a CRX3 extension.
111
125
  ### packCrx2 (deprecated)
112
126
 
113
127
  ```ts
114
- function packCrx2(privateKey: Uint8Array, publicKey: Uint8Array, contents: Uint8Array): Uint8Array
128
+ function packCrx2(
129
+ privateKey: Uint8Array,
130
+ publicKey: Uint8Array,
131
+ contents: Uint8Array,
132
+ ): Uint8Array;
115
133
  ```
116
134
 
117
135
  Pack a CRX2 extension. Chrome stopped supporting these entirely in version 73.0.3683, which released in October of 2017.
@@ -125,7 +143,7 @@ Pack a CRX2 extension. Chrome stopped supporting these entirely in version 73.0.
125
143
  ### generateCrxId
126
144
 
127
145
  ```ts
128
- function generateCrxId(publicKey: Uint8Array): string
146
+ function generateCrxId(publicKey: Uint8Array): string;
129
147
  ```
130
148
 
131
149
  Generate an extension's ID (32 characters, a-p) from its public key.
@@ -137,21 +155,29 @@ Generate an extension's ID (32 characters, a-p) from its public key.
137
155
  ### packContents
138
156
 
139
157
  ```ts
140
- function packContents(where: string): Promise<{contents: Uint8Array, manifest: ChromeManifest}>
158
+ function packContents(
159
+ where: string,
160
+ ): Promise<{ contents: Uint8Array; manifest: ChromeManifest }>;
141
161
  ```
142
162
 
143
163
  Load a directory from the filesystem into a ZIP archive, using the node:fs API.
144
164
 
145
165
  (param) `where` (`string`) - The path to the directory.
146
166
 
147
- (returns) `object`
148
- * `contents` (`Uint8Array`) - The ZIP-encoded data.
149
- * `manifest` (`ChromeManifest`) - The manifest for the extension, parsed as JSON.
167
+ (returns) `object`
168
+
169
+ - `contents` (`Uint8Array`) - The ZIP-encoded data.
170
+ - `manifest` (`ChromeManifest`) - The manifest for the extension, parsed as JSON.
150
171
 
151
172
  ### generateUpdateXML
152
173
 
153
174
  ```ts
154
- function generateUpdateXML(crxId: string, url: string, version: string, minChromeVersion?: string): string
175
+ function generateUpdateXML(
176
+ crxId: string,
177
+ url: string,
178
+ version: string,
179
+ minChromeVersion?: string,
180
+ ): string;
155
181
  ```
156
182
 
157
183
  Generate the updates XML file for [serving an extension yourself](https://developer.chrome.com/docs/extensions/how-to/distribute/host-on-linux).
@@ -166,7 +192,7 @@ Generate the updates XML file for [serving an extension yourself](https://develo
166
192
  ### unpack
167
193
 
168
194
  ```ts
169
- function unpack(crx: Uint8Array): Uint8Array
195
+ function unpack(crx: Uint8Array): Uint8Array;
170
196
  ```
171
197
 
172
198
  Unpack a CRX file and extract its contents as ZIP data.
@@ -174,10 +200,11 @@ Unpack a CRX file and extract its contents as ZIP data.
174
200
  (param) `crx` (`Uint8Array`) - The CRX to be unpacked.
175
201
 
176
202
  (returns) `object`
203
+
177
204
  - `archive` (`Uint8Array`) - The ZIP data.
178
205
  - `crxVersion` (`3`) - The CRX format version.
179
206
  - `header` (`CrxFileHeader`) - The header for the CRX file, for signatures and things.
180
- OR
207
+ OR
181
208
  - `archive` (`Uint8Array`) - The ZIP data.
182
209
  - `crxVersion` (`2`) - The CRX format version.
183
210
  - `key` (`Uint8Array`) - The extension's public key.
@@ -188,10 +215,10 @@ OR
188
215
  The following functions are self-explanatory:
189
216
 
190
217
  ```ts
191
- function generatePrivateKey(bits?: number): Uint8Array
192
- function generatePublicKey(privateKey: Uint8Array): Uint8Array
193
- function convertToPem(key: Uint8Array, type: "private" | "public"): string
194
- function convertFromPem(key: string, type: "private" | "public"): Uint8Array
218
+ function generatePrivateKey(bits?: number): Uint8Array;
219
+ function generatePublicKey(privateKey: Uint8Array): Uint8Array;
220
+ function convertToPem(key: Uint8Array, type: "private" | "public"): string;
221
+ function convertFromPem(key: string, type: "private" | "public"): Uint8Array;
195
222
  ```
196
223
 
197
- However, they all create new NodeRSA instances which are immediately discarded, so it is recommended to make your own RSA instance (or use the one from `pack`) and its methods to export/import keys.
224
+ However, they all create new NodeRSA instances which are immediately discarded, so it is recommended to make your own RSA instance (or use the one from `pack`) and its methods to export/import keys.
@@ -0,0 +1,15 @@
1
+ export namespace CrxFileHeader {
2
+ function read(pbf: any, end: any): any;
3
+ function _readField(tag: any, obj: any, pbf: any): void;
4
+ function write(obj: any, pbf: any): void;
5
+ }
6
+ export namespace AsymmetricKeyProof {
7
+ function read(pbf: any, end: any): any;
8
+ function _readField(tag: any, obj: any, pbf: any): void;
9
+ function write(obj: any, pbf: any): void;
10
+ }
11
+ export namespace SignedData {
12
+ function read(pbf: any, end: any): any;
13
+ function _readField(tag: any, obj: any, pbf: any): void;
14
+ function write(obj: any, pbf: any): void;
15
+ }
@@ -0,0 +1,354 @@
1
+ import RSA from "node-rsa";
2
+ interface ChromeBaseManifest {
3
+ manifest_version: number;
4
+ name: string;
5
+ version: string;
6
+ description?: string;
7
+ icons?: {
8
+ [x: `${number}`]: string;
9
+ };
10
+ author?: string;
11
+ background?: {
12
+ service_worker?: string;
13
+ type?: "module";
14
+ };
15
+ chrome_settings_overrides?: {
16
+ alternate_urls?: string[];
17
+ encoding?: string;
18
+ favicon_url?: string;
19
+ homepage?: string;
20
+ image_url?: string;
21
+ image_url_post_params?: string;
22
+ is_default?: boolean;
23
+ keyword?: string;
24
+ name?: string;
25
+ prepopulated_id?: number;
26
+ search_provider?: object;
27
+ search_url?: string;
28
+ search_url_post_params?: string;
29
+ startup_pages?: string[];
30
+ suggest_url?: string;
31
+ suggest_url_post_params?: string;
32
+ };
33
+ chrome_url_overrides?: {
34
+ bookmarks?: string;
35
+ history?: string;
36
+ newtab?: string;
37
+ };
38
+ commands?: {
39
+ [x: string]: {
40
+ description: string;
41
+ suggested_key?: string;
42
+ };
43
+ };
44
+ content_scripts?: {
45
+ matches: string[];
46
+ css?: string[];
47
+ js?: string[];
48
+ run_at?: "document_start" | "document_end" | "document_idle";
49
+ match_about_blank?: boolean;
50
+ match_origin_as_fallback?: boolean;
51
+ world?: "ISOLATED" | "MAIN";
52
+ }[];
53
+ content_security_policy?: {
54
+ extension_pages?: string;
55
+ sandbox?: string;
56
+ };
57
+ cross_origin_embedder_policy?: string;
58
+ cross_origin_opener_policy?: string;
59
+ declarative_net_request?: {
60
+ rule_resources?: {
61
+ id: string;
62
+ enabled: boolean;
63
+ path: string;
64
+ }[];
65
+ };
66
+ default_locale?: string;
67
+ devtools_page?: string;
68
+ export?: {
69
+ allowlist?: string[];
70
+ };
71
+ externally_connectable?: {
72
+ ids?: string[];
73
+ matches?: string[];
74
+ accepts_tls_channel_id?: boolean;
75
+ };
76
+ homepage_url?: string;
77
+ host_permissions?: string[];
78
+ import?: {
79
+ id: string;
80
+ minimum_version?: string;
81
+ }[];
82
+ incognito?: "spanning" | "split" | "not_allowed";
83
+ key?: string;
84
+ minimum_chrome_version?: string;
85
+ oauth2?: {
86
+ client_id: string;
87
+ scopes: string[];
88
+ };
89
+ omnibox?: {
90
+ keyword?: string;
91
+ };
92
+ optional_host_permissions?: string[];
93
+ optional_permissions?: string[];
94
+ options_page?: string;
95
+ options_ui?: {
96
+ page: string;
97
+ open_in_tab?: boolean;
98
+ };
99
+ permissions?: string[];
100
+ requirements?: {
101
+ [x: string]: {
102
+ features: string[];
103
+ };
104
+ };
105
+ sandbox?: {
106
+ pages: string[];
107
+ };
108
+ short_name?: string;
109
+ side_panel?: string;
110
+ storage?: {
111
+ managed_schema?: string;
112
+ };
113
+ tts_engine?: {
114
+ voices?: {
115
+ voice_name: string;
116
+ lang?: string;
117
+ event_types?: ("start" | "word" | "sentence" | "marker" | "end" | "error")[];
118
+ }[];
119
+ };
120
+ update_url?: string;
121
+ version_name?: string;
122
+ web_accessible_resources?: ({
123
+ resources: string[];
124
+ } & ({
125
+ matches: string[];
126
+ } | {
127
+ extension_ids: string[];
128
+ }))[];
129
+ file_browser_handlers?: {
130
+ id: string;
131
+ default_title: string;
132
+ file_filters: string[];
133
+ }[];
134
+ file_handlers?: {
135
+ action: string;
136
+ name: string;
137
+ accept: {
138
+ [x: string]: string[];
139
+ };
140
+ launch_type?: "single-client" | "multiple-clients";
141
+ }[];
142
+ file_system_provider_capabilities?: {
143
+ configurable?: boolean;
144
+ multiple_mounts?: boolean;
145
+ watchable?: boolean;
146
+ source: "file" | "device" | "network";
147
+ };
148
+ input_components?: {
149
+ name: string;
150
+ id?: string;
151
+ language?: string | string[];
152
+ layouts?: string | string[];
153
+ input_view?: string;
154
+ options_page?: string;
155
+ }[];
156
+ }
157
+ export type ChromeMV2Manifest = ChromeBaseManifest & {
158
+ manifest_version: 2;
159
+ browser_action?: {
160
+ default_icon?: {
161
+ [x: `${number}`]: string;
162
+ };
163
+ default_title?: string;
164
+ default_popup?: string;
165
+ };
166
+ page_action?: {
167
+ default_icon?: {
168
+ [x: `${number}`]: string;
169
+ };
170
+ default_title?: string;
171
+ default_popup?: string;
172
+ };
173
+ };
174
+ export type ChromeMV3Manifest = ChromeBaseManifest & {
175
+ manifest_version: 3;
176
+ action?: {
177
+ default_icon?: {
178
+ [x: `${number}`]: string;
179
+ };
180
+ default_title?: string;
181
+ default_popup?: string;
182
+ };
183
+ };
184
+ export type ChromeManifest = ChromeMV2Manifest | ChromeMV3Manifest;
185
+ export interface CrxFileHeader {
186
+ sha256_with_rsa?: AsymmetricKeyProof[];
187
+ sha256_with_ecdsa?: AsymmetricKeyProof[];
188
+ signed_header_data?: Uint8Array;
189
+ }
190
+ export interface AsymmetricKeyProof {
191
+ public_key?: Uint8Array;
192
+ signature?: Uint8Array;
193
+ }
194
+ /**
195
+ * Pack a CRX2 extension. Chrome stopped supporting these entirely in version 73.0.3683, which released in October of 2017.
196
+ *
197
+ * @param privateKey The extension's private key.
198
+ * @param publicKey The extension's public key.
199
+ * @param contents The zipped contents of the extension. This should contain a `manifest.json` file directly inside it, but we don't validate that in this function.
200
+ *
201
+ * @returns The contents of the packaged extension.
202
+ *
203
+ * @deprecated
204
+ */
205
+ export declare function packCrx2(privateKey: Uint8Array, publicKey: Uint8Array, contents: Uint8Array, rsa?: RSA): Uint8Array;
206
+ /**
207
+ * Pack a CRX3 extension.
208
+ *
209
+ * @param privateKey The extension's private key.
210
+ * @param publicKey The extension's public key.
211
+ * @param contents The zipped contents of the extension. This should contain a `manifest.json` file directly inside it, but we don't validate that in this function.
212
+ *
213
+ * @returns The contents of the packaged extension.
214
+ */
215
+ export declare function packCrx3(privateKey: Uint8Array, publicKey: Uint8Array, contents: Uint8Array, rsa?: RSA): Uint8Array;
216
+ /**
217
+ * Generate an extension's ID (32 characters, a-p) from its public key.
218
+ *
219
+ * @param publicKey The public key of the extension.
220
+ *
221
+ * @returns The generated extension ID.
222
+ */
223
+ export declare function generateCrxId(publicKey: Uint8Array): string;
224
+ /**
225
+ * Load a directory from the filesystem into a ZIP archive, using the node:fs API.
226
+ *
227
+ * @param where The path to the directory.
228
+ */
229
+ export declare function packContents(where: string): Promise<{
230
+ /** The ZIP-encoded data. */
231
+ contents: Uint8Array;
232
+ /** The manifest for the extension, parsed as JSON. */
233
+ manifest: ChromeManifest;
234
+ }>;
235
+ /**
236
+ * Generate the updates XML file for [serving an extension yourself](https://developer.chrome.com/docs/extensions/how-to/distribute/host-on-linux).
237
+ *
238
+ * @param crxId The extension's ID.
239
+ * @param url The URL where the extension's CRX file will be hosted.
240
+ * @param version The extension's version.
241
+ * @param minChromeVersion The minimum Chrome version that the extension can be installed on.
242
+ *
243
+ * @returns The updates XML text
244
+ */
245
+ export declare function generateUpdateXML(crxId: string, url: string, version: string, minChromeVersion?: string): string;
246
+ export declare function generatePrivateKey(bits?: number): Uint8Array;
247
+ export declare function generatePublicKey(privateKey: Uint8Array): Uint8Array;
248
+ export declare function convertToPem(key: Uint8Array, type: "private" | "public"): string;
249
+ export declare function convertFromPem(key: string, type: "private" | "public"): Uint8Array;
250
+ /**
251
+ * Unpack a CRX file and extract its contents as ZIP data.
252
+ *
253
+ * @param crx The CRX to be unpacked.
254
+ */
255
+ export declare function unpack(crx: Uint8Array): {
256
+ /** The ZIP data. */
257
+ archive: Uint8Array;
258
+ /** The CRX format version. */
259
+ crxVersion: 2;
260
+ /** The extension's public key. */
261
+ key: Uint8Array;
262
+ /** The signature over the contents of the extension. */
263
+ sign: Uint8Array;
264
+ } | {
265
+ /** The ZIP data. */
266
+ archive: Uint8Array;
267
+ /** The CRX format version. */
268
+ crxVersion: 3;
269
+ /** The header for the CRX file, for signatures and things. */
270
+ header: CrxFileHeader;
271
+ };
272
+ export interface PackInput {
273
+ /** The ZIP archive of the contents of the extension, or a path to the folder containing the extension. */
274
+ contents?: Uint8Array | string;
275
+ /** The private key for the extension, or a path to it. */
276
+ privateKey?: Uint8Array | string | null;
277
+ /** The size of key to generate, if needed. */
278
+ keySize?: number;
279
+ /** The public key for the extension, or a path to it. */
280
+ publicKey?: Uint8Array | string | null;
281
+ /** The instance of NodeRSA to use. */
282
+ rsa?: RSA;
283
+ /** The extension's ID. */
284
+ id?: string | null;
285
+ /** The outputted CRX file. */
286
+ crx?: Uint8Array | null;
287
+ /** The CRX format version to use. Defaults to 3. */
288
+ crxVersion?: number;
289
+ /** The URL to where the CRX file (not the updates XML) will be hosted. */
290
+ crxUrl?: string;
291
+ /** The [updates XML file](https://developer.chrome.com/docs/extensions/how-to/distribute/host-on-linux). */
292
+ updateXML?: string | null;
293
+ /** The extension's version. */
294
+ extVersion?: string | null;
295
+ /** The minimum Chrome version the extension requires. */
296
+ minChromeVersion?: string | null;
297
+ /** The extension's [manifest](https://developer.chrome.com/docs/extensions/reference/manifest). */
298
+ manifest?: ChromeManifest | null;
299
+ }
300
+ type SetKeys<A extends object, B extends object> = {
301
+ [x in keyof A | keyof B]: x extends keyof B ? unknown extends B[x] ? x extends keyof A ? A[x] : never : B[x] : x extends keyof A ? A[x] : never;
302
+ };
303
+ export type TransformPack<I extends PackInput> = I["privateKey"] extends string ? TransformPack<SetKeys<I, {
304
+ privateKey: Uint8Array | undefined;
305
+ rsa: RSA;
306
+ }>> : I["publicKey"] extends string ? TransformPack<SetKeys<I, {
307
+ publicKey: Uint8Array | undefined;
308
+ }>> : I["updateXML"] extends null ? undefined extends I["crxUrl"] ? never : TransformPack<SetKeys<I, {
309
+ updateXML: string;
310
+ id: undefined extends I["id"] ? null : I["id"];
311
+ extVersion: undefined extends I["extVersion"] ? null : I["extVersion"];
312
+ minChromeVersion: undefined extends I["minChromeVersion"] ? null : I["minChromeVersion"];
313
+ }>> : I["extVersion"] extends null ? TransformPack<SetKeys<I, {
314
+ extVersion: string;
315
+ manifest: undefined extends I["manifest"] ? null : I["manifest"];
316
+ }>> : I["minChromeVersion"] extends null ? TransformPack<SetKeys<I, {
317
+ minChromeVersion: string | undefined;
318
+ manifest: undefined extends I["manifest"] ? null : I["manifest"];
319
+ }>> : I["manifest"] extends null ? undefined extends I["contents"] ? never : Uint8Array extends I["contents"] ? never : TransformPack<SetKeys<I, {
320
+ manifest: ChromeManifest;
321
+ }>> : I["crx"] extends null ? undefined extends I["contents"] ? never : TransformPack<SetKeys<I, {
322
+ crx: Uint8Array;
323
+ privateKey: undefined extends I["privateKey"] ? null : I["privateKey"];
324
+ publicKey: undefined extends I["publicKey"] ? null : I["publicKey"];
325
+ }>> : I["id"] extends null ? TransformPack<SetKeys<I, {
326
+ id: string;
327
+ publicKey: undefined extends I["publicKey"] ? null : I["publicKey"];
328
+ }>> : I["publicKey"] extends null ? TransformPack<SetKeys<I, {
329
+ publicKey: Uint8Array;
330
+ privateKey: undefined extends I["privateKey"] ? null : I["privateKey"];
331
+ }>> : I["privateKey"] extends null ? TransformPack<SetKeys<I, {
332
+ privateKey: Uint8Array;
333
+ rsa: RSA;
334
+ }>> : I["contents"] extends string ? TransformPack<SetKeys<I, {
335
+ contents: Uint8Array;
336
+ manifest: ChromeManifest;
337
+ }>> : I;
338
+ /**
339
+ * Use the entirety of this API in one function.
340
+ *
341
+ * @param options An object containing input parameters.
342
+ *
343
+ * If `null` is given for a property, then the function will generate a value for it based on the other properties.
344
+ *
345
+ * If a property requires another but that property is not requested (with `null`), then it is generated and given anyways.
346
+ *
347
+ * If `privateKey` or `publicKey` are strings, `pack` will load the file at each path as a key. If the extension is `.pem`, they are loaded as pkcs8-pem and converted to pkcs8-der.
348
+ *
349
+ * `pack` always returns a `Promise`, even if all of the operations inside are synchronous.
350
+ *
351
+ * However, the return result is the same object as the input - just with the properties modified - so if you *really* want synchronous operations, you can keep a reference to the input object, call the function, and access the synchronous results from that object. Just make sure you don't set `privateKey` or `manifest` to `null` or `contents` to a string, otherwise some of your values might not arrive synchronously.
352
+ */
353
+ export declare function pack<I extends PackInput>(options: I): Promise<TransformPack<I>>;
354
+ export default pack;