netlify-cli 10.17.3 → 10.17.6
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/npm-shrinkwrap.json +9 -9
- package/package.json +3 -2
- package/src/commands/graph/graph-edit.js +2 -4
- package/src/commands/graph/graph-handler.js +4 -1
- package/src/commands/sites/sites-create.js +14 -4
- package/src/functions-templates/javascript/scheduled-function/package.json +1 -1
- package/src/functions-templates/typescript/hello-world/package-lock.json +7 -7
- package/src/functions-templates/typescript/hello-world/package.json +1 -1
- package/src/functions-templates/typescript/scheduled-function/package.json +1 -1
- package/src/lib/one-graph/cli-client.js +13 -29
- package/src/lib/one-graph/cli-netlify-graph.js +12 -6
- package/src/utils/proxy.js +3 -4
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "netlify-cli",
|
|
3
|
-
"version": "10.17.
|
|
3
|
+
"version": "10.17.6",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "netlify-cli",
|
|
9
|
-
"version": "10.17.
|
|
9
|
+
"version": "10.17.6",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"dependencies": {
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"multiparty": "^4.2.1",
|
|
82
82
|
"netlify": "^12.0.0",
|
|
83
83
|
"netlify-headers-parser": "^6.0.2",
|
|
84
|
-
"netlify-onegraph-internal": "0.8.
|
|
84
|
+
"netlify-onegraph-internal": "0.8.7",
|
|
85
85
|
"netlify-redirect-parser": "^13.0.5",
|
|
86
86
|
"netlify-redirector": "^0.2.1",
|
|
87
87
|
"node-fetch": "^2.6.0",
|
|
@@ -15996,9 +15996,9 @@
|
|
|
15996
15996
|
}
|
|
15997
15997
|
},
|
|
15998
15998
|
"node_modules/netlify-onegraph-internal": {
|
|
15999
|
-
"version": "0.8.
|
|
16000
|
-
"resolved": "https://registry.npmjs.org/netlify-onegraph-internal/-/netlify-onegraph-internal-0.8.
|
|
16001
|
-
"integrity": "sha512-
|
|
15999
|
+
"version": "0.8.7",
|
|
16000
|
+
"resolved": "https://registry.npmjs.org/netlify-onegraph-internal/-/netlify-onegraph-internal-0.8.7.tgz",
|
|
16001
|
+
"integrity": "sha512-FDHQes/GP7UjlzAwJ+qwKfhESBo9NQDN9Ed6U+9a5CW5o2j8Lr23P9Ac1MKp7jDP5h0uAq73r9P86J9Kl1yzLQ==",
|
|
16002
16002
|
"dependencies": {
|
|
16003
16003
|
"graphql": "16.5.0",
|
|
16004
16004
|
"node-fetch": "^2.6.0",
|
|
@@ -34229,9 +34229,9 @@
|
|
|
34229
34229
|
}
|
|
34230
34230
|
},
|
|
34231
34231
|
"netlify-onegraph-internal": {
|
|
34232
|
-
"version": "0.8.
|
|
34233
|
-
"resolved": "https://registry.npmjs.org/netlify-onegraph-internal/-/netlify-onegraph-internal-0.8.
|
|
34234
|
-
"integrity": "sha512-
|
|
34232
|
+
"version": "0.8.7",
|
|
34233
|
+
"resolved": "https://registry.npmjs.org/netlify-onegraph-internal/-/netlify-onegraph-internal-0.8.7.tgz",
|
|
34234
|
+
"integrity": "sha512-FDHQes/GP7UjlzAwJ+qwKfhESBo9NQDN9Ed6U+9a5CW5o2j8Lr23P9Ac1MKp7jDP5h0uAq73r9P86J9Kl1yzLQ==",
|
|
34235
34235
|
"requires": {
|
|
34236
34236
|
"graphql": "16.5.0",
|
|
34237
34237
|
"node-fetch": "^2.6.0",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "netlify-cli",
|
|
3
3
|
"description": "Netlify command line tool",
|
|
4
|
-
"version": "10.17.
|
|
4
|
+
"version": "10.17.6",
|
|
5
5
|
"author": "Netlify Inc.",
|
|
6
6
|
"contributors": [
|
|
7
7
|
"@whitep4nth3r (https://twitter.com/whitep4nth3r)",
|
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
"Liran Tal <liran.tal@gmail.com> (https://twitter.com/liran_tal)",
|
|
82
82
|
"Louis DeScioli (https://twitter.com/descioli)",
|
|
83
83
|
"Lukas Holzer <lukas.holzer@netlify.com> (https://twitter.com/luka5c0m)",
|
|
84
|
+
"Lxxyx <Lxxyxzj@gmail.com> (https://twitter.com/Lxxyx_)",
|
|
84
85
|
"Marc Littlemore (https://twitter.com/marclittlemore)",
|
|
85
86
|
"Marcus Weiner",
|
|
86
87
|
"Mark Bello <mark@markbello.dev> (https://markbello.dev)",
|
|
@@ -292,7 +293,7 @@
|
|
|
292
293
|
"multiparty": "^4.2.1",
|
|
293
294
|
"netlify": "^12.0.0",
|
|
294
295
|
"netlify-headers-parser": "^6.0.2",
|
|
295
|
-
"netlify-onegraph-internal": "0.8.
|
|
296
|
+
"netlify-onegraph-internal": "0.8.7",
|
|
296
297
|
"netlify-redirect-parser": "^13.0.5",
|
|
297
298
|
"netlify-redirector": "^0.2.1",
|
|
298
299
|
"node-fetch": "^2.6.0",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
const gitRepoInfo = require('git-repo-info')
|
|
3
|
-
const { OneGraphClient } = require('netlify-onegraph-internal')
|
|
4
3
|
|
|
5
4
|
const { OneGraphCliClient, ensureCLISession, upsertMergeCLISessionMetadata } = require('../../lib/one-graph/cli-client')
|
|
6
5
|
const {
|
|
@@ -40,6 +39,7 @@ const graphEdit = async (options, command) => {
|
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
const netlifyToken = await command.authenticate()
|
|
42
|
+
const { jwt } = await OneGraphCliClient.getGraphJwtForSite({ siteId, nfToken: netlifyToken })
|
|
43
43
|
|
|
44
44
|
await ensureAppForSite(netlifyToken, siteId)
|
|
45
45
|
|
|
@@ -62,8 +62,7 @@ const graphEdit = async (options, command) => {
|
|
|
62
62
|
tags: ['netlify-cli', `session:${oneGraphSessionId}`, `git-branch:${branch}`],
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
|
-
accessToken:
|
|
66
|
-
|
|
65
|
+
accessToken: jwt,
|
|
67
66
|
siteId,
|
|
68
67
|
},
|
|
69
68
|
)
|
|
@@ -76,7 +75,6 @@ const graphEdit = async (options, command) => {
|
|
|
76
75
|
|
|
77
76
|
const newMetadata = { docId: persistedDoc.id }
|
|
78
77
|
|
|
79
|
-
const { jwt } = await OneGraphClient.getGraphJwtForSite({ siteId, nfToken: netlifyToken })
|
|
80
78
|
await upsertMergeCLISessionMetadata({
|
|
81
79
|
config,
|
|
82
80
|
jwt,
|
|
@@ -36,6 +36,8 @@ const graphHandler = async (args, options, command) => {
|
|
|
36
36
|
const userOperationName = args.operationName
|
|
37
37
|
const userCodegenId = options.codegen
|
|
38
38
|
|
|
39
|
+
const handlerOptions = options.data ? JSON.parse(options.data) : {}
|
|
40
|
+
|
|
39
41
|
let operationName = userOperationName
|
|
40
42
|
if (!operationName) {
|
|
41
43
|
operationName = await autocompleteOperationNames({ netlifyGraphConfig })
|
|
@@ -70,7 +72,7 @@ const graphHandler = async (args, options, command) => {
|
|
|
70
72
|
netlifyGraphConfig,
|
|
71
73
|
schema,
|
|
72
74
|
operationName,
|
|
73
|
-
handlerOptions
|
|
75
|
+
handlerOptions,
|
|
74
76
|
})
|
|
75
77
|
} else {
|
|
76
78
|
error(`Failed to parse Netlify GraphQL schema`)
|
|
@@ -87,6 +89,7 @@ const createGraphHandlerCommand = (program) =>
|
|
|
87
89
|
.command('graph:handler')
|
|
88
90
|
.argument('[name]', 'Operation name')
|
|
89
91
|
.option('-c, --codegen <id>', 'The id of the specific code generator to use')
|
|
92
|
+
.option("-d, --data '<json>'", 'Optional data to pass along to the code generator')
|
|
90
93
|
.description(
|
|
91
94
|
'Generate a handler for a Graph operation given its name. See `graph:operations` for a list of operations.',
|
|
92
95
|
)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
3
|
const slugify = require('@sindresorhus/slugify')
|
|
4
|
+
const { InvalidArgumentError } = require('commander')
|
|
4
5
|
const inquirer = require('inquirer')
|
|
5
6
|
const pick = require('lodash/pick')
|
|
6
7
|
const sample = require('lodash/sample')
|
|
@@ -84,7 +85,6 @@ const sitesCreate = async (options, command) => {
|
|
|
84
85
|
accountSlug = accountSlugInput
|
|
85
86
|
}
|
|
86
87
|
|
|
87
|
-
const { name: nameFlag } = options
|
|
88
88
|
let user
|
|
89
89
|
let site
|
|
90
90
|
|
|
@@ -110,7 +110,7 @@ const sitesCreate = async (options, command) => {
|
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
|
-
await inputSiteName(
|
|
113
|
+
await inputSiteName(options.name)
|
|
114
114
|
|
|
115
115
|
log()
|
|
116
116
|
log(chalk.greenBright.bold.underline(`Site Created`))
|
|
@@ -175,6 +175,16 @@ const sitesCreate = async (options, command) => {
|
|
|
175
175
|
return site
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
+
const MAX_SITE_NAME_LENGTH = 63
|
|
179
|
+
const validateName = function (value) {
|
|
180
|
+
// netlify sites:create --name <A string of more than 63 words>
|
|
181
|
+
if (typeof value === 'string' && value.length > MAX_SITE_NAME_LENGTH) {
|
|
182
|
+
throw new InvalidArgumentError(`--name should be less than 64 characters, input length: ${value.length}`)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return value
|
|
186
|
+
}
|
|
187
|
+
|
|
178
188
|
/**
|
|
179
189
|
* Creates the `netlify sites:create` command
|
|
180
190
|
* @param {import('../base-command').BaseCommand} program
|
|
@@ -187,8 +197,8 @@ const createSitesCreateCommand = (program) =>
|
|
|
187
197
|
`Create an empty site (advanced)
|
|
188
198
|
Create a blank site that isn't associated with any git remote. Will link the site to the current working directory.`,
|
|
189
199
|
)
|
|
190
|
-
.option('-n, --name
|
|
191
|
-
.option('-a, --account-slug
|
|
200
|
+
.option('-n, --name <name>', 'name of site', validateName)
|
|
201
|
+
.option('-a, --account-slug <slug>', 'account slug to create the site under')
|
|
192
202
|
.option('-c, --with-ci', 'initialize CI hooks during site creation')
|
|
193
203
|
.option('-m, --manual', 'force manual CI setup. Used --with-ci flag')
|
|
194
204
|
.option('--disable-linking', 'create the site without linking it to current directory')
|
|
@@ -9,15 +9,15 @@
|
|
|
9
9
|
"version": "1.0.0",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@netlify/functions": "^1.
|
|
12
|
+
"@netlify/functions": "^1.1.0",
|
|
13
13
|
"@types/node": "^14.0.0",
|
|
14
14
|
"typescript": "^4.0.0"
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"node_modules/@netlify/functions": {
|
|
18
|
-
"version": "1.
|
|
19
|
-
"resolved": "https://registry.npmjs.org/@netlify/functions/-/functions-1.
|
|
20
|
-
"integrity": "sha512-
|
|
18
|
+
"version": "1.1.0",
|
|
19
|
+
"resolved": "https://registry.npmjs.org/@netlify/functions/-/functions-1.1.0.tgz",
|
|
20
|
+
"integrity": "sha512-XUFC5nt4iLMrDK+6WjYrDOW9h6XGIQlEk3o++xglFbDKc6dsP+k6rjfz3vl0w8S9Oiosxj3uLaPW18szJc1UgA==",
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"is-promise": "^4.0.0"
|
|
23
23
|
},
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"@netlify/functions": {
|
|
53
|
-
"version": "1.
|
|
54
|
-
"resolved": "https://registry.npmjs.org/@netlify/functions/-/functions-1.
|
|
55
|
-
"integrity": "sha512-
|
|
53
|
+
"version": "1.1.0",
|
|
54
|
+
"resolved": "https://registry.npmjs.org/@netlify/functions/-/functions-1.1.0.tgz",
|
|
55
|
+
"integrity": "sha512-XUFC5nt4iLMrDK+6WjYrDOW9h6XGIQlEk3o++xglFbDKc6dsP+k6rjfz3vl0w8S9Oiosxj3uLaPW18szJc1UgA==",
|
|
56
56
|
"requires": {
|
|
57
57
|
"is-promise": "^4.0.0"
|
|
58
58
|
}
|
|
@@ -780,10 +780,9 @@ const getCLISessionMetadata = async ({ jwt, oneGraphSessionId, siteId }) => {
|
|
|
780
780
|
* Look at the current project, filesystem, etc. and determine relevant metadata for a cli session
|
|
781
781
|
* @param {object} input
|
|
782
782
|
* @param {string} input.siteRoot The root file path for the site
|
|
783
|
-
* @param {object} input.config The parsed netlify.toml config file
|
|
784
783
|
* @returns {Promise<CliEventHelper.DetectedLocalCLISessionMetadata>} Any locally detected facts that are relevant to include in the cli session metadata
|
|
785
784
|
*/
|
|
786
|
-
const detectLocalCLISessionMetadata = async ({
|
|
785
|
+
const detectLocalCLISessionMetadata = async ({ siteRoot }) => {
|
|
787
786
|
// @ts-ignore
|
|
788
787
|
const { listFrameworks } = await frameworkInfoPromise
|
|
789
788
|
|
|
@@ -806,25 +805,6 @@ const detectLocalCLISessionMetadata = async ({ config, siteRoot }) => {
|
|
|
806
805
|
|
|
807
806
|
const editor = process.env.EDITOR || null
|
|
808
807
|
|
|
809
|
-
/** @type {CodegenHelpers.CodegenModuleMeta | null} */
|
|
810
|
-
let codegen = null
|
|
811
|
-
|
|
812
|
-
const codegenModule = await getCodegenModule({ config })
|
|
813
|
-
|
|
814
|
-
if (codegenModule) {
|
|
815
|
-
codegen = {
|
|
816
|
-
id: codegenModule.id,
|
|
817
|
-
version: codegenModule.id,
|
|
818
|
-
generators: codegenModule.generators.map((generator) => ({
|
|
819
|
-
id: generator.id,
|
|
820
|
-
name: generator.name,
|
|
821
|
-
options: generator.generateHandlerOptions || null,
|
|
822
|
-
supportedDefinitionTypes: generator.supportedDefinitionTypes,
|
|
823
|
-
version: generator.version,
|
|
824
|
-
})),
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
|
|
828
808
|
const detectedMetadata = {
|
|
829
809
|
gitBranch: branch,
|
|
830
810
|
hostname,
|
|
@@ -835,8 +815,8 @@ const detectLocalCLISessionMetadata = async ({ config, siteRoot }) => {
|
|
|
835
815
|
platform,
|
|
836
816
|
arch,
|
|
837
817
|
nodeVersion: process.version,
|
|
838
|
-
codegen,
|
|
839
818
|
framework,
|
|
819
|
+
codegen: null,
|
|
840
820
|
}
|
|
841
821
|
|
|
842
822
|
return detectedMetadata
|
|
@@ -847,13 +827,12 @@ const detectLocalCLISessionMetadata = async ({ config, siteRoot }) => {
|
|
|
847
827
|
* @param {object} input
|
|
848
828
|
* @param {string} input.jwt The GraphJWT string
|
|
849
829
|
* @param {string} input.sessionId The id of the cli session to fetch the current metadata for
|
|
850
|
-
* @param {object} input.config The parsed netlify.toml config file
|
|
851
830
|
* @param {string} input.siteRoot Path to the root of the project
|
|
852
831
|
* @param {string} input.docId The GraphQL operations document id to fetch
|
|
853
832
|
* @param {string} input.schemaId The GraphQL schemaId to use when generating code
|
|
854
833
|
*/
|
|
855
|
-
const publishCliSessionMetadataPublishEvent = async ({
|
|
856
|
-
const detectedMetadata = await detectLocalCLISessionMetadata({
|
|
834
|
+
const publishCliSessionMetadataPublishEvent = async ({ docId, jwt, schemaId, sessionId, siteRoot }) => {
|
|
835
|
+
const detectedMetadata = await detectLocalCLISessionMetadata({ siteRoot })
|
|
857
836
|
|
|
858
837
|
/** @type {CliEventHelper.OneGraphNetlifyCliSessionMetadataPublishEvent} */
|
|
859
838
|
const event = {
|
|
@@ -901,13 +880,13 @@ const publishCliSessionMetadataPublishEvent = async ({ config, docId, jwt, schem
|
|
|
901
880
|
* @param {object} input.newMetadata The metadata to merge into (with priority) the existing metadata
|
|
902
881
|
* @returns {Promise<object>}
|
|
903
882
|
*/
|
|
904
|
-
const upsertMergeCLISessionMetadata = async ({
|
|
883
|
+
const upsertMergeCLISessionMetadata = async ({ jwt, newMetadata, oneGraphSessionId, siteId, siteRoot }) => {
|
|
905
884
|
const { errors, metadata } = await getCLISessionMetadata({ jwt, oneGraphSessionId, siteId })
|
|
906
885
|
if (errors) {
|
|
907
886
|
warn(`Error fetching cli session metadata: ${JSON.stringify(errors, null, 2)}`)
|
|
908
887
|
}
|
|
909
888
|
|
|
910
|
-
const detectedMetadata = await detectLocalCLISessionMetadata({
|
|
889
|
+
const detectedMetadata = await detectLocalCLISessionMetadata({ siteRoot })
|
|
911
890
|
|
|
912
891
|
// @ts-ignore
|
|
913
892
|
const finalMetadata = { ...metadata, ...detectedMetadata, ...newMetadata }
|
|
@@ -992,7 +971,13 @@ const persistNewOperationsDocForSession = async ({
|
|
|
992
971
|
})
|
|
993
972
|
|
|
994
973
|
if (!result || result.errors) {
|
|
995
|
-
warn(
|
|
974
|
+
warn(
|
|
975
|
+
`Unable to update session metadata with updated operations docId="${persistedDoc.id}": ${JSON.stringify(
|
|
976
|
+
result && result.errors,
|
|
977
|
+
null,
|
|
978
|
+
2,
|
|
979
|
+
)}`,
|
|
980
|
+
)
|
|
996
981
|
} else if (lockfile != null) {
|
|
997
982
|
// Now that we've persisted the document, lock it in the lockfile
|
|
998
983
|
const currentOperationsDoc = readGraphQLOperationsSourceFile(netlifyGraphConfig)
|
|
@@ -1336,7 +1321,6 @@ const ensureCLISession = async (input) => {
|
|
|
1336
1321
|
// If we can't access the session in the state.json or it doesn't exist, create a new one
|
|
1337
1322
|
const sessionName = generateSessionName()
|
|
1338
1323
|
const detectedMetadata = await detectLocalCLISessionMetadata({
|
|
1339
|
-
config,
|
|
1340
1324
|
siteRoot: site.root,
|
|
1341
1325
|
})
|
|
1342
1326
|
const newSessionMetadata = parentCliSessionId ? { parentCliSessionId } : {}
|
|
@@ -459,7 +459,7 @@ const generateFunctionsFile = async ({ config, netlifyGraphConfig, operationsDoc
|
|
|
459
459
|
|
|
460
460
|
const codegenModule = await getCodegenModule({ config })
|
|
461
461
|
if (!codegenModule) {
|
|
462
|
-
|
|
462
|
+
warn(
|
|
463
463
|
`No Netlify Graph codegen module specified in netlify.toml under the [graph] header. Please specify 'codeGenerator' field and try again.`,
|
|
464
464
|
)
|
|
465
465
|
return
|
|
@@ -685,13 +685,19 @@ const generateHandlerByOperationName = ({
|
|
|
685
685
|
}
|
|
686
686
|
|
|
687
687
|
const parsedDoc = parse(currentOperationsDoc)
|
|
688
|
-
const { functions } = extractFunctionsFromOperationDoc(GraphQL, parsedDoc)
|
|
688
|
+
const { fragments, functions } = extractFunctionsFromOperationDoc(GraphQL, parsedDoc)
|
|
689
689
|
|
|
690
|
-
const
|
|
691
|
-
(
|
|
690
|
+
const functionDefinition = Object.values(functions).find(
|
|
691
|
+
(potentialDefinition) => potentialDefinition.operationName === operationName,
|
|
692
692
|
)
|
|
693
693
|
|
|
694
|
-
|
|
694
|
+
const fragmentDefinition = Object.values(fragments).find(
|
|
695
|
+
(potentialDefinition) => potentialDefinition.fragmentName === operationName,
|
|
696
|
+
)
|
|
697
|
+
|
|
698
|
+
const definition = functionDefinition || fragmentDefinition
|
|
699
|
+
|
|
700
|
+
if (!definition) {
|
|
695
701
|
warn(`No operation named ${operationName} was found in the operations doc`)
|
|
696
702
|
return
|
|
697
703
|
}
|
|
@@ -701,7 +707,7 @@ const generateHandlerByOperationName = ({
|
|
|
701
707
|
generate,
|
|
702
708
|
netlifyGraphConfig,
|
|
703
709
|
schema,
|
|
704
|
-
operationId:
|
|
710
|
+
operationId: definition.id,
|
|
705
711
|
handlerOptions,
|
|
706
712
|
})
|
|
707
713
|
}
|
package/src/utils/proxy.js
CHANGED
|
@@ -201,10 +201,9 @@ const serveRedirect = async function ({ match, options, proxy, req, res }) {
|
|
|
201
201
|
// construct destination URL from redirect rule match
|
|
202
202
|
const dest = new URL(match.to, `${reqUrl.protocol}//${reqUrl.host}`)
|
|
203
203
|
|
|
204
|
-
// We pass through request params
|
|
205
|
-
//
|
|
206
|
-
|
|
207
|
-
if ([...dest.searchParams].length === 0 || isFunction(options.functionsPort, stripOrigin(dest))) {
|
|
204
|
+
// We pass through request params if the redirect rule
|
|
205
|
+
// doesn't have any query params
|
|
206
|
+
if ([...dest.searchParams].length === 0) {
|
|
208
207
|
dest.searchParams.forEach((_, key) => {
|
|
209
208
|
dest.searchParams.delete(key)
|
|
210
209
|
})
|