netlify-cli 18.1.0 → 19.0.0-pre.5fc044d
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/dist/commands/base-command.d.ts.map +1 -1
- package/dist/commands/base-command.js +2 -13
- package/dist/commands/blobs/blobs.js +2 -2
- package/dist/commands/build/build.d.ts +4 -11
- package/dist/commands/build/build.d.ts.map +1 -1
- package/dist/commands/build/build.js +1 -7
- package/dist/commands/build/index.js +1 -1
- package/dist/commands/completion/completion.d.ts +4 -4
- package/dist/commands/completion/completion.d.ts.map +1 -1
- package/dist/commands/completion/completion.js +4 -5
- package/dist/commands/deploy/index.d.ts.map +1 -1
- package/dist/commands/deploy/index.js +5 -6
- package/dist/commands/dev/dev.d.ts.map +1 -1
- package/dist/commands/dev/dev.js +1 -15
- package/dist/commands/env/env-list.d.ts +2 -2
- package/dist/commands/env/env-list.d.ts.map +1 -1
- package/dist/commands/env/env.d.ts.map +1 -1
- package/dist/commands/env/env.js +5 -4
- package/dist/commands/functions/functions.d.ts +1 -1
- package/dist/commands/functions/functions.d.ts.map +1 -1
- package/dist/commands/functions/functions.js +4 -2
- package/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +0 -2
- package/dist/commands/link/index.d.ts.map +1 -1
- package/dist/commands/link/index.js +0 -2
- package/dist/commands/main.d.ts.map +1 -1
- package/dist/commands/main.js +0 -3
- package/dist/commands/serve/index.d.ts.map +1 -1
- package/dist/commands/serve/index.js +1 -4
- package/dist/commands/status/index.d.ts +1 -1
- package/dist/commands/status/index.d.ts.map +1 -1
- package/dist/commands/status/index.js +2 -1
- package/dist/lib/build.d.ts +36 -67
- package/dist/lib/build.d.ts.map +1 -1
- package/dist/lib/build.js +6 -41
- package/dist/lib/completion/script.js +3 -13
- package/dist/lib/functions/form-submissions-handler.d.ts.map +1 -1
- package/dist/lib/functions/form-submissions-handler.js +0 -2
- package/dist/lib/functions/runtimes/js/builders/netlify-lambda.d.ts.map +1 -1
- package/dist/lib/functions/runtimes/js/builders/netlify-lambda.js +8 -7
- package/dist/lib/functions/runtimes/js/builders/zisi.d.ts.map +1 -1
- package/dist/lib/functions/runtimes/js/builders/zisi.js +0 -1
- package/dist/lib/functions/runtimes/js/worker.js +0 -1
- package/dist/recipes/vscode/settings.d.ts.map +1 -1
- package/dist/recipes/vscode/settings.js +5 -4
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/command-helpers.d.ts +2 -2
- package/dist/utils/command-helpers.js +1 -1
- package/dist/utils/deploy/hash-files.js +3 -3
- package/dist/utils/deploy/hash-fns.d.ts.map +1 -1
- package/dist/utils/deploy/hash-fns.js +3 -2
- package/dist/utils/deploy/hasher-segments.d.ts +3 -3
- package/dist/utils/deploy/hasher-segments.d.ts.map +1 -1
- package/dist/utils/deploy/hasher-segments.js +2 -9
- package/dist/utils/get-global-config.d.ts.map +1 -1
- package/dist/utils/get-global-config.js +2 -2
- package/dist/utils/get-repo-data.d.ts +4 -4
- package/dist/utils/get-repo-data.d.ts.map +1 -1
- package/dist/utils/get-repo-data.js +7 -6
- package/dist/utils/open-browser.d.ts.map +1 -1
- package/dist/utils/open-browser.js +1 -2
- package/dist/utils/proxy.d.ts.map +1 -1
- package/dist/utils/proxy.js +3 -5
- package/dist/utils/rules-proxy.d.ts.map +1 -1
- package/dist/utils/rules-proxy.js +0 -1
- package/dist/utils/run-build.d.ts.map +1 -1
- package/dist/utils/run-build.js +7 -2
- package/dist/utils/sites/create-template.d.ts.map +1 -1
- package/dist/utils/sites/create-template.js +2 -3
- package/dist/utils/state-config.d.ts.map +1 -1
- package/dist/utils/state-config.js +0 -1
- package/dist/utils/types.d.ts +7 -0
- package/dist/utils/types.d.ts.map +1 -1
- package/npm-shrinkwrap.json +1027 -720
- package/package.json +9 -12
- package/dist/commands/integration/deploy.d.ts +0 -8
- package/dist/commands/integration/deploy.d.ts.map +0 -1
- package/dist/commands/integration/deploy.js +0 -353
- package/dist/commands/integration/index.d.ts +0 -4
- package/dist/commands/integration/index.d.ts.map +0 -1
- package/dist/commands/integration/index.js +0 -26
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "netlify-cli",
|
|
3
3
|
"description": "Netlify command line tool",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "19.0.0-pre.5fc044d",
|
|
5
5
|
"author": "Netlify Inc.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"@bugsnag/js": "8.2.0",
|
|
39
39
|
"@fastify/static": "7.0.4",
|
|
40
40
|
"@netlify/blobs": "8.1.1",
|
|
41
|
-
"@netlify/build": "29.58.
|
|
41
|
+
"@netlify/build": "29.58.10",
|
|
42
42
|
"@netlify/build-info": "8.0.0",
|
|
43
43
|
"@netlify/config": "20.21.7",
|
|
44
44
|
"@netlify/edge-bundler": "12.3.2",
|
|
@@ -47,23 +47,23 @@
|
|
|
47
47
|
"@netlify/local-functions-proxy": "1.1.1",
|
|
48
48
|
"@netlify/redirect-parser": "14.5.0",
|
|
49
49
|
"@netlify/zip-it-and-ship-it": "9.42.5",
|
|
50
|
-
"@octokit/rest": "21.1.
|
|
50
|
+
"@octokit/rest": "21.1.1",
|
|
51
51
|
"@opentelemetry/api": "1.8.0",
|
|
52
|
+
"@pnpm/tabtab": "0.5.4",
|
|
52
53
|
"ansi-escapes": "7.0.0",
|
|
53
54
|
"ansi-to-html": "0.7.2",
|
|
54
55
|
"ascii-table": "0.0.9",
|
|
55
56
|
"backoff": "2.5.0",
|
|
56
|
-
"better-opn": "3.0.2",
|
|
57
57
|
"boxen": "8.0.1",
|
|
58
58
|
"chalk": "5.4.1",
|
|
59
59
|
"chokidar": "3.6.0",
|
|
60
60
|
"ci-info": "4.1.0",
|
|
61
61
|
"clean-deep": "3.4.0",
|
|
62
|
-
"commander": "
|
|
62
|
+
"commander": "12.1.0",
|
|
63
63
|
"comment-json": "4.2.5",
|
|
64
64
|
"configstore": "7.0.0",
|
|
65
65
|
"content-type": "1.0.5",
|
|
66
|
-
"cookie": "0.
|
|
66
|
+
"cookie": "1.0.2",
|
|
67
67
|
"cron-parser": "4.9.0",
|
|
68
68
|
"debug": "4.4.0",
|
|
69
69
|
"decache": "4.6.2",
|
|
@@ -97,7 +97,6 @@
|
|
|
97
97
|
"is-stream": "4.0.1",
|
|
98
98
|
"is-wsl": "3.1.0",
|
|
99
99
|
"isexe": "3.1.1",
|
|
100
|
-
"js-yaml": "4.1.0",
|
|
101
100
|
"jsonwebtoken": "9.0.2",
|
|
102
101
|
"jwt-decode": "4.0.0",
|
|
103
102
|
"lambda-local": "2.2.0",
|
|
@@ -111,6 +110,7 @@
|
|
|
111
110
|
"netlify": "13.3.3",
|
|
112
111
|
"netlify-redirector": "0.5.0",
|
|
113
112
|
"node-fetch": "3.3.2",
|
|
113
|
+
"open": "10.1.0",
|
|
114
114
|
"ora": "8.2.0",
|
|
115
115
|
"p-filter": "4.1.0",
|
|
116
116
|
"p-map": "7.0.3",
|
|
@@ -122,11 +122,10 @@
|
|
|
122
122
|
"pump": "3.0.2",
|
|
123
123
|
"raw-body": "3.0.0",
|
|
124
124
|
"read-package-up": "11.0.0",
|
|
125
|
-
"readdirp": "4.1.
|
|
125
|
+
"readdirp": "4.1.2",
|
|
126
126
|
"semver": "7.7.1",
|
|
127
127
|
"source-map-support": "0.5.21",
|
|
128
128
|
"strip-ansi-control-characters": "2.0.0",
|
|
129
|
-
"tabtab": "3.0.2",
|
|
130
129
|
"tempy": "3.1.0",
|
|
131
130
|
"terminal-link": "3.0.0",
|
|
132
131
|
"through2-filter": "4.0.0",
|
|
@@ -134,12 +133,10 @@
|
|
|
134
133
|
"toml": "3.0.0",
|
|
135
134
|
"tomlify-j0.4": "3.0.0",
|
|
136
135
|
"ulid": "2.3.0",
|
|
137
|
-
"unixify": "1.0.0",
|
|
138
136
|
"update-notifier": "7.3.1",
|
|
139
137
|
"uuid": "11.0.5",
|
|
140
138
|
"wait-port": "1.1.0",
|
|
141
139
|
"write-file-atomic": "5.0.1",
|
|
142
|
-
"ws": "8.18.0"
|
|
143
|
-
"zod": "3.24.1"
|
|
140
|
+
"ws": "8.18.0"
|
|
144
141
|
}
|
|
145
142
|
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { OptionValues } from 'commander';
|
|
2
|
-
import BaseCommand from '../base-command.js';
|
|
3
|
-
export declare function areScopesEqual(localScopes: any, remoteScopes: any): any;
|
|
4
|
-
export declare function registerIntegration(workingDir: any, siteId: any, accountId: any, localIntegrationConfig: any, token: any): Promise<void>;
|
|
5
|
-
export declare function updateIntegration(workingDir: any, options: any, siteId: any, accountId: any, localIntegrationConfig: any, token: any, registeredIntegration: any): Promise<void>;
|
|
6
|
-
export declare const getConfiguration: (workingDir: any) => any;
|
|
7
|
-
export declare const deploy: (options: OptionValues, command: BaseCommand) => Promise<void>;
|
|
8
|
-
//# sourceMappingURL=deploy.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../../src/commands/integration/deploy.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAUxC,OAAO,WAAW,MAAM,oBAAoB,CAAA;AAS5C,wBAAgB,cAAc,CAAC,WAAW,KAAA,EAAE,YAAY,KAAA,OAOvD;AAuFD,wBAAsB,mBAAmB,CAAC,UAAU,KAAA,EAAE,MAAM,KAAA,EAAE,SAAS,KAAA,EAAE,sBAAsB,KAAA,EAAE,KAAK,KAAA,iBAyErG;AAED,wBAAsB,iBAAiB,CAErC,UAAU,KAAA,EAEV,OAAO,KAAA,EAEP,MAAM,KAAA,EAEN,SAAS,KAAA,EAET,sBAAsB,KAAA,EAEtB,KAAK,KAAA,EAEL,qBAAqB,KAAA,iBAsHtB;AA2BD,eAAO,MAAM,gBAAgB,0BA6B5B,CAAA;AAED,eAAO,MAAM,MAAM,YAAmB,YAAY,WAAW,WAAW,kBAgEvE,CAAA"}
|
|
@@ -1,353 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import process from 'process';
|
|
3
|
-
import { resolve } from 'path';
|
|
4
|
-
import { exit } from 'process';
|
|
5
|
-
import inquirer from 'inquirer';
|
|
6
|
-
// @ts-expect-error TS(7016) FIXME: Could not find a declaration file for module 'js-y... Remove this comment to see the full error message
|
|
7
|
-
import yaml from 'js-yaml';
|
|
8
|
-
import fetch from 'node-fetch';
|
|
9
|
-
import { z } from 'zod';
|
|
10
|
-
import { getBuildOptions } from '../../lib/build.js';
|
|
11
|
-
import { chalk, getToken, log } from '../../utils/command-helpers.js';
|
|
12
|
-
import { getSiteInformation } from '../../utils/dev.js';
|
|
13
|
-
import { checkOptions } from '../build/build.js';
|
|
14
|
-
import { deploy as siteDeploy } from '../deploy/deploy.js';
|
|
15
|
-
function getIntegrationAPIUrl() {
|
|
16
|
-
return process.env.INTEGRATION_URL || 'https://api.netlifysdk.com';
|
|
17
|
-
}
|
|
18
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'localScopes' implicitly has an 'any' ty... Remove this comment to see the full error message
|
|
19
|
-
export function areScopesEqual(localScopes, remoteScopes) {
|
|
20
|
-
if (localScopes.length !== remoteScopes.length) {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'scope' implicitly has an 'any' type.
|
|
24
|
-
return localScopes.every((scope) => remoteScopes.includes(scope));
|
|
25
|
-
}
|
|
26
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'localScopes' implicitly has an 'any' ty... Remove this comment to see the full error message
|
|
27
|
-
function logScopeConfirmationMessage(localScopes, remoteScopes) {
|
|
28
|
-
log(chalk.yellow(`This integration is already registered. The current required scopes are:`));
|
|
29
|
-
for (const scope of remoteScopes) {
|
|
30
|
-
log(chalk.green(`- ${scope}`));
|
|
31
|
-
}
|
|
32
|
-
log(chalk.yellow('and will be updated to:'));
|
|
33
|
-
for (const scope of localScopes) {
|
|
34
|
-
log(chalk.green(`- ${scope}`));
|
|
35
|
-
}
|
|
36
|
-
log(chalk.yellow('if you continue. This will only affect future installations of the integration.'));
|
|
37
|
-
}
|
|
38
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'registeredIntegrationScopes' implicitly... Remove this comment to see the full error message
|
|
39
|
-
function formatScopesToWrite(registeredIntegrationScopes) {
|
|
40
|
-
let scopesToWrite = {};
|
|
41
|
-
for (const scope of registeredIntegrationScopes) {
|
|
42
|
-
const [resource, permission] = scope.split(':');
|
|
43
|
-
if (resource === 'all') {
|
|
44
|
-
scopesToWrite = { all: true };
|
|
45
|
-
break;
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
// @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
|
|
49
|
-
if (!scopesToWrite[resource]) {
|
|
50
|
-
// @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
|
|
51
|
-
scopesToWrite[resource] = [];
|
|
52
|
-
}
|
|
53
|
-
// @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
|
|
54
|
-
scopesToWrite[resource].push(permission);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return scopesToWrite;
|
|
58
|
-
}
|
|
59
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'scopes' implicitly has an 'any' type.
|
|
60
|
-
function formatScopesForRemote(scopes) {
|
|
61
|
-
const scopesToWrite = [];
|
|
62
|
-
if (scopes.all) {
|
|
63
|
-
scopesToWrite.push('all');
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
const scopeResources = Object.keys(scopes);
|
|
67
|
-
scopeResources.forEach((resource) => {
|
|
68
|
-
const permissionsRequested = scopes[resource];
|
|
69
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'permission' implicitly has an 'any' typ... Remove this comment to see the full error message
|
|
70
|
-
permissionsRequested.forEach((permission) => {
|
|
71
|
-
scopesToWrite.push(`${resource}:${permission}`);
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
return scopesToWrite.join(',');
|
|
76
|
-
}
|
|
77
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'name' implicitly has an 'any' type.
|
|
78
|
-
function verifyRequiredFieldsAreInConfig(name, description, scopes) {
|
|
79
|
-
const missingFields = [];
|
|
80
|
-
if (!name) {
|
|
81
|
-
missingFields.push('name');
|
|
82
|
-
}
|
|
83
|
-
if (!description) {
|
|
84
|
-
missingFields.push('description');
|
|
85
|
-
}
|
|
86
|
-
if (!scopes) {
|
|
87
|
-
missingFields.push('scopes');
|
|
88
|
-
}
|
|
89
|
-
if (missingFields.length !== 0) {
|
|
90
|
-
log(chalk.yellow(`You are missing the following fields for the integration to be deployed: ${missingFields.join(', ')}. Please add a these fields as an entry to the integration.yaml file and try again.`));
|
|
91
|
-
log(chalk.yellow('For more information on the required fields, please see the documentation: https://ntl.fyi/create-private-integration'));
|
|
92
|
-
return false;
|
|
93
|
-
}
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'workingDir' implicitly has an 'any' typ... Remove this comment to see the full error message
|
|
97
|
-
export async function registerIntegration(workingDir, siteId, accountId, localIntegrationConfig, token) {
|
|
98
|
-
const { description, name, scopes, slug } = localIntegrationConfig;
|
|
99
|
-
log(chalk.yellow(`An integration associated with the site ID ${siteId} is not registered.`));
|
|
100
|
-
const registerPrompt = await inquirer.prompt([
|
|
101
|
-
{
|
|
102
|
-
type: 'confirm',
|
|
103
|
-
name: 'registerIntegration',
|
|
104
|
-
message: `Would you like to register this site as a private integration now?`,
|
|
105
|
-
default: false,
|
|
106
|
-
},
|
|
107
|
-
]);
|
|
108
|
-
if (!registerPrompt.registerIntegration) {
|
|
109
|
-
log(chalk.white("Cancelling deployment. Please run 'netlify int deploy' again when you are ready to register the integration."));
|
|
110
|
-
log(chalk.white("You can also register the integration through the Netlify UI on the 'Integrations' > 'Create private integration' page"));
|
|
111
|
-
exit(1);
|
|
112
|
-
}
|
|
113
|
-
if (!verifyRequiredFieldsAreInConfig(name, description, scopes)) {
|
|
114
|
-
exit(1);
|
|
115
|
-
}
|
|
116
|
-
log(chalk.white('Registering the integration...'));
|
|
117
|
-
const { body, statusCode } = await fetch(`${getIntegrationAPIUrl()}/${accountId}/integrations`, {
|
|
118
|
-
method: 'POST',
|
|
119
|
-
headers: {
|
|
120
|
-
'netlify-token': token,
|
|
121
|
-
},
|
|
122
|
-
body: JSON.stringify({
|
|
123
|
-
name,
|
|
124
|
-
slug,
|
|
125
|
-
description,
|
|
126
|
-
hostSiteId: siteId,
|
|
127
|
-
scopes: formatScopesForRemote(scopes),
|
|
128
|
-
}),
|
|
129
|
-
}).then(async (res) => {
|
|
130
|
-
const response = await res.json();
|
|
131
|
-
return { body: response, statusCode: res.status };
|
|
132
|
-
});
|
|
133
|
-
if (statusCode !== 201) {
|
|
134
|
-
log(chalk.red(`There was an error registering the integration:`));
|
|
135
|
-
log();
|
|
136
|
-
log(chalk.red(`-----------------------------------------------`));
|
|
137
|
-
// @ts-expect-error TS(18046) - 'body' is of type 'unknown'
|
|
138
|
-
log(chalk.red(body.msg));
|
|
139
|
-
log(chalk.red(`-----------------------------------------------`));
|
|
140
|
-
log();
|
|
141
|
-
log(chalk.red(`Please try again. If the problem persists, please contact support.`));
|
|
142
|
-
exit(1);
|
|
143
|
-
}
|
|
144
|
-
// @ts-expect-error TS(18046) - 'body' is of type 'unknown'
|
|
145
|
-
log(chalk.green(`Successfully registered the integration with the slug: ${body.slug}`));
|
|
146
|
-
const updatedIntegrationConfig = yaml.dump({
|
|
147
|
-
// @ts-expect-error TS(18046) - 'body' is of type 'unknown'
|
|
148
|
-
config: { name, description, slug: body.slug, scopes },
|
|
149
|
-
});
|
|
150
|
-
const filePath = resolve(workingDir, 'integration.yaml');
|
|
151
|
-
await fs.promises.writeFile(filePath, updatedIntegrationConfig);
|
|
152
|
-
log(chalk.yellow('Your integration.yaml file has been updated. Please commit and push these changes.'));
|
|
153
|
-
}
|
|
154
|
-
export async function updateIntegration(
|
|
155
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'workingDir' implicitly has an 'any' typ... Remove this comment to see the full error message
|
|
156
|
-
workingDir,
|
|
157
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'options' implicitly has an 'any' type.
|
|
158
|
-
options,
|
|
159
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'siteId' implicitly has an 'any' type.
|
|
160
|
-
siteId,
|
|
161
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'accountId' implicitly has an 'any' type... Remove this comment to see the full error message
|
|
162
|
-
accountId,
|
|
163
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'localIntegrationConfig' implicitly has ... Remove this comment to see the full error message
|
|
164
|
-
localIntegrationConfig,
|
|
165
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'token' implicitly has an 'any' type.
|
|
166
|
-
token,
|
|
167
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'registeredIntegration' implicitly has a... Remove this comment to see the full error message
|
|
168
|
-
registeredIntegration) {
|
|
169
|
-
let { description, name, scopes, slug } = localIntegrationConfig;
|
|
170
|
-
let integrationSlug = slug;
|
|
171
|
-
if (slug !== registeredIntegration.slug) {
|
|
172
|
-
// Update the project's integration.yaml file with the remote slug since that will
|
|
173
|
-
// be considered the source of truth and is a value that can't be edited by the user.
|
|
174
|
-
// Let the user know they need to commit and push the changes.
|
|
175
|
-
integrationSlug = registeredIntegration.slug;
|
|
176
|
-
}
|
|
177
|
-
if (!name) {
|
|
178
|
-
// Disabling this lint rule because the destructuring was not assigning the variable correct and leading to a bug
|
|
179
|
-
// eslint-disable-next-line prefer-destructuring
|
|
180
|
-
name = registeredIntegration.name;
|
|
181
|
-
}
|
|
182
|
-
if (!description) {
|
|
183
|
-
// eslint-disable-next-line prefer-destructuring
|
|
184
|
-
description = registeredIntegration.description;
|
|
185
|
-
}
|
|
186
|
-
// This is returned as a comma separated string and will be easier to manage here as an array
|
|
187
|
-
const registeredIntegrationScopes = registeredIntegration.scopes.split(',');
|
|
188
|
-
const scopeResources = Object.keys(scopes);
|
|
189
|
-
// @ts-expect-error TS(7034) FIXME: Variable 'localScopes' implicitly has type 'any[]'... Remove this comment to see the full error message
|
|
190
|
-
let localScopes = [];
|
|
191
|
-
if (scopeResources.includes('all')) {
|
|
192
|
-
localScopes = ['all'];
|
|
193
|
-
}
|
|
194
|
-
else {
|
|
195
|
-
scopeResources.forEach((resource) => {
|
|
196
|
-
const permissionsRequested = scopes[resource];
|
|
197
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'permission' implicitly has an 'any' typ... Remove this comment to see the full error message
|
|
198
|
-
permissionsRequested.forEach((permission) => {
|
|
199
|
-
localScopes.push(`${resource}:${permission}`);
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'localScopes' implicitly has an 'any[]' t... Remove this comment to see the full error message
|
|
204
|
-
if (!areScopesEqual(localScopes, registeredIntegrationScopes)) {
|
|
205
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'localScopes' implicitly has an 'any[]' t... Remove this comment to see the full error message
|
|
206
|
-
logScopeConfirmationMessage(localScopes, registeredIntegrationScopes);
|
|
207
|
-
const scopePrompt = await inquirer.prompt([
|
|
208
|
-
{
|
|
209
|
-
type: 'confirm',
|
|
210
|
-
name: 'updateScopes',
|
|
211
|
-
message: `Do you want to update the scopes?`,
|
|
212
|
-
default: false,
|
|
213
|
-
},
|
|
214
|
-
]);
|
|
215
|
-
let scopesToWrite;
|
|
216
|
-
if (scopePrompt.updateScopes) {
|
|
217
|
-
// Update the scopes in remote
|
|
218
|
-
scopesToWrite = scopes;
|
|
219
|
-
const { statusCode, updateResponse } = await fetch(`${getIntegrationAPIUrl()}/${accountId}/integrations/${integrationSlug}`, {
|
|
220
|
-
method: 'PUT',
|
|
221
|
-
headers: {
|
|
222
|
-
'netlify-token': token,
|
|
223
|
-
},
|
|
224
|
-
body: JSON.stringify({
|
|
225
|
-
name,
|
|
226
|
-
description,
|
|
227
|
-
hostSiteId: siteId,
|
|
228
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'localScopes' implicitly has an 'any[]' t... Remove this comment to see the full error message
|
|
229
|
-
scopes: localScopes.join(','),
|
|
230
|
-
}),
|
|
231
|
-
}).then(async (res) => {
|
|
232
|
-
const response = await res.json();
|
|
233
|
-
return { updateResponse: response, statusCode: res.status };
|
|
234
|
-
});
|
|
235
|
-
if (statusCode !== 200) {
|
|
236
|
-
log(chalk.red(`There was an error updating the integration: ${updateResponse}`), chalk.red('Please try again. If the problem persists, please contact support.'));
|
|
237
|
-
exit(1);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
else {
|
|
241
|
-
const useRegisteredScopesPrompt = await inquirer.prompt([
|
|
242
|
-
{
|
|
243
|
-
type: 'confirm',
|
|
244
|
-
name: 'useRegisteredScopes',
|
|
245
|
-
message: `Do you want to save the scopes registered for your integration in your local configuration file?`,
|
|
246
|
-
default: false,
|
|
247
|
-
},
|
|
248
|
-
]);
|
|
249
|
-
if (useRegisteredScopesPrompt.useRegisteredScopes) {
|
|
250
|
-
// Use the scopes that are already registered
|
|
251
|
-
log(chalk.white('Saving the currently registered scopes to the integration.yaml file.'));
|
|
252
|
-
scopesToWrite = formatScopesToWrite(registeredIntegrationScopes);
|
|
253
|
-
}
|
|
254
|
-
if (!useRegisteredScopesPrompt.useRegisteredScopes && options.prod) {
|
|
255
|
-
log(chalk.red('Unable to deploy your integration to production without updating the registered scopes.'));
|
|
256
|
-
exit(1);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
const updatedIntegrationConfig = yaml.dump({
|
|
260
|
-
config: { name, description, slug: integrationSlug, scopes: scopesToWrite },
|
|
261
|
-
});
|
|
262
|
-
const filePath = resolve(workingDir, 'integration.yaml');
|
|
263
|
-
await fs.promises.writeFile(filePath, updatedIntegrationConfig);
|
|
264
|
-
log(chalk.yellow('Changes to the integration.yaml file are complete. Please commit and push these changes.'));
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
const possibleFiles = ['integration.yaml', 'integration.yml', 'integration.netlify.yaml', 'integration.netlify.yml'];
|
|
268
|
-
const IntegrationConfigurationSchema = z.object({
|
|
269
|
-
name: z.string().optional(),
|
|
270
|
-
description: z.string().optional(),
|
|
271
|
-
slug: z.string().regex(/^[a-z\d-]+$/, 'slug must be lowercase with dashes'),
|
|
272
|
-
scopes: z
|
|
273
|
-
.object({
|
|
274
|
-
all: z.boolean().optional(),
|
|
275
|
-
site: z.array(z.enum(['read', 'write'])).optional(),
|
|
276
|
-
env: z.array(z.enum(['read', 'write', 'delete'])).optional(),
|
|
277
|
-
user: z.array(z.enum(['read', 'write'])).optional(),
|
|
278
|
-
})
|
|
279
|
-
.optional(),
|
|
280
|
-
});
|
|
281
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'workingDir' implicitly has an 'any' typ... Remove this comment to see the full error message
|
|
282
|
-
const getConfigurationFile = (workingDir) => {
|
|
283
|
-
const pwd = workingDir;
|
|
284
|
-
const fileName = possibleFiles.find((configFileName) => fs.existsSync(resolve(pwd, configFileName)));
|
|
285
|
-
return fileName;
|
|
286
|
-
};
|
|
287
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'workingDir' implicitly has an 'any' typ... Remove this comment to see the full error message
|
|
288
|
-
export const getConfiguration = (workingDir) => {
|
|
289
|
-
const pwd = workingDir;
|
|
290
|
-
const fileName = getConfigurationFile(workingDir);
|
|
291
|
-
if (!fileName) {
|
|
292
|
-
throw new Error('No configuration file found');
|
|
293
|
-
}
|
|
294
|
-
try {
|
|
295
|
-
const { config } = yaml.load(fs.readFileSync(resolve(pwd, fileName), 'utf-8'));
|
|
296
|
-
if (!config) {
|
|
297
|
-
throw new Error('No configuration found');
|
|
298
|
-
}
|
|
299
|
-
const parseResult = IntegrationConfigurationSchema.safeParse(config);
|
|
300
|
-
if (!parseResult.success) {
|
|
301
|
-
console.error(parseResult.error.message);
|
|
302
|
-
throw new Error('Invalid Configuration');
|
|
303
|
-
}
|
|
304
|
-
return config;
|
|
305
|
-
}
|
|
306
|
-
catch (error) {
|
|
307
|
-
console.error(error);
|
|
308
|
-
console.error(`No configuration found in ${fileName} in ${pwd}`);
|
|
309
|
-
exit(1);
|
|
310
|
-
}
|
|
311
|
-
};
|
|
312
|
-
export const deploy = async (options, command) => {
|
|
313
|
-
const { api, cachedConfig, site, siteInfo } = command.netlify;
|
|
314
|
-
const { id: siteId } = site;
|
|
315
|
-
const [token] = await getToken();
|
|
316
|
-
const workingDir = resolve(command.workingDir);
|
|
317
|
-
const buildOptions = await getBuildOptions({
|
|
318
|
-
cachedConfig,
|
|
319
|
-
packagePath: command.workspacePackage,
|
|
320
|
-
currentDir: command.workingDir,
|
|
321
|
-
token,
|
|
322
|
-
// @ts-expect-error TS(2740)
|
|
323
|
-
options,
|
|
324
|
-
});
|
|
325
|
-
// Confirm that a site is linked and that the user is logged in
|
|
326
|
-
checkOptions(buildOptions);
|
|
327
|
-
const { description, name, scopes, slug } = await getConfiguration(command.workingDir);
|
|
328
|
-
const localIntegrationConfig = { name, description, scopes, slug };
|
|
329
|
-
const headers = token ? { 'netlify-token': token } : undefined;
|
|
330
|
-
// @ts-expect-error TS(2345) FIXME: Argument of type '{ api: any; site: any; siteInfo:... Remove this comment to see the full error message
|
|
331
|
-
const { accountId } = await getSiteInformation({
|
|
332
|
-
api,
|
|
333
|
-
site,
|
|
334
|
-
siteInfo,
|
|
335
|
-
});
|
|
336
|
-
const { body: registeredIntegration, statusCode } = await fetch(`${getIntegrationAPIUrl()}/${accountId}/integrations?site_id=${siteId}`, {
|
|
337
|
-
headers,
|
|
338
|
-
}).then(async (res) => {
|
|
339
|
-
const body = await res.json();
|
|
340
|
-
return { body, statusCode: res.status };
|
|
341
|
-
});
|
|
342
|
-
// The integration is registered on the remote
|
|
343
|
-
statusCode === 200
|
|
344
|
-
? await updateIntegration(workingDir, options, siteId, accountId, localIntegrationConfig, token, registeredIntegration)
|
|
345
|
-
: await registerIntegration(workingDir, siteId, accountId, localIntegrationConfig, token);
|
|
346
|
-
// Set the prod flag to true if the integration is being initially registered because we don't want the user
|
|
347
|
-
// to be in a weird state where the card is appearing in the integrations list but there's no production
|
|
348
|
-
// version of the integration deployed
|
|
349
|
-
options = statusCode === 200 ? options : { ...options, prod: true };
|
|
350
|
-
// Deploy the integration to that site
|
|
351
|
-
await siteDeploy(options, command);
|
|
352
|
-
log(`${chalk.cyanBright.bold(`Your integration has been deployed. Next step is to enable it for a team or site.`)} https://ntl.fyi/create-private-integration`);
|
|
353
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/integration/index.ts"],"names":[],"mappings":"AAIA,OAAO,WAAW,MAAM,oBAAoB,CAAA;AAM5C,eAAO,MAAM,8BAA8B,YAAa,WAAW,SAalE,CAAA;AAED,eAAO,MAAM,wBAAwB,YAAa,WAAW,gBAQ5D,CAAA"}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { env } from 'process';
|
|
2
|
-
const integrations = (options, command) => {
|
|
3
|
-
command.help();
|
|
4
|
-
};
|
|
5
|
-
export const createIntegrationDeployCommand = (program) => {
|
|
6
|
-
program
|
|
7
|
-
.command('integration:deploy')
|
|
8
|
-
.alias('int:deploy')
|
|
9
|
-
.description('Register, build, and deploy a private integration on Netlify')
|
|
10
|
-
.option('-p, --prod', 'Deploy to production', false)
|
|
11
|
-
.option('-b, --build', 'Build the integration', false)
|
|
12
|
-
.option('-a, --auth <token>', 'Netlify auth token to deploy with', env.NETLIFY_AUTH_TOKEN)
|
|
13
|
-
.option('-s, --site <name-or-id>', 'A site name or ID to deploy to', env.NETLIFY_SITE_ID)
|
|
14
|
-
.action(async (options, command) => {
|
|
15
|
-
const { deploy } = await import('./deploy.js');
|
|
16
|
-
await deploy(options, command);
|
|
17
|
-
});
|
|
18
|
-
};
|
|
19
|
-
export const createIntegrationCommand = (program) => {
|
|
20
|
-
createIntegrationDeployCommand(program);
|
|
21
|
-
return program
|
|
22
|
-
.command('integration')
|
|
23
|
-
.alias('int')
|
|
24
|
-
.description('Manage Netlify Integrations built with the Netlify SDK')
|
|
25
|
-
.action(integrations);
|
|
26
|
-
};
|