netlify-cli 17.3.2 → 17.4.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 +2 -138
- package/npm-shrinkwrap.json +76 -76
- package/package.json +16 -15
- package/src/commands/addons/addons-auth.mjs +27 -30
- package/src/commands/addons/addons-config.mjs +145 -154
- package/src/commands/addons/addons-create.mjs +94 -108
- package/src/commands/addons/addons-delete.mjs +36 -41
- package/src/commands/addons/addons-list.mjs +38 -42
- package/src/commands/addons/addons.mjs +26 -28
- package/src/commands/addons/index.mjs +1 -1
- package/src/commands/api/api.mjs +45 -53
- package/src/commands/api/index.mjs +1 -1
- package/src/commands/base-command.mjs +597 -684
- package/src/commands/blobs/blobs-delete.mjs +35 -0
- package/src/commands/blobs/blobs-get.mjs +44 -0
- package/src/commands/blobs/blobs-list.mjs +48 -0
- package/src/commands/blobs/blobs-set.mjs +54 -0
- package/src/commands/blobs/blobs.mjs +32 -0
- package/src/commands/blobs/index.mjs +1 -0
- package/src/commands/build/build.mjs +55 -67
- package/src/commands/build/index.mjs +1 -1
- package/src/commands/completion/completion.mjs +41 -46
- package/src/commands/completion/index.mjs +1 -1
- package/src/commands/deploy/deploy.mjs +675 -710
- package/src/commands/deploy/index.mjs +1 -1
- package/src/commands/dev/dev-exec.mjs +20 -32
- package/src/commands/dev/dev.mjs +217 -302
- package/src/commands/dev/index.mjs +1 -1
- package/src/commands/dev/types.d.ts +30 -0
- package/src/commands/env/env-clone.mjs +157 -184
- package/src/commands/env/env-get.mjs +49 -68
- package/src/commands/env/env-import.mjs +100 -119
- package/src/commands/env/env-list.mjs +104 -129
- package/src/commands/env/env-set.mjs +160 -185
- package/src/commands/env/env-unset.mjs +104 -122
- package/src/commands/env/env.mjs +28 -30
- package/src/commands/env/index.mjs +1 -1
- package/src/commands/functions/functions-build.mjs +29 -41
- package/src/commands/functions/functions-create.mjs +533 -601
- package/src/commands/functions/functions-invoke.mjs +193 -216
- package/src/commands/functions/functions-list.mjs +45 -55
- package/src/commands/functions/functions-serve.mjs +51 -61
- package/src/commands/functions/functions.mjs +26 -32
- package/src/commands/functions/index.mjs +1 -1
- package/src/commands/index.mjs +2 -2
- package/src/commands/init/index.mjs +1 -1
- package/src/commands/init/init.mjs +138 -167
- package/src/commands/integration/deploy.mjs +337 -399
- package/src/commands/integration/index.mjs +12 -13
- package/src/commands/link/index.mjs +1 -1
- package/src/commands/link/link.mjs +298 -317
- package/src/commands/lm/index.mjs +1 -1
- package/src/commands/lm/lm-info.mjs +23 -31
- package/src/commands/lm/lm-install.mjs +13 -17
- package/src/commands/lm/lm-setup.mjs +80 -84
- package/src/commands/lm/lm-uninstall.mjs +7 -12
- package/src/commands/lm/lm.mjs +18 -22
- package/src/commands/login/index.mjs +1 -1
- package/src/commands/login/login.mjs +35 -41
- package/src/commands/logout/index.mjs +1 -1
- package/src/commands/logout/logout.mjs +25 -31
- package/src/commands/main.mjs +166 -201
- package/src/commands/open/index.mjs +1 -1
- package/src/commands/open/open-admin.mjs +15 -18
- package/src/commands/open/open-site.mjs +16 -19
- package/src/commands/open/open.mjs +24 -27
- package/src/commands/recipes/common.mjs +23 -34
- package/src/commands/recipes/index.mjs +1 -1
- package/src/commands/recipes/recipes-list.mjs +13 -20
- package/src/commands/recipes/recipes.mjs +59 -72
- package/src/commands/serve/index.mjs +1 -1
- package/src/commands/serve/serve.mjs +142 -189
- package/src/commands/sites/index.mjs +2 -2
- package/src/commands/sites/sites-create-template.mjs +214 -236
- package/src/commands/sites/sites-create.mjs +145 -157
- package/src/commands/sites/sites-delete.mjs +75 -81
- package/src/commands/sites/sites-list.mjs +63 -66
- package/src/commands/sites/sites.mjs +18 -20
- package/src/commands/status/index.mjs +1 -1
- package/src/commands/status/status-hooks.mjs +32 -34
- package/src/commands/status/status.mjs +99 -106
- package/src/commands/switch/index.mjs +1 -1
- package/src/commands/switch/switch.mjs +32 -37
- package/src/commands/types.d.ts +31 -0
- package/src/commands/unlink/index.mjs +1 -1
- package/src/commands/unlink/unlink.mjs +23 -29
- package/src/commands/watch/index.mjs +1 -1
- package/src/commands/watch/watch.mjs +91 -105
- package/src/functions-templates/javascript/hello/{{name}}.js +2 -3
- package/src/lib/account.mjs +4 -5
- package/src/lib/api.mjs +22 -20
- package/src/lib/blobs/blobs.mjs +36 -45
- package/src/lib/build.mjs +82 -85
- package/src/lib/completion/constants.mjs +2 -4
- package/src/lib/completion/generate-autocompletion.mjs +33 -36
- package/src/lib/completion/get-autocompletion.mjs +31 -35
- package/src/lib/completion/index.mjs +1 -1
- package/src/lib/completion/script.mjs +12 -19
- package/src/lib/edge-functions/bootstrap.mjs +3 -5
- package/src/lib/edge-functions/consts.mjs +9 -10
- package/src/lib/edge-functions/deploy.mjs +28 -34
- package/src/lib/edge-functions/editor-helper.mjs +29 -42
- package/src/lib/edge-functions/headers.mjs +24 -26
- package/src/lib/edge-functions/internal.mjs +38 -44
- package/src/lib/edge-functions/proxy.mjs +229 -228
- package/src/lib/edge-functions/registry.mjs +473 -574
- package/src/lib/exec-fetcher.mjs +115 -122
- package/src/lib/fs.mjs +28 -27
- package/src/lib/functions/background.mjs +16 -20
- package/src/lib/functions/config.mjs +12 -9
- package/src/lib/functions/form-submissions-handler.mjs +143 -149
- package/src/lib/functions/local-proxy.mjs +40 -44
- package/src/lib/functions/memoized-build.mjs +19 -21
- package/src/lib/functions/netlify-function.mjs +269 -249
- package/src/lib/functions/registry.mjs +509 -568
- package/src/lib/functions/runtimes/go/index.mjs +62 -71
- package/src/lib/functions/runtimes/index.mjs +8 -15
- package/src/lib/functions/runtimes/js/builders/netlify-lambda.mjs +55 -64
- package/src/lib/functions/runtimes/js/builders/zisi.mjs +135 -154
- package/src/lib/functions/runtimes/js/constants.mjs +1 -1
- package/src/lib/functions/runtimes/js/index.mjs +92 -109
- package/src/lib/functions/runtimes/js/worker.mjs +43 -45
- package/src/lib/functions/runtimes/rust/index.mjs +64 -73
- package/src/lib/functions/scheduled.mjs +70 -88
- package/src/lib/functions/server.mjs +269 -327
- package/src/lib/functions/synchronous.mjs +118 -147
- package/src/lib/functions/utils.mjs +38 -46
- package/src/lib/geo-location.mjs +69 -81
- package/src/lib/http-agent.mjs +87 -90
- package/src/lib/images/proxy.mjs +97 -99
- package/src/lib/log.mjs +6 -9
- package/src/lib/path.mjs +2 -1
- package/src/lib/render-error-template.mjs +19 -20
- package/src/lib/settings.mjs +17 -19
- package/src/lib/spinner.mjs +21 -23
- package/src/lib/string.mjs +4 -2
- package/src/recipes/vscode/index.mjs +69 -85
- package/src/recipes/vscode/settings.mjs +53 -58
- package/src/utils/addons/compare.mjs +31 -32
- package/src/utils/addons/diffs/index.mjs +16 -17
- package/src/utils/addons/diffs/options.mjs +99 -101
- package/src/utils/addons/prepare.mjs +100 -97
- package/src/utils/addons/prompts.mjs +73 -76
- package/src/utils/addons/render.mjs +33 -36
- package/src/utils/addons/validation.mjs +19 -15
- package/src/utils/banner.mjs +11 -16
- package/src/utils/build-info.mjs +65 -66
- package/src/utils/command-helpers.mjs +185 -199
- package/src/utils/create-deferred.mjs +9 -12
- package/src/utils/create-stream-promise.mjs +54 -47
- package/src/utils/deploy/constants.mjs +9 -11
- package/src/utils/deploy/deploy-site.mjs +162 -182
- package/src/utils/deploy/hash-config.mjs +21 -21
- package/src/utils/deploy/hash-files.mjs +34 -38
- package/src/utils/deploy/hash-fns.mjs +149 -154
- package/src/utils/deploy/hasher-segments.mjs +58 -52
- package/src/utils/deploy/upload-files.mjs +99 -113
- package/src/utils/deploy/util.mjs +85 -91
- package/src/utils/detect-server-settings.mjs +236 -268
- package/src/utils/dev.mjs +163 -178
- package/src/utils/dot-env.mjs +37 -42
- package/src/utils/env/index.mjs +148 -148
- package/src/utils/execa.mjs +9 -13
- package/src/utils/feature-flags.mjs +6 -5
- package/src/utils/framework-server.mjs +43 -52
- package/src/utils/functions/constants.mjs +1 -1
- package/src/utils/functions/functions.mjs +30 -40
- package/src/utils/functions/get-functions.mjs +28 -29
- package/src/utils/functions/index.mjs +3 -3
- package/src/utils/get-global-config.mjs +33 -36
- package/src/utils/get-package-json.mjs +14 -15
- package/src/utils/get-repo-data.mjs +54 -64
- package/src/utils/get-site.mjs +14 -14
- package/src/utils/gh-auth.mjs +79 -100
- package/src/utils/gitignore.mjs +37 -40
- package/src/utils/headers.mjs +33 -35
- package/src/utils/hooks/requires-site-info.mjs +26 -22
- package/src/utils/init/config-github.mjs +207 -219
- package/src/utils/init/config-manual.mjs +83 -100
- package/src/utils/init/config.mjs +25 -26
- package/src/utils/init/node-version.mjs +23 -30
- package/src/utils/init/plugins.mjs +12 -8
- package/src/utils/init/utils.mjs +152 -172
- package/src/utils/live-tunnel.mjs +118 -141
- package/src/utils/lm/install.mjs +220 -259
- package/src/utils/lm/requirements.mjs +54 -63
- package/src/utils/lm/steps.mjs +31 -31
- package/src/utils/lm/ui.mjs +13 -20
- package/src/utils/open-browser.mjs +31 -32
- package/src/utils/parse-raw-flags.mjs +39 -35
- package/src/utils/proxy-server.mjs +84 -71
- package/src/utils/proxy.mjs +696 -750
- package/src/utils/read-repo-url.mjs +48 -47
- package/src/utils/redirects.mjs +49 -49
- package/src/utils/request-id.mjs +2 -4
- package/src/utils/rules-proxy.mjs +96 -100
- package/src/utils/run-build.mjs +109 -132
- package/src/utils/shell.mjs +99 -106
- package/src/utils/sign-redirect.mjs +14 -14
- package/src/utils/sites/utils.mjs +48 -55
- package/src/utils/state-config.mjs +101 -101
- package/src/utils/static-server.mjs +28 -34
- package/src/utils/telemetry/index.mjs +2 -2
- package/src/utils/telemetry/report-error.mjs +45 -49
- package/src/utils/telemetry/request.mjs +36 -43
- package/src/utils/telemetry/telemetry.mjs +90 -105
- package/src/utils/telemetry/utils.mjs +5 -6
- package/src/utils/telemetry/validation.mjs +55 -53
- package/src/utils/types.d.ts +46 -0
- package/src/utils/validation.mjs +10 -13
|
@@ -1,353 +1,334 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import { ensureNetlifyIgnore } from '../../utils/gitignore.mjs'
|
|
10
|
-
import { track } from '../../utils/telemetry/index.mjs'
|
|
11
|
-
|
|
1
|
+
import { Option } from 'commander';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import isEmpty from 'lodash/isEmpty.js';
|
|
4
|
+
import { listSites } from '../../lib/api.mjs';
|
|
5
|
+
import { chalk, error, exit, log } from '../../utils/command-helpers.mjs';
|
|
6
|
+
import getRepoData from '../../utils/get-repo-data.mjs';
|
|
7
|
+
import { ensureNetlifyIgnore } from '../../utils/gitignore.mjs';
|
|
8
|
+
import { track } from '../../utils/telemetry/index.mjs';
|
|
12
9
|
/**
|
|
13
10
|
*
|
|
14
11
|
* @param {import('../base-command.mjs').default} command
|
|
15
12
|
* @param {import('commander').OptionValues} options
|
|
16
13
|
*/
|
|
14
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'command' implicitly has an 'any' type.
|
|
17
15
|
const linkPrompt = async (command, options) => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (!repoData.error) {
|
|
32
|
-
// Add git GIT_REMOTE_PROMPT if in a repo
|
|
33
|
-
GIT_REMOTE_PROMPT = `Use current git remote origin (${repoData.httpsUrl})`
|
|
34
|
-
linkChoices = [GIT_REMOTE_PROMPT, ...linkChoices]
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
log()
|
|
38
|
-
log(`${chalk.cyanBright('netlify link')} will connect this folder to a site on Netlify`)
|
|
39
|
-
log()
|
|
40
|
-
const { linkType } = await inquirer.prompt([
|
|
41
|
-
{
|
|
42
|
-
type: 'list',
|
|
43
|
-
name: 'linkType',
|
|
44
|
-
message: 'How do you want to link this folder to a site?',
|
|
45
|
-
choices: linkChoices,
|
|
46
|
-
},
|
|
47
|
-
])
|
|
48
|
-
|
|
49
|
-
let kind
|
|
50
|
-
switch (linkType) {
|
|
51
|
-
case GIT_REMOTE_PROMPT: {
|
|
52
|
-
kind = 'gitRemote'
|
|
53
|
-
log()
|
|
54
|
-
log(`Looking for sites connected to '${repoData.httpsUrl}'...`)
|
|
55
|
-
log()
|
|
56
|
-
const sites = await listSites({ api, options: { filter: 'all' } })
|
|
57
|
-
|
|
58
|
-
if (sites.length === 0) {
|
|
59
|
-
error(`You don't have any sites yet. Run ${chalk.cyanBright('netlify sites:create')} to create a site.`)
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const matchingSites = sites.filter(
|
|
63
|
-
({ build_settings: buildSettings = {} }) => repoData.httpsUrl === buildSettings.repo_url,
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
// If no remote matches. Throw error
|
|
67
|
-
if (matchingSites.length === 0) {
|
|
68
|
-
log(chalk.redBright.bold.underline(`No Matching Site Found`))
|
|
69
|
-
log()
|
|
70
|
-
log(`No site found with the remote ${repoData.httpsUrl}.
|
|
71
|
-
|
|
72
|
-
Double check you are in the correct working directory and a remote origin repo is configured.
|
|
73
|
-
|
|
74
|
-
Run ${chalk.cyanBright('git remote -v')} to see a list of your git remotes.`)
|
|
75
|
-
|
|
76
|
-
exit()
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Matches a single site hooray!
|
|
80
|
-
if (matchingSites.length === 1) {
|
|
81
|
-
const [firstSite] = matchingSites
|
|
82
|
-
site = firstSite
|
|
83
|
-
} else if (matchingSites.length > 1) {
|
|
84
|
-
// Matches multiple sites. Users must choose which to link.
|
|
85
|
-
log(`Found ${matchingSites.length} matching sites!`)
|
|
86
|
-
|
|
87
|
-
// Prompt which options
|
|
88
|
-
const { selectedSite } = await inquirer.prompt([
|
|
89
|
-
{
|
|
90
|
-
type: 'list',
|
|
91
|
-
name: 'selectedSite',
|
|
92
|
-
message: 'Which site do you want to link?',
|
|
93
|
-
choices: matchingSites.map((matchingSite) => ({
|
|
94
|
-
name: `${matchingSite.name} - ${matchingSite.ssl_url}`,
|
|
95
|
-
value: matchingSite,
|
|
96
|
-
})),
|
|
97
|
-
},
|
|
98
|
-
])
|
|
99
|
-
if (!selectedSite) {
|
|
100
|
-
error('No site selected')
|
|
101
|
-
}
|
|
102
|
-
site = selectedSite
|
|
103
|
-
}
|
|
104
|
-
break
|
|
16
|
+
const { api, state } = command.netlify;
|
|
17
|
+
const SITE_NAME_PROMPT = 'Search by full or partial site name';
|
|
18
|
+
const SITE_LIST_PROMPT = 'Choose from a list of your recently updated sites';
|
|
19
|
+
const SITE_ID_PROMPT = 'Enter a site ID';
|
|
20
|
+
let GIT_REMOTE_PROMPT = 'Use the current git remote origin URL';
|
|
21
|
+
let site;
|
|
22
|
+
// Get git remote data if exists
|
|
23
|
+
const repoData = await getRepoData({ workingDir: command.workingDir, remoteName: options.gitRemoteName });
|
|
24
|
+
let linkChoices = [SITE_NAME_PROMPT, SITE_LIST_PROMPT, SITE_ID_PROMPT];
|
|
25
|
+
if (!repoData.error) {
|
|
26
|
+
// Add git GIT_REMOTE_PROMPT if in a repo
|
|
27
|
+
GIT_REMOTE_PROMPT = `Use current git remote origin (${repoData.httpsUrl})`;
|
|
28
|
+
linkChoices = [GIT_REMOTE_PROMPT, ...linkChoices];
|
|
105
29
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
30
|
+
log();
|
|
31
|
+
log(`${chalk.cyanBright('netlify link')} will connect this folder to a site on Netlify`);
|
|
32
|
+
log();
|
|
33
|
+
const { linkType } = await inquirer.prompt([
|
|
109
34
|
{
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
35
|
+
type: 'list',
|
|
36
|
+
name: 'linkType',
|
|
37
|
+
message: 'How do you want to link this folder to a site?',
|
|
38
|
+
choices: linkChoices,
|
|
113
39
|
},
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
40
|
+
]);
|
|
41
|
+
let kind;
|
|
42
|
+
switch (linkType) {
|
|
43
|
+
case GIT_REMOTE_PROMPT: {
|
|
44
|
+
kind = 'gitRemote';
|
|
45
|
+
log();
|
|
46
|
+
log(`Looking for sites connected to '${repoData.httpsUrl}'...`);
|
|
47
|
+
log();
|
|
48
|
+
const sites = await listSites({ api, options: { filter: 'all' } });
|
|
49
|
+
if (sites.length === 0) {
|
|
50
|
+
error(`You don't have any sites yet. Run ${chalk.cyanBright('netlify sites:create')} to create a site.`);
|
|
51
|
+
}
|
|
52
|
+
const matchingSites = sites.filter(
|
|
53
|
+
// @ts-expect-error TS(2339) FIXME: Property 'repo_url' does not exist on type '{}'.
|
|
54
|
+
({ build_settings: buildSettings = {} }) => repoData.httpsUrl === buildSettings.repo_url);
|
|
55
|
+
// If no remote matches. Throw error
|
|
56
|
+
if (matchingSites.length === 0) {
|
|
57
|
+
log(chalk.redBright.bold.underline(`No Matching Site Found`));
|
|
58
|
+
log();
|
|
59
|
+
log(`No site found with the remote ${repoData.httpsUrl}.
|
|
117
60
|
|
|
118
|
-
|
|
119
|
-
try {
|
|
120
|
-
matchingSites = await listSites({
|
|
121
|
-
api,
|
|
122
|
-
options: { name: searchTerm, filter: 'all' },
|
|
123
|
-
})
|
|
124
|
-
} catch (error_) {
|
|
125
|
-
if (error_.status === 404) {
|
|
126
|
-
error(`'${searchTerm}' not found`)
|
|
127
|
-
} else {
|
|
128
|
-
error(error_)
|
|
129
|
-
}
|
|
130
|
-
}
|
|
61
|
+
Double check you are in the correct working directory and a remote origin repo is configured.
|
|
131
62
|
|
|
132
|
-
|
|
133
|
-
|
|
63
|
+
Run ${chalk.cyanBright('git remote -v')} to see a list of your git remotes.`);
|
|
64
|
+
exit();
|
|
65
|
+
}
|
|
66
|
+
// Matches a single site hooray!
|
|
67
|
+
if (matchingSites.length === 1) {
|
|
68
|
+
const [firstSite] = matchingSites;
|
|
69
|
+
site = firstSite;
|
|
70
|
+
}
|
|
71
|
+
else if (matchingSites.length > 1) {
|
|
72
|
+
// Matches multiple sites. Users must choose which to link.
|
|
73
|
+
log(`Found ${matchingSites.length} matching sites!`);
|
|
74
|
+
// Prompt which options
|
|
75
|
+
const { selectedSite } = await inquirer.prompt([
|
|
76
|
+
{
|
|
77
|
+
type: 'list',
|
|
78
|
+
name: 'selectedSite',
|
|
79
|
+
message: 'Which site do you want to link?',
|
|
80
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'matchingSite' implicitly has an 'any' t... Remove this comment to see the full error message
|
|
81
|
+
choices: matchingSites.map((matchingSite) => ({
|
|
82
|
+
name: `${matchingSite.name} - ${matchingSite.ssl_url}`,
|
|
83
|
+
value: matchingSite,
|
|
84
|
+
})),
|
|
85
|
+
},
|
|
86
|
+
]);
|
|
87
|
+
if (!selectedSite) {
|
|
88
|
+
error('No site selected');
|
|
89
|
+
}
|
|
90
|
+
site = selectedSite;
|
|
91
|
+
}
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
case SITE_NAME_PROMPT: {
|
|
95
|
+
kind = 'byName';
|
|
96
|
+
const { searchTerm } = await inquirer.prompt([
|
|
97
|
+
{
|
|
98
|
+
type: 'input',
|
|
99
|
+
name: 'searchTerm',
|
|
100
|
+
message: 'Enter the site name (or just part of it):',
|
|
101
|
+
},
|
|
102
|
+
]);
|
|
103
|
+
log(`Looking for sites with names containing '${searchTerm}'...`);
|
|
104
|
+
log();
|
|
105
|
+
let matchingSites;
|
|
106
|
+
try {
|
|
107
|
+
matchingSites = await listSites({
|
|
108
|
+
api,
|
|
109
|
+
options: { name: searchTerm, filter: 'all' },
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
catch (error_) {
|
|
113
|
+
// @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
|
|
114
|
+
if (error_.status === 404) {
|
|
115
|
+
error(`'${searchTerm}' not found`);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
// @ts-expect-error TS(2345) FIXME: Argument of type 'unknown' is not assignable to pa... Remove this comment to see the full error message
|
|
119
|
+
error(error_);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (!matchingSites || matchingSites.length === 0) {
|
|
123
|
+
error(`No site names found containing '${searchTerm}'.
|
|
134
124
|
|
|
135
125
|
Run ${chalk.cyanBright('netlify link')} again to try a new search,
|
|
136
|
-
or run ${chalk.cyanBright('netlify sites:create')} to create a site.`)
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
126
|
+
or run ${chalk.cyanBright('netlify sites:create')} to create a site.`);
|
|
127
|
+
}
|
|
128
|
+
if (matchingSites.length > 1) {
|
|
129
|
+
log(`Found ${matchingSites.length} matching sites!`);
|
|
130
|
+
const { selectedSite } = await inquirer.prompt([
|
|
131
|
+
{
|
|
132
|
+
type: 'list',
|
|
133
|
+
name: 'selectedSite',
|
|
134
|
+
message: 'Which site do you want to link?',
|
|
135
|
+
paginated: true,
|
|
136
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'matchingSite' implicitly has an 'any' t... Remove this comment to see the full error message
|
|
137
|
+
choices: matchingSites.map((matchingSite) => ({ name: matchingSite.name, value: matchingSite })),
|
|
138
|
+
},
|
|
139
|
+
]);
|
|
140
|
+
if (!selectedSite) {
|
|
141
|
+
error('No site selected');
|
|
142
|
+
}
|
|
143
|
+
site = selectedSite;
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
const [firstSite] = matchingSites;
|
|
147
|
+
site = firstSite;
|
|
148
|
+
}
|
|
149
|
+
break;
|
|
152
150
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
},
|
|
184
|
-
])
|
|
185
|
-
if (!selectedSite) {
|
|
186
|
-
error('No site selected')
|
|
187
|
-
}
|
|
188
|
-
site = selectedSite
|
|
189
|
-
break
|
|
190
|
-
}
|
|
191
|
-
case SITE_ID_PROMPT: {
|
|
192
|
-
kind = 'bySiteId'
|
|
193
|
-
const { siteId } = await inquirer.prompt([
|
|
194
|
-
{
|
|
195
|
-
type: 'input',
|
|
196
|
-
name: 'siteId',
|
|
197
|
-
message: 'What is the site ID?',
|
|
198
|
-
},
|
|
199
|
-
])
|
|
200
|
-
|
|
201
|
-
try {
|
|
202
|
-
// @ts-ignore types from API are wrong they cannot recognize `getSite` of API
|
|
203
|
-
site = await api.getSite({ siteId })
|
|
204
|
-
} catch (error_) {
|
|
205
|
-
if (error_.status === 404) {
|
|
206
|
-
error(new Error(`Site ID '${siteId}' not found`))
|
|
207
|
-
} else {
|
|
208
|
-
error(error_)
|
|
151
|
+
case SITE_LIST_PROMPT: {
|
|
152
|
+
kind = 'fromList';
|
|
153
|
+
log(`Fetching recently updated sites...`);
|
|
154
|
+
log();
|
|
155
|
+
let sites;
|
|
156
|
+
try {
|
|
157
|
+
sites = await listSites({ api, options: { maxPages: 1, filter: 'all' } });
|
|
158
|
+
}
|
|
159
|
+
catch (error_) {
|
|
160
|
+
// @ts-expect-error TS(2345) FIXME: Argument of type 'unknown' is not assignable to pa... Remove this comment to see the full error message
|
|
161
|
+
error(error_);
|
|
162
|
+
}
|
|
163
|
+
if (!sites || sites.length === 0) {
|
|
164
|
+
error(`You don't have any sites yet. Run ${chalk.cyanBright('netlify sites:create')} to create a site.`);
|
|
165
|
+
}
|
|
166
|
+
const { selectedSite } = await inquirer.prompt([
|
|
167
|
+
{
|
|
168
|
+
type: 'list',
|
|
169
|
+
name: 'selectedSite',
|
|
170
|
+
message: 'Which site do you want to link?',
|
|
171
|
+
paginated: true,
|
|
172
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'matchingSite' implicitly has an 'any' t... Remove this comment to see the full error message
|
|
173
|
+
choices: sites.map((matchingSite) => ({ name: matchingSite.name, value: matchingSite })),
|
|
174
|
+
},
|
|
175
|
+
]);
|
|
176
|
+
if (!selectedSite) {
|
|
177
|
+
error('No site selected');
|
|
178
|
+
}
|
|
179
|
+
site = selectedSite;
|
|
180
|
+
break;
|
|
209
181
|
}
|
|
210
|
-
|
|
211
|
-
|
|
182
|
+
case SITE_ID_PROMPT: {
|
|
183
|
+
kind = 'bySiteId';
|
|
184
|
+
const { siteId } = await inquirer.prompt([
|
|
185
|
+
{
|
|
186
|
+
type: 'input',
|
|
187
|
+
name: 'siteId',
|
|
188
|
+
message: 'What is the site ID?',
|
|
189
|
+
},
|
|
190
|
+
]);
|
|
191
|
+
try {
|
|
192
|
+
site = await api.getSite({ siteId });
|
|
193
|
+
}
|
|
194
|
+
catch (error_) {
|
|
195
|
+
// @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
|
|
196
|
+
if (error_.status === 404) {
|
|
197
|
+
// @ts-expect-error TS(2345) FIXME: Argument of type 'Error' is not assignable to para... Remove this comment to see the full error message
|
|
198
|
+
error(new Error(`Site ID '${siteId}' not found`));
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
// @ts-expect-error TS(2345) FIXME: Argument of type 'unknown' is not assignable to pa... Remove this comment to see the full error message
|
|
202
|
+
error(error_);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
default:
|
|
208
|
+
return;
|
|
212
209
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
log(`Admin url: ${chalk.magentaBright(site.admin_url)}`)
|
|
235
|
-
log(`Site url: ${chalk.cyanBright(site.ssl_url || site.url)}`)
|
|
236
|
-
log()
|
|
237
|
-
log(`You can now run other \`netlify\` cli commands in this directory`)
|
|
238
|
-
|
|
239
|
-
return site
|
|
240
|
-
}
|
|
241
|
-
|
|
210
|
+
if (!site) {
|
|
211
|
+
// @ts-expect-error TS(2345) FIXME: Argument of type 'Error' is not assignable to para... Remove this comment to see the full error message
|
|
212
|
+
error(new Error(`No site found`));
|
|
213
|
+
}
|
|
214
|
+
// Save site ID to config
|
|
215
|
+
state.set('siteId', site.id);
|
|
216
|
+
await track('sites_linked', {
|
|
217
|
+
siteId: site.id,
|
|
218
|
+
linkType: 'prompt',
|
|
219
|
+
kind,
|
|
220
|
+
});
|
|
221
|
+
// Log output
|
|
222
|
+
log();
|
|
223
|
+
log(chalk.greenBright.bold.underline(`Directory Linked`));
|
|
224
|
+
log();
|
|
225
|
+
log(`Admin url: ${chalk.magentaBright(site.admin_url)}`);
|
|
226
|
+
log(`Site url: ${chalk.cyanBright(site.ssl_url || site.url)}`);
|
|
227
|
+
log();
|
|
228
|
+
log(`You can now run other \`netlify\` cli commands in this directory`);
|
|
229
|
+
return site;
|
|
230
|
+
};
|
|
242
231
|
/**
|
|
243
232
|
* The link command
|
|
244
233
|
* @param {import('commander').OptionValues} options
|
|
245
234
|
* @param {import('../base-command.mjs').default} command
|
|
246
235
|
*/
|
|
236
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'options' implicitly has an 'any' type.
|
|
247
237
|
export const link = async (options, command) => {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
repositoryRoot
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
let siteData = siteInfo
|
|
259
|
-
|
|
260
|
-
// Add .netlify to .gitignore file
|
|
261
|
-
await ensureNetlifyIgnore(repositoryRoot)
|
|
262
|
-
|
|
263
|
-
// Site id is incorrect
|
|
264
|
-
if (siteId && isEmpty(siteData)) {
|
|
265
|
-
log(`"${siteId}" was not found in your Netlify account.`)
|
|
266
|
-
log(`Please double check your siteID and which account you are logged into via \`netlify status\`.`)
|
|
267
|
-
return exit()
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if (!isEmpty(siteInfo)) {
|
|
271
|
-
// If already linked to site. exit and prompt for unlink
|
|
272
|
-
log(`Site already linked to "${siteData.name}"`)
|
|
273
|
-
log(`Admin url: ${siteData.admin_url}`)
|
|
274
|
-
log()
|
|
275
|
-
log(`To unlink this site, run: ${chalk.cyanBright('netlify unlink')}`)
|
|
276
|
-
} else if (options.id) {
|
|
277
|
-
try {
|
|
278
|
-
// @ts-ignore types from API are wrong they cannot recognize `getSite` of API
|
|
279
|
-
siteData = await api.getSite({ site_id: options.id })
|
|
280
|
-
} catch (error_) {
|
|
281
|
-
if (error_.status === 404) {
|
|
282
|
-
error(new Error(`Site id ${options.id} not found`))
|
|
283
|
-
} else {
|
|
284
|
-
error(error_)
|
|
285
|
-
}
|
|
238
|
+
await command.authenticate();
|
|
239
|
+
const { api, repositoryRoot, site: { id: siteId }, siteInfo, state, } = command.netlify;
|
|
240
|
+
let siteData = siteInfo;
|
|
241
|
+
// Add .netlify to .gitignore file
|
|
242
|
+
await ensureNetlifyIgnore(repositoryRoot);
|
|
243
|
+
// Site id is incorrect
|
|
244
|
+
if (siteId && isEmpty(siteData)) {
|
|
245
|
+
log(`"${siteId}" was not found in your Netlify account.`);
|
|
246
|
+
log(`Please double check your siteID and which account you are logged into via \`netlify status\`.`);
|
|
247
|
+
return exit();
|
|
286
248
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
siteId: siteData.id,
|
|
294
|
-
linkType: 'manual',
|
|
295
|
-
kind: 'byId',
|
|
296
|
-
})
|
|
297
|
-
} else if (options.name) {
|
|
298
|
-
let results
|
|
299
|
-
try {
|
|
300
|
-
results = await listSites({
|
|
301
|
-
api,
|
|
302
|
-
options: {
|
|
303
|
-
name: options.name,
|
|
304
|
-
filter: 'all',
|
|
305
|
-
},
|
|
306
|
-
})
|
|
307
|
-
} catch (error_) {
|
|
308
|
-
if (error_.status === 404) {
|
|
309
|
-
error(new Error(`${options.name} not found`))
|
|
310
|
-
} else {
|
|
311
|
-
error(error_)
|
|
312
|
-
}
|
|
249
|
+
if (!isEmpty(siteInfo)) {
|
|
250
|
+
// If already linked to site. exit and prompt for unlink
|
|
251
|
+
log(`Site already linked to "${siteData.name}"`);
|
|
252
|
+
log(`Admin url: ${siteData.admin_url}`);
|
|
253
|
+
log();
|
|
254
|
+
log(`To unlink this site, run: ${chalk.cyanBright('netlify unlink')}`);
|
|
313
255
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
256
|
+
else if (options.id) {
|
|
257
|
+
try {
|
|
258
|
+
siteData = await api.getSite({ site_id: options.id });
|
|
259
|
+
}
|
|
260
|
+
catch (error_) {
|
|
261
|
+
// @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
|
|
262
|
+
if (error_.status === 404) {
|
|
263
|
+
// @ts-expect-error TS(2345) FIXME: Argument of type 'Error' is not assignable to para... Remove this comment to see the full error message
|
|
264
|
+
error(new Error(`Site id ${options.id} not found`));
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
// @ts-expect-error TS(2345) FIXME: Argument of type 'unknown' is not assignable to pa... Remove this comment to see the full error message
|
|
268
|
+
error(error_);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
// Save site ID
|
|
272
|
+
state.set('siteId', siteData.id);
|
|
273
|
+
log(`Linked to ${siteData.name}`);
|
|
274
|
+
await track('sites_linked', {
|
|
275
|
+
siteId: siteData.id,
|
|
276
|
+
linkType: 'manual',
|
|
277
|
+
kind: 'byId',
|
|
278
|
+
});
|
|
317
279
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
280
|
+
else if (options.name) {
|
|
281
|
+
let results;
|
|
282
|
+
try {
|
|
283
|
+
results = await listSites({
|
|
284
|
+
api,
|
|
285
|
+
options: {
|
|
286
|
+
name: options.name,
|
|
287
|
+
filter: 'all',
|
|
288
|
+
},
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
catch (error_) {
|
|
292
|
+
// @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
|
|
293
|
+
if (error_.status === 404) {
|
|
294
|
+
// @ts-expect-error TS(2345) FIXME: Argument of type 'Error' is not assignable to para... Remove this comment to see the full error message
|
|
295
|
+
error(new Error(`${options.name} not found`));
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
// @ts-expect-error TS(2345) FIXME: Argument of type 'unknown' is not assignable to pa... Remove this comment to see the full error message
|
|
299
|
+
error(error_);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
if (results.length === 0) {
|
|
303
|
+
// @ts-expect-error TS(2345) FIXME: Argument of type 'Error' is not assignable to para... Remove this comment to see the full error message
|
|
304
|
+
error(new Error(`No sites found named ${options.name}`));
|
|
305
|
+
}
|
|
306
|
+
const [firstSiteData] = results;
|
|
307
|
+
state.set('siteId', firstSiteData.id);
|
|
308
|
+
log(`Linked to ${firstSiteData.name}`);
|
|
309
|
+
await track('sites_linked', {
|
|
310
|
+
siteId: (firstSiteData && firstSiteData.id) || siteId,
|
|
311
|
+
linkType: 'manual',
|
|
312
|
+
kind: 'byName',
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
siteData = await linkPrompt(command, options);
|
|
317
|
+
}
|
|
318
|
+
return siteData;
|
|
319
|
+
};
|
|
334
320
|
/**
|
|
335
321
|
* Creates the `netlify link` command
|
|
336
322
|
* @param {import('../base-command.mjs').default} program
|
|
337
323
|
* @returns
|
|
338
324
|
*/
|
|
339
|
-
|
|
340
|
-
|
|
325
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'program' implicitly has an 'any' type.
|
|
326
|
+
export const createLinkCommand = (program) => program
|
|
341
327
|
.command('link')
|
|
342
328
|
.description('Link a local repo or project folder to an existing site on Netlify')
|
|
343
329
|
.option('--id <id>', 'ID of site to link to')
|
|
344
330
|
.option('--name <name>', 'Name of site to link to')
|
|
345
|
-
.addOption(
|
|
346
|
-
new Option(
|
|
347
|
-
'--gitRemoteName <name>',
|
|
348
|
-
'Old, prefer --git-remote-name. Name of Git remote to use. e.g. "origin"',
|
|
349
|
-
).hideHelp(true),
|
|
350
|
-
)
|
|
331
|
+
.addOption(new Option('--gitRemoteName <name>', 'Old, prefer --git-remote-name. Name of Git remote to use. e.g. "origin"').hideHelp(true))
|
|
351
332
|
.option('--git-remote-name <name>', 'Name of Git remote to use. e.g. "origin"')
|
|
352
333
|
.addExamples(['netlify link', 'netlify link --id 123-123-123-123', 'netlify link --name my-site-name'])
|
|
353
|
-
.action(link)
|
|
334
|
+
.action(link);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { createLmCommand } from './lm.mjs'
|
|
1
|
+
export { createLmCommand } from './lm.mjs';
|