netlify-cli 16.9.2 → 16.9.3
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 +5 -5
- package/npm-shrinkwrap.json +230 -6455
- package/package.json +3 -5
- package/src/commands/build/build.mjs +1 -1
- package/src/commands/completion/completion.mjs +1 -1
- package/src/commands/integration/deploy.mjs +59 -9
- package/src/commands/recipes/recipes-list.mjs +1 -1
- package/src/commands/recipes/recipes.mjs +1 -1
- package/src/commands/serve/serve.mjs +1 -1
- package/src/utils/deploy/deploy-site.mjs +5 -15
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "netlify-cli",
|
|
3
3
|
"description": "Netlify command line tool",
|
|
4
|
-
"version": "16.9.
|
|
4
|
+
"version": "16.9.3",
|
|
5
5
|
"author": "Netlify Inc.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
@@ -49,8 +49,6 @@
|
|
|
49
49
|
"@netlify/config": "20.9.0",
|
|
50
50
|
"@netlify/edge-bundler": "9.4.1",
|
|
51
51
|
"@netlify/local-functions-proxy": "1.1.1",
|
|
52
|
-
"@netlify/sdk": "^1.1.5",
|
|
53
|
-
"@netlify/serverless-functions-api": "1.10.0",
|
|
54
52
|
"@netlify/zip-it-and-ship-it": "9.25.4",
|
|
55
53
|
"@octokit/rest": "19.0.13",
|
|
56
54
|
"ansi-escapes": "6.2.0",
|
|
@@ -149,7 +147,7 @@
|
|
|
149
147
|
"update-notifier": "6.0.2",
|
|
150
148
|
"uuid": "9.0.0",
|
|
151
149
|
"wait-port": "1.0.4",
|
|
152
|
-
"
|
|
153
|
-
"
|
|
150
|
+
"write-file-atomic": "5.0.1",
|
|
151
|
+
"zod": "^3.22.4"
|
|
154
152
|
}
|
|
155
153
|
}
|
|
@@ -74,7 +74,7 @@ const build = async (options, command) => {
|
|
|
74
74
|
export const createBuildCommand = (program) =>
|
|
75
75
|
program
|
|
76
76
|
.command('build')
|
|
77
|
-
.description('
|
|
77
|
+
.description('Build on your local machine')
|
|
78
78
|
.option(
|
|
79
79
|
'--context <context>',
|
|
80
80
|
'Specify a build context or branch (contexts: "production", "deploy-preview", "branch-deploy", "dev")',
|
|
@@ -50,7 +50,7 @@ export const createCompletionCommand = (program) => {
|
|
|
50
50
|
|
|
51
51
|
return program
|
|
52
52
|
.command('completion')
|
|
53
|
-
.description('
|
|
53
|
+
.description('Generate shell completion script\nRun this command to see instructions for your shell.')
|
|
54
54
|
.addExamples(['netlify completion:install'])
|
|
55
55
|
.action((options, command) => {
|
|
56
56
|
command.help()
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import fs from 'fs'
|
|
2
2
|
import { resolve } from 'path'
|
|
3
3
|
import { exit, env } from 'process'
|
|
4
4
|
|
|
5
|
-
// eslint-disable-next-line n/no-missing-import
|
|
6
|
-
import { getConfiguration } from '@netlify/sdk/cli-utils'
|
|
7
|
-
// eslint-disable-next-line n/no-unpublished-import
|
|
8
|
-
import fs from 'fs-extra'
|
|
9
5
|
import inquirer from 'inquirer'
|
|
10
6
|
import yaml from 'js-yaml'
|
|
11
7
|
import fetch from 'node-fetch'
|
|
8
|
+
import { z } from 'zod'
|
|
12
9
|
|
|
13
10
|
import { getBuildOptions } from '../../lib/build.mjs'
|
|
14
11
|
import { getToken, chalk, log } from '../../utils/command-helpers.mjs'
|
|
@@ -176,7 +173,7 @@ export async function registerIntegration(workingDir, siteId, accountId, localIn
|
|
|
176
173
|
})
|
|
177
174
|
|
|
178
175
|
const filePath = resolve(workingDir, 'integration.yaml')
|
|
179
|
-
await fs.writeFile(filePath, updatedIntegrationConfig)
|
|
176
|
+
await fs.promises.writeFile(filePath, updatedIntegrationConfig)
|
|
180
177
|
|
|
181
178
|
log(chalk.yellow('Your integration.yaml file has been updated. Please commit and push these changes.'))
|
|
182
179
|
}
|
|
@@ -304,12 +301,66 @@ export async function updateIntegration(
|
|
|
304
301
|
})
|
|
305
302
|
|
|
306
303
|
const filePath = resolve(workingDir, 'integration.yaml')
|
|
307
|
-
await fs.writeFile(filePath, updatedIntegrationConfig)
|
|
304
|
+
await fs.promises.writeFile(filePath, updatedIntegrationConfig)
|
|
308
305
|
|
|
309
306
|
log(chalk.yellow('Changes to the integration.yaml file are complete. Please commit and push these changes.'))
|
|
310
307
|
}
|
|
311
308
|
}
|
|
312
309
|
|
|
310
|
+
const possibleFiles = ['integration.yaml', 'integration.yml', 'integration.netlify.yaml', 'integration.netlify.yml']
|
|
311
|
+
const IntegrationConfigurationSchema = z.object({
|
|
312
|
+
name: z.string().optional(),
|
|
313
|
+
description: z.string().optional(),
|
|
314
|
+
slug: z.string().regex(/^[a-z\d-]+$/, 'slug must be lowercase with dashes'),
|
|
315
|
+
scopes: z
|
|
316
|
+
.object({
|
|
317
|
+
all: z.boolean().optional(),
|
|
318
|
+
site: z.array(z.enum(['read', 'write'])).optional(),
|
|
319
|
+
env: z.array(z.enum(['read', 'write', 'delete'])).optional(),
|
|
320
|
+
user: z.array(z.enum(['read', 'write'])).optional(),
|
|
321
|
+
})
|
|
322
|
+
.optional(),
|
|
323
|
+
integrationLevel: z.enum(['site', 'team', 'team-and-site']).optional(),
|
|
324
|
+
})
|
|
325
|
+
|
|
326
|
+
const getConfigurationFile = (workingDir) => {
|
|
327
|
+
const pwd = workingDir
|
|
328
|
+
|
|
329
|
+
const fileName = possibleFiles.find((configFileName) => fs.existsSync(resolve(pwd, configFileName)))
|
|
330
|
+
|
|
331
|
+
return fileName
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
export const getConfiguration = (workingDir) => {
|
|
335
|
+
const pwd = workingDir
|
|
336
|
+
|
|
337
|
+
const fileName = getConfigurationFile(workingDir)
|
|
338
|
+
|
|
339
|
+
if (!fileName) {
|
|
340
|
+
throw new Error('No configuration file found')
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
try {
|
|
344
|
+
const { config } = yaml.load(fs.readFileSync(resolve(pwd, fileName), 'utf-8'))
|
|
345
|
+
|
|
346
|
+
if (!config) {
|
|
347
|
+
throw new Error('No configuration found')
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const parseResult = IntegrationConfigurationSchema.safeParse(config)
|
|
351
|
+
|
|
352
|
+
if (!parseResult.success) {
|
|
353
|
+
console.error(parseResult.error.message)
|
|
354
|
+
throw new Error('Invalid Configuration')
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return config
|
|
358
|
+
} catch (error) {
|
|
359
|
+
console.error(error)
|
|
360
|
+
console.error(`No configuration found in ${fileName} in ${pwd}`)
|
|
361
|
+
exit(1)
|
|
362
|
+
}
|
|
363
|
+
}
|
|
313
364
|
/**
|
|
314
365
|
* The deploy command for Netlify Integrations
|
|
315
366
|
* @param {import('commander').OptionValues} options
|
|
@@ -330,7 +381,7 @@ const deploy = async (options, command) => {
|
|
|
330
381
|
// Confirm that a site is linked and that the user is logged in
|
|
331
382
|
checkOptions(buildOptions)
|
|
332
383
|
|
|
333
|
-
const { description, integrationLevel, name, scopes, slug } = await getConfiguration()
|
|
384
|
+
const { description, integrationLevel, name, scopes, slug } = await getConfiguration(command.workingDir)
|
|
334
385
|
const localIntegrationConfig = { name, description, scopes, slug, integrationLevel }
|
|
335
386
|
|
|
336
387
|
const { accountId } = await getSiteInformation({
|
|
@@ -394,4 +445,3 @@ export const createDeployCommand = (program) =>
|
|
|
394
445
|
.option('-a, --auth <token>', 'Netlify auth token to deploy with', env.NETLIFY_AUTH_TOKEN)
|
|
395
446
|
.option('-s, --site <name-or-id>', 'A site name or ID to deploy to', env.NETLIFY_SITE_ID)
|
|
396
447
|
.action(deploy)
|
|
397
|
-
/* eslint-enable import/extensions */
|
|
@@ -27,6 +27,6 @@ const recipesListCommand = async () => {
|
|
|
27
27
|
export const createRecipesListCommand = (program) =>
|
|
28
28
|
program
|
|
29
29
|
.command('recipes:list')
|
|
30
|
-
.description(`
|
|
30
|
+
.description(`List the recipes available to create and modify files in a project`)
|
|
31
31
|
.addExamples(['netlify recipes:list'])
|
|
32
32
|
.action(recipesListCommand)
|
|
@@ -81,7 +81,7 @@ export const createRecipesCommand = (program) => {
|
|
|
81
81
|
program
|
|
82
82
|
.command('recipes')
|
|
83
83
|
.argument('[name]', 'name of the recipe')
|
|
84
|
-
.description(`
|
|
84
|
+
.description(`Create and modify files in a project using pre-defined recipes`)
|
|
85
85
|
.option('-n, --name <name>', 'recipe name to use')
|
|
86
86
|
.addExamples(['netlify recipes my-recipe', 'netlify recipes --name my-recipe'])
|
|
87
87
|
.action(recipesCommand)
|
|
@@ -167,7 +167,7 @@ export const createServeCommand = (program) =>
|
|
|
167
167
|
program
|
|
168
168
|
.command('serve')
|
|
169
169
|
.description(
|
|
170
|
-
'
|
|
170
|
+
'Build the site for production and serve locally. This does not watch the code for changes, so if you need to rebuild your site then you must exit and run `serve` again.',
|
|
171
171
|
)
|
|
172
172
|
.option(
|
|
173
173
|
'--context <context>',
|
|
@@ -28,7 +28,7 @@ export const deploySite = async (
|
|
|
28
28
|
concurrentHash = DEFAULT_CONCURRENT_HASH,
|
|
29
29
|
concurrentUpload = DEFAULT_CONCURRENT_UPLOAD,
|
|
30
30
|
configPath = null,
|
|
31
|
-
deployId
|
|
31
|
+
deployId,
|
|
32
32
|
deployTimeout = DEFAULT_DEPLOY_TIMEOUT,
|
|
33
33
|
draft = false,
|
|
34
34
|
filter,
|
|
@@ -37,8 +37,6 @@ export const deploySite = async (
|
|
|
37
37
|
hashAlgorithm,
|
|
38
38
|
manifestPath,
|
|
39
39
|
maxRetry = DEFAULT_MAX_RETRY,
|
|
40
|
-
// API calls this the 'title'
|
|
41
|
-
message: title,
|
|
42
40
|
siteEnv,
|
|
43
41
|
siteRoot,
|
|
44
42
|
skipFunctionsCache,
|
|
@@ -120,9 +118,9 @@ For more information, visit https://ntl.fyi/cli-native-modules.`)
|
|
|
120
118
|
phase: 'start',
|
|
121
119
|
})
|
|
122
120
|
|
|
123
|
-
|
|
124
|
-
let deployParams = cleanDeep({
|
|
121
|
+
const deployParams = cleanDeep({
|
|
125
122
|
siteId,
|
|
123
|
+
deploy_id: deployId,
|
|
126
124
|
body: {
|
|
127
125
|
files,
|
|
128
126
|
functions,
|
|
@@ -133,19 +131,11 @@ For more information, visit https://ntl.fyi/cli-native-modules.`)
|
|
|
133
131
|
draft,
|
|
134
132
|
},
|
|
135
133
|
})
|
|
136
|
-
|
|
137
|
-
if (title) {
|
|
138
|
-
deployParams = { ...deployParams, title }
|
|
139
|
-
}
|
|
140
|
-
deploy = await api.createSiteDeploy(deployParams)
|
|
141
|
-
} else {
|
|
142
|
-
deployParams = { ...deployParams, deploy_id: deployIdOpt }
|
|
143
|
-
deploy = await api.updateSiteDeploy(deployParams)
|
|
144
|
-
}
|
|
134
|
+
let deploy = await api.updateSiteDeploy(deployParams)
|
|
145
135
|
|
|
146
136
|
if (deployParams.body.async) deploy = await waitForDiff(api, deploy.id, siteId, deployTimeout)
|
|
147
137
|
|
|
148
|
-
const {
|
|
138
|
+
const { required: requiredFiles, required_functions: requiredFns } = deploy
|
|
149
139
|
|
|
150
140
|
statusCb({
|
|
151
141
|
type: 'create-deploy',
|