netlify-cli 14.3.0 → 15.0.0-rc.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 +0 -16
- package/npm-shrinkwrap.json +2233 -3087
- package/package.json +7 -8
- package/src/commands/build/build.mjs +1 -24
- package/src/commands/dev/dev.mjs +1 -26
- package/src/commands/main.mjs +0 -2
- package/src/commands/serve/serve.mjs +1 -1
- package/src/lib/functions/server.mjs +1 -10
- package/src/utils/dev.mjs +0 -22
- package/src/commands/graph/graph-config-write.mjs +0 -56
- package/src/commands/graph/graph-edit.mjs +0 -104
- package/src/commands/graph/graph-handler.mjs +0 -102
- package/src/commands/graph/graph-init.mjs +0 -163
- package/src/commands/graph/graph-library.mjs +0 -88
- package/src/commands/graph/graph-operations.mjs +0 -116
- package/src/commands/graph/graph-pull.mjs +0 -168
- package/src/commands/graph/graph.mjs +0 -45
- package/src/commands/graph/index.mjs +0 -1
- package/src/lib/one-graph/cli-client.mjs +0 -1392
- package/src/lib/one-graph/cli-netlify-graph.mjs +0 -1033
- package/src/utils/graph.mjs +0 -170
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": "15.0.0-rc.0",
|
|
5
5
|
"author": "Netlify Inc.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
@@ -44,13 +44,13 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@bugsnag/js": "^7.20.0",
|
|
46
46
|
"@fastify/static": "^6.6.0",
|
|
47
|
-
"@netlify/build": "^29.10.
|
|
48
|
-
"@netlify/build-info": "^7.0.0-pre-
|
|
49
|
-
"@netlify/config": "^20.4.
|
|
47
|
+
"@netlify/build": "^29.10.1",
|
|
48
|
+
"@netlify/build-info": "^7.0.0-pre-20230425.0",
|
|
49
|
+
"@netlify/config": "^20.4.1",
|
|
50
50
|
"@netlify/edge-bundler": "^8.13.2",
|
|
51
|
-
"@netlify/framework-info": "^9.8.
|
|
51
|
+
"@netlify/framework-info": "^9.8.6",
|
|
52
52
|
"@netlify/local-functions-proxy": "^1.1.1",
|
|
53
|
-
"@netlify/zip-it-and-ship-it": "^
|
|
53
|
+
"@netlify/zip-it-and-ship-it": "^9.2.1",
|
|
54
54
|
"@octokit/rest": "^19.0.0",
|
|
55
55
|
"ansi-escapes": "^6.0.0",
|
|
56
56
|
"ansi-styles": "^5.0.0",
|
|
@@ -113,9 +113,8 @@
|
|
|
113
113
|
"log-update": "^5.0.0",
|
|
114
114
|
"minimist": "^1.2.5",
|
|
115
115
|
"multiparty": "^4.2.1",
|
|
116
|
-
"netlify": "^13.1.
|
|
116
|
+
"netlify": "^13.1.5",
|
|
117
117
|
"netlify-headers-parser": "^7.1.2",
|
|
118
|
-
"netlify-onegraph-internal": "0.10.1",
|
|
119
118
|
"netlify-redirect-parser": "^14.1.2",
|
|
120
119
|
"netlify-redirector": "^0.4.0",
|
|
121
120
|
"node-fetch": "^2.6.0",
|
|
@@ -3,7 +3,6 @@ import process from 'process'
|
|
|
3
3
|
|
|
4
4
|
import { getBuildOptions, runBuild } from '../../lib/build.mjs'
|
|
5
5
|
import { error, exit, getToken } from '../../utils/command-helpers.mjs'
|
|
6
|
-
import { generateNetlifyGraphJWT } from '../../utils/dev.mjs'
|
|
7
6
|
import { getEnvelopeEnv, normalizeContext } from '../../utils/env/index.mjs'
|
|
8
7
|
|
|
9
8
|
/**
|
|
@@ -19,35 +18,13 @@ const checkOptions = ({ cachedConfig: { siteInfo = {} }, token }) => {
|
|
|
19
18
|
}
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
const injectEnv = async function (command, { api, buildOptions, context,
|
|
21
|
+
const injectEnv = async function (command, { api, buildOptions, context, siteInfo }) {
|
|
23
22
|
const isUsingEnvelope = siteInfo && siteInfo.use_envelope
|
|
24
|
-
const authlifyTokenId = siteInfo && siteInfo.authlify_token_id
|
|
25
23
|
|
|
26
24
|
const { env } = buildOptions.cachedConfig
|
|
27
25
|
if (isUsingEnvelope) {
|
|
28
26
|
buildOptions.cachedConfig.env = await getEnvelopeEnv({ api, context, env, siteInfo })
|
|
29
27
|
}
|
|
30
|
-
|
|
31
|
-
if (authlifyTokenId) {
|
|
32
|
-
const netlifyToken = await command.authenticate()
|
|
33
|
-
// Only inject the authlify config if a token ID exists. This prevents
|
|
34
|
-
// calling command.authenticate() (which opens a browser window) if the
|
|
35
|
-
// user hasn't enabled API Authentication
|
|
36
|
-
const netlifyGraphConfig = {
|
|
37
|
-
netlifyToken,
|
|
38
|
-
authlifyTokenId,
|
|
39
|
-
siteId: site.id,
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const netlifyGraphJWT = generateNetlifyGraphJWT(netlifyGraphConfig)
|
|
43
|
-
|
|
44
|
-
if (netlifyGraphJWT != null) {
|
|
45
|
-
// XXX(anmonteiro): this name is deprecated. Delete after 3/31/2022
|
|
46
|
-
const varData = { sources: ['general'], value: netlifyGraphJWT }
|
|
47
|
-
buildOptions.cachedConfig.env.ONEGRAPH_AUTHLIFY_TOKEN = varData
|
|
48
|
-
buildOptions.cachedConfig.env.NETLIFY_GRAPH_TOKEN = varData
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
28
|
}
|
|
52
29
|
|
|
53
30
|
/**
|
package/src/commands/dev/dev.mjs
CHANGED
|
@@ -21,7 +21,6 @@ import detectServerSettings, { getConfigWithPlugins } from '../../utils/detect-s
|
|
|
21
21
|
import { getDotEnvVariables, getSiteInformation, injectEnvVariables } from '../../utils/dev.mjs'
|
|
22
22
|
import { getEnvelopeEnv, normalizeContext } from '../../utils/env/index.mjs'
|
|
23
23
|
import { ensureNetlifyIgnore } from '../../utils/gitignore.mjs'
|
|
24
|
-
import { startNetlifyGraph, startPollingForAPIAuthentication } from '../../utils/graph.mjs'
|
|
25
24
|
import { startLiveTunnel } from '../../utils/live-tunnel.mjs'
|
|
26
25
|
import openBrowser from '../../utils/open-browser.mjs'
|
|
27
26
|
import { generateInspectSettings, startProxyServer } from '../../utils/proxy-server.mjs'
|
|
@@ -124,12 +123,7 @@ const dev = async (options, command) => {
|
|
|
124
123
|
exit(1)
|
|
125
124
|
}
|
|
126
125
|
|
|
127
|
-
command.setAnalyticsPayload({ projectType: settings.framework || 'custom', live: options.live
|
|
128
|
-
|
|
129
|
-
const startNetlifyGraphWatcher = Boolean(options.graph)
|
|
130
|
-
if (startNetlifyGraphWatcher) {
|
|
131
|
-
startPollingForAPIAuthentication({ api, command, config, site, siteInfo })
|
|
132
|
-
}
|
|
126
|
+
command.setAnalyticsPayload({ projectType: settings.framework || 'custom', live: options.live })
|
|
133
127
|
|
|
134
128
|
const liveTunnelUrl = await handleLiveTunnel({ options, site, api, settings })
|
|
135
129
|
const url = liveTunnelUrl || getProxyUrl(settings)
|
|
@@ -201,16 +195,6 @@ const dev = async (options, command) => {
|
|
|
201
195
|
await openBrowser({ url, silentBrowserNoneError: true })
|
|
202
196
|
}
|
|
203
197
|
|
|
204
|
-
await startNetlifyGraph({
|
|
205
|
-
command,
|
|
206
|
-
config,
|
|
207
|
-
options,
|
|
208
|
-
settings,
|
|
209
|
-
site,
|
|
210
|
-
startNetlifyGraphWatcher,
|
|
211
|
-
state,
|
|
212
|
-
})
|
|
213
|
-
|
|
214
198
|
printBanner({ url })
|
|
215
199
|
}
|
|
216
200
|
|
|
@@ -271,14 +255,6 @@ export const createDevCommand = (program) => {
|
|
|
271
255
|
.argParser((value) => Number.parseInt(value))
|
|
272
256
|
.hideHelp(),
|
|
273
257
|
)
|
|
274
|
-
.addOption(new Option('--graph', 'enable Netlify Graph support').hideHelp())
|
|
275
|
-
.addOption(
|
|
276
|
-
new Option(
|
|
277
|
-
'--sessionId [sessionId]',
|
|
278
|
-
'Old, prefer --session-id. (Graph) connect to cloud session with ID [sessionId]',
|
|
279
|
-
).hideHelp(true),
|
|
280
|
-
)
|
|
281
|
-
.option('--session-id [sessionId]', '(Graph) connect to cloud session with ID [sessionId]')
|
|
282
258
|
.addOption(
|
|
283
259
|
new Option(
|
|
284
260
|
'-e, --edgeInspect [address]',
|
|
@@ -318,7 +294,6 @@ export const createDevCommand = (program) => {
|
|
|
318
294
|
'netlify dev -d public',
|
|
319
295
|
'netlify dev -c "hugo server -w" --target-port 1313',
|
|
320
296
|
'netlify dev --context production',
|
|
321
|
-
'netlify dev --graph',
|
|
322
297
|
'netlify dev --edge-inspect',
|
|
323
298
|
'netlify dev --edge-inspect=127.0.0.1:9229',
|
|
324
299
|
'netlify dev --edge-inspect-brk',
|
package/src/commands/main.mjs
CHANGED
|
@@ -20,7 +20,6 @@ import { createDeployCommand } from './deploy/index.mjs'
|
|
|
20
20
|
import { createDevCommand } from './dev/index.mjs'
|
|
21
21
|
import { createEnvCommand } from './env/index.mjs'
|
|
22
22
|
import { createFunctionsCommand } from './functions/index.mjs'
|
|
23
|
-
import { createGraphCommand } from './graph/index.mjs'
|
|
24
23
|
import { createInitCommand } from './init/index.mjs'
|
|
25
24
|
import { createLinkCommand } from './link/index.mjs'
|
|
26
25
|
import { createLmCommand } from './lm/index.mjs'
|
|
@@ -167,7 +166,6 @@ export const createMainCommand = () => {
|
|
|
167
166
|
createEnvCommand(program)
|
|
168
167
|
createFunctionsCommand(program)
|
|
169
168
|
createRecipesCommand(program)
|
|
170
|
-
createGraphCommand(program)
|
|
171
169
|
createInitCommand(program)
|
|
172
170
|
createLinkCommand(program)
|
|
173
171
|
createLmCommand(program)
|
|
@@ -80,7 +80,7 @@ const serve = async (options, command) => {
|
|
|
80
80
|
exit(1)
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
command.setAnalyticsPayload({ projectType: settings.framework || 'custom', live: options.live
|
|
83
|
+
command.setAnalyticsPayload({ projectType: settings.framework || 'custom', live: options.live })
|
|
84
84
|
|
|
85
85
|
log(`${NETLIFYDEVLOG} Building site for production`)
|
|
86
86
|
log(
|
|
@@ -3,7 +3,6 @@ import { get } from 'dot-prop'
|
|
|
3
3
|
import jwtDecode from 'jwt-decode'
|
|
4
4
|
|
|
5
5
|
import { NETLIFYDEVERR, NETLIFYDEVLOG, error as errorExit, log } from '../../utils/command-helpers.mjs'
|
|
6
|
-
import { generateNetlifyGraphJWT } from '../../utils/dev.mjs'
|
|
7
6
|
import { CLOCKWORK_USERAGENT, getFunctionsDistPath, getInternalFunctionsDir } from '../../utils/functions/index.mjs'
|
|
8
7
|
|
|
9
8
|
import { handleBackgroundFunction, handleBackgroundFunctionResult } from './background.mjs'
|
|
@@ -49,7 +48,7 @@ const hasBody = (req) =>
|
|
|
49
48
|
(typeof req.body === 'string' || Buffer.isBuffer(req.body))
|
|
50
49
|
|
|
51
50
|
export const createHandler = function (options) {
|
|
52
|
-
const {
|
|
51
|
+
const { functionsRegistry } = options
|
|
53
52
|
|
|
54
53
|
return async function handler(request, response) {
|
|
55
54
|
// handle proxies without path re-writes (http-servr)
|
|
@@ -115,14 +114,6 @@ export const createHandler = function (options) {
|
|
|
115
114
|
rawQuery,
|
|
116
115
|
}
|
|
117
116
|
|
|
118
|
-
if (config && config.netlifyGraphConfig && config.netlifyGraphConfig.authlifyTokenId != null) {
|
|
119
|
-
// XXX(anmonteiro): this name is deprecated. Delete after 3/31/2022
|
|
120
|
-
const jwt = generateNetlifyGraphJWT(config.netlifyGraphConfig)
|
|
121
|
-
event.authlifyToken = jwt
|
|
122
|
-
event.netlifyGraphToken = jwt
|
|
123
|
-
event.headers['X-Nf-Graph-Token'] = jwt
|
|
124
|
-
}
|
|
125
|
-
|
|
126
117
|
const clientContext = buildClientContext(request.headers) || {}
|
|
127
118
|
|
|
128
119
|
if (func.isBackground) {
|
package/src/utils/dev.mjs
CHANGED
|
@@ -3,7 +3,6 @@ import process from 'process'
|
|
|
3
3
|
|
|
4
4
|
import { get } from 'dot-prop'
|
|
5
5
|
import getPort from 'get-port'
|
|
6
|
-
import jwt from 'jsonwebtoken'
|
|
7
6
|
import isEmpty from 'lodash/isEmpty.js'
|
|
8
7
|
|
|
9
8
|
import { supportsBackgroundFunctions } from '../lib/account.mjs'
|
|
@@ -207,27 +206,6 @@ export const acquirePort = async ({ configuredPort, defaultPort, errorMessage })
|
|
|
207
206
|
return acquiredPort
|
|
208
207
|
}
|
|
209
208
|
|
|
210
|
-
// Generates a Netlify Graph JWT with the following claims:
|
|
211
|
-
// - site_id
|
|
212
|
-
// - netlify_token -- the bearer token for the Netlify API
|
|
213
|
-
// - authlify_token_id -- the authlify token ID stored for the site after
|
|
214
|
-
// enabling API Authentication.
|
|
215
|
-
export const generateNetlifyGraphJWT = ({ authlifyTokenId, netlifyToken, siteId }) => {
|
|
216
|
-
const claims = {
|
|
217
|
-
netlify_token: netlifyToken,
|
|
218
|
-
authlify_token_id: authlifyTokenId,
|
|
219
|
-
site_id: siteId,
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
return jwt.sign(
|
|
223
|
-
{ 'https://netlify.com/jwt/claims': claims },
|
|
224
|
-
// doesn't matter. OneGraph doesn't check the signature. The presence of
|
|
225
|
-
// the Netlify API bearer token is enough because we've authenticated the
|
|
226
|
-
// user through `command.authenticate()`
|
|
227
|
-
'NOT_SIGNED',
|
|
228
|
-
)
|
|
229
|
-
}
|
|
230
|
-
|
|
231
209
|
export const processOnExit = (fn) => {
|
|
232
210
|
const signals = ['SIGINT', 'SIGTERM', 'SIGQUIT', 'SIGHUP', 'exit']
|
|
233
211
|
signals.forEach((signal) => {
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
import fs from 'fs'
|
|
3
|
-
import path from 'path'
|
|
4
|
-
import process from 'process'
|
|
5
|
-
|
|
6
|
-
import { getNetlifyGraphConfig } from '../../lib/one-graph/cli-netlify-graph.mjs'
|
|
7
|
-
import { NETLIFYDEVERR, chalk, error, log } from '../../utils/command-helpers.mjs'
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Creates the `netlify graph:config:write` command
|
|
11
|
-
* @param {import('commander').OptionValues} options
|
|
12
|
-
* @param {import('../base-command.mjs').default} command
|
|
13
|
-
* @returns
|
|
14
|
-
*/
|
|
15
|
-
const graphConfigWrite = async (options, command) => {
|
|
16
|
-
const { site } = command.netlify
|
|
17
|
-
|
|
18
|
-
if (!site.id) {
|
|
19
|
-
error(
|
|
20
|
-
`${NETLIFYDEVERR} Warning: no siteId defined, unable to start Netlify Graph. To enable, run ${chalk.yellow(
|
|
21
|
-
'netlify init',
|
|
22
|
-
)} or ${chalk.yellow('netlify link')}`,
|
|
23
|
-
)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const netlifyGraphConfig = await getNetlifyGraphConfig({ command, options })
|
|
27
|
-
|
|
28
|
-
const schemaPath = netlifyGraphConfig.graphQLSchemaFilename.join('/')
|
|
29
|
-
|
|
30
|
-
// Support tools that looks for the schema under different keys
|
|
31
|
-
const graphQLConfig = {
|
|
32
|
-
schema: [schemaPath],
|
|
33
|
-
schemaPath: [schemaPath],
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const filePath = path.resolve(...netlifyGraphConfig.graphQLConfigJsonFilename)
|
|
37
|
-
fs.writeFileSync(filePath, JSON.stringify(graphQLConfig, null, 2))
|
|
38
|
-
|
|
39
|
-
const relativePath = path.relative(process.cwd(), filePath)
|
|
40
|
-
log(`Wrote ${chalk.cyan(relativePath)}`)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Creates the `netlify graph:config:write` command
|
|
45
|
-
* @param {import('../base-command.mjs').default} program
|
|
46
|
-
* @returns
|
|
47
|
-
*/
|
|
48
|
-
export const createGraphConfigWriteCommand = (program) =>
|
|
49
|
-
program
|
|
50
|
-
.command('graph:config:write')
|
|
51
|
-
.description(
|
|
52
|
-
'Write a .graphqlrc.json file to the current directory for use with local tooling (e.g. the graphql extension for vscode)',
|
|
53
|
-
)
|
|
54
|
-
.action(async (options, command) => {
|
|
55
|
-
await graphConfigWrite(options, command)
|
|
56
|
-
})
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
import gitRepoInfo from 'git-repo-info'
|
|
3
|
-
|
|
4
|
-
import { OneGraphCliClient, ensureCLISession, upsertMergeCLISessionMetadata } from '../../lib/one-graph/cli-client.mjs'
|
|
5
|
-
import {
|
|
6
|
-
defaultExampleOperationsDoc,
|
|
7
|
-
getGraphEditUrlBySiteId,
|
|
8
|
-
getNetlifyGraphConfig,
|
|
9
|
-
readGraphQLOperationsSourceFile,
|
|
10
|
-
} from '../../lib/one-graph/cli-netlify-graph.mjs'
|
|
11
|
-
import { NETLIFYDEVERR, chalk, error, log } from '../../utils/command-helpers.mjs'
|
|
12
|
-
import openBrowser from '../../utils/open-browser.mjs'
|
|
13
|
-
|
|
14
|
-
const { ensureAppForSite, executeCreatePersistedQueryMutation } = OneGraphCliClient
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Creates the `netlify graph:edit` command
|
|
18
|
-
* @param {import('commander').OptionValues} options
|
|
19
|
-
* @param {import('../base-command.mjs').default} command
|
|
20
|
-
* @returns
|
|
21
|
-
*/
|
|
22
|
-
const graphEdit = async (options, command) => {
|
|
23
|
-
const { config, site, state } = command.netlify
|
|
24
|
-
const siteId = site.id
|
|
25
|
-
|
|
26
|
-
if (!site.id) {
|
|
27
|
-
error(
|
|
28
|
-
`${NETLIFYDEVERR} Warning: no siteId defined, unable to start Netlify Graph. To enable, run ${chalk.yellow(
|
|
29
|
-
'netlify init',
|
|
30
|
-
)} or ${chalk.yellow('netlify link')}`,
|
|
31
|
-
)
|
|
32
|
-
}
|
|
33
|
-
const netlifyGraphConfig = await getNetlifyGraphConfig({ command, options })
|
|
34
|
-
|
|
35
|
-
let graphqlDocument = readGraphQLOperationsSourceFile(netlifyGraphConfig)
|
|
36
|
-
|
|
37
|
-
if (graphqlDocument.trim().length === 0) {
|
|
38
|
-
graphqlDocument = defaultExampleOperationsDoc
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const netlifyToken = await command.authenticate()
|
|
42
|
-
const { jwt } = await OneGraphCliClient.getGraphJwtForSite({ siteId, nfToken: netlifyToken })
|
|
43
|
-
|
|
44
|
-
await ensureAppForSite(netlifyToken, siteId)
|
|
45
|
-
|
|
46
|
-
const oneGraphSessionId = await ensureCLISession({
|
|
47
|
-
config,
|
|
48
|
-
metadata: {},
|
|
49
|
-
netlifyToken,
|
|
50
|
-
site,
|
|
51
|
-
state,
|
|
52
|
-
netlifyGraphConfig,
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
const { branch } = gitRepoInfo()
|
|
56
|
-
const persistedResult = await executeCreatePersistedQueryMutation(
|
|
57
|
-
{
|
|
58
|
-
nfToken: netlifyToken,
|
|
59
|
-
appId: siteId,
|
|
60
|
-
description: 'Temporary snapshot of local queries',
|
|
61
|
-
query: graphqlDocument,
|
|
62
|
-
tags: ['netlify-cli', `session:${oneGraphSessionId}`, `git-branch:${branch}`],
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
accessToken: jwt,
|
|
66
|
-
siteId,
|
|
67
|
-
},
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
const persistedDoc =
|
|
71
|
-
persistedResult.data &&
|
|
72
|
-
persistedResult.data.oneGraph &&
|
|
73
|
-
persistedResult.data.oneGraph.createPersistedQuery &&
|
|
74
|
-
persistedResult.data.oneGraph.createPersistedQuery.persistedQuery
|
|
75
|
-
|
|
76
|
-
const newMetadata = { docId: persistedDoc.id }
|
|
77
|
-
|
|
78
|
-
await upsertMergeCLISessionMetadata({
|
|
79
|
-
config,
|
|
80
|
-
jwt,
|
|
81
|
-
siteId,
|
|
82
|
-
siteRoot: site.root,
|
|
83
|
-
oneGraphSessionId,
|
|
84
|
-
newMetadata,
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
const graphEditUrl = getGraphEditUrlBySiteId({ siteId, oneGraphSessionId })
|
|
88
|
-
|
|
89
|
-
log(`Opening graph:edit session at ${chalk.cyan(graphEditUrl)}`)
|
|
90
|
-
await openBrowser({ url: graphEditUrl })
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Creates the `netlify graph:edit` command
|
|
95
|
-
* @param {import('../base-command.mjs').default} program
|
|
96
|
-
* @returns
|
|
97
|
-
*/
|
|
98
|
-
export const createGraphEditCommand = (program) =>
|
|
99
|
-
program
|
|
100
|
-
.command('graph:edit')
|
|
101
|
-
.description('Launch the browser to edit your local graph functions from Netlify')
|
|
102
|
-
.action(async (options, command) => {
|
|
103
|
-
await graphEdit(options, command)
|
|
104
|
-
})
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
/* eslint-disable eslint-comments/disable-enable-pair */
|
|
2
|
-
// @ts-check
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
autocompleteCodegenModules,
|
|
6
|
-
autocompleteOperationNames,
|
|
7
|
-
buildSchema,
|
|
8
|
-
generateHandlerByOperationName,
|
|
9
|
-
getCodegenFunctionById,
|
|
10
|
-
getCodegenModule,
|
|
11
|
-
getNetlifyGraphConfig,
|
|
12
|
-
readGraphQLSchemaFile,
|
|
13
|
-
} from '../../lib/one-graph/cli-netlify-graph.mjs'
|
|
14
|
-
import { error, log } from '../../utils/command-helpers.mjs'
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Creates the `netlify graph:handler` command
|
|
18
|
-
* @param {import('commander').OptionValues} options
|
|
19
|
-
* @param {import('../base-command.mjs').default} command
|
|
20
|
-
* @returns
|
|
21
|
-
*/
|
|
22
|
-
const graphHandler = async (args, options, command) => {
|
|
23
|
-
const netlifyGraphConfig = await getNetlifyGraphConfig({ command, options })
|
|
24
|
-
const { config } = command.netlify
|
|
25
|
-
|
|
26
|
-
const schemaString = readGraphQLSchemaFile(netlifyGraphConfig)
|
|
27
|
-
|
|
28
|
-
let schema
|
|
29
|
-
|
|
30
|
-
try {
|
|
31
|
-
schema = buildSchema(schemaString)
|
|
32
|
-
} catch (buildSchemaError) {
|
|
33
|
-
error(`Error parsing schema: ${buildSchemaError}`)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const userOperationNames = args.operationNames
|
|
37
|
-
const userCodegenId = options.codegen
|
|
38
|
-
|
|
39
|
-
const handlerOptions = options.data ? JSON.parse(options.data) : {}
|
|
40
|
-
|
|
41
|
-
let operationNames = userOperationNames
|
|
42
|
-
if (!operationNames || operationNames.length === 0) {
|
|
43
|
-
const operationName = await autocompleteOperationNames({ netlifyGraphConfig })
|
|
44
|
-
operationNames = [operationName]
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (!operationNames || operationNames.length === 0) {
|
|
48
|
-
error(`No operation name provided`)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const codegenModule = await getCodegenModule({ config })
|
|
52
|
-
if (!codegenModule) {
|
|
53
|
-
error(
|
|
54
|
-
`No Netlify Graph codegen module specified in netlify.toml under the [graph] header. Please specify 'codeGenerator' field and try again.`,
|
|
55
|
-
)
|
|
56
|
-
return
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
let codeGenerator = userCodegenId ? await getCodegenFunctionById({ config, id: userCodegenId }) : null
|
|
60
|
-
if (!codeGenerator) {
|
|
61
|
-
codeGenerator = await autocompleteCodegenModules({ config })
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (!codeGenerator) {
|
|
65
|
-
error(`Unable to select appropriate Netlify Graph code generator`)
|
|
66
|
-
return
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (schema) {
|
|
70
|
-
/* eslint-disable fp/no-loops */
|
|
71
|
-
for (const operationName of operationNames) {
|
|
72
|
-
await generateHandlerByOperationName({
|
|
73
|
-
generate: codeGenerator.generateHandler,
|
|
74
|
-
logger: log,
|
|
75
|
-
netlifyGraphConfig,
|
|
76
|
-
schema,
|
|
77
|
-
operationName,
|
|
78
|
-
handlerOptions,
|
|
79
|
-
})
|
|
80
|
-
}
|
|
81
|
-
} else {
|
|
82
|
-
error(`Failed to parse Netlify GraphQL schema`)
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Creates the `netlify graph:handler` command
|
|
88
|
-
* @param {import('../base-command.mjs').default} program
|
|
89
|
-
* @returns
|
|
90
|
-
*/
|
|
91
|
-
export const createGraphHandlerCommand = (program) =>
|
|
92
|
-
program
|
|
93
|
-
.command('graph:handler')
|
|
94
|
-
.argument('[name...]', 'Operation name(s)')
|
|
95
|
-
.option('-c, --codegen <id>', 'The id of the specific code generator to use')
|
|
96
|
-
.option("-d, --data '<json>'", 'Optional data to pass along to the code generator')
|
|
97
|
-
.description(
|
|
98
|
-
'Generate a handler for a Graph operation given its name. See `graph:operations` for a list of operations.',
|
|
99
|
-
)
|
|
100
|
-
.action(async (operationNames, options, command) => {
|
|
101
|
-
await graphHandler({ operationNames }, options, command)
|
|
102
|
-
})
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
import { Buffer } from 'buffer'
|
|
3
|
-
import process from 'process'
|
|
4
|
-
|
|
5
|
-
import { OneGraphClient } from 'netlify-onegraph-internal'
|
|
6
|
-
import { v4 as uuidv4 } from 'uuid'
|
|
7
|
-
|
|
8
|
-
import { OneGraphCliClient, ensureCLISession } from '../../lib/one-graph/cli-client.mjs'
|
|
9
|
-
import { getNetlifyGraphConfig } from '../../lib/one-graph/cli-netlify-graph.mjs'
|
|
10
|
-
import { NETLIFYDEVERR, chalk, error, exit, getToken, log } from '../../utils/command-helpers.mjs'
|
|
11
|
-
import { translateFromEnvelopeToMongo } from '../../utils/env/index.mjs'
|
|
12
|
-
|
|
13
|
-
const { ensureAppForSite, executeCreateApiTokenMutation } = OneGraphCliClient
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Creates the `netlify graph:init` command
|
|
17
|
-
* @param {import('commander').OptionValues} options
|
|
18
|
-
* @param {import('../base-command.mjs').default} command
|
|
19
|
-
* @returns
|
|
20
|
-
*/
|
|
21
|
-
const graphInit = async (options, command) => {
|
|
22
|
-
const { api, config, site, siteInfo, state } = command.netlify
|
|
23
|
-
const accountId = siteInfo.account_slug
|
|
24
|
-
const siteId = site.id
|
|
25
|
-
|
|
26
|
-
if (!siteId) {
|
|
27
|
-
error(
|
|
28
|
-
`${NETLIFYDEVERR} Warning: no siteId defined, unable to start Netlify Graph. To enable, run ${chalk.yellow(
|
|
29
|
-
'netlify init',
|
|
30
|
-
)} or ${chalk.yellow('netlify link')}`,
|
|
31
|
-
)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
let [netlifyToken] = await getToken()
|
|
35
|
-
if (!netlifyToken) {
|
|
36
|
-
netlifyToken = await command.authenticate()
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (netlifyToken == null) {
|
|
40
|
-
error(
|
|
41
|
-
`${NETLIFYDEVERR} Error: Unable to start Netlify Graph without a login. To enable, run ${chalk.yellow(
|
|
42
|
-
'netlify login',
|
|
43
|
-
)} first`,
|
|
44
|
-
)
|
|
45
|
-
return exit()
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
await ensureAppForSite(netlifyToken, siteId)
|
|
49
|
-
|
|
50
|
-
const netlifyGraphConfig = await getNetlifyGraphConfig({ command, options })
|
|
51
|
-
|
|
52
|
-
if (process.env.NODE_ENV !== 'test') {
|
|
53
|
-
await ensureCLISession({
|
|
54
|
-
config,
|
|
55
|
-
metadata: {},
|
|
56
|
-
netlifyToken,
|
|
57
|
-
site,
|
|
58
|
-
state,
|
|
59
|
-
netlifyGraphConfig,
|
|
60
|
-
})
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
let envChanged = false
|
|
64
|
-
|
|
65
|
-
// Get current environment variables set in the UI
|
|
66
|
-
let env = (siteInfo.build_settings && siteInfo.build_settings.env) || {}
|
|
67
|
-
const isUsingEnvelope = siteInfo.use_envelope
|
|
68
|
-
if (isUsingEnvelope) {
|
|
69
|
-
const envelopeVariables = await api.getEnvVars({ accountId, siteId })
|
|
70
|
-
env = translateFromEnvelopeToMongo(envelopeVariables)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const newEnv = {
|
|
74
|
-
...env,
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (!env.NETLIFY_GRAPH_WEBHOOK_SECRET) {
|
|
78
|
-
envChanged = true
|
|
79
|
-
const secret = Buffer.from(uuidv4()).toString('base64')
|
|
80
|
-
newEnv.NETLIFY_GRAPH_WEBHOOK_SECRET = secret
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (!env.NETLIFY_GRAPH_PERSIST_QUERY_TOKEN) {
|
|
84
|
-
const variables = {
|
|
85
|
-
input: {
|
|
86
|
-
appId: siteId,
|
|
87
|
-
scopes: ['MODIFY_SCHEMA', 'PERSIST_QUERY'],
|
|
88
|
-
},
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const { jwt } = await OneGraphClient.getGraphJwtForSite({ siteId, nfToken: netlifyToken })
|
|
92
|
-
const result = await executeCreateApiTokenMutation(variables, {
|
|
93
|
-
siteId,
|
|
94
|
-
accessToken: jwt,
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
const token =
|
|
98
|
-
result.data &&
|
|
99
|
-
result.data.oneGraph &&
|
|
100
|
-
result.data.oneGraph.createApiToken &&
|
|
101
|
-
result.data.oneGraph.createApiToken.accessToken &&
|
|
102
|
-
result.data.oneGraph.createApiToken.accessToken.token
|
|
103
|
-
|
|
104
|
-
if (token) {
|
|
105
|
-
envChanged = true
|
|
106
|
-
newEnv.NETLIFY_GRAPH_PERSIST_QUERY_TOKEN = token
|
|
107
|
-
} else {
|
|
108
|
-
error(`Unable to create Netlify Graph persist query token: ${JSON.stringify(result.errors, null, 2)}`)
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (!envChanged) {
|
|
113
|
-
log(`Graph-related environment variables already set for site ${siteInfo.name}`)
|
|
114
|
-
return true
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Apply environment variable updates
|
|
118
|
-
|
|
119
|
-
// eslint-disable-next-line unicorn/prefer-ternary
|
|
120
|
-
if (isUsingEnvelope) {
|
|
121
|
-
await api.createEnvVars({
|
|
122
|
-
accountId,
|
|
123
|
-
siteId,
|
|
124
|
-
body: [
|
|
125
|
-
!env.NETLIFY_GRAPH_WEBHOOK_SECRET && {
|
|
126
|
-
key: 'NETLIFY_GRAPH_WEBHOOK_SECRET',
|
|
127
|
-
scopes: ['functions'],
|
|
128
|
-
values: [{ context: 'all', value: newEnv.NETLIFY_GRAPH_WEBHOOK_SECRET }],
|
|
129
|
-
},
|
|
130
|
-
!env.NETLIFY_GRAPH_PERSIST_QUERY_TOKEN && {
|
|
131
|
-
key: 'NETLIFY_GRAPH_PERSIST_QUERY_TOKEN',
|
|
132
|
-
scopes: ['builds', 'functions'],
|
|
133
|
-
values: [{ context: 'all', value: newEnv.NETLIFY_GRAPH_PERSIST_QUERY_TOKEN }],
|
|
134
|
-
},
|
|
135
|
-
].filter(Boolean),
|
|
136
|
-
})
|
|
137
|
-
} else {
|
|
138
|
-
// @ts-ignore
|
|
139
|
-
await api.updateSite({
|
|
140
|
-
siteId,
|
|
141
|
-
body: {
|
|
142
|
-
build_settings: {
|
|
143
|
-
env: newEnv,
|
|
144
|
-
},
|
|
145
|
-
},
|
|
146
|
-
})
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
log(`Finished updating Graph-related environment variables for site ${siteInfo.name}`)
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Creates the `netlify graph:init` command
|
|
154
|
-
* @param {import('../base-command.mjs').default} program
|
|
155
|
-
* @returns
|
|
156
|
-
*/
|
|
157
|
-
export const createGraphInitCommand = (program) =>
|
|
158
|
-
program
|
|
159
|
-
.command('graph:init')
|
|
160
|
-
.description('Initialize all the resources for Netlify Graph')
|
|
161
|
-
.action(async (options, command) => {
|
|
162
|
-
await graphInit(options, command)
|
|
163
|
-
})
|