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,68 +1,56 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import {
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
logJson,
|
|
29
|
-
NETLIFYDEV,
|
|
30
|
-
NETLIFYDEVERR,
|
|
31
|
-
NETLIFYDEVLOG,
|
|
32
|
-
warn,
|
|
33
|
-
} from '../../utils/command-helpers.mjs'
|
|
34
|
-
import { DEFAULT_DEPLOY_TIMEOUT } from '../../utils/deploy/constants.mjs'
|
|
35
|
-
import { deploySite } from '../../utils/deploy/deploy-site.mjs'
|
|
36
|
-
import { getEnvelopeEnv } from '../../utils/env/index.mjs'
|
|
37
|
-
import { getFunctionsManifestPath, getInternalFunctionsDir } from '../../utils/functions/index.mjs'
|
|
38
|
-
import openBrowser from '../../utils/open-browser.mjs'
|
|
39
|
-
import { link } from '../link/index.mjs'
|
|
40
|
-
import { sitesCreate } from '../sites/index.mjs'
|
|
41
|
-
|
|
1
|
+
import { stat } from 'fs/promises';
|
|
2
|
+
import { basename, resolve } from 'path';
|
|
3
|
+
import { env } from 'process';
|
|
4
|
+
import { runCoreSteps } from '@netlify/build';
|
|
5
|
+
import { Option } from 'commander';
|
|
6
|
+
import inquirer from 'inquirer';
|
|
7
|
+
import isEmpty from 'lodash/isEmpty.js';
|
|
8
|
+
import isObject from 'lodash/isObject.js';
|
|
9
|
+
import { parseAllHeaders } from 'netlify-headers-parser';
|
|
10
|
+
import { parseAllRedirects } from 'netlify-redirect-parser';
|
|
11
|
+
import prettyjson from 'prettyjson';
|
|
12
|
+
import { cancelDeploy } from '../../lib/api.mjs';
|
|
13
|
+
import { getBuildOptions, runBuild } from '../../lib/build.mjs';
|
|
14
|
+
import { getBootstrapURL } from '../../lib/edge-functions/bootstrap.mjs';
|
|
15
|
+
import { featureFlags as edgeFunctionsFeatureFlags } from '../../lib/edge-functions/consts.mjs';
|
|
16
|
+
import { normalizeFunctionsConfig } from '../../lib/functions/config.mjs';
|
|
17
|
+
import { BACKGROUND_FUNCTIONS_WARNING } from '../../lib/log.mjs';
|
|
18
|
+
import { startSpinner, stopSpinner } from '../../lib/spinner.mjs';
|
|
19
|
+
import { chalk, error, exit, getToken, log, logJson, NETLIFYDEV, NETLIFYDEVERR, NETLIFYDEVLOG, warn, } from '../../utils/command-helpers.mjs';
|
|
20
|
+
import { DEFAULT_DEPLOY_TIMEOUT } from '../../utils/deploy/constants.mjs';
|
|
21
|
+
import { deploySite } from '../../utils/deploy/deploy-site.mjs';
|
|
22
|
+
import { getEnvelopeEnv } from '../../utils/env/index.mjs';
|
|
23
|
+
import { getFunctionsManifestPath, getInternalFunctionsDir } from '../../utils/functions/index.mjs';
|
|
24
|
+
import openBrowser from '../../utils/open-browser.mjs';
|
|
25
|
+
import { link } from '../link/index.mjs';
|
|
26
|
+
import { sitesCreate } from '../sites/index.mjs';
|
|
27
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
|
|
42
28
|
const triggerDeploy = async ({ api, options, siteData, siteId }) => {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
29
|
+
try {
|
|
30
|
+
const siteBuild = await api.createSiteBuild({ siteId });
|
|
31
|
+
if (options.json) {
|
|
32
|
+
logJson({
|
|
33
|
+
site_id: siteId,
|
|
34
|
+
site_name: siteData.name,
|
|
35
|
+
deploy_id: `${siteBuild.deploy_id}`,
|
|
36
|
+
logs: `https://app.netlify.com/sites/${siteData.name}/deploys/${siteBuild.deploy_id}`,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
log(`${NETLIFYDEV} A new deployment was triggered successfully. Visit https://app.netlify.com/sites/${siteData.name}/deploys/${siteBuild.deploy_id} to see the logs.`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch (error_) {
|
|
44
|
+
// @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
|
|
45
|
+
if (error_.status === 404) {
|
|
46
|
+
error('Site not found. Please rerun "netlify link" and make sure that your site has CI configured.');
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
// @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
|
|
50
|
+
error(error_.message);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
};
|
|
66
54
|
/**
|
|
67
55
|
* Retrieves the folder containing the static files that need to be deployed
|
|
68
56
|
* @param {object} config
|
|
@@ -73,64 +61,65 @@ const triggerDeploy = async ({ api, options, siteData, siteId }) => {
|
|
|
73
61
|
* @param {object} config.siteData
|
|
74
62
|
* @returns {Promise<string>}
|
|
75
63
|
*/
|
|
64
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'command' implicitly has an 'any' ... Remove this comment to see the full error message
|
|
76
65
|
const getDeployFolder = async ({ command, config, options, site, siteData }) => {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
|
|
66
|
+
let deployFolder;
|
|
67
|
+
// if the `--dir .` flag is provided we should resolve it to the working directory.
|
|
68
|
+
// - in regular sites this is the `process.cwd`
|
|
69
|
+
// - in mono repositories this will be the root of the jsWorkspace
|
|
70
|
+
if (options.dir) {
|
|
71
|
+
deployFolder = command.workspacePackage
|
|
72
|
+
? resolve(command.jsWorkspaceRoot || site.root, options.dir)
|
|
73
|
+
: resolve(command.workingDir, options.dir);
|
|
74
|
+
}
|
|
75
|
+
else if (config?.build?.publish) {
|
|
76
|
+
deployFolder = resolve(site.root, config.build.publish);
|
|
77
|
+
}
|
|
78
|
+
else if (siteData?.build_settings?.dir) {
|
|
79
|
+
deployFolder = resolve(site.root, siteData.build_settings.dir);
|
|
80
|
+
}
|
|
81
|
+
if (!deployFolder) {
|
|
82
|
+
log('Please provide a publish directory (e.g. "public" or "dist" or "."):');
|
|
83
|
+
const { promptPath } = await inquirer.prompt([
|
|
84
|
+
{
|
|
85
|
+
type: 'input',
|
|
86
|
+
name: 'promptPath',
|
|
87
|
+
message: 'Publish directory',
|
|
88
|
+
default: '.',
|
|
89
|
+
filter: (input) => resolve(command.workingDir, input),
|
|
90
|
+
},
|
|
91
|
+
]);
|
|
92
|
+
deployFolder = promptPath;
|
|
93
|
+
}
|
|
94
|
+
return deployFolder;
|
|
95
|
+
};
|
|
108
96
|
/**
|
|
109
97
|
* @param {string} deployFolder
|
|
110
98
|
*/
|
|
99
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'deployFolder' implicitly has an 'any' t... Remove this comment to see the full error message
|
|
111
100
|
const validateDeployFolder = async (deployFolder) => {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
} catch (error_) {
|
|
117
|
-
if (error_.code === 'ENOENT') {
|
|
118
|
-
return error(`No such directory ${deployFolder}! Did you forget to run a build?`)
|
|
101
|
+
/** @type {import('fs').Stats} */
|
|
102
|
+
let stats;
|
|
103
|
+
try {
|
|
104
|
+
stats = await stat(deployFolder);
|
|
119
105
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
106
|
+
catch (error_) {
|
|
107
|
+
// @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
|
|
108
|
+
if (error_.code === 'ENOENT') {
|
|
109
|
+
return error(`No such directory ${deployFolder}! Did you forget to run a build?`);
|
|
110
|
+
}
|
|
111
|
+
// Improve the message of permission errors
|
|
112
|
+
// @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
|
|
113
|
+
if (error_.code === 'EACCES') {
|
|
114
|
+
return error('Permission error when trying to access deploy folder');
|
|
115
|
+
}
|
|
116
|
+
throw error_;
|
|
124
117
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
return stats
|
|
132
|
-
}
|
|
133
|
-
|
|
118
|
+
if (!stats.isDirectory()) {
|
|
119
|
+
return error('Deploy target must be a path to a directory');
|
|
120
|
+
}
|
|
121
|
+
return stats;
|
|
122
|
+
};
|
|
134
123
|
/**
|
|
135
124
|
* get the functions directory
|
|
136
125
|
* @param {object} config
|
|
@@ -141,291 +130,299 @@ const validateDeployFolder = async (deployFolder) => {
|
|
|
141
130
|
* @param {string} config.workingDir // The process working directory
|
|
142
131
|
* @returns {string|undefined}
|
|
143
132
|
*/
|
|
133
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'config' implicitly has an 'any' t... Remove this comment to see the full error message
|
|
144
134
|
const getFunctionsFolder = ({ config, options, site, siteData, workingDir }) => {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
|
|
135
|
+
let functionsFolder;
|
|
136
|
+
// Support "functions" and "Functions"
|
|
137
|
+
const funcConfig = config.functionsDirectory;
|
|
138
|
+
if (options.functions) {
|
|
139
|
+
functionsFolder = resolve(workingDir, options.functions);
|
|
140
|
+
}
|
|
141
|
+
else if (funcConfig) {
|
|
142
|
+
functionsFolder = resolve(site.root, funcConfig);
|
|
143
|
+
}
|
|
144
|
+
else if (siteData?.build_settings?.functions_dir) {
|
|
145
|
+
functionsFolder = resolve(site.root, siteData.build_settings.functions_dir);
|
|
146
|
+
}
|
|
147
|
+
return functionsFolder;
|
|
148
|
+
};
|
|
158
149
|
/**
|
|
159
150
|
*
|
|
160
151
|
* @param {string|undefined} functionsFolder
|
|
161
152
|
*/
|
|
153
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'functionsFolder' implicitly has an 'any... Remove this comment to see the full error message
|
|
162
154
|
const validateFunctionsFolder = async (functionsFolder) => {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
155
|
+
/** @type {import('fs').Stats|undefined} */
|
|
156
|
+
let stats;
|
|
157
|
+
if (functionsFolder) {
|
|
158
|
+
// we used to hard error if functions folder is specified but doesn't exist
|
|
159
|
+
// but this was too strict for onboarding. we can just log a warning.
|
|
160
|
+
try {
|
|
161
|
+
stats = await stat(functionsFolder);
|
|
162
|
+
}
|
|
163
|
+
catch (error_) {
|
|
164
|
+
// @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
|
|
165
|
+
if (error_.code === 'ENOENT') {
|
|
166
|
+
log(`Functions folder "${functionsFolder}" specified but it doesn't exist! Will proceed without deploying functions`);
|
|
167
|
+
}
|
|
168
|
+
// Improve the message of permission errors
|
|
169
|
+
// @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
|
|
170
|
+
if (error_.code === 'EACCES') {
|
|
171
|
+
error('Permission error when trying to access functions folder');
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (stats && !stats.isDirectory()) {
|
|
176
|
+
error('Functions folder must be a path to a directory');
|
|
177
|
+
}
|
|
178
|
+
return stats;
|
|
179
|
+
};
|
|
180
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'deployFolder' implicitly has an '... Remove this comment to see the full error message
|
|
190
181
|
const validateFolders = async ({ deployFolder, functionsFolder }) => {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
-
|
|
182
|
+
const deployFolderStat = await validateDeployFolder(deployFolder);
|
|
183
|
+
const functionsFolderStat = await validateFunctionsFolder(functionsFolder);
|
|
184
|
+
return { deployFolderStat, functionsFolderStat };
|
|
185
|
+
};
|
|
196
186
|
/**
|
|
197
187
|
* @param {object} config
|
|
198
188
|
* @param {string} config.deployFolder
|
|
199
189
|
* @param {*} config.site
|
|
200
190
|
* @returns
|
|
201
191
|
*/
|
|
192
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'deployFolder' implicitly has an '... Remove this comment to see the full error message
|
|
202
193
|
const getDeployFilesFilter = ({ deployFolder, site }) => {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
const SEC_TO_MILLISEC = 1e3
|
|
194
|
+
// site.root === deployFolder can happen when users run `netlify deploy --dir .`
|
|
195
|
+
// in that specific case we don't want to publish the repo node_modules
|
|
196
|
+
// when site.root !== deployFolder the behaviour matches our buildbot
|
|
197
|
+
const skipNodeModules = site.root === deployFolder;
|
|
198
|
+
/**
|
|
199
|
+
* @param {string} filename
|
|
200
|
+
*/
|
|
201
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'filename' implicitly has an 'any' type.
|
|
202
|
+
return (filename) => {
|
|
203
|
+
if (filename == null) {
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
if (filename === deployFolder) {
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
const base = basename(filename);
|
|
210
|
+
const skipFile = (skipNodeModules && base === 'node_modules') ||
|
|
211
|
+
(base.startsWith('.') && base !== '.well-known') ||
|
|
212
|
+
base.startsWith('__MACOSX') ||
|
|
213
|
+
base.includes('/.') ||
|
|
214
|
+
// headers and redirects are bundled in the config
|
|
215
|
+
base === '_redirects' ||
|
|
216
|
+
base === '_headers';
|
|
217
|
+
return !skipFile;
|
|
218
|
+
};
|
|
219
|
+
};
|
|
220
|
+
const SEC_TO_MILLISEC = 1e3;
|
|
234
221
|
// 100 bytes
|
|
235
|
-
const SYNC_FILE_LIMIT = 1e2
|
|
236
|
-
|
|
222
|
+
const SYNC_FILE_LIMIT = 1e2;
|
|
223
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
|
|
237
224
|
const prepareProductionDeploy = async ({ api, siteData }) => {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
225
|
+
if (isObject(siteData.published_deploy) && siteData.published_deploy.locked) {
|
|
226
|
+
log(`\n${NETLIFYDEVERR} Deployments are "locked" for production context of this site\n`);
|
|
227
|
+
const { unlockChoice } = await inquirer.prompt([
|
|
228
|
+
{
|
|
229
|
+
type: 'confirm',
|
|
230
|
+
name: 'unlockChoice',
|
|
231
|
+
message: 'Would you like to "unlock" deployments for production context to proceed?',
|
|
232
|
+
default: false,
|
|
233
|
+
},
|
|
234
|
+
]);
|
|
235
|
+
if (!unlockChoice)
|
|
236
|
+
exit(0);
|
|
237
|
+
await api.unlockDeploy({ deploy_id: siteData.published_deploy.id });
|
|
238
|
+
log(`\n${NETLIFYDEVLOG} "Auto publishing" has been enabled for production context\n`);
|
|
239
|
+
}
|
|
240
|
+
log('Deploying to main site URL...');
|
|
241
|
+
};
|
|
242
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'actual' implicitly has an 'any' type.
|
|
255
243
|
const hasErrorMessage = (actual, expected) => {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
}
|
|
261
|
-
|
|
244
|
+
if (typeof actual === 'string') {
|
|
245
|
+
return actual.includes(expected);
|
|
246
|
+
}
|
|
247
|
+
return false;
|
|
248
|
+
};
|
|
249
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'error_' implicitly has an 'any' t... Remove this comment to see the full error message
|
|
262
250
|
const reportDeployError = ({ error_, failAndExit }) => {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
291
|
-
|
|
251
|
+
switch (true) {
|
|
252
|
+
case error_.name === 'JSONHTTPError': {
|
|
253
|
+
const message = error_?.json?.message ?? '';
|
|
254
|
+
if (hasErrorMessage(message, 'Background Functions not allowed by team plan')) {
|
|
255
|
+
return failAndExit(`\n${BACKGROUND_FUNCTIONS_WARNING}`);
|
|
256
|
+
}
|
|
257
|
+
warn(`JSONHTTPError: ${message} ${error_.status}`);
|
|
258
|
+
warn(`\n${JSON.stringify(error_, null, ' ')}\n`);
|
|
259
|
+
failAndExit(error_);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
case error_.name === 'TextHTTPError': {
|
|
263
|
+
warn(`TextHTTPError: ${error_.status}`);
|
|
264
|
+
warn(`\n${error_}\n`);
|
|
265
|
+
failAndExit(error_);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
case hasErrorMessage(error_.message, 'Invalid filename'): {
|
|
269
|
+
warn(error_.message);
|
|
270
|
+
failAndExit(error_);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
default: {
|
|
274
|
+
warn(`\n${JSON.stringify(error_, null, ' ')}\n`);
|
|
275
|
+
failAndExit(error_);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
};
|
|
292
279
|
const deployProgressCb = function () {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
280
|
+
/**
|
|
281
|
+
* @type {Record<string, import('ora').Ora>}
|
|
282
|
+
*/
|
|
283
|
+
const events = {};
|
|
284
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'event' implicitly has an 'any' type.
|
|
285
|
+
return (event) => {
|
|
286
|
+
switch (event.phase) {
|
|
287
|
+
case 'start': {
|
|
288
|
+
// @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
|
|
289
|
+
events[event.type] = startSpinner({
|
|
290
|
+
text: event.msg,
|
|
291
|
+
});
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
case 'progress': {
|
|
295
|
+
// @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
|
|
296
|
+
const spinner = events[event.type];
|
|
297
|
+
if (spinner) {
|
|
298
|
+
spinner.text = event.msg;
|
|
299
|
+
}
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
case 'error':
|
|
303
|
+
// @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
|
|
304
|
+
stopSpinner({ error: true, spinner: events[event.type], text: event.msg });
|
|
305
|
+
// @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
|
|
306
|
+
delete events[event.type];
|
|
307
|
+
return;
|
|
308
|
+
case 'stop':
|
|
309
|
+
default: {
|
|
310
|
+
// @ts-expect-error TS(2345) FIXME: Argument of type '{ spinner: any; text: any; }' is... Remove this comment to see the full error message
|
|
311
|
+
stopSpinner({ spinner: events[event.type], text: event.msg });
|
|
312
|
+
// @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
|
|
313
|
+
delete events[event.type];
|
|
314
|
+
}
|
|
309
315
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
316
|
+
};
|
|
317
|
+
};
|
|
318
|
+
const runDeploy = async ({
|
|
319
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'alias' implicitly has an 'any' ty... Remove this comment to see the full error message
|
|
320
|
+
alias,
|
|
321
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
|
|
322
|
+
api,
|
|
323
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'command' implicitly has an 'any' ... Remove this comment to see the full error message
|
|
324
|
+
command,
|
|
325
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'config' implicitly has an 'any' t... Remove this comment to see the full error message
|
|
326
|
+
config,
|
|
327
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'deployFolder' implicitly has an '... Remove this comment to see the full error message
|
|
328
|
+
deployFolder,
|
|
329
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'deployTimeout' implicitly has an ... Remove this comment to see the full error message
|
|
330
|
+
deployTimeout,
|
|
331
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'deployToProduction' implicitly ha... Remove this comment to see the full error message
|
|
332
|
+
deployToProduction,
|
|
333
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'functionsConfig' implicitly has a... Remove this comment to see the full error message
|
|
334
|
+
functionsConfig,
|
|
335
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'functionsFolder' implicitly has a... Remove this comment to see the full error message
|
|
336
|
+
functionsFolder,
|
|
337
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'packagePath' implicitly has an 'a... Remove this comment to see the full error message
|
|
338
|
+
packagePath,
|
|
339
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'silent' implicitly has an 'any' t... Remove this comment to see the full error message
|
|
340
|
+
silent,
|
|
341
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'site' implicitly has an 'any' typ... Remove this comment to see the full error message
|
|
342
|
+
site,
|
|
343
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'siteData' implicitly has an 'any'... Remove this comment to see the full error message
|
|
344
|
+
siteData,
|
|
345
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'siteId' implicitly has an 'any' t... Remove this comment to see the full error message
|
|
346
|
+
siteId,
|
|
347
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'skipFunctionsCache' implicitly ha... Remove this comment to see the full error message
|
|
348
|
+
skipFunctionsCache,
|
|
349
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'title' implicitly has an 'any' ty... Remove this comment to see the full error message
|
|
350
|
+
title, }) => {
|
|
351
|
+
let results;
|
|
352
|
+
let deployId;
|
|
353
|
+
try {
|
|
354
|
+
if (deployToProduction) {
|
|
355
|
+
await prepareProductionDeploy({ siteData, api });
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
log('Deploying to draft URL...');
|
|
359
|
+
}
|
|
360
|
+
const draft = !deployToProduction && !alias;
|
|
361
|
+
results = await api.createSiteDeploy({ siteId, title, body: { draft, branch: alias } });
|
|
362
|
+
deployId = results.id;
|
|
363
|
+
// @ts-expect-error TS(2345) FIXME: Argument of type '{ base: any; packagePath: any; }... Remove this comment to see the full error message
|
|
364
|
+
const internalFunctionsFolder = await getInternalFunctionsDir({ base: site.root, packagePath });
|
|
365
|
+
// The order of the directories matter: zip-it-and-ship-it will prioritize
|
|
366
|
+
// functions from the rightmost directories. In this case, we want user
|
|
367
|
+
// functions to take precedence over internal functions.
|
|
368
|
+
const functionDirectories = [internalFunctionsFolder, functionsFolder].filter(Boolean);
|
|
369
|
+
const manifestPath = skipFunctionsCache ? null : await getFunctionsManifestPath({ base: site.root, packagePath });
|
|
370
|
+
const redirectsPath = `${deployFolder}/_redirects`;
|
|
371
|
+
const headersPath = `${deployFolder}/_headers`;
|
|
372
|
+
const { redirects } = await parseAllRedirects({
|
|
373
|
+
configRedirects: config.redirects,
|
|
374
|
+
redirectsFiles: [redirectsPath],
|
|
375
|
+
minimal: true,
|
|
376
|
+
});
|
|
377
|
+
config.redirects = redirects;
|
|
378
|
+
const { headers } = await parseAllHeaders({
|
|
379
|
+
configHeaders: config.headers,
|
|
380
|
+
// @ts-expect-error TS(2322) FIXME: Type 'string' is not assignable to type 'never'.
|
|
381
|
+
headersFiles: [headersPath],
|
|
382
|
+
minimal: true,
|
|
383
|
+
});
|
|
384
|
+
config.headers = headers;
|
|
385
|
+
results = await deploySite(api, siteId, deployFolder, {
|
|
386
|
+
config,
|
|
387
|
+
// @ts-expect-error TS(2322) FIXME: Type 'any[]' is not assignable to type 'never[]'.
|
|
388
|
+
fnDir: functionDirectories,
|
|
389
|
+
functionsConfig,
|
|
390
|
+
// @ts-expect-error TS(2322) FIXME: Type '(event: any) => void' is not assignable to t... Remove this comment to see the full error message
|
|
391
|
+
statusCb: silent ? () => { } : deployProgressCb(),
|
|
392
|
+
deployTimeout,
|
|
393
|
+
syncFileLimit: SYNC_FILE_LIMIT,
|
|
394
|
+
// pass an existing deployId to update
|
|
395
|
+
deployId,
|
|
396
|
+
filter: getDeployFilesFilter({ site, deployFolder }),
|
|
397
|
+
workingDir: command.workingDir,
|
|
398
|
+
manifestPath,
|
|
399
|
+
skipFunctionsCache,
|
|
400
|
+
siteRoot: site.root,
|
|
401
|
+
});
|
|
351
402
|
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
const { headers } = await parseAllHeaders({
|
|
377
|
-
configHeaders: config.headers,
|
|
378
|
-
// @ts-ignore
|
|
379
|
-
headersFiles: [headersPath],
|
|
380
|
-
minimal: true,
|
|
381
|
-
})
|
|
382
|
-
|
|
383
|
-
config.headers = headers
|
|
384
|
-
|
|
385
|
-
// @ts-ignore
|
|
386
|
-
results = await deploySite(api, siteId, deployFolder, {
|
|
387
|
-
config,
|
|
388
|
-
fnDir: functionDirectories,
|
|
389
|
-
functionsConfig,
|
|
390
|
-
statusCb: silent ? () => {} : deployProgressCb(),
|
|
391
|
-
deployTimeout,
|
|
392
|
-
syncFileLimit: SYNC_FILE_LIMIT,
|
|
393
|
-
// pass an existing deployId to update
|
|
394
|
-
deployId,
|
|
395
|
-
filter: getDeployFilesFilter({ site, deployFolder }),
|
|
396
|
-
workingDir: command.workingDir,
|
|
397
|
-
manifestPath,
|
|
398
|
-
skipFunctionsCache,
|
|
399
|
-
siteRoot: site.root,
|
|
400
|
-
})
|
|
401
|
-
} catch (error_) {
|
|
402
|
-
if (deployId) {
|
|
403
|
-
await cancelDeploy({ api, deployId })
|
|
404
|
-
}
|
|
405
|
-
reportDeployError({ error_, failAndExit: error })
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
const siteUrl = results.deploy.ssl_url || results.deploy.url
|
|
409
|
-
const deployUrl = results.deploy.deploy_ssl_url || results.deploy.deploy_url
|
|
410
|
-
const logsUrl = `${results.deploy.admin_url}/deploys/${results.deploy.id}`
|
|
411
|
-
|
|
412
|
-
let functionLogsUrl = `${results.deploy.admin_url}/functions`
|
|
413
|
-
|
|
414
|
-
if (!deployToProduction) {
|
|
415
|
-
functionLogsUrl += `?scope=deploy:${deployId}`
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
return {
|
|
419
|
-
siteId: results.deploy.site_id,
|
|
420
|
-
siteName: results.deploy.name,
|
|
421
|
-
deployId: results.deployId,
|
|
422
|
-
siteUrl,
|
|
423
|
-
deployUrl,
|
|
424
|
-
logsUrl,
|
|
425
|
-
functionLogsUrl,
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
|
|
403
|
+
catch (error_) {
|
|
404
|
+
if (deployId) {
|
|
405
|
+
await cancelDeploy({ api, deployId });
|
|
406
|
+
}
|
|
407
|
+
reportDeployError({ error_, failAndExit: error });
|
|
408
|
+
}
|
|
409
|
+
const siteUrl = results.deploy.ssl_url || results.deploy.url;
|
|
410
|
+
const deployUrl = results.deploy.deploy_ssl_url || results.deploy.deploy_url;
|
|
411
|
+
const logsUrl = `${results.deploy.admin_url}/deploys/${results.deploy.id}`;
|
|
412
|
+
let functionLogsUrl = `${results.deploy.admin_url}/functions`;
|
|
413
|
+
if (!deployToProduction) {
|
|
414
|
+
functionLogsUrl += `?scope=deploy:${deployId}`;
|
|
415
|
+
}
|
|
416
|
+
return {
|
|
417
|
+
siteId: results.deploy.site_id,
|
|
418
|
+
siteName: results.deploy.name,
|
|
419
|
+
deployId: results.deployId,
|
|
420
|
+
siteUrl,
|
|
421
|
+
deployUrl,
|
|
422
|
+
logsUrl,
|
|
423
|
+
functionLogsUrl,
|
|
424
|
+
};
|
|
425
|
+
};
|
|
429
426
|
/**
|
|
430
427
|
*
|
|
431
428
|
* @param {object} config
|
|
@@ -436,69 +433,64 @@ const runDeploy = async ({
|
|
|
436
433
|
* @param {import('commander').OptionValues} config.options The options of the command
|
|
437
434
|
* @returns
|
|
438
435
|
*/
|
|
436
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'cachedConfig' implicitly has an '... Remove this comment to see the full error message
|
|
439
437
|
const handleBuild = async ({ cachedConfig, currentDir, deployHandler, options, packagePath }) => {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
}
|
|
458
|
-
|
|
438
|
+
if (!options.build) {
|
|
439
|
+
return {};
|
|
440
|
+
}
|
|
441
|
+
// @ts-expect-error TS(2554) FIXME: Expected 1 arguments, but got 0.
|
|
442
|
+
const [token] = await getToken();
|
|
443
|
+
const resolvedOptions = await getBuildOptions({
|
|
444
|
+
cachedConfig,
|
|
445
|
+
packagePath,
|
|
446
|
+
token,
|
|
447
|
+
options,
|
|
448
|
+
currentDir,
|
|
449
|
+
deployHandler,
|
|
450
|
+
});
|
|
451
|
+
const { configMutations, exitCode, newConfig } = await runBuild(resolvedOptions);
|
|
452
|
+
if (exitCode !== 0) {
|
|
453
|
+
exit(exitCode);
|
|
454
|
+
}
|
|
455
|
+
return { newConfig, configMutations };
|
|
456
|
+
};
|
|
459
457
|
/**
|
|
460
458
|
*
|
|
461
459
|
* @param {*} options Bundling options
|
|
462
460
|
* @param {import('..//base-command.mjs').default} command
|
|
463
461
|
* @returns
|
|
464
462
|
*/
|
|
463
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'options' implicitly has an 'any' type.
|
|
465
464
|
const bundleEdgeFunctions = async (options, command) => {
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
options.silent || argv.includes('--json') || argv.includes('--silent') ? () => {} : deployProgressCb()
|
|
470
|
-
|
|
471
|
-
statusCb({
|
|
472
|
-
type: 'edge-functions-bundling',
|
|
473
|
-
msg: 'Bundling edge functions...\n',
|
|
474
|
-
phase: 'start',
|
|
475
|
-
})
|
|
476
|
-
|
|
477
|
-
const { severityCode, success } = await runCoreSteps(['edge_functions_bundling'], {
|
|
478
|
-
...options,
|
|
479
|
-
packagePath: command.workspacePackage,
|
|
480
|
-
buffer: true,
|
|
481
|
-
featureFlags: edgeFunctionsFeatureFlags,
|
|
482
|
-
edgeFunctionsBootstrapURL: getBootstrapURL(),
|
|
483
|
-
})
|
|
484
|
-
|
|
485
|
-
if (!success) {
|
|
465
|
+
// eslint-disable-next-line n/prefer-global/process, unicorn/prefer-set-has
|
|
466
|
+
const argv = process.argv.slice(2);
|
|
467
|
+
const statusCb = options.silent || argv.includes('--json') || argv.includes('--silent') ? () => { } : deployProgressCb();
|
|
486
468
|
statusCb({
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
})
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
469
|
+
type: 'edge-functions-bundling',
|
|
470
|
+
msg: 'Bundling edge functions...\n',
|
|
471
|
+
phase: 'start',
|
|
472
|
+
});
|
|
473
|
+
const { severityCode, success } = await runCoreSteps(['edge_functions_bundling'], {
|
|
474
|
+
...options,
|
|
475
|
+
packagePath: command.workspacePackage,
|
|
476
|
+
buffer: true,
|
|
477
|
+
featureFlags: edgeFunctionsFeatureFlags,
|
|
478
|
+
edgeFunctionsBootstrapURL: getBootstrapURL(),
|
|
479
|
+
});
|
|
480
|
+
if (!success) {
|
|
481
|
+
statusCb({
|
|
482
|
+
type: 'edge-functions-bundling',
|
|
483
|
+
msg: 'Deploy aborted due to error while bundling edge functions',
|
|
484
|
+
phase: 'error',
|
|
485
|
+
});
|
|
486
|
+
exit(severityCode);
|
|
487
|
+
}
|
|
488
|
+
statusCb({
|
|
489
|
+
type: 'edge-functions-bundling',
|
|
490
|
+
msg: 'Finished bundling edge functions',
|
|
491
|
+
phase: 'stop',
|
|
492
|
+
});
|
|
493
|
+
};
|
|
502
494
|
/**
|
|
503
495
|
*
|
|
504
496
|
* @param {object} config
|
|
@@ -509,266 +501,254 @@ const bundleEdgeFunctions = async (options, command) => {
|
|
|
509
501
|
* @param {object} config.results
|
|
510
502
|
* @returns {void}
|
|
511
503
|
*/
|
|
504
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'deployToProduction' implicitly ha... Remove this comment to see the full error message
|
|
512
505
|
const printResults = ({ deployToProduction, isIntegrationDeploy, json, results, runBuildCommand }) => {
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
if (deployToProduction) {
|
|
519
|
-
msgData['Unique deploy URL'] = results.deployUrl
|
|
520
|
-
msgData['Website URL'] = results.siteUrl
|
|
521
|
-
} else {
|
|
522
|
-
msgData['Website draft URL'] = results.deployUrl
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
// Spacer
|
|
526
|
-
log()
|
|
527
|
-
|
|
528
|
-
// Json response for piping commands
|
|
529
|
-
if (json) {
|
|
530
|
-
const jsonData = {
|
|
531
|
-
name: results.name,
|
|
532
|
-
site_id: results.site_id,
|
|
533
|
-
site_name: results.siteName,
|
|
534
|
-
deploy_id: results.deployId,
|
|
535
|
-
deploy_url: results.deployUrl,
|
|
536
|
-
logs: results.logsUrl,
|
|
537
|
-
}
|
|
506
|
+
const msgData = {
|
|
507
|
+
'Build logs': results.logsUrl,
|
|
508
|
+
'Function logs': results.functionLogsUrl,
|
|
509
|
+
};
|
|
538
510
|
if (deployToProduction) {
|
|
539
|
-
|
|
511
|
+
// @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
|
|
512
|
+
msgData['Unique deploy URL'] = results.deployUrl;
|
|
513
|
+
// @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
|
|
514
|
+
msgData['Website URL'] = results.siteUrl;
|
|
540
515
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
516
|
+
else {
|
|
517
|
+
// @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
|
|
518
|
+
msgData['Website draft URL'] = results.deployUrl;
|
|
519
|
+
}
|
|
520
|
+
// Spacer
|
|
521
|
+
log();
|
|
522
|
+
// Json response for piping commands
|
|
523
|
+
if (json) {
|
|
524
|
+
const jsonData = {
|
|
525
|
+
name: results.name,
|
|
526
|
+
site_id: results.site_id,
|
|
527
|
+
site_name: results.siteName,
|
|
528
|
+
deploy_id: results.deployId,
|
|
529
|
+
deploy_url: results.deployUrl,
|
|
530
|
+
logs: results.logsUrl,
|
|
531
|
+
};
|
|
532
|
+
if (deployToProduction) {
|
|
533
|
+
// @ts-expect-error TS(2339) FIXME: Property 'url' does not exist on type '{ name: any... Remove this comment to see the full error message
|
|
534
|
+
jsonData.url = results.siteUrl;
|
|
535
|
+
}
|
|
536
|
+
logJson(jsonData);
|
|
537
|
+
exit(0);
|
|
538
|
+
}
|
|
539
|
+
else {
|
|
540
|
+
log(prettyjson.render(msgData));
|
|
541
|
+
if (!deployToProduction) {
|
|
542
|
+
log();
|
|
543
|
+
log('If everything looks good on your draft URL, deploy it to your main site URL with the --prod flag.');
|
|
544
|
+
log(`${chalk.cyanBright.bold(`netlify ${isIntegrationDeploy ? 'integration:' : ''}deploy${runBuildCommand ? ' --build' : ''} --prod`)}`);
|
|
545
|
+
log();
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
};
|
|
549
|
+
const prepAndRunDeploy = async ({
|
|
550
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
|
|
551
|
+
api,
|
|
552
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'command' implicitly has an 'any' ... Remove this comment to see the full error message
|
|
553
|
+
command,
|
|
554
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'config' implicitly has an 'any' t... Remove this comment to see the full error message
|
|
555
|
+
config,
|
|
556
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'deployToProduction' implicitly ha... Remove this comment to see the full error message
|
|
557
|
+
deployToProduction,
|
|
558
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'options' implicitly has an 'any' ... Remove this comment to see the full error message
|
|
559
|
+
options,
|
|
560
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'site' implicitly has an 'any' typ... Remove this comment to see the full error message
|
|
561
|
+
site,
|
|
562
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'siteData' implicitly has an 'any'... Remove this comment to see the full error message
|
|
563
|
+
siteData,
|
|
564
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'siteId' implicitly has an 'any' t... Remove this comment to see the full error message
|
|
565
|
+
siteId,
|
|
566
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'workingDir' implicitly has an 'an... Remove this comment to see the full error message
|
|
567
|
+
workingDir, }) => {
|
|
568
|
+
const alias = options.alias || options.branch;
|
|
569
|
+
const isUsingEnvelope = siteData && siteData.use_envelope;
|
|
570
|
+
// if a context is passed besides dev, we need to pull env vars from that specific context
|
|
571
|
+
if (isUsingEnvelope && options.context && options.context !== 'dev') {
|
|
572
|
+
command.netlify.cachedConfig.env = await getEnvelopeEnv({
|
|
573
|
+
api,
|
|
574
|
+
context: options.context,
|
|
575
|
+
env: command.netlify.cachedConfig.env,
|
|
576
|
+
siteInfo: siteData,
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
const deployFolder = await getDeployFolder({ command, options, config, site, siteData });
|
|
580
|
+
const functionsFolder = getFunctionsFolder({ workingDir, options, config, site, siteData });
|
|
581
|
+
const { configPath } = site;
|
|
582
|
+
const edgeFunctionsConfig = command.netlify.config.edge_functions;
|
|
583
|
+
// build flag wasn't used and edge functions exist
|
|
584
|
+
if (!options.build && edgeFunctionsConfig && edgeFunctionsConfig.length !== 0) {
|
|
585
|
+
await bundleEdgeFunctions(options, command);
|
|
586
|
+
}
|
|
587
|
+
log(prettyjson.render({
|
|
588
|
+
'Deploy path': deployFolder,
|
|
589
|
+
'Functions path': functionsFolder,
|
|
590
|
+
'Configuration path': configPath,
|
|
591
|
+
}));
|
|
592
|
+
const { functionsFolderStat } = await validateFolders({
|
|
593
|
+
deployFolder,
|
|
594
|
+
functionsFolder,
|
|
595
|
+
});
|
|
596
|
+
const siteEnv = isUsingEnvelope
|
|
597
|
+
? await getEnvelopeEnv({
|
|
598
|
+
api,
|
|
599
|
+
context: options.context,
|
|
600
|
+
env: command.netlify.cachedConfig.env,
|
|
601
|
+
raw: true,
|
|
602
|
+
scope: 'functions',
|
|
603
|
+
siteInfo: siteData,
|
|
604
|
+
})
|
|
605
|
+
: siteData?.build_settings?.env;
|
|
606
|
+
const functionsConfig = normalizeFunctionsConfig({
|
|
607
|
+
functionsConfig: config.functions,
|
|
608
|
+
projectRoot: site.root,
|
|
609
|
+
siteEnv,
|
|
610
|
+
});
|
|
611
|
+
const results = await runDeploy({
|
|
612
|
+
alias,
|
|
609
613
|
api,
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
config,
|
|
629
|
-
deployFolder,
|
|
630
|
-
deployTimeout: options.timeout * SEC_TO_MILLISEC || DEFAULT_DEPLOY_TIMEOUT,
|
|
631
|
-
deployToProduction,
|
|
632
|
-
functionsConfig,
|
|
633
|
-
// pass undefined functionsFolder if doesn't exist
|
|
634
|
-
functionsFolder: functionsFolderStat && functionsFolder,
|
|
635
|
-
packagePath: command.workspacePackage,
|
|
636
|
-
silent: options.json || options.silent,
|
|
637
|
-
site,
|
|
638
|
-
siteData,
|
|
639
|
-
siteId,
|
|
640
|
-
skipFunctionsCache: options.skipFunctionsCache,
|
|
641
|
-
title: options.message,
|
|
642
|
-
})
|
|
643
|
-
|
|
644
|
-
return results
|
|
645
|
-
}
|
|
646
|
-
|
|
614
|
+
command,
|
|
615
|
+
config,
|
|
616
|
+
deployFolder,
|
|
617
|
+
deployTimeout: options.timeout * SEC_TO_MILLISEC || DEFAULT_DEPLOY_TIMEOUT,
|
|
618
|
+
deployToProduction,
|
|
619
|
+
functionsConfig,
|
|
620
|
+
// pass undefined functionsFolder if doesn't exist
|
|
621
|
+
functionsFolder: functionsFolderStat && functionsFolder,
|
|
622
|
+
packagePath: command.workspacePackage,
|
|
623
|
+
silent: options.json || options.silent,
|
|
624
|
+
site,
|
|
625
|
+
siteData,
|
|
626
|
+
siteId,
|
|
627
|
+
skipFunctionsCache: options.skipFunctionsCache,
|
|
628
|
+
title: options.message,
|
|
629
|
+
});
|
|
630
|
+
return results;
|
|
631
|
+
};
|
|
647
632
|
/**
|
|
648
633
|
* The deploy command
|
|
649
634
|
* @param {import('commander').OptionValues} options
|
|
650
635
|
* @param {import('../base-command.mjs').default} command
|
|
651
636
|
*/
|
|
637
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'options' implicitly has an 'any' type.
|
|
652
638
|
export const deploy = async (options, command) => {
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
639
|
+
const { workingDir } = command;
|
|
640
|
+
const { api, site, siteInfo } = command.netlify;
|
|
641
|
+
const alias = options.alias || options.branch;
|
|
642
|
+
command.setAnalyticsPayload({ open: options.open, prod: options.prod, json: options.json, alias: Boolean(alias) });
|
|
643
|
+
if (options.branch) {
|
|
644
|
+
warn('--branch flag has been renamed to --alias and will be removed in future versions');
|
|
645
|
+
}
|
|
646
|
+
if (options.context && !options.build) {
|
|
647
|
+
return error('--context flag is only available when using the --build flag');
|
|
648
|
+
}
|
|
649
|
+
await command.authenticate(options.auth);
|
|
650
|
+
let siteId = site.id || options.site;
|
|
651
|
+
let siteData = {};
|
|
652
|
+
if (siteId && !isEmpty(siteInfo)) {
|
|
653
|
+
siteData = siteInfo;
|
|
654
|
+
// @ts-expect-error TS(2339) FIXME: Property 'id' does not exist on type '{}'.
|
|
655
|
+
siteId = siteData.id;
|
|
656
|
+
}
|
|
657
|
+
else {
|
|
658
|
+
log("This folder isn't linked to a site yet");
|
|
659
|
+
const NEW_SITE = '+ Create & configure a new site';
|
|
660
|
+
const EXISTING_SITE = 'Link this directory to an existing site';
|
|
661
|
+
const initializeOpts = [EXISTING_SITE, NEW_SITE];
|
|
662
|
+
const { initChoice } = await inquirer.prompt([
|
|
663
|
+
{
|
|
664
|
+
type: 'list',
|
|
665
|
+
name: 'initChoice',
|
|
666
|
+
message: 'What would you like to do?',
|
|
667
|
+
choices: initializeOpts,
|
|
668
|
+
},
|
|
669
|
+
]);
|
|
670
|
+
// create site or search for one
|
|
671
|
+
if (initChoice === NEW_SITE) {
|
|
672
|
+
// @ts-expect-error TS(2322) FIXME: Type 'undefined' is not assignable to type '{}'.
|
|
673
|
+
siteData = await sitesCreate({}, command);
|
|
674
|
+
// @ts-expect-error TS(2339) FIXME: Property 'id' does not exist on type '{}'.
|
|
675
|
+
site.id = siteData.id;
|
|
676
|
+
siteId = site.id;
|
|
677
|
+
}
|
|
678
|
+
else if (initChoice === EXISTING_SITE) {
|
|
679
|
+
siteData = await link({}, command);
|
|
680
|
+
// @ts-expect-error TS(2339) FIXME: Property 'id' does not exist on type '{}'.
|
|
681
|
+
site.id = siteData.id;
|
|
682
|
+
siteId = site.id;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
if (options.trigger) {
|
|
686
|
+
return triggerDeploy({ api, options, siteData, siteId });
|
|
687
|
+
}
|
|
688
|
+
// @ts-expect-error TS(2339) FIXME: Property 'published_deploy' does not exist on type... Remove this comment to see the full error message
|
|
689
|
+
const deployToProduction = options.prod || (options.prodIfUnlocked && !siteData.published_deploy.locked);
|
|
690
|
+
let results = {};
|
|
691
|
+
if (options.build) {
|
|
692
|
+
await handleBuild({
|
|
693
|
+
packagePath: command.workspacePackage,
|
|
694
|
+
cachedConfig: command.netlify.cachedConfig,
|
|
695
|
+
currentDir: command.workingDir,
|
|
696
|
+
options,
|
|
697
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'netlifyConfig' implicitly has an ... Remove this comment to see the full error message
|
|
698
|
+
deployHandler: async ({ netlifyConfig }) => {
|
|
699
|
+
results = await prepAndRunDeploy({
|
|
700
|
+
command,
|
|
701
|
+
options,
|
|
702
|
+
workingDir,
|
|
703
|
+
api,
|
|
704
|
+
site,
|
|
705
|
+
config: netlifyConfig,
|
|
706
|
+
siteData,
|
|
707
|
+
siteId,
|
|
708
|
+
deployToProduction,
|
|
709
|
+
});
|
|
710
|
+
return {};
|
|
711
|
+
},
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
else {
|
|
717
715
|
results = await prepAndRunDeploy({
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
})
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
const isIntegrationDeploy = command.name() === 'integration:deploy'
|
|
746
|
-
|
|
747
|
-
printResults({
|
|
748
|
-
runBuildCommand: options.build,
|
|
749
|
-
isIntegrationDeploy,
|
|
750
|
-
json: options.json,
|
|
751
|
-
results,
|
|
752
|
-
deployToProduction,
|
|
753
|
-
})
|
|
754
|
-
|
|
755
|
-
if (options.open) {
|
|
756
|
-
const urlToOpen = deployToProduction ? results.siteUrl : results.deployUrl
|
|
757
|
-
await openBrowser({ url: urlToOpen })
|
|
758
|
-
exit()
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
|
|
716
|
+
command,
|
|
717
|
+
options,
|
|
718
|
+
workingDir,
|
|
719
|
+
api,
|
|
720
|
+
site,
|
|
721
|
+
config: command.netlify.config,
|
|
722
|
+
siteData,
|
|
723
|
+
siteId,
|
|
724
|
+
deployToProduction,
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
const isIntegrationDeploy = command.name() === 'integration:deploy';
|
|
728
|
+
printResults({
|
|
729
|
+
runBuildCommand: options.build,
|
|
730
|
+
isIntegrationDeploy,
|
|
731
|
+
json: options.json,
|
|
732
|
+
results,
|
|
733
|
+
deployToProduction,
|
|
734
|
+
});
|
|
735
|
+
if (options.open) {
|
|
736
|
+
// @ts-expect-error TS(2339) FIXME: Property 'siteUrl' does not exist on type '{}'.
|
|
737
|
+
const urlToOpen = deployToProduction ? results.siteUrl : results.deployUrl;
|
|
738
|
+
// @ts-expect-error TS(2345) FIXME: Argument of type '{ url: any; }' is not assignable... Remove this comment to see the full error message
|
|
739
|
+
await openBrowser({ url: urlToOpen });
|
|
740
|
+
exit();
|
|
741
|
+
}
|
|
742
|
+
};
|
|
762
743
|
/**
|
|
763
744
|
* Creates the `netlify deploy` command
|
|
764
745
|
* @param {import('../base-command.mjs').default} program
|
|
765
746
|
* @returns
|
|
766
747
|
*/
|
|
767
|
-
|
|
768
|
-
|
|
748
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'program' implicitly has an 'any' type.
|
|
749
|
+
export const createDeployCommand = (program) => program
|
|
769
750
|
.command('deploy')
|
|
770
|
-
.description(
|
|
771
|
-
`Create a new deploy from the contents of a folder
|
|
751
|
+
.description(`Create a new deploy from the contents of a folder
|
|
772
752
|
Deploys from the build settings found in the netlify.toml file, or settings from the API.
|
|
773
753
|
|
|
774
754
|
The following environment variables can be used to override configuration file lookups and prompts:
|
|
@@ -835,51 +815,36 @@ functions/
|
|
|
835
815
|
└── functionName.js
|
|
836
816
|
\`\`\`
|
|
837
817
|
|
|
838
|
-
Support for package.json's main field, and intrinsic index.js entrypoints are coming soon
|
|
839
|
-
)
|
|
818
|
+
Support for package.json's main field, and intrinsic index.js entrypoints are coming soon.`)
|
|
840
819
|
.option('-d, --dir <path>', 'Specify a folder to deploy')
|
|
841
820
|
.option('-f, --functions <folder>', 'Specify a functions folder to deploy')
|
|
842
821
|
.option('-p, --prod', 'Deploy to production', false)
|
|
843
|
-
.addOption(
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
'Old, prefer --prod-if-unlocked. Deploy to production if unlocked, create a draft otherwise',
|
|
847
|
-
)
|
|
848
|
-
.default(false)
|
|
849
|
-
.hideHelp(true),
|
|
850
|
-
)
|
|
822
|
+
.addOption(new Option('--prodIfUnlocked', 'Old, prefer --prod-if-unlocked. Deploy to production if unlocked, create a draft otherwise')
|
|
823
|
+
.default(false)
|
|
824
|
+
.hideHelp(true))
|
|
851
825
|
.option('--prod-if-unlocked', 'Deploy to production if unlocked, create a draft otherwise', false)
|
|
852
|
-
.option(
|
|
853
|
-
|
|
854
|
-
'Specifies the alias for deployment, the string at the beginning of the deploy subdomain. Useful for creating predictable deployment URLs. Avoid setting an alias string to the same value as a deployed branch. `alias` doesn’t create a branch deploy and can’t be used in conjunction with the branch subdomain feature. Maximum 37 characters.',
|
|
855
|
-
)
|
|
856
|
-
.option(
|
|
857
|
-
'-b, --branch <name>',
|
|
858
|
-
'Serves the same functionality as --alias. Deprecated and will be removed in future versions',
|
|
859
|
-
)
|
|
826
|
+
.option('--alias <name>', 'Specifies the alias for deployment, the string at the beginning of the deploy subdomain. Useful for creating predictable deployment URLs. Avoid setting an alias string to the same value as a deployed branch. `alias` doesn’t create a branch deploy and can’t be used in conjunction with the branch subdomain feature. Maximum 37 characters.')
|
|
827
|
+
.option('-b, --branch <name>', 'Serves the same functionality as --alias. Deprecated and will be removed in future versions')
|
|
860
828
|
.option('-o, --open', 'Open site after deploy', false)
|
|
861
829
|
.option('-m, --message <message>', 'A short message to include in the deploy log')
|
|
862
830
|
.option('-a, --auth <token>', 'Netlify auth token to deploy with', env.NETLIFY_AUTH_TOKEN)
|
|
863
831
|
.option('-s, --site <name-or-id>', 'A site name or ID to deploy to', env.NETLIFY_SITE_ID)
|
|
864
832
|
.option('--json', 'Output deployment data as JSON')
|
|
833
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'value' implicitly has an 'any' type.
|
|
865
834
|
.option('--timeout <number>', 'Timeout to wait for deployment to finish', (value) => Number.parseInt(value))
|
|
866
835
|
.option('--trigger', 'Trigger a new build of your site on Netlify without uploading local files')
|
|
867
836
|
.option('--build', 'Run build command before deploying')
|
|
868
837
|
.option('--context <context>', 'Context to use when resolving build configuration')
|
|
869
|
-
.option(
|
|
870
|
-
'--skip-functions-cache',
|
|
871
|
-
'Ignore any functions created as part of a previous `build` or `deploy` commands, forcing them to be bundled again as part of the deployment',
|
|
872
|
-
false,
|
|
873
|
-
)
|
|
838
|
+
.option('--skip-functions-cache', 'Ignore any functions created as part of a previous `build` or `deploy` commands, forcing them to be bundled again as part of the deployment', false)
|
|
874
839
|
.addExamples([
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
.action(deploy)
|
|
840
|
+
'netlify deploy',
|
|
841
|
+
'netlify deploy --site my-first-site',
|
|
842
|
+
'netlify deploy --prod',
|
|
843
|
+
'netlify deploy --prod --open',
|
|
844
|
+
'netlify deploy --prod-if-unlocked',
|
|
845
|
+
'netlify deploy --message "A message with an $ENV_VAR"',
|
|
846
|
+
'netlify deploy --auth $NETLIFY_AUTH_TOKEN',
|
|
847
|
+
'netlify deploy --trigger',
|
|
848
|
+
'netlify deploy --build --context deploy-preview',
|
|
849
|
+
])
|
|
850
|
+
.action(deploy);
|