diff --git a/CHANGELOG.md b/CHANGELOG.md index a3fd21f1eb2..334a700c58a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,20 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +## [17.9.0](https://github.com/netlify/cli/compare/v17.8.1...v17.9.0) (2023-12-04) + + +### Features + +* set Netlify environment variables in edge functions ([#6229](https://github.com/netlify/cli/issues/6229)) ([3268f29](https://github.com/netlify/cli/commit/3268f29d9e94b52cf07819b3a83b7886d8330c1e)) + + +### Bug Fixes + +* **deps:** update dependency @netlify/build to v29.29.4 ([#6238](https://github.com/netlify/cli/issues/6238)) ([9a48cb5](https://github.com/netlify/cli/commit/9a48cb5f8a9b1444bc35339d68cb58e0de75a606)) +* **deps:** update dependency @netlify/zip-it-and-ship-it to v9.28.1 ([#6237](https://github.com/netlify/cli/issues/6237)) ([042cc23](https://github.com/netlify/cli/commit/042cc237265c914e801c306a8c4350def42aa271)) +* **deps:** update netlify packages ([#6227](https://github.com/netlify/cli/issues/6227)) ([d37ec4b](https://github.com/netlify/cli/commit/d37ec4b2b891b2222c91335eb7f048fb34907c9b)) + ## [17.8.1](https://github.com/netlify/cli/compare/v17.8.0...v17.8.1) (2023-11-28) diff --git a/package-lock.json b/package-lock.json index 5a4b0d87252..a6805ce593f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,24 +1,24 @@ { "name": "netlify-cli", - "version": "17.8.1", + "version": "17.9.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "netlify-cli", - "version": "17.8.1", + "version": "17.9.0", "hasInstallScript": true, "license": "MIT", "dependencies": { "@bugsnag/js": "7.20.2", "@fastify/static": "6.10.2", "@netlify/blobs": "6.3.1", - "@netlify/build": "29.29.2", + "@netlify/build": "29.29.4", "@netlify/build-info": "7.11.1", "@netlify/config": "20.10.0", "@netlify/edge-bundler": "10.1.3", "@netlify/local-functions-proxy": "1.1.1", - "@netlify/zip-it-and-ship-it": "9.27.0", + "@netlify/zip-it-and-ship-it": "9.28.1", "@octokit/rest": "19.0.13", "ansi-escapes": "6.2.0", "ansi-styles": "6.2.1", @@ -136,7 +136,7 @@ "@types/prettyjson": "0.0.30", "@types/semver": "7.5.0", "@types/uuid": "9.0.7", - "@types/ws": "8.5.9", + "@types/ws": "8.5.10", "@vitest/coverage-v8": "1.0.0-beta.4", "c8": "7.14.0", "eslint-plugin-sort-destructure-keys": "1.5.0", @@ -2287,9 +2287,9 @@ } }, "node_modules/@netlify/build": { - "version": "29.29.2", - "resolved": "https://registry.npmjs.org/@netlify/build/-/build-29.29.2.tgz", - "integrity": "sha512-8q1SEL+gLxNDJySzZ3wGGpX+EZX6H9N/4WWnKaNFzH3dmN1ZVOlYpldsKmscou3BWUJugwp00l+JQImLYERmWg==", + "version": "29.29.4", + "resolved": "https://registry.npmjs.org/@netlify/build/-/build-29.29.4.tgz", + "integrity": "sha512-Df0f5M4FN3uUrYImvVOY6SRON+YgsWwBoeJKsNUso3EIAPjCXNLoGYExH1LE/LmS6MgDbYQcm/jKndhTVY0sIA==", "dependencies": { "@bugsnag/js": "^7.0.0", "@honeycombio/opentelemetry-node": "^0.5.0", @@ -2298,11 +2298,11 @@ "@netlify/config": "^20.10.0", "@netlify/edge-bundler": "10.1.3", "@netlify/framework-info": "^9.8.10", - "@netlify/functions-utils": "^5.2.43", + "@netlify/functions-utils": "^5.2.45", "@netlify/git-utils": "^5.1.1", "@netlify/plugins-list": "^6.72.0", "@netlify/run-utils": "^5.1.1", - "@netlify/zip-it-and-ship-it": "9.27.0", + "@netlify/zip-it-and-ship-it": "9.28.1", "@opentelemetry/api": "^1.4.1", "@opentelemetry/core": "^1.17.1", "@sindresorhus/slugify": "^2.0.0", @@ -3919,11 +3919,11 @@ } }, "node_modules/@netlify/functions-utils": { - "version": "5.2.43", - "resolved": "https://registry.npmjs.org/@netlify/functions-utils/-/functions-utils-5.2.43.tgz", - "integrity": "sha512-AdPOExEvW84IngtENV96DdEef9IVUodUDVP8gynumIEmbjjnhczhiWv6DKY5thPaop+p1LEsZwsYcJseuGMNSA==", + "version": "5.2.45", + "resolved": "https://registry.npmjs.org/@netlify/functions-utils/-/functions-utils-5.2.45.tgz", + "integrity": "sha512-p7NQwOUmDbOG8G+J0UlMOKtTnEoaQemMCM8DgzFd4aOvlzZP870ociP/e6hfaxrq1cFB/cFGax+xfuRWAX66pA==", "dependencies": { - "@netlify/zip-it-and-ship-it": "9.27.0", + "@netlify/zip-it-and-ship-it": "9.28.1", "cpy": "^9.0.0", "path-exists": "^5.0.0" }, @@ -4368,9 +4368,9 @@ } }, "node_modules/@netlify/zip-it-and-ship-it": { - "version": "9.27.0", - "resolved": "https://registry.npmjs.org/@netlify/zip-it-and-ship-it/-/zip-it-and-ship-it-9.27.0.tgz", - "integrity": "sha512-CPlHCKixB9zfaRne5LNiyu14ugyYUmhAfxQJd9h+4eLfAKV52Hd+h3J74Xd+y6sDDrCSMWPmBFmTUTeOUBKX3Q==", + "version": "9.28.1", + "resolved": "https://registry.npmjs.org/@netlify/zip-it-and-ship-it/-/zip-it-and-ship-it-9.28.1.tgz", + "integrity": "sha512-cihW7K9JvlhcrhbdUO9Rhe0r5pydKr8HL++4A2/J7S4Vzl3KftBHyS7O/2Vh54+u3aMon6m4CDXWwErSwjjLNQ==", "dependencies": { "@babel/parser": "^7.22.5", "@babel/types": "7.23.4", @@ -4383,6 +4383,7 @@ "es-module-lexer": "^1.0.0", "esbuild": "0.19.6", "execa": "^6.0.0", + "fast-glob": "^3.3.2", "filter-obj": "^5.0.0", "find-up": "^6.0.0", "glob": "^8.0.3", @@ -4808,6 +4809,21 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/@netlify/zip-it-and-ship-it/node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, "node_modules/@netlify/zip-it-and-ship-it/node_modules/glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -7097,9 +7113,9 @@ "dev": true }, "node_modules/@types/ws": { - "version": "8.5.9", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.9.tgz", - "integrity": "sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==", + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", "dev": true, "dependencies": { "@types/node": "*" @@ -8334,6 +8350,32 @@ "node": ">= 6.0.0" } }, + "node_modules/aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "dependencies": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/aggregate-error/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -19609,32 +19651,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-map/node_modules/aggregate-error": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", - "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", - "dependencies": { - "clean-stack": "^4.0.0", - "indent-string": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map/node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/p-reduce": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-3.0.0.tgz", @@ -26432,9 +26448,9 @@ "integrity": "sha512-JjLz3WW7Wp6NVwQtDxPpWio4L3u9pnnDXnQ7Q16zgAFE9IA1rSjZVSsyOQrtkiBQIxaJ1Zr5eky8vrXJ5mdRWg==" }, "@netlify/build": { - "version": "29.29.2", - "resolved": "https://registry.npmjs.org/@netlify/build/-/build-29.29.2.tgz", - "integrity": "sha512-8q1SEL+gLxNDJySzZ3wGGpX+EZX6H9N/4WWnKaNFzH3dmN1ZVOlYpldsKmscou3BWUJugwp00l+JQImLYERmWg==", + "version": "29.29.4", + "resolved": "https://registry.npmjs.org/@netlify/build/-/build-29.29.4.tgz", + "integrity": "sha512-Df0f5M4FN3uUrYImvVOY6SRON+YgsWwBoeJKsNUso3EIAPjCXNLoGYExH1LE/LmS6MgDbYQcm/jKndhTVY0sIA==", "requires": { "@bugsnag/js": "^7.0.0", "@honeycombio/opentelemetry-node": "^0.5.0", @@ -26443,11 +26459,11 @@ "@netlify/config": "^20.10.0", "@netlify/edge-bundler": "10.1.3", "@netlify/framework-info": "^9.8.10", - "@netlify/functions-utils": "^5.2.43", + "@netlify/functions-utils": "^5.2.45", "@netlify/git-utils": "^5.1.1", "@netlify/plugins-list": "^6.72.0", "@netlify/run-utils": "^5.1.1", - "@netlify/zip-it-and-ship-it": "9.27.0", + "@netlify/zip-it-and-ship-it": "9.28.1", "@opentelemetry/api": "^1.4.1", "@opentelemetry/core": "^1.17.1", "@sindresorhus/slugify": "^2.0.0", @@ -27439,11 +27455,11 @@ } }, "@netlify/functions-utils": { - "version": "5.2.43", - "resolved": "https://registry.npmjs.org/@netlify/functions-utils/-/functions-utils-5.2.43.tgz", - "integrity": "sha512-AdPOExEvW84IngtENV96DdEef9IVUodUDVP8gynumIEmbjjnhczhiWv6DKY5thPaop+p1LEsZwsYcJseuGMNSA==", + "version": "5.2.45", + "resolved": "https://registry.npmjs.org/@netlify/functions-utils/-/functions-utils-5.2.45.tgz", + "integrity": "sha512-p7NQwOUmDbOG8G+J0UlMOKtTnEoaQemMCM8DgzFd4aOvlzZP870ociP/e6hfaxrq1cFB/cFGax+xfuRWAX66pA==", "requires": { - "@netlify/zip-it-and-ship-it": "9.27.0", + "@netlify/zip-it-and-ship-it": "9.28.1", "cpy": "^9.0.0", "path-exists": "^5.0.0" }, @@ -27689,9 +27705,9 @@ } }, "@netlify/zip-it-and-ship-it": { - "version": "9.27.0", - "resolved": "https://registry.npmjs.org/@netlify/zip-it-and-ship-it/-/zip-it-and-ship-it-9.27.0.tgz", - "integrity": "sha512-CPlHCKixB9zfaRne5LNiyu14ugyYUmhAfxQJd9h+4eLfAKV52Hd+h3J74Xd+y6sDDrCSMWPmBFmTUTeOUBKX3Q==", + "version": "9.28.1", + "resolved": "https://registry.npmjs.org/@netlify/zip-it-and-ship-it/-/zip-it-and-ship-it-9.28.1.tgz", + "integrity": "sha512-cihW7K9JvlhcrhbdUO9Rhe0r5pydKr8HL++4A2/J7S4Vzl3KftBHyS7O/2Vh54+u3aMon6m4CDXWwErSwjjLNQ==", "requires": { "@babel/parser": "^7.22.5", "@babel/types": "7.23.4", @@ -27704,6 +27720,7 @@ "es-module-lexer": "^1.0.0", "esbuild": "0.19.6", "execa": "^6.0.0", + "fast-glob": "^3.3.2", "filter-obj": "^5.0.0", "find-up": "^6.0.0", "glob": "^8.0.3", @@ -27912,6 +27929,18 @@ "strip-final-newline": "^3.0.0" } }, + "fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, "glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -29517,9 +29546,9 @@ "dev": true }, "@types/ws": { - "version": "8.5.9", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.9.tgz", - "integrity": "sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==", + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", "dev": true, "requires": { "@types/node": "*" @@ -30356,6 +30385,22 @@ "debug": "4" } }, + "aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "requires": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + }, + "dependencies": { + "indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==" + } + } + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -38611,22 +38656,6 @@ "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", "requires": { "aggregate-error": "^4.0.0" - }, - "dependencies": { - "aggregate-error": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", - "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", - "requires": { - "clean-stack": "^4.0.0", - "indent-string": "^5.0.0" - } - }, - "indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==" - } } }, "p-reduce": { diff --git a/package.json b/package.json index a9cd8f7492f..c4497327f62 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "netlify-cli", "description": "Netlify command line tool", - "version": "17.8.1", + "version": "17.9.0", "author": "Netlify Inc.", "type": "module", "engines": { @@ -81,12 +81,12 @@ "@bugsnag/js": "7.20.2", "@fastify/static": "6.10.2", "@netlify/blobs": "6.3.1", - "@netlify/build": "29.29.2", + "@netlify/build": "29.29.4", "@netlify/build-info": "7.11.1", "@netlify/config": "20.10.0", "@netlify/edge-bundler": "10.1.3", "@netlify/local-functions-proxy": "1.1.1", - "@netlify/zip-it-and-ship-it": "9.27.0", + "@netlify/zip-it-and-ship-it": "9.28.1", "@octokit/rest": "19.0.13", "ansi-escapes": "6.2.0", "ansi-styles": "6.2.1", @@ -200,7 +200,7 @@ "@types/prettyjson": "0.0.30", "@types/semver": "7.5.0", "@types/uuid": "9.0.7", - "@types/ws": "8.5.9", + "@types/ws": "8.5.10", "@vitest/coverage-v8": "1.0.0-beta.4", "c8": "7.14.0", "eslint-plugin-sort-destructure-keys": "1.5.0", diff --git a/src/commands/deploy/deploy.ts b/src/commands/deploy/deploy.ts index a4299b5ce07..1a5ab4f012e 100644 --- a/src/commands/deploy/deploy.ts +++ b/src/commands/deploy/deploy.ts @@ -345,6 +345,55 @@ const deployProgressCb = function () { } } +const uploadDeployBlobs = async ({ + cachedConfig, + deployId, + options, + silent, + siteId, +}: { + cachedConfig: any + deployId: string + options: OptionValues + silent: boolean + siteId: string +}) => { + const statusCb = silent ? () => {} : deployProgressCb() + + statusCb({ + type: 'blobs-uploading', + msg: 'Uploading blobs to deploy store...\n', + phase: 'start', + }) + + const [token] = await getToken(false) + + const { success } = await runCoreSteps(['blobs_upload'], { + ...options, + quiet: silent, + cachedConfig, + deployId, + siteId, + token, + }) + + if (!success) { + statusCb({ + type: 'blobs-uploading', + msg: 'Deploy aborted due to error while uploading blobs to deploy store', + phase: 'error', + }) + + error('Error while uploading blobs to deploy store') + } + + statusCb({ + type: 'blobs-uploading', + msg: 'Finished uploading blobs to deploy store', + phase: 'stop', + }) +} + const runDeploy = async ({ // @ts-expect-error TS(7031) FIXME: Binding element 'alias' implicitly has an 'any' ty... Remove this comment to see the full error message alias, @@ -364,6 +413,8 @@ const runDeploy = async ({ functionsConfig, // @ts-expect-error TS(7031) FIXME: Binding element 'functionsFolder' implicitly has a... Remove this comment to see the full error message functionsFolder, + // @ts-expect-error TS(7031) FIXME: Binding element 'options' implicitly has an 'a... Remove this comment to see the full error message + options, // @ts-expect-error TS(7031) FIXME: Binding element 'packagePath' implicitly has an 'a... Remove this comment to see the full error message packagePath, // @ts-expect-error TS(7031) FIXME: Binding element 'silent' implicitly has an 'any' t... Remove this comment to see the full error message @@ -421,6 +472,7 @@ const runDeploy = async ({ }) config.headers = headers + uploadDeployBlobs({ deployId, siteId, silent, options, cachedConfig: command.netlify.cachedConfig }) results = await deploySite(api, siteId, deployFolder, { config, @@ -690,6 +742,7 @@ const prepAndRunDeploy = async ({ functionsConfig, // pass undefined functionsFolder if doesn't exist functionsFolder: functionsFolderStat && functionsFolder, + options, packagePath: command.workspacePackage, silent: options.json || options.silent, site, diff --git a/tests/integration/commands/deploy/deploy.test.js b/tests/integration/commands/deploy/deploy.test.js index 3861592aef4..a092e147fa2 100644 --- a/tests/integration/commands/deploy/deploy.test.js +++ b/tests/integration/commands/deploy/deploy.test.js @@ -2,6 +2,7 @@ import path from 'path' import process from 'process' import { fileURLToPath } from 'url' +import execa from 'execa' import fetch from 'node-fetch' import { afterAll, beforeAll, describe, test } from 'vitest' @@ -817,4 +818,59 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co t.expect(response).toEqual('Bundled at deployment') }) }) + + test('should upload blobs when saved into .netlify directory', async (t) => { + await withSiteBuilder('site-with-blobs', async (builder) => { + await builder + .withNetlifyToml({ + config: { + build: { publish: 'dist', functions: 'functions' }, + }, + }) + .withContentFile({ + path: 'dist/.netlify/blobs/deploy/hello', + content: 'hello from the blob', + }) + .withPackageJson({ + packageJson: { + dependencies: { + '@netlify/blobs': '^6.3.0', + '@netlify/functions': '^2.4.0', + }, + }, + }) + .withContentFile({ + path: 'functions/read-blob.ts', + content: ` + import { getDeployStore } from "@netlify/blobs" + import { Config, Context } from "@netlify/functions" + + export default async (req: Request, context: Context) => { + const store = getDeployStore() + const blob = await store.get('hello') + + return new Response(blob) + } + + export const config: Config = { + path: "/read-blob" + } + `, + }) + .buildAsync() + + await execa.command('npm install', { cwd: builder.directory }) + const { deploy_url: deployUrl } = await callCli( + ['deploy', '--json'], + { + cwd: builder.directory, + env: { NETLIFY_SITE_ID: context.siteId }, + }, + true, + ) + + const response = await fetch(`${deployUrl}/read-blob`).then((res) => res.text()) + t.expect(response).toEqual('hello from the blob') + }) + }) })