netlify-cli 8.15.2 → 8.16.0-rc-eh

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.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "netlify-cli",
3
- "version": "8.15.2",
3
+ "version": "8.16.0-rc-eh",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "netlify-cli",
9
- "version": "8.15.2",
9
+ "version": "8.16.0-rc-eh",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT",
12
12
  "dependencies": {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "netlify-cli",
3
3
  "description": "Netlify command line tool",
4
- "version": "8.15.2",
4
+ "version": "8.16.0-rc-eh",
5
5
  "author": "Netlify Inc.",
6
6
  "contributors": [
7
7
  "Mathias Biilmann <matt@netlify.com> (https://twitter.com/biilmann)",
@@ -20,7 +20,6 @@ const {
20
20
  NETLIFYDEVERR,
21
21
  NETLIFYDEVLOG,
22
22
  chalk,
23
- deployEdgeHandlers,
24
23
  deploySite,
25
24
  error,
26
25
  exit,
@@ -313,12 +312,6 @@ const runDeploy = async ({
313
312
  results = await api.createSiteDeploy({ siteId, title, body: { draft, branch: alias } })
314
313
  deployId = results.id
315
314
 
316
- await deployEdgeHandlers({
317
- site,
318
- deployId,
319
- api,
320
- silent,
321
- })
322
315
  const internalFunctionsFolder = await getInternalFunctionsDir({ base: site.root })
323
316
 
324
317
  // The order of the directories matter: zip-it-and-ship-it will prioritize
@@ -156,7 +156,7 @@ const functionsInvoke = async (nameArgument, options, command) => {
156
156
  console.warn(`${NETLIFYDEVWARN} "port" flag was not specified. Attempting to connect to localhost:8888 by default`)
157
157
  const port = options.port || DEFAULT_PORT
158
158
 
159
- const functions = await getFunctions(functionsDir, config)
159
+ const functions = await getFunctions(functionsDir)
160
160
  const functionToTrigger = await getNameFromArgs(functions, options, nameArgument)
161
161
  const functionObj = functions.find((func) => func.name === functionToTrigger)
162
162
 
@@ -0,0 +1,23 @@
1
+ // @ts-check
2
+ const path = require('path')
3
+
4
+ const { getPathInProject } = require('../settings')
5
+
6
+ const EDGE_HANDLERS_FOLDER = 'edge-handlers-dist'
7
+ const PUBLIC_URL_PATH = '.netlify/internal/edge-handlers'
8
+
9
+ const internalPath = getPathInProject([EDGE_HANDLERS_FOLDER])
10
+
11
+ const deployFileNormalizer = (file) => {
12
+ const isEdgeHandler = file.root === internalPath
13
+ const normalizedPath = isEdgeHandler ? path.join(PUBLIC_URL_PATH, file.normalizedPath) : file.normalizedPath
14
+
15
+ return {
16
+ ...file,
17
+ normalizedPath,
18
+ }
19
+ }
20
+
21
+ const isEdgeHandlerFile = (filePath) => filePath.startsWith(`${PUBLIC_URL_PATH}${path.sep}`)
22
+
23
+ module.exports = { deployFileNormalizer, internalPath, isEdgeHandlerFile }
@@ -1,6 +1,7 @@
1
1
  const cleanDeep = require('clean-deep')
2
2
  const tempy = require('tempy')
3
3
 
4
+ const edgeHandlers = require('../../lib/edge-handlers')
4
5
  const { rmdirRecursiveAsync } = require('../../lib/fs')
5
6
  const { warn } = require('../command-helpers')
6
7
 
@@ -52,9 +53,18 @@ const deploySite = async (
52
53
  phase: 'start',
53
54
  })
54
55
 
56
+ const edgeHandlersPath = edgeHandlers.internalPath
55
57
  const [{ files, filesShaMap }, { fnShaMap, functionSchedules, functions, functionsWithNativeModules }] =
56
58
  await Promise.all([
57
- hashFiles(dir, configPath, { concurrentHash, hashAlgorithm, assetType, statusCb, filter }),
59
+ hashFiles({
60
+ assetType,
61
+ concurrentHash,
62
+ directories: [configPath, dir, edgeHandlersPath],
63
+ filter,
64
+ hashAlgorithm,
65
+ normalizer: edgeHandlers.deployFileNormalizer,
66
+ statusCb,
67
+ }),
58
68
  hashFns(fnDir, {
59
69
  functionsConfig,
60
70
  tmpDir,
@@ -67,13 +77,18 @@ const deploySite = async (
67
77
  skipFunctionsCache,
68
78
  }),
69
79
  ])
70
- const filesCount = Object.keys(files).length
80
+ const edgeHandlersCount = Object.keys(files).filter(edgeHandlers.isEdgeHandlerFile).length
81
+ const filesCount = Object.keys(files).length - edgeHandlersCount
71
82
  const functionsCount = Object.keys(functions).length
72
- const hasFunctionDirectories = fnDir.length !== 0
83
+ const stats = buildStatsString([
84
+ filesCount > 0 && `${filesCount} files`,
85
+ functionsCount > 0 && `${functionsCount} functions`,
86
+ edgeHandlersCount > 0 && `${edgeHandlersCount} Edge Handlers`,
87
+ ])
73
88
 
74
89
  statusCb({
75
90
  type: 'hashing',
76
- msg: `Finished hashing ${filesCount} files${hasFunctionDirectories ? ` and ${functionsCount} functions` : ''}`,
91
+ msg: `Finished hashing ${stats}`,
77
92
  phase: 'stop',
78
93
  })
79
94
 
@@ -163,4 +178,11 @@ For more information, visit https://ntl.fyi/cli-native-modules.`)
163
178
  return deployManifest
164
179
  }
165
180
 
181
+ const buildStatsString = (possibleParts) => {
182
+ const parts = possibleParts.filter(Boolean)
183
+ const message = parts.slice(0, -1).join(', ')
184
+
185
+ return parts.length > 1 ? `${message} and ${parts[parts.length - 1]}` : message
186
+ }
187
+
166
188
  module.exports = { deploySite }
@@ -5,16 +5,21 @@ const pump = promisify(require('pump'))
5
5
 
6
6
  const { fileFilterCtor, fileNormalizerCtor, hasherCtor, manifestCollectorCtor } = require('./hasher-segments')
7
7
 
8
- const hashFiles = async (
9
- dir,
10
- configPath,
11
- { assetType = 'file', concurrentHash, filter, hashAlgorithm = 'sha1', statusCb },
12
- ) => {
8
+ const hashFiles = async ({
9
+ assetType = 'file',
10
+ concurrentHash,
11
+ directories,
12
+ filter,
13
+ hashAlgorithm = 'sha1',
14
+ normalizer,
15
+ statusCb,
16
+ }) => {
13
17
  if (!filter) throw new Error('Missing filter function option')
14
- const fileStream = walker([configPath, dir], { filter })
18
+
19
+ const fileStream = walker(directories, { filter })
15
20
  const fileFilter = fileFilterCtor()
16
21
  const hasher = hasherCtor({ concurrentHash, hashAlgorithm })
17
- const fileNormalizer = fileNormalizerCtor({ assetType })
22
+ const fileNormalizer = fileNormalizerCtor({ assetType, normalizer })
18
23
 
19
24
  // Written to by manifestCollector
20
25
  // normalizedPath: hash (wanted by deploy API)
@@ -24,8 +24,16 @@ const hasherCtor = ({ concurrentHash, hashAlgorithm }) => {
24
24
  }
25
25
 
26
26
  // Inject normalized file names into normalizedPath and assetType
27
- const fileNormalizerCtor = ({ assetType }) =>
28
- map((fileObj) => ({ ...fileObj, assetType, normalizedPath: normalizePath(fileObj.relname) }))
27
+ const fileNormalizerCtor = ({ assetType, normalizer: normalizeFunction }) =>
28
+ map((fileObj) => {
29
+ const normalizedFile = { ...fileObj, assetType, normalizedPath: normalizePath(fileObj.relname) }
30
+
31
+ if (normalizeFunction !== undefined) {
32
+ return normalizeFunction(normalizedFile)
33
+ }
34
+
35
+ return normalizedFile
36
+ })
29
37
 
30
38
  // A writable stream segment ctor that normalizes file paths, and writes shaMap's
31
39
  const manifestCollectorCtor = (filesObj, shaMap, { assetType, statusCb }) => {
@@ -13,14 +13,7 @@ const addFunctionProps = ({ mainFile, name, runtime, schedule }) => {
13
13
 
14
14
  const JS = 'js'
15
15
 
16
- /**
17
- * @param {Record<string, { schedule?: string }>} functionConfigRecord
18
- * @returns {Record<string, { schedule?: string }>}
19
- */
20
- const extractSchedule = (functionConfigRecord) =>
21
- Object.fromEntries(Object.entries(functionConfigRecord).map(([name, { schedule }]) => [name, { schedule }]))
22
-
23
- const getFunctions = async (functionsSrcDir, config = {}) => {
16
+ const getFunctions = async (functionsSrcDir) => {
24
17
  if (!(await fileExistsAsync(functionsSrcDir))) {
25
18
  return []
26
19
  }
@@ -29,7 +22,6 @@ const getFunctions = async (functionsSrcDir, config = {}) => {
29
22
  // eslint-disable-next-line node/global-require
30
23
  const { listFunctions } = require('@netlify/zip-it-and-ship-it')
31
24
  const functions = await listFunctions(functionsSrcDir, {
32
- config: config.functions ? extractSchedule(config.functions) : undefined,
33
25
  parseISC: true,
34
26
  })
35
27
  const functionsWithProps = functions.filter(({ runtime }) => runtime === JS).map((func) => addFunctionProps(func))
@@ -1,5 +1,6 @@
1
+ const edgeHandlers = require('../../lib/edge-handlers')
2
+
1
3
  const constants = require('./constants')
2
- const edgeHandlers = require('./edge-handlers')
3
4
  const functions = require('./functions')
4
5
  const getFunctions = require('./get-functions')
5
6
 
@@ -123,8 +123,8 @@ const getPromptInputs = async ({
123
123
  .map(({ name }) => `${name} plugin`)
124
124
  .map(formatTitle)
125
125
  .join(', ')}${EOL}➡️ OK to install??`,
126
- choices: infos.map((info) => ({ name: `${info.name} plugin`, value: info.package })),
127
- default: infos.map((info) => info.package),
126
+ choices: infos.map(({ name, package }) => ({ name: `${name} plugin`, value: package })),
127
+ default: infos.map(({ package }) => package),
128
128
  },
129
129
  ]
130
130
  }
@@ -1,88 +0,0 @@
1
- // @ts-check
2
- const fs = require('fs').promises
3
- const path = require('path')
4
-
5
- const { cancelDeploy, uploadEdgeHandlers } = require('../../lib/api')
6
- const { readFileAsyncCatchError } = require('../../lib/fs')
7
- const { startSpinner, stopSpinner } = require('../../lib/spinner')
8
- const { error } = require('../command-helpers')
9
-
10
- const MANIFEST_FILENAME = 'manifest.json'
11
- const EDGE_HANDLERS_FOLDER = '.netlify/edge-handlers'
12
-
13
- const validateEdgeHandlerFolder = async ({ site }) => {
14
- try {
15
- const resolvedFolder = path.resolve(site.root, EDGE_HANDLERS_FOLDER)
16
- const stat = await fs.stat(resolvedFolder)
17
- if (!stat.isDirectory()) {
18
- error(`Edge Handlers folder ${EDGE_HANDLERS_FOLDER} must be a path to a directory`)
19
- }
20
- return resolvedFolder
21
- } catch {
22
- // ignore errors at the moment
23
- // TODO: report error if 'edge_handlers' config exists after
24
- // https://github.com/netlify/build/pull/1829 is published
25
- }
26
- }
27
-
28
- const readBundleAndManifest = async ({ edgeHandlersResolvedFolder }) => {
29
- const manifestPath = path.resolve(edgeHandlersResolvedFolder, MANIFEST_FILENAME)
30
- const { content: manifest, error: manifestError } = await readFileAsyncCatchError(manifestPath)
31
- if (manifestError) {
32
- error(`Could not read Edge Handlers manifest file ${manifestPath}: ${manifestError.message}`)
33
- }
34
-
35
- let manifestJson
36
- try {
37
- manifestJson = JSON.parse(manifest)
38
- } catch (error_) {
39
- error(`Edge Handlers manifest file is not a valid JSON file: ${error_.message}`)
40
- }
41
-
42
- if (!manifestJson.sha) {
43
- error(`Edge Handlers manifest file is missing the 'sha' property`)
44
- }
45
-
46
- const bundlePath = path.resolve(edgeHandlersResolvedFolder, manifestJson.sha)
47
- const { content: bundleBuffer, error: bundleError } = await readFileAsyncCatchError(bundlePath)
48
-
49
- if (bundleError) {
50
- error(`Could not read Edge Handlers bundle file ${bundlePath}: ${bundleError.message}`)
51
- }
52
-
53
- return { bundleBuffer, manifest: manifestJson }
54
- }
55
-
56
- const deployEdgeHandlers = async ({ api, deployId, silent, site }) => {
57
- const edgeHandlersResolvedFolder = await validateEdgeHandlerFolder({ site })
58
- if (edgeHandlersResolvedFolder) {
59
- let spinner
60
- try {
61
- spinner = silent
62
- ? null
63
- : startSpinner({ text: `Deploying Edge Handlers from directory ${edgeHandlersResolvedFolder}` })
64
-
65
- const { bundleBuffer, manifest } = await readBundleAndManifest({ edgeHandlersResolvedFolder })
66
- // returns false if the bundle exists, true on success, throws on error
67
- const success = await uploadEdgeHandlers({
68
- api,
69
- deployId,
70
- bundleBuffer,
71
- manifest,
72
- })
73
-
74
- const text = success
75
- ? `Finished deploying Edge Handlers from directory: ${edgeHandlersResolvedFolder}`
76
- : `Skipped deploying Edge Handlers since the bundle already exists`
77
- stopSpinner({ spinner, text, error: false })
78
- } catch (error_) {
79
- const text = `Failed deploying Edge Handlers: ${error_.message}`
80
- stopSpinner({ spinner, text, error: true })
81
- await cancelDeploy({ api, deployId })
82
- // no need to report the error again
83
- error('')
84
- }
85
- }
86
- }
87
-
88
- module.exports = { deployEdgeHandlers }