UNPKG

oclif

Version:

oclif: create your own CLI

120 lines (119 loc) 5.07 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.appendToIndex = void 0; const client_s3_1 = require("@aws-sdk/client-s3"); const fs = __importStar(require("fs-extra")); const node_path_1 = __importDefault(require("node:path")); const aws_1 = __importDefault(require("./aws")); const log_1 = require("./log"); const debug = log_1.debug.new('version-indexes'); const sortVersionsObjectByKeysDesc = (input, keyLimit) => { const keys = Reflect.ownKeys(input).sort((a, b) => { const splitA = a.split('.').map((part) => Number.parseInt(part, 10)); const splitB = b.split('.').map((part) => Number.parseInt(part, 10)); // sort by major if (splitA[0] < splitB[0]) return 1; if (splitA[0] > splitB[0]) return -1; // sort by minor if (splitA[1] < splitB[1]) return 1; if (splitA[1] > splitB[1]) return -1; // sort by patch if (splitA[2] < splitB[2]) return 1; if (splitA[2] > splitB[2]) return -1; return 0; }).slice(0, keyLimit); // undefined keyLimit returns the entire array const result = {}; for (const key of keys) { result[key] = input[key]; } return result; }; // appends to an existing file (or writes a new one) with the versions in descending order, with an optional limit from the pjson file const appendToIndex = async (input) => { const { filename, maxAge, originalUrl, s3Config, version } = input; // these checks are both nice for users AND helpful for TS if (!s3Config.bucket) throw new Error('[package.json].oclif.s3.bucket is required for indexes'); if (!s3Config.host) throw new Error('[package.json].oclif.s3.host is required for indexes'); // json-friendly filenames like sfdx-linux-x64-tar-gz const jsonFileName = `${filename.replaceAll('.', '-')}.json`; // folder is optional, but honored if present const key = node_path_1.default.posix.join(s3Config.folder ?? '', 'versions', jsonFileName); // retrieve existing index file let existing = {}; try { const { Body } = await aws_1.default.s3.getObject({ Bucket: s3Config.bucket, Key: key, }); // @ts-expect-error because StreamingBlobTypes doesn't have transformToString // but it's expected to be there according to the docs // https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-smithy-types/TypeAlias/StreamingBlobPayloadOutputTypes/ // https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-smithy-types/Interface/SdkStreamMixin/ existing = JSON.parse(await Body?.transformToString()); debug('appending to existing index file'); } catch (error) { debug(`error on ${key}`, error); } // appends new version from this promotion if not already present (idempotent) await fs.writeJSON(jsonFileName, sortVersionsObjectByKeysDesc({ ...existing, [version]: originalUrl.replace(s3Config.bucket, s3Config.host), }, s3Config.indexVersionLimit), { spaces: 2 }); // put the file back in the same place await aws_1.default.s3.uploadFile(jsonFileName, { ACL: s3Config.acl ?? client_s3_1.ObjectCannedACL.public_read, Bucket: s3Config.bucket, CacheControl: maxAge, Key: key, }, { dryRun: input.dryRun, }); // cleans up local fs await fs.remove(jsonFileName); }; exports.appendToIndex = appendToIndex;