@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
JavaScript
;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;