netlify-cli 17.3.1 → 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 +3 -139
- package/npm-shrinkwrap.json +82 -82
- 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 -89
- 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,35 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
export const BACKGROUND = '-background'
|
|
9
|
-
const JS = 'js'
|
|
10
|
-
|
|
1
|
+
import { listFunctions } from '@netlify/zip-it-and-ship-it';
|
|
2
|
+
import { fileExistsAsync } from '../../lib/fs.mjs';
|
|
3
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'functionName' implicitly has an 'any' t... Remove this comment to see the full error message
|
|
4
|
+
const getUrlPath = (functionName) => `/.netlify/functions/${functionName}`;
|
|
5
|
+
export const BACKGROUND = '-background';
|
|
6
|
+
const JS = 'js';
|
|
7
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'mainFile' implicitly has an 'any'... Remove this comment to see the full error message
|
|
11
8
|
const addFunctionProps = ({ mainFile, name, runtime, schedule }) => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
9
|
+
const urlPath = getUrlPath(name);
|
|
10
|
+
const isBackground = name.endsWith(BACKGROUND);
|
|
11
|
+
return { mainFile, name, runtime, urlPath, isBackground, schedule };
|
|
12
|
+
};
|
|
17
13
|
/**
|
|
18
14
|
* @param {Record<string, { schedule?: string }>} functionConfigRecord
|
|
19
15
|
* @returns {Record<string, { schedule?: string }>}
|
|
20
16
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'functionConfigRecord' implicitly has an... Remove this comment to see the full error message
|
|
18
|
+
const extractSchedule = (functionConfigRecord) =>
|
|
19
|
+
// @ts-expect-error TS(2339) FIXME: Property 'schedule' does not exist on type 'unknow... Remove this comment to see the full error message
|
|
20
|
+
Object.fromEntries(Object.entries(functionConfigRecord).map(([name, { schedule }]) => [name, { schedule }]));
|
|
21
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'functionsSrcDir' implicitly has an 'any... Remove this comment to see the full error message
|
|
24
22
|
export const getFunctions = async (functionsSrcDir, config = {}) => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
23
|
+
if (!(await fileExistsAsync(functionsSrcDir))) {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
const functions = await listFunctions(functionsSrcDir, {
|
|
27
|
+
// @ts-expect-error TS(2339) FIXME: Property 'functions' does not exist on type '{}'.
|
|
28
|
+
config: config.functions ? extractSchedule(config.functions) : undefined,
|
|
29
|
+
parseISC: true,
|
|
30
|
+
});
|
|
31
|
+
// @ts-expect-error TS(2345) FIXME: Argument of type 'ListedFunction' is not assignabl... Remove this comment to see the full error message
|
|
32
|
+
const functionsWithProps = functions.filter(({ runtime }) => runtime === JS).map((func) => addFunctionProps(func));
|
|
33
|
+
return functionsWithProps;
|
|
34
|
+
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from './constants.mjs'
|
|
2
|
-
export * from './functions.mjs'
|
|
3
|
-
export * from './get-functions.mjs'
|
|
1
|
+
export * from './constants.mjs';
|
|
2
|
+
export * from './functions.mjs';
|
|
3
|
+
export * from './get-functions.mjs';
|
|
@@ -1,43 +1,40 @@
|
|
|
1
|
-
import { readFile } from 'fs/promises'
|
|
2
|
-
|
|
3
|
-
import Configstore from 'configstore'
|
|
4
|
-
import { v4 as uuidv4 } from 'uuid'
|
|
5
|
-
|
|
6
|
-
import { getLegacyPathInHome, getPathInHome } from '../lib/settings.mjs'
|
|
7
|
-
|
|
1
|
+
import { readFile } from 'fs/promises';
|
|
2
|
+
// @ts-expect-error TS(7016) FIXME: Could not find a declaration file for module 'conf... Remove this comment to see the full error message
|
|
3
|
+
import Configstore from 'configstore';
|
|
4
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
5
|
+
import { getLegacyPathInHome, getPathInHome } from '../lib/settings.mjs';
|
|
8
6
|
const globalConfigDefaults = {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
7
|
+
/* disable stats from being sent to Netlify */
|
|
8
|
+
telemetryDisabled: false,
|
|
9
|
+
/* cliId */
|
|
10
|
+
cliId: uuidv4(),
|
|
11
|
+
};
|
|
15
12
|
// Memoise config result so that we only load it once
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
// @ts-expect-error TS(7034) FIXME: Variable 'configStore' implicitly has type 'any' i... Remove this comment to see the full error message
|
|
14
|
+
let configStore;
|
|
18
15
|
/**
|
|
19
16
|
* @returns {Promise<Configstore>}
|
|
20
17
|
*/
|
|
21
18
|
const getGlobalConfig = async function () {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
19
|
+
// @ts-expect-error TS(7005) FIXME: Variable 'configStore' implicitly has an 'any' typ... Remove this comment to see the full error message
|
|
20
|
+
if (!configStore) {
|
|
21
|
+
const configPath = getPathInHome(['config.json']);
|
|
22
|
+
// Legacy config file in home ~/.netlify/config.json
|
|
23
|
+
const legacyPath = getLegacyPathInHome(['config.json']);
|
|
24
|
+
let legacyConfig;
|
|
25
|
+
// Read legacy config if exists
|
|
26
|
+
try {
|
|
27
|
+
// @ts-expect-error TS(2345) FIXME: Argument of type 'Buffer' is not assignable to par... Remove this comment to see the full error message
|
|
28
|
+
legacyConfig = JSON.parse(await readFile(legacyPath));
|
|
29
|
+
}
|
|
30
|
+
catch { }
|
|
31
|
+
// Use legacy config as default values
|
|
32
|
+
const defaults = { ...globalConfigDefaults, ...legacyConfig };
|
|
33
|
+
configStore = new Configstore(null, defaults, { configPath });
|
|
34
|
+
}
|
|
35
|
+
return configStore;
|
|
36
|
+
};
|
|
39
37
|
export const resetConfigCache = () => {
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export default getGlobalConfig
|
|
38
|
+
configStore = undefined;
|
|
39
|
+
};
|
|
40
|
+
export default getGlobalConfig;
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import { readFile } from 'fs/promises'
|
|
2
|
-
import { dirname, join } from 'path'
|
|
3
|
-
import { fileURLToPath } from 'url'
|
|
4
|
-
|
|
5
|
-
let packageJson
|
|
6
|
-
|
|
1
|
+
import { readFile } from 'fs/promises';
|
|
2
|
+
import { dirname, join } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
// @ts-expect-error TS(7034) FIXME: Variable 'packageJson' implicitly has type 'any' i... Remove this comment to see the full error message
|
|
5
|
+
let packageJson;
|
|
7
6
|
const getPackageJson = async () => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
export default getPackageJson
|
|
7
|
+
// @ts-expect-error TS(7005) FIXME: Variable 'packageJson' implicitly has an 'any' typ... Remove this comment to see the full error message
|
|
8
|
+
if (!packageJson) {
|
|
9
|
+
const packageJsonPath = join(dirname(fileURLToPath(import.meta.url)), '../../package.json');
|
|
10
|
+
// @ts-expect-error TS(2345) FIXME: Argument of type 'Buffer' is not assignable to par... Remove this comment to see the full error message
|
|
11
|
+
packageJson = JSON.parse(await readFile(packageJsonPath));
|
|
12
|
+
}
|
|
13
|
+
return packageJson;
|
|
14
|
+
};
|
|
15
|
+
export default getPackageJson;
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
import parseGitRemote from 'parse-github-url'
|
|
9
|
-
|
|
10
|
-
import { log } from './command-helpers.mjs'
|
|
11
|
-
|
|
1
|
+
import { dirname } from 'path';
|
|
2
|
+
import util from 'util';
|
|
3
|
+
import { findUp } from 'find-up';
|
|
4
|
+
import gitRepoInfo from 'git-repo-info';
|
|
5
|
+
// @ts-expect-error TS(7016) FIXME: Could not find a declaration file for module 'gitc... Remove this comment to see the full error message
|
|
6
|
+
import gitconfiglocal from 'gitconfiglocal';
|
|
7
|
+
// @ts-expect-error TS(7016) FIXME: Could not find a declaration file for module 'pars... Remove this comment to see the full error message
|
|
8
|
+
import parseGitRemote from 'parse-github-url';
|
|
9
|
+
import { log } from './command-helpers.mjs';
|
|
12
10
|
/**
|
|
13
11
|
*
|
|
14
12
|
* @param {object} config
|
|
@@ -16,60 +14,52 @@ import { log } from './command-helpers.mjs'
|
|
|
16
14
|
* @param {string} config.workingDir
|
|
17
15
|
* @returns
|
|
18
16
|
*/
|
|
17
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'remoteName' implicitly has an 'an... Remove this comment to see the full error message
|
|
19
18
|
const getRepoData = async function ({ remoteName, workingDir }) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
19
|
+
try {
|
|
20
|
+
const [gitConfig, gitDirectory] = await Promise.all([
|
|
21
|
+
util.promisify(gitconfiglocal)(workingDir),
|
|
22
|
+
findUp('.git', { cwd: workingDir, type: 'directory' }),
|
|
23
|
+
]);
|
|
24
|
+
if (!gitDirectory || !gitConfig || !gitConfig.remote || Object.keys(gitConfig.remote).length === 0) {
|
|
25
|
+
throw new Error('No Git remote found');
|
|
26
|
+
}
|
|
27
|
+
const baseGitPath = dirname(gitDirectory);
|
|
28
|
+
if (workingDir !== baseGitPath) {
|
|
29
|
+
log(`Git directory located in ${baseGitPath}`);
|
|
30
|
+
}
|
|
31
|
+
if (!remoteName) {
|
|
32
|
+
const remotes = Object.keys(gitConfig.remote);
|
|
33
|
+
remoteName = remotes.find((remote) => remote === 'origin') || remotes[0];
|
|
34
|
+
}
|
|
35
|
+
if (!Object.prototype.hasOwnProperty.call(gitConfig.remote, remoteName) ||
|
|
36
|
+
!gitConfig.remote[remoteName] ||
|
|
37
|
+
Object.keys(gitConfig.remote[remoteName]).length === 0) {
|
|
38
|
+
throw new Error(`The specified remote "${remoteName}" is not defined in Git repo. Please use --git-remote-name flag to specify a remote.`);
|
|
39
|
+
}
|
|
40
|
+
const { url } = gitConfig.remote[remoteName];
|
|
41
|
+
const { host, name, owner, repo } = parseGitRemote(url);
|
|
42
|
+
const { branch } = gitRepoInfo();
|
|
43
|
+
return {
|
|
44
|
+
name,
|
|
45
|
+
owner,
|
|
46
|
+
repo,
|
|
47
|
+
url,
|
|
48
|
+
branch,
|
|
49
|
+
// @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
|
|
50
|
+
provider: PROVIDERS[host] || host,
|
|
51
|
+
httpsUrl: `https://${host}/${repo}`,
|
|
52
|
+
};
|
|
28
53
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
54
|
+
catch (error) {
|
|
55
|
+
return {
|
|
56
|
+
// @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
|
|
57
|
+
error: error.message,
|
|
58
|
+
};
|
|
34
59
|
}
|
|
35
|
-
|
|
36
|
-
if (!remoteName) {
|
|
37
|
-
const remotes = Object.keys(gitConfig.remote)
|
|
38
|
-
remoteName = remotes.find((remote) => remote === 'origin') || remotes[0]
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (
|
|
42
|
-
!Object.prototype.hasOwnProperty.call(gitConfig.remote, remoteName) ||
|
|
43
|
-
!gitConfig.remote[remoteName] ||
|
|
44
|
-
Object.keys(gitConfig.remote[remoteName]).length === 0
|
|
45
|
-
) {
|
|
46
|
-
throw new Error(
|
|
47
|
-
`The specified remote "${remoteName}" is not defined in Git repo. Please use --git-remote-name flag to specify a remote.`,
|
|
48
|
-
)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const { url } = gitConfig.remote[remoteName]
|
|
52
|
-
const { host, name, owner, repo } = parseGitRemote(url)
|
|
53
|
-
const { branch } = gitRepoInfo()
|
|
54
|
-
return {
|
|
55
|
-
name,
|
|
56
|
-
owner,
|
|
57
|
-
repo,
|
|
58
|
-
url,
|
|
59
|
-
branch,
|
|
60
|
-
provider: PROVIDERS[host] || host,
|
|
61
|
-
httpsUrl: `https://${host}/${repo}`,
|
|
62
|
-
}
|
|
63
|
-
} catch (error) {
|
|
64
|
-
return {
|
|
65
|
-
error: error.message,
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
60
|
+
};
|
|
70
61
|
const PROVIDERS = {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export default getRepoData
|
|
62
|
+
'github.com': 'github',
|
|
63
|
+
'gitlab.com': 'gitlab',
|
|
64
|
+
};
|
|
65
|
+
export default getRepoData;
|
package/src/utils/get-site.mjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { error } from './command-helpers.mjs'
|
|
2
|
-
|
|
1
|
+
import { error } from './command-helpers.mjs';
|
|
2
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'api' implicitly has an 'any' type.
|
|
3
3
|
export const getSiteByName = async (api, siteName) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
try {
|
|
5
|
+
const sites = await api.listSites({ name: siteName, filter: 'all' });
|
|
6
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'filteredSite' implicitly has an 'any' t... Remove this comment to see the full error message
|
|
7
|
+
const siteFoundByName = sites.find((filteredSite) => filteredSite.name === siteName);
|
|
8
|
+
if (!siteFoundByName) {
|
|
9
|
+
throw Error;
|
|
10
|
+
}
|
|
11
|
+
return siteFoundByName;
|
|
10
12
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
}
|
|
13
|
+
catch {
|
|
14
|
+
error('Site not found. Please rerun "netlify link"');
|
|
15
|
+
}
|
|
16
|
+
};
|
package/src/utils/gh-auth.mjs
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
// @ts-check
|
|
2
1
|
// A simple ghauth inspired library for getting a personal access token
|
|
3
|
-
import http from 'http'
|
|
4
|
-
import process from 'process'
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
import openBrowser from './open-browser.mjs'
|
|
13
|
-
|
|
14
|
-
const SERVER_PORT = 3000
|
|
15
|
-
|
|
2
|
+
import http from 'http';
|
|
3
|
+
import process from 'process';
|
|
4
|
+
import { Octokit } from '@octokit/rest';
|
|
5
|
+
import getPort from 'get-port';
|
|
6
|
+
import inquirer from 'inquirer';
|
|
7
|
+
import { log } from './command-helpers.mjs';
|
|
8
|
+
import createDeferred from './create-deferred.mjs';
|
|
9
|
+
import openBrowser from './open-browser.mjs';
|
|
10
|
+
const SERVER_PORT = 3000;
|
|
16
11
|
/**
|
|
17
12
|
* @typedef Token
|
|
18
13
|
* @type {object}
|
|
@@ -20,106 +15,90 @@ const SERVER_PORT = 3000
|
|
|
20
15
|
* @property {string} token - The actual token value starting with `gho_`
|
|
21
16
|
* @property {string} provider - The Provider where the token is associated with ('github').
|
|
22
17
|
*/
|
|
23
|
-
|
|
24
18
|
const promptForAuthMethod = async () => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return authMethod === authChoiceNetlify
|
|
41
|
-
}
|
|
42
|
-
|
|
19
|
+
const authChoiceNetlify = 'Authorize with GitHub through app.netlify.com';
|
|
20
|
+
const authChoiceToken = 'Authorize with a GitHub personal access token';
|
|
21
|
+
const authChoices = [authChoiceNetlify, authChoiceToken];
|
|
22
|
+
const { authMethod } = await inquirer.prompt([
|
|
23
|
+
{
|
|
24
|
+
type: 'list',
|
|
25
|
+
name: 'authMethod',
|
|
26
|
+
message: 'Netlify CLI needs access to your GitHub account to configure Webhooks and Deploy Keys. ' +
|
|
27
|
+
'What would you like to do?',
|
|
28
|
+
choices: authChoices,
|
|
29
|
+
},
|
|
30
|
+
]);
|
|
31
|
+
return authMethod === authChoiceNetlify;
|
|
32
|
+
};
|
|
43
33
|
/**
|
|
44
34
|
* Authenticate with the netlify app
|
|
45
35
|
* @returns {Promise<Token>} Returns a Promise with a token object
|
|
46
36
|
*/
|
|
47
37
|
export const authWithNetlify = async () => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
await openBrowser({ url })
|
|
82
|
-
|
|
83
|
-
return deferredPromise
|
|
84
|
-
}
|
|
85
|
-
|
|
38
|
+
const port = await getPort({ port: SERVER_PORT });
|
|
39
|
+
const { promise: deferredPromise, reject: deferredReject, resolve: deferredResolve } = createDeferred();
|
|
40
|
+
const server = http.createServer(function onRequest(req, res) {
|
|
41
|
+
// @ts-expect-error TS(2532) FIXME: Object is possibly 'undefined'.
|
|
42
|
+
const parameters = new URLSearchParams(req.url.slice(req.url.indexOf('?') + 1));
|
|
43
|
+
if (parameters.get('token')) {
|
|
44
|
+
// @ts-expect-error TS(2722) FIXME: Cannot invoke an object which is possibly 'undefin... Remove this comment to see the full error message
|
|
45
|
+
deferredResolve(Object.fromEntries(parameters));
|
|
46
|
+
res.end(`${"<html><head><script>if(history.replaceState){history.replaceState({},'','/')}</script><style>html{font-family:sans-serif;background:#0e1e25}body{overflow:hidden;position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;height:100vh;width:100vw;}h3{margin:0}.card{position:relative;display:flex;flex-direction:column;width:75%;max-width:364px;padding:24px;background:white;color:rgb(14,30,37);border-radius:8px;box-shadow:0 2px 4px 0 rgba(14,30,37,.16);}</style></head>" +
|
|
47
|
+
"<body><div class=card><h3>Logged In</h3><p>You're now logged into Netlify CLI with your "}${parameters.get('provider')} credentials. Please close this window.</p></div>`);
|
|
48
|
+
server.close();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
res.end('BAD PARAMETERS');
|
|
52
|
+
server.close();
|
|
53
|
+
// @ts-expect-error TS(2722) FIXME: Cannot invoke an object which is possibly 'undefin... Remove this comment to see the full error message
|
|
54
|
+
deferredReject(new Error('Got invalid parameters for CLI login'));
|
|
55
|
+
});
|
|
56
|
+
await new Promise(function waitForListening(resolve, reject) {
|
|
57
|
+
server.on('error', reject);
|
|
58
|
+
// @ts-expect-error TS(2769) FIXME: No overload matches this call.
|
|
59
|
+
server.listen(port, resolve);
|
|
60
|
+
});
|
|
61
|
+
const webUI = process.env.NETLIFY_WEB_UI || 'https://app.netlify.com';
|
|
62
|
+
const urlParams = new URLSearchParams({
|
|
63
|
+
host: `http://localhost:${port}`,
|
|
64
|
+
provider: 'github',
|
|
65
|
+
});
|
|
66
|
+
const url = `${webUI}/cli?${urlParams.toString()}`;
|
|
67
|
+
// @ts-expect-error TS(2345) FIXME: Argument of type '{ url: string; }' is not assigna... Remove this comment to see the full error message
|
|
68
|
+
await openBrowser({ url });
|
|
69
|
+
return deferredPromise;
|
|
70
|
+
};
|
|
86
71
|
const getPersonalAccessToken = async () => {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
72
|
+
const { token } = await inquirer.prompt([
|
|
73
|
+
{
|
|
74
|
+
type: 'input',
|
|
75
|
+
name: 'token',
|
|
76
|
+
message: 'Your GitHub personal access token:',
|
|
77
|
+
filter: (input) => input.trim(),
|
|
78
|
+
},
|
|
79
|
+
]);
|
|
80
|
+
return { token };
|
|
81
|
+
};
|
|
99
82
|
/**
|
|
100
83
|
* Authenticate with the netlify app
|
|
101
84
|
* @returns {Promise<Token>} Returns a Promise with a token object
|
|
102
85
|
*/
|
|
103
86
|
const authWithToken = async () => {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
|
|
87
|
+
const { token } = await getPersonalAccessToken();
|
|
88
|
+
if (!token) {
|
|
89
|
+
throw new Error('GitHub authentication failed');
|
|
90
|
+
}
|
|
91
|
+
const octokit = new Octokit({ auth: `token ${token}` });
|
|
92
|
+
// @ts-expect-error TS(2339) FIXME: Property 'login' does not exist on type 'OctokitRe... Remove this comment to see the full error message
|
|
93
|
+
const { login: user } = await octokit.users.getAuthenticated();
|
|
94
|
+
return { token, user, provider: 'github' };
|
|
95
|
+
};
|
|
115
96
|
/**
|
|
116
97
|
* Get a GitHub token
|
|
117
98
|
* @returns {Promise<Token>} Returns a Promise with a token object
|
|
118
99
|
*/
|
|
119
100
|
export const getGitHubToken = async () => {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
return withNetlify ? await authWithNetlify() : await authWithToken()
|
|
125
|
-
}
|
|
101
|
+
log('');
|
|
102
|
+
const withNetlify = await promptForAuthMethod();
|
|
103
|
+
return withNetlify ? await authWithNetlify() : await authWithToken();
|
|
104
|
+
};
|
package/src/utils/gitignore.mjs
CHANGED
|
@@ -1,42 +1,39 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import { log } from './command-helpers.mjs'
|
|
10
|
-
|
|
1
|
+
import { readFile, writeFile } from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
// @ts-expect-error TS(7016) FIXME: Could not find a declaration file for module 'pars... Remove this comment to see the full error message
|
|
4
|
+
import parseIgnore from 'parse-gitignore';
|
|
5
|
+
import { fileExistsAsync } from '../lib/fs.mjs';
|
|
6
|
+
import { log } from './command-helpers.mjs';
|
|
7
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'dir' implicitly has an 'any' type.
|
|
11
8
|
const hasGitIgnore = async function (dir) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
9
|
+
const gitIgnorePath = path.join(dir, '.gitignore');
|
|
10
|
+
const hasIgnore = await fileExistsAsync(gitIgnorePath);
|
|
11
|
+
return hasIgnore;
|
|
12
|
+
};
|
|
13
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'dir' implicitly has an 'any' type.
|
|
17
14
|
export const ensureNetlifyIgnore = async function (dir) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
15
|
+
const gitIgnorePath = path.join(dir, '.gitignore');
|
|
16
|
+
const ignoreContent = '# Local Netlify folder\n.netlify\n';
|
|
17
|
+
/* No .gitignore file. Create one and ignore .netlify folder */
|
|
18
|
+
if (!(await hasGitIgnore(dir))) {
|
|
19
|
+
await writeFile(gitIgnorePath, ignoreContent, 'utf8');
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
let gitIgnoreContents;
|
|
23
|
+
let ignorePatterns;
|
|
24
|
+
try {
|
|
25
|
+
gitIgnoreContents = await readFile(gitIgnorePath, 'utf8');
|
|
26
|
+
ignorePatterns = parseIgnore.parse(gitIgnoreContents);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// ignore
|
|
30
|
+
}
|
|
31
|
+
/* Not ignoring .netlify folder. Add to .gitignore */
|
|
32
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'pattern' implicitly has an 'any' type.
|
|
33
|
+
if (!ignorePatterns || !ignorePatterns.patterns.some((pattern) => /(^|\/|\\)\.netlify($|\/|\\)/.test(pattern))) {
|
|
34
|
+
log();
|
|
35
|
+
log('Adding local .netlify folder to .gitignore file...');
|
|
36
|
+
const newContents = `${gitIgnoreContents}\n${ignoreContent}`;
|
|
37
|
+
await writeFile(gitIgnorePath, newContents, 'utf8');
|
|
38
|
+
}
|
|
39
|
+
};
|