zapier-platform-cli 18.0.1 → 18.0.5
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/oclif.manifest.json +98 -98
- package/package.json +19 -21
- package/src/generators/templates/README.template.md +1 -1
- package/src/generators/templates/gitignore +3 -0
- package/src/utils/build.js +1 -1
- package/src/utils/decompress.js +121 -0
- package/src/generators/templates/search-or-create/.gitignore +0 -6
package/oclif.manifest.json
CHANGED
|
@@ -2176,9 +2176,9 @@
|
|
|
2176
2176
|
"unset.js"
|
|
2177
2177
|
]
|
|
2178
2178
|
},
|
|
2179
|
-
"
|
|
2179
|
+
"team:add": {
|
|
2180
2180
|
"aliases": [
|
|
2181
|
-
"
|
|
2181
|
+
"team:invite"
|
|
2182
2182
|
],
|
|
2183
2183
|
"args": {
|
|
2184
2184
|
"email": {
|
|
@@ -2186,24 +2186,28 @@
|
|
|
2186
2186
|
"name": "email",
|
|
2187
2187
|
"required": true
|
|
2188
2188
|
},
|
|
2189
|
-
"
|
|
2190
|
-
"description": "
|
|
2191
|
-
"name": "
|
|
2189
|
+
"role": {
|
|
2190
|
+
"description": "The level the invited team member should be at. Admins can edit everything and get email updates. Collaborators have read-access to the app and get email updates. Subscribers only get email updates.",
|
|
2191
|
+
"name": "role",
|
|
2192
|
+
"options": [
|
|
2193
|
+
"admin",
|
|
2194
|
+
"collaborator",
|
|
2195
|
+
"subscriber"
|
|
2196
|
+
],
|
|
2197
|
+
"required": true
|
|
2198
|
+
},
|
|
2199
|
+
"message": {
|
|
2200
|
+
"description": "A message sent in the email to your team member, if you need to provide context. Wrap the message in quotes to ensure spaces get saved.",
|
|
2201
|
+
"name": "message"
|
|
2192
2202
|
}
|
|
2193
2203
|
},
|
|
2194
|
-
"description": "Add a
|
|
2204
|
+
"description": "Add a team member to your integration.\n\nThese users come in three levels:\n\n * `admin`, who can edit everything about the integration\n * `collaborator`, who has read-only access for the app, and will receive periodic email updates. These updates include quarterly health scores and more.\n * `subscriber`, who can't directly access the app, but will receive periodic email updates. These updates include quarterly health scores and more.\n\nTeam members can be freely added and removed.",
|
|
2195
2205
|
"examples": [
|
|
2196
|
-
"zapier
|
|
2197
|
-
"zapier
|
|
2206
|
+
"zapier team:add bruce@wayne.com admin",
|
|
2207
|
+
"zapier team:add robin@wayne.com collaborator \"Hey Robin, check out this app.\"",
|
|
2208
|
+
"zapier team:add alfred@wayne.com subscriber \"Hey Alfred, check out this app.\""
|
|
2198
2209
|
],
|
|
2199
2210
|
"flags": {
|
|
2200
|
-
"force": {
|
|
2201
|
-
"char": "f",
|
|
2202
|
-
"description": "Skip confirmation. Useful for running programatically.",
|
|
2203
|
-
"name": "force",
|
|
2204
|
-
"allowNo": false,
|
|
2205
|
-
"type": "boolean"
|
|
2206
|
-
},
|
|
2207
2211
|
"debug": {
|
|
2208
2212
|
"char": "d",
|
|
2209
2213
|
"description": "Show extra debugging output.",
|
|
@@ -2220,7 +2224,7 @@
|
|
|
2220
2224
|
},
|
|
2221
2225
|
"hasDynamicHelp": false,
|
|
2222
2226
|
"hiddenAliases": [],
|
|
2223
|
-
"id": "
|
|
2227
|
+
"id": "team:add",
|
|
2224
2228
|
"pluginAlias": "zapier-platform-cli",
|
|
2225
2229
|
"pluginName": "zapier-platform-cli",
|
|
2226
2230
|
"pluginType": "core",
|
|
@@ -2232,16 +2236,16 @@
|
|
|
2232
2236
|
"src",
|
|
2233
2237
|
"oclif",
|
|
2234
2238
|
"commands",
|
|
2235
|
-
"
|
|
2239
|
+
"team",
|
|
2236
2240
|
"add.js"
|
|
2237
2241
|
]
|
|
2238
2242
|
},
|
|
2239
|
-
"
|
|
2243
|
+
"team:get": {
|
|
2240
2244
|
"aliases": [
|
|
2241
|
-
"
|
|
2245
|
+
"team:list"
|
|
2242
2246
|
],
|
|
2243
2247
|
"args": {},
|
|
2244
|
-
"description": "Get
|
|
2248
|
+
"description": "Get team members involved with your integration.\n\nThese users come in three levels:\n\n * `admin`, who can edit everything about the integration\n * `collaborator`, who has read-only access for the app, and will receive periodic email updates. These updates include quarterly health scores and more.\n * `subscriber`, who can't directly access the app, but will receive periodic email updates. These updates include quarterly health scores and more.\n\nUse the `zapier team:add` and `zapier team:remove` commands to modify your team.\n",
|
|
2245
2249
|
"flags": {
|
|
2246
2250
|
"debug": {
|
|
2247
2251
|
"char": "d",
|
|
@@ -2275,7 +2279,7 @@
|
|
|
2275
2279
|
},
|
|
2276
2280
|
"hasDynamicHelp": false,
|
|
2277
2281
|
"hiddenAliases": [],
|
|
2278
|
-
"id": "
|
|
2282
|
+
"id": "team:get",
|
|
2279
2283
|
"pluginAlias": "zapier-platform-cli",
|
|
2280
2284
|
"pluginName": "zapier-platform-cli",
|
|
2281
2285
|
"pluginType": "core",
|
|
@@ -2287,14 +2291,16 @@
|
|
|
2287
2291
|
"src",
|
|
2288
2292
|
"oclif",
|
|
2289
2293
|
"commands",
|
|
2290
|
-
"
|
|
2294
|
+
"team",
|
|
2291
2295
|
"get.js"
|
|
2292
2296
|
]
|
|
2293
2297
|
},
|
|
2294
|
-
"
|
|
2295
|
-
"aliases": [
|
|
2298
|
+
"team:remove": {
|
|
2299
|
+
"aliases": [
|
|
2300
|
+
"team:delete"
|
|
2301
|
+
],
|
|
2296
2302
|
"args": {},
|
|
2297
|
-
"description": "
|
|
2303
|
+
"description": "Remove a team member from all versions of your integration.\n\nAdmins will immediately lose write access to the integration.\nCollaborators will immediately lose read access to the integration.\nSubscribers won't receive future email updates.",
|
|
2298
2304
|
"flags": {
|
|
2299
2305
|
"debug": {
|
|
2300
2306
|
"char": "d",
|
|
@@ -2303,22 +2309,6 @@
|
|
|
2303
2309
|
"allowNo": false,
|
|
2304
2310
|
"type": "boolean"
|
|
2305
2311
|
},
|
|
2306
|
-
"format": {
|
|
2307
|
-
"char": "f",
|
|
2308
|
-
"description": "Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.",
|
|
2309
|
-
"name": "format",
|
|
2310
|
-
"default": "table",
|
|
2311
|
-
"hasDynamicHelp": false,
|
|
2312
|
-
"multiple": false,
|
|
2313
|
-
"options": [
|
|
2314
|
-
"plain",
|
|
2315
|
-
"json",
|
|
2316
|
-
"raw",
|
|
2317
|
-
"row",
|
|
2318
|
-
"table"
|
|
2319
|
-
],
|
|
2320
|
-
"type": "option"
|
|
2321
|
-
},
|
|
2322
2312
|
"invokedFromAnotherCommand": {
|
|
2323
2313
|
"hidden": true,
|
|
2324
2314
|
"name": "invokedFromAnotherCommand",
|
|
@@ -2328,7 +2318,7 @@
|
|
|
2328
2318
|
},
|
|
2329
2319
|
"hasDynamicHelp": false,
|
|
2330
2320
|
"hiddenAliases": [],
|
|
2331
|
-
"id": "
|
|
2321
|
+
"id": "team:remove",
|
|
2332
2322
|
"pluginAlias": "zapier-platform-cli",
|
|
2333
2323
|
"pluginName": "zapier-platform-cli",
|
|
2334
2324
|
"pluginType": "core",
|
|
@@ -2340,26 +2330,34 @@
|
|
|
2340
2330
|
"src",
|
|
2341
2331
|
"oclif",
|
|
2342
2332
|
"commands",
|
|
2343
|
-
"
|
|
2344
|
-
"
|
|
2333
|
+
"team",
|
|
2334
|
+
"remove.js"
|
|
2345
2335
|
]
|
|
2346
2336
|
},
|
|
2347
|
-
"users:
|
|
2337
|
+
"users:add": {
|
|
2348
2338
|
"aliases": [
|
|
2349
|
-
"users:
|
|
2339
|
+
"users:invite"
|
|
2350
2340
|
],
|
|
2351
2341
|
"args": {
|
|
2352
2342
|
"email": {
|
|
2353
|
-
"description": "The user to be
|
|
2343
|
+
"description": "The user to be invited. If they don't have a Zapier account, they'll be prompted to create one.",
|
|
2354
2344
|
"name": "email",
|
|
2355
2345
|
"required": true
|
|
2346
|
+
},
|
|
2347
|
+
"version": {
|
|
2348
|
+
"description": "A version string (like 1.2.3). Optional, used only if you want to invite a user to a specific version instead of all versions.",
|
|
2349
|
+
"name": "version"
|
|
2356
2350
|
}
|
|
2357
2351
|
},
|
|
2358
|
-
"description": "
|
|
2352
|
+
"description": "Add a user to some or all versions of your integration.\n\nWhen this command is run, we'll send an email to the user inviting them to try your integration. You can track the status of that invite using the `zapier users:get` command.\n\nInvited users will be able to see your integration's name, logo, and description. They'll also be able to create Zaps using any available triggers and actions.",
|
|
2353
|
+
"examples": [
|
|
2354
|
+
"zapier users:add bruce@wayne.com",
|
|
2355
|
+
"zapier users:add alfred@wayne.com 1.2.3"
|
|
2356
|
+
],
|
|
2359
2357
|
"flags": {
|
|
2360
2358
|
"force": {
|
|
2361
2359
|
"char": "f",
|
|
2362
|
-
"description": "
|
|
2360
|
+
"description": "Skip confirmation. Useful for running programatically.",
|
|
2363
2361
|
"name": "force",
|
|
2364
2362
|
"allowNo": false,
|
|
2365
2363
|
"type": "boolean"
|
|
@@ -2380,7 +2378,7 @@
|
|
|
2380
2378
|
},
|
|
2381
2379
|
"hasDynamicHelp": false,
|
|
2382
2380
|
"hiddenAliases": [],
|
|
2383
|
-
"id": "users:
|
|
2381
|
+
"id": "users:add",
|
|
2384
2382
|
"pluginAlias": "zapier-platform-cli",
|
|
2385
2383
|
"pluginName": "zapier-platform-cli",
|
|
2386
2384
|
"pluginType": "core",
|
|
@@ -2393,40 +2391,15 @@
|
|
|
2393
2391
|
"oclif",
|
|
2394
2392
|
"commands",
|
|
2395
2393
|
"users",
|
|
2396
|
-
"
|
|
2394
|
+
"add.js"
|
|
2397
2395
|
]
|
|
2398
2396
|
},
|
|
2399
|
-
"
|
|
2397
|
+
"users:get": {
|
|
2400
2398
|
"aliases": [
|
|
2401
|
-
"
|
|
2402
|
-
],
|
|
2403
|
-
"args": {
|
|
2404
|
-
"email": {
|
|
2405
|
-
"description": "The user to be invited. If they don't have a Zapier account, they'll be prompted to create one.",
|
|
2406
|
-
"name": "email",
|
|
2407
|
-
"required": true
|
|
2408
|
-
},
|
|
2409
|
-
"role": {
|
|
2410
|
-
"description": "The level the invited team member should be at. Admins can edit everything and get email updates. Collaborators have read-access to the app and get email updates. Subscribers only get email updates.",
|
|
2411
|
-
"name": "role",
|
|
2412
|
-
"options": [
|
|
2413
|
-
"admin",
|
|
2414
|
-
"collaborator",
|
|
2415
|
-
"subscriber"
|
|
2416
|
-
],
|
|
2417
|
-
"required": true
|
|
2418
|
-
},
|
|
2419
|
-
"message": {
|
|
2420
|
-
"description": "A message sent in the email to your team member, if you need to provide context. Wrap the message in quotes to ensure spaces get saved.",
|
|
2421
|
-
"name": "message"
|
|
2422
|
-
}
|
|
2423
|
-
},
|
|
2424
|
-
"description": "Add a team member to your integration.\n\nThese users come in three levels:\n\n * `admin`, who can edit everything about the integration\n * `collaborator`, who has read-only access for the app, and will receive periodic email updates. These updates include quarterly health scores and more.\n * `subscriber`, who can't directly access the app, but will receive periodic email updates. These updates include quarterly health scores and more.\n\nTeam members can be freely added and removed.",
|
|
2425
|
-
"examples": [
|
|
2426
|
-
"zapier team:add bruce@wayne.com admin",
|
|
2427
|
-
"zapier team:add robin@wayne.com collaborator \"Hey Robin, check out this app.\"",
|
|
2428
|
-
"zapier team:add alfred@wayne.com subscriber \"Hey Alfred, check out this app.\""
|
|
2399
|
+
"users:list"
|
|
2429
2400
|
],
|
|
2401
|
+
"args": {},
|
|
2402
|
+
"description": "Get a list of users who have been invited to your integration.\n\nNote that this list of users is NOT a comprehensive list of everyone who is using your integration. It only includes users who were invited directly by email (using the `\u001b[36mzapier users:add\u001b[39m` command or the web UI). Users who joined by clicking links generated using the `\u001b[36mzapier user:links\u001b[39m` command won't show up here.",
|
|
2430
2403
|
"flags": {
|
|
2431
2404
|
"debug": {
|
|
2432
2405
|
"char": "d",
|
|
@@ -2435,6 +2408,22 @@
|
|
|
2435
2408
|
"allowNo": false,
|
|
2436
2409
|
"type": "boolean"
|
|
2437
2410
|
},
|
|
2411
|
+
"format": {
|
|
2412
|
+
"char": "f",
|
|
2413
|
+
"description": "Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.",
|
|
2414
|
+
"name": "format",
|
|
2415
|
+
"default": "table",
|
|
2416
|
+
"hasDynamicHelp": false,
|
|
2417
|
+
"multiple": false,
|
|
2418
|
+
"options": [
|
|
2419
|
+
"plain",
|
|
2420
|
+
"json",
|
|
2421
|
+
"raw",
|
|
2422
|
+
"row",
|
|
2423
|
+
"table"
|
|
2424
|
+
],
|
|
2425
|
+
"type": "option"
|
|
2426
|
+
},
|
|
2438
2427
|
"invokedFromAnotherCommand": {
|
|
2439
2428
|
"hidden": true,
|
|
2440
2429
|
"name": "invokedFromAnotherCommand",
|
|
@@ -2444,7 +2433,7 @@
|
|
|
2444
2433
|
},
|
|
2445
2434
|
"hasDynamicHelp": false,
|
|
2446
2435
|
"hiddenAliases": [],
|
|
2447
|
-
"id": "
|
|
2436
|
+
"id": "users:get",
|
|
2448
2437
|
"pluginAlias": "zapier-platform-cli",
|
|
2449
2438
|
"pluginName": "zapier-platform-cli",
|
|
2450
2439
|
"pluginType": "core",
|
|
@@ -2456,16 +2445,14 @@
|
|
|
2456
2445
|
"src",
|
|
2457
2446
|
"oclif",
|
|
2458
2447
|
"commands",
|
|
2459
|
-
"
|
|
2460
|
-
"
|
|
2448
|
+
"users",
|
|
2449
|
+
"get.js"
|
|
2461
2450
|
]
|
|
2462
2451
|
},
|
|
2463
|
-
"
|
|
2464
|
-
"aliases": [
|
|
2465
|
-
"team:list"
|
|
2466
|
-
],
|
|
2452
|
+
"users:links": {
|
|
2453
|
+
"aliases": [],
|
|
2467
2454
|
"args": {},
|
|
2468
|
-
"description": "Get
|
|
2455
|
+
"description": "Get a list of links that are used to invite users to your integration.",
|
|
2469
2456
|
"flags": {
|
|
2470
2457
|
"debug": {
|
|
2471
2458
|
"char": "d",
|
|
@@ -2499,7 +2486,7 @@
|
|
|
2499
2486
|
},
|
|
2500
2487
|
"hasDynamicHelp": false,
|
|
2501
2488
|
"hiddenAliases": [],
|
|
2502
|
-
"id": "
|
|
2489
|
+
"id": "users:links",
|
|
2503
2490
|
"pluginAlias": "zapier-platform-cli",
|
|
2504
2491
|
"pluginName": "zapier-platform-cli",
|
|
2505
2492
|
"pluginType": "core",
|
|
@@ -2511,17 +2498,30 @@
|
|
|
2511
2498
|
"src",
|
|
2512
2499
|
"oclif",
|
|
2513
2500
|
"commands",
|
|
2514
|
-
"
|
|
2515
|
-
"
|
|
2501
|
+
"users",
|
|
2502
|
+
"links.js"
|
|
2516
2503
|
]
|
|
2517
2504
|
},
|
|
2518
|
-
"
|
|
2505
|
+
"users:remove": {
|
|
2519
2506
|
"aliases": [
|
|
2520
|
-
"
|
|
2507
|
+
"users:delete"
|
|
2521
2508
|
],
|
|
2522
|
-
"args": {
|
|
2523
|
-
|
|
2509
|
+
"args": {
|
|
2510
|
+
"email": {
|
|
2511
|
+
"description": "The user to be removed.",
|
|
2512
|
+
"name": "email",
|
|
2513
|
+
"required": true
|
|
2514
|
+
}
|
|
2515
|
+
},
|
|
2516
|
+
"description": "Remove a user from all versions of your integration.\n\nWhen this command is run, their Zaps will immediately turn off. They won't be able to use your app again until they're re-invited or it has gone public. In practice, this command isn't run often as it's very disruptive to users.",
|
|
2524
2517
|
"flags": {
|
|
2518
|
+
"force": {
|
|
2519
|
+
"char": "f",
|
|
2520
|
+
"description": "Skips confirmation. Useful for running programatically.",
|
|
2521
|
+
"name": "force",
|
|
2522
|
+
"allowNo": false,
|
|
2523
|
+
"type": "boolean"
|
|
2524
|
+
},
|
|
2525
2525
|
"debug": {
|
|
2526
2526
|
"char": "d",
|
|
2527
2527
|
"description": "Show extra debugging output.",
|
|
@@ -2538,7 +2538,7 @@
|
|
|
2538
2538
|
},
|
|
2539
2539
|
"hasDynamicHelp": false,
|
|
2540
2540
|
"hiddenAliases": [],
|
|
2541
|
-
"id": "
|
|
2541
|
+
"id": "users:remove",
|
|
2542
2542
|
"pluginAlias": "zapier-platform-cli",
|
|
2543
2543
|
"pluginName": "zapier-platform-cli",
|
|
2544
2544
|
"pluginType": "core",
|
|
@@ -2550,10 +2550,10 @@
|
|
|
2550
2550
|
"src",
|
|
2551
2551
|
"oclif",
|
|
2552
2552
|
"commands",
|
|
2553
|
-
"
|
|
2553
|
+
"users",
|
|
2554
2554
|
"remove.js"
|
|
2555
2555
|
]
|
|
2556
2556
|
}
|
|
2557
2557
|
},
|
|
2558
|
-
"version": "18.0.
|
|
2558
|
+
"version": "18.0.5"
|
|
2559
2559
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zapier-platform-cli",
|
|
3
|
-
"version": "18.0.
|
|
3
|
+
"version": "18.0.5",
|
|
4
4
|
"description": "The CLI for managing integrations in Zapier Developer Platform.",
|
|
5
5
|
"repository": "zapier/zapier-platform",
|
|
6
6
|
"homepage": "https://platform.zapier.com/",
|
|
@@ -20,24 +20,6 @@
|
|
|
20
20
|
"engines": {
|
|
21
21
|
"node": ">=18.20"
|
|
22
22
|
},
|
|
23
|
-
"scripts": {
|
|
24
|
-
"docs": "ZAPIER_BASE_ENDPOINT='' node scripts/docs.js",
|
|
25
|
-
"preversion": "git pull && yarn validate",
|
|
26
|
-
"prepack": "oclif manifest",
|
|
27
|
-
"postpack": "rimraf oclif.manifest.json",
|
|
28
|
-
"precommit": "yarn docs && git add docs",
|
|
29
|
-
"version": "yarn docs && git add docs/*",
|
|
30
|
-
"postversion": "git push && git push --tags",
|
|
31
|
-
"lint": "eslint src",
|
|
32
|
-
"lint:fix": "eslint --fix src",
|
|
33
|
-
"test": "cross-env NODE_ENV=test mocha -t 200s --recursive src/tests --exit",
|
|
34
|
-
"test:debug": "cross-env NODE_ENV=test node inspect ../../node_modules/.bin/mocha -t 200s --recursive src/tests --exit",
|
|
35
|
-
"smoke-test": "cross-env NODE_ENV=test mocha -t 6m --recursive src/smoke-tests --exit",
|
|
36
|
-
"smoke-test:debug": "cross-env NODE_ENV=test node inspect ../../node_modules/.bin/mocha -t 6m --recursive src/smoke-tests --exit",
|
|
37
|
-
"validate-templates": "./scripts/validate-app-templates.js",
|
|
38
|
-
"set-template-versions": "./scripts/set-app-template-versions.js",
|
|
39
|
-
"validate": "yarn test && yarn smoke-test && yarn lint"
|
|
40
|
-
},
|
|
41
23
|
"dependencies": {
|
|
42
24
|
"@oclif/core": "4.5.2",
|
|
43
25
|
"@oclif/plugin-autocomplete": "3.2.34",
|
|
@@ -50,7 +32,7 @@
|
|
|
50
32
|
"cli-table3": "0.6.5",
|
|
51
33
|
"colors": "1.4.0",
|
|
52
34
|
"debug": "4.4.1",
|
|
53
|
-
"decompress": "4.
|
|
35
|
+
"decompress-unzip": "4.0.1",
|
|
54
36
|
"dotenv": "17.2.1",
|
|
55
37
|
"esbuild": "0.25.8",
|
|
56
38
|
"fs-extra": "11.3.1",
|
|
@@ -136,5 +118,21 @@
|
|
|
136
118
|
"description": "Add, remove, or get invited users of your integration."
|
|
137
119
|
}
|
|
138
120
|
}
|
|
121
|
+
},
|
|
122
|
+
"scripts": {
|
|
123
|
+
"build-docs": "ZAPIER_BASE_ENDPOINT='' node scripts/docs.js",
|
|
124
|
+
"preversion": "git pull && pnpm validate",
|
|
125
|
+
"precommit": "pnpm build-docs && git add docs",
|
|
126
|
+
"version": "pnpm build-docs && git add docs/*",
|
|
127
|
+
"postversion": "git push && git push --tags",
|
|
128
|
+
"lint": "eslint src",
|
|
129
|
+
"lint:fix": "eslint --fix src",
|
|
130
|
+
"test": "cross-env NODE_ENV=test mocha -t 200s --recursive src/tests --exit",
|
|
131
|
+
"test:debug": "cross-env NODE_ENV=test node inspect ../../node_modules/.bin/mocha -t 200s --recursive src/tests --exit",
|
|
132
|
+
"smoke-test": "cross-env NODE_ENV=test mocha -t 6m --recursive src/smoke-tests --exit",
|
|
133
|
+
"smoke-test:debug": "cross-env NODE_ENV=test node inspect ../../node_modules/.bin/mocha -t 6m --recursive src/smoke-tests --exit",
|
|
134
|
+
"validate-templates": "./scripts/validate-app-templates.js",
|
|
135
|
+
"set-template-versions": "./scripts/set-app-template-versions.js",
|
|
136
|
+
"validate": "pnpm test && pnpm smoke-test && pnpm lint"
|
|
139
137
|
}
|
|
140
|
-
}
|
|
138
|
+
}
|
package/src/utils/build.js
CHANGED
|
@@ -12,7 +12,7 @@ const colors = require('colors/safe');
|
|
|
12
12
|
const esbuild = require('esbuild');
|
|
13
13
|
const fse = require('fs-extra');
|
|
14
14
|
const { createUpdateNotifier } = require('./esm-wrapper');
|
|
15
|
-
const decompress = require('decompress');
|
|
15
|
+
const decompress = require('./decompress');
|
|
16
16
|
|
|
17
17
|
const {
|
|
18
18
|
BUILD_DIR,
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// This is a modernized version of the decompress package.
|
|
2
|
+
// Instead of letting decompress import many of its plugins, such as
|
|
3
|
+
// decompress-unzip, decompress-tar, etc, we extracted only the unzip part,
|
|
4
|
+
// so we only depend on decompress-unzip.
|
|
5
|
+
// Original source: https://github.com/kevva/decompress/blob/84a8c104/index.js
|
|
6
|
+
|
|
7
|
+
const fsP = require('node:fs/promises');
|
|
8
|
+
const path = require('node:path');
|
|
9
|
+
|
|
10
|
+
const decompressUnzip = require('decompress-unzip');
|
|
11
|
+
|
|
12
|
+
const safeMakeDir = async (dir, realOutputPath) => {
|
|
13
|
+
let resolvedPathToCheck;
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
resolvedPathToCheck = await fsP.realpath(dir);
|
|
17
|
+
} catch (error) {
|
|
18
|
+
const parent = path.dirname(dir);
|
|
19
|
+
resolvedPathToCheck = await safeMakeDir(parent, realOutputPath);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Security check for zip slip vulnerability
|
|
23
|
+
if (!resolvedPathToCheck.startsWith(realOutputPath)) {
|
|
24
|
+
throw new Error('Refusing to create a directory outside the output path.');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
await fsP.mkdir(dir, { recursive: true });
|
|
28
|
+
return await fsP.realpath(dir);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const preventWritingThroughSymlink = async (destination, realOutputPath) => {
|
|
32
|
+
let symlinkPointsTo;
|
|
33
|
+
try {
|
|
34
|
+
symlinkPointsTo = await fsP.readlink(destination);
|
|
35
|
+
} catch (error) {
|
|
36
|
+
// Either no file exists, or it's not a symlink. In either case, this is
|
|
37
|
+
// not an escape we need to worry about in this phase.
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (symlinkPointsTo) {
|
|
41
|
+
throw new Error('Refusing to write into a symlink');
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const extractItem = async (item, realOutputPath) => {
|
|
46
|
+
const dest = path.join(realOutputPath, item.path);
|
|
47
|
+
const mode = item.mode & ~process.umask();
|
|
48
|
+
const now = new Date();
|
|
49
|
+
|
|
50
|
+
if (item.type === 'directory') {
|
|
51
|
+
await safeMakeDir(dest, realOutputPath);
|
|
52
|
+
await fsP.utimes(dest, now, item.mtime);
|
|
53
|
+
return item;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
await safeMakeDir(path.dirname(dest), realOutputPath);
|
|
57
|
+
|
|
58
|
+
if (item.type === 'file') {
|
|
59
|
+
await preventWritingThroughSymlink(dest, realOutputPath);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const realDestinationDir = await fsP.realpath(path.dirname(dest));
|
|
63
|
+
if (!realDestinationDir.startsWith(realOutputPath)) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
'Refusing to write outside output directory: ' + realDestinationDir,
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (item.type === 'symlink') {
|
|
70
|
+
// Security check to block symlinks pointing outside output directory,
|
|
71
|
+
// like evil_link -> ../../../../../etc/passwd. We don't throw an error
|
|
72
|
+
// here, just skip creating the symlink, because there are known zip files
|
|
73
|
+
// containing such symlinks (such as .editorconfig) that are not essential
|
|
74
|
+
// to the integration.
|
|
75
|
+
const absTargetPath = path.resolve(realDestinationDir, item.linkname);
|
|
76
|
+
const relTargetPath = path.relative(realOutputPath, absTargetPath);
|
|
77
|
+
if (!relTargetPath.startsWith('..')) {
|
|
78
|
+
// Windows will have issues with the following line, since creating a
|
|
79
|
+
// symlink on Windows requires Administrator privilege. But that's fine
|
|
80
|
+
// because we only run decompress on Windows in CI tests, which do run
|
|
81
|
+
// with Administrator privilege.
|
|
82
|
+
await fsP.symlink(item.linkname, dest);
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
await fsP.writeFile(dest, item.data, { mode });
|
|
86
|
+
await fsP.utimes(dest, now, item.mtime);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return item;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const decompress = async (input, output) => {
|
|
93
|
+
if (typeof input !== 'string') {
|
|
94
|
+
throw new TypeError('input must be a file path (string)');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (typeof output !== 'string') {
|
|
98
|
+
throw new TypeError('output must be a directory path (string)');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
let fd, buf;
|
|
102
|
+
try {
|
|
103
|
+
fd = await fsP.open(input);
|
|
104
|
+
buf = await fd.readFile();
|
|
105
|
+
} finally {
|
|
106
|
+
await fd?.close();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Ensure output directory exists
|
|
110
|
+
await fsP.mkdir(output, { recursive: true });
|
|
111
|
+
const realOutputPath = await fsP.realpath(output);
|
|
112
|
+
|
|
113
|
+
const items = await decompressUnzip()(buf);
|
|
114
|
+
return await Promise.all(
|
|
115
|
+
items.map(async (x) => {
|
|
116
|
+
return await extractItem(x, realOutputPath);
|
|
117
|
+
}),
|
|
118
|
+
);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
module.exports = decompress;
|