UNPKG

@storm-software/cloudflare-tools

Version:

A Nx plugin package that contains various executors, generators, and utilities that assist in managing Cloudflare services.

232 lines (202 loc) 10.6 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _chunkKUGEZPUOjs = require('./chunk-KUGEZPUO.js'); var _chunkJGJLU4ONjs = require('./chunk-JGJLU4ON.js'); var _chunkXKQ3HGETjs = require('./chunk-XKQ3HGET.js'); var _chunkWROOA5AXjs = require('./chunk-WROOA5AX.js'); var _chunkOZPXCCZBjs = require('./chunk-OZPXCCZB.js'); // src/executors/r2-upload-publish/executor.ts var _clients3 = require('@aws-sdk/client-s3'); var _devkit = require('@nx/devkit'); var _glob = require('glob'); var _mimetypes = require('mime-types'); var _mimetypes2 = _interopRequireDefault(_mimetypes); var _child_process = require('child_process'); var _fs = require('fs'); var _promises = require('fs/promises'); async function runExecutor(options, context) { const isDryRun = process.env.NX_DRY_RUN === "true" || options.dryRun || false; if (!context.projectName) { throw new Error("The executor requires a projectName."); } if (!options.path) { throw new Error("The executor requires the `path` option to upload."); } console.info( `\u{1F680} Running Storm Cloudflare Publish executor on the ${context.projectName} worker` ); if (!context.projectName || !_optionalChain([context, 'access', _ => _.projectsConfigurations, 'optionalAccess', _2 => _2.projects]) || !context.projectsConfigurations.projects[context.projectName] || !_optionalChain([context, 'access', _3 => _3.projectsConfigurations, 'access', _4 => _4.projects, 'access', _5 => _5[context.projectName], 'optionalAccess', _6 => _6.root])) { throw new Error("The executor requires projectsConfigurations."); } try { const workspaceRoot = _chunkWROOA5AXjs.findWorkspaceRoot.call(void 0, ); const config = await _chunkWROOA5AXjs.getConfig.call(void 0, workspaceRoot); const projectName = _nullishCoalesce(_optionalChain([context, 'access', _7 => _7.projectsConfigurations, 'access', _8 => _8.projects, 'access', _9 => _9[context.projectName], 'optionalAccess', _10 => _10.name]), () => ( context.projectName)); const projectDetails = _chunkXKQ3HGETjs.getPackageInfo.call(void 0, context.projectsConfigurations.projects[context.projectName] ); const bucketId = options.bucketId; const bucketPath = options.bucketPath || "/"; if (!bucketId) { throw new Error("The executor requires a bucketId."); } const args = _chunkXKQ3HGETjs.createCliOptions.call(void 0, { ...options }); if (isDryRun) { args.push("--dry-run"); } const cloudflareAccountId = process.env.CLOUDFLARE_ACCOUNT_ID || process.env.STORM_BOT_CLOUDFLARE_ACCOUNT; if (!_optionalChain([options, 'optionalAccess', _11 => _11.registry]) && !cloudflareAccountId) { throw new Error( "The registry option and `CLOUDFLARE_ACCOUNT_ID` (or `STORM_BOT_CLOUDFLARE_ACCOUNT`) environment variable are not set. Please set one of these values to upload to the Cloudflare R2 bucket." ); } if (!process.env.STORM_BOT_ACCESS_KEY_ID && !process.env.ACCESS_KEY_ID && !process.env.CLOUDFLARE_ACCESS_KEY_ID && !process.env.AWS_ACCESS_KEY_ID || !process.env.STORM_BOT_SECRET_ACCESS_KEY && !process.env.CLOUDFLARE_SECRET_ACCESS_KEY && !process.env.SECRET_ACCESS_KEY && !process.env.AWS_SECRET_ACCESS_KEY) { throw new Error( "The `ACCESS_KEY_ID` (or `STORM_BOT_ACCESS_KEY_ID`) and `SECRET_ACCESS_KEY` (or `STORM_BOT_SECRET_ACCESS_KEY`) environment variables are not set. Please set these environment variables to upload to the Cloudflare R2 bucket." ); } const registry = _optionalChain([options, 'optionalAccess', _12 => _12.registry]) ? options.registry : `https://${cloudflareAccountId}.r2.cloudflarestorage.com`; let projectGraph; try { projectGraph = _devkit.readCachedProjectGraph.call(void 0, ); } catch (e) { await _devkit.createProjectGraphAsync.call(void 0, ); projectGraph = _devkit.readCachedProjectGraph.call(void 0, ); } if (!projectGraph) { throw new Error( "The executor failed because the project graph is not available. Please run the build command again." ); } _chunkOZPXCCZBjs.writeDebug.call(void 0, `Publishing ${context.projectName} to the ${bucketId} R2 Bucket (at ${registry})` ); const client = new (0, _clients3.S3Client)({ region: "auto", endpoint: registry, credentials: { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion accessKeyId: process.env.STORM_BOT_ACCESS_KEY_ID || process.env.CLOUDFLARE_ACCESS_KEY_ID || process.env.AWS_ACCESS_KEY_ID || process.env.ACCESS_KEY_ID, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion secretAccessKey: process.env.STORM_BOT_SECRET_ACCESS_KEY || process.env.CLOUDFLARE_SECRET_ACCESS_KEY || process.env.AWS_SECRET_ACCESS_KEY || process.env.SECRET_ACCESS_KEY }, requestHandler: _chunkKUGEZPUOjs.createHttpHandler.call(void 0, ) }); const version = _optionalChain([projectDetails, 'optionalAccess', _13 => _13.content, 'optionalAccess', _14 => _14.version]); if (version) { _chunkOZPXCCZBjs.writeDebug.call(void 0, `Starting upload version ${version}`); } const basePath = options.path; const files = await _glob.glob.call(void 0, _chunkOZPXCCZBjs.joinPaths.call(void 0, basePath, "**/*"), { ignore: "**/{*.stories.tsx,*.stories.ts,*.spec.tsx,*.spec.ts}" }); const internalDependencies = await _chunkJGJLU4ONjs.getInternalDependencies.call(void 0, context.projectName, projectGraph ); const dependencies = internalDependencies.filter( (projectNode) => !projectNode.data.tags || projectNode.data.tags.every((tag) => tag.toLowerCase() !== "component") ).reduce((ret, dep) => { if (!ret[dep.name]) { ret[dep.name] = "latest"; } return ret; }, _nullishCoalesce(_optionalChain([projectDetails, 'optionalAccess', _15 => _15.content, 'access', _16 => _16.dependencies]), () => ( {}))); const release = _nullishCoalesce(options.tag, () => ( _child_process.execSync.call(void 0, "npm config get tag").toString().trim())); if (options.clean === true) { _chunkOZPXCCZBjs.writeDebug.call(void 0, `Clearing out existing items in ${bucketPath}`); if (!isDryRun) { const response = await client.send( new (0, _clients3.ListObjectsCommand)({ Bucket: bucketId, Prefix: !bucketPath || bucketPath === "/" ? void 0 : bucketPath }) ); if (_optionalChain([response, 'optionalAccess', _17 => _17.Contents]) && response.Contents.length > 0) { _chunkOZPXCCZBjs.writeTrace.call(void 0, `Deleting the following existing items from the R2 bucket path ${bucketPath}: ${response.Contents.map((item) => item.Key).join(", ")}` ); await client.send( new (0, _clients3.DeleteObjectsCommand)({ Bucket: bucketId, Delete: { Objects: response.Contents.map((item) => ({ Key: item.Key })), Quiet: false } }) ); } else { _chunkOZPXCCZBjs.writeDebug.call(void 0, `No existing items to delete in the R2 bucket path ${bucketPath}` ); } } else { _chunkOZPXCCZBjs.writeWarning.call(void 0, "[Dry run]: Skipping R2 bucket clean."); } } if (options.writeMetaJson === true) { const meta = { name: context.projectName, version, release, description: _optionalChain([projectDetails, 'optionalAccess', _18 => _18.content, 'optionalAccess', _19 => _19.description]), tags: _optionalChain([projectDetails, 'optionalAccess', _20 => _20.content, 'optionalAccess', _21 => _21.keywords]), dependencies, devDependencies: null, internalDependencies: internalDependencies.filter( (projectNode) => projectNode.data.tags && projectNode.data.tags.some( (tag) => tag.toLowerCase() === "component" ) ).map((dep) => dep.name) }; if (_optionalChain([projectDetails, 'optionalAccess', _22 => _22.type]) === "package.json") { meta.devDependencies = _optionalChain([projectDetails, 'optionalAccess', _23 => _23.content, 'optionalAccess', _24 => _24.devDependencies]); } await _chunkJGJLU4ONjs.uploadFile.call(void 0, client, bucketId, bucketPath, "meta.json", version, JSON.stringify(meta), "application/json", isDryRun ); } await Promise.all( files.map(async (file) => { if (_optionalChain([_fs.statSync.call(void 0, file, { throwIfNoEntry: false }), 'optionalAccess', _25 => _25.isFile, 'call', _26 => _26()])) { const name = _chunkOZPXCCZBjs.correctPaths.call(void 0, file).replace(_chunkOZPXCCZBjs.correctPaths.call(void 0, basePath), ""); const type = _mimetypes2.default.lookup(name) || "application/octet-stream"; await _chunkJGJLU4ONjs.uploadFile.call(void 0, client, bucketId, bucketPath, name, version, await _promises.readFile.call(void 0, file, _chunkJGJLU4ONjs.getEncoding.call(void 0, type)), type, isDryRun ); } }) ); _chunkOZPXCCZBjs.writeSuccess.call(void 0, `Successfully uploaded the ${projectName} project to the Cloudflare R2 bucket.`, config ); return { success: true }; } catch (error) { console.error("Failed to publish to Cloudflare R2 bucket"); console.error(error); console.log(""); return { success: false }; } } exports.runExecutor = runExecutor;