UNPKG

@supernovaio/cli

Version:

Supernova.io Command Line Interface

227 lines (225 loc) 9.66 kB
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a8c4f73e-02e8-52a9-8859-155cc944878f")}catch(e){}}(); var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; import { Flags } from "@oclif/core"; import { SentryTraced } from "@sentry/nestjs"; import pulsarCoreTypes from "@supernova-studio/pulsar-core"; import axios from "axios"; import * as fs from "node:fs"; import { createRequire } from "node:module"; import path from "node:path"; import "colors"; import { z } from "zod"; import { SentryCommand } from "../types/index.js"; import { exportConfiguration } from "../utils/run-exporter/exporter-utils.js"; import { getWritableVersion } from "../utils/sdk.js"; const require = createRequire(import.meta.url); const pulsarCoreProvider = require("@supernova-studio/pulsar-core"); const pulsarLanguageProvider = require("@supernova-studio/pulsar-language"); export class RunLocalExporter extends SentryCommand { static aliases = ["run-local-exporter"]; static description = "Run local exporter package"; static examples = [ `$ @supernovaio/cli run-local-exporter \ --apiKey="[API_KEY]" \ --designSystemId="[DESIGN_SYSTEM_ID]" \ --themeId="[THEME_ID]" \ --brandId="[BRAND_ID]" \ --exporterDir="[./path/to/exporter/dir]" \ --outputDir="[./path/to/output/dir]" \ --allowOverridingOutput `, ]; static flags = { allowOverridingOutput: Flags.boolean({ default: false, description: "When enabled, CLI will override output in the output directory if same files where present. When disabled, encountering the same file with throw an error.", required: false, }), apiKey: Flags.string({ description: "API key to use for accessing Supernova instance", required: true }), brandId: Flags.string({ description: "Brand to export. Will only be used when exporter has usesBrands: true, but then it is required to be provided", required: false, }), designSystemId: Flags.string({ description: "Design System to export from", required: true }), exporterDir: Flags.string({ description: "Path to exporter package", required: true }), outputDir: Flags.string({ description: "Path to output folder. Must be empty, unless `forceClearOutputDir` is set", required: true, }), proxyUrl: Flags.string({ description: "When set, CLI will use provided proxy URL for all requests", hidden: true, required: false, }), themeId: Flags.string({ description: "Theme to export. Will only be used when exporter has usesThemes: true, and is optional", required: false, }), }; get commandId() { return RunLocalExporter.id; } get configSchema() { return z.object({}); } async executeExporter(flags, versionId) { const logger = new pulsarLanguageProvider.PLLogger(); const pulsarEngine = new pulsarCoreProvider.PCPulsar(pulsarCoreTypes.PCPulsarExporterMode.full, logger); try { await pulsarEngine.initiateWithLocalFolderURL(flags.exporterDir, pulsarCoreTypes.PCExporterEnvironment.ci); const config = exportConfiguration({ apiKey: flags.apiKey, brandId: flags.brandId, dsId: flags.designSystemId, environment: this.env, exportPath: flags.exporterDir, logger, proxyUrl: flags.proxyUrl, themeId: flags.themeId, versionId, }); const result = await pulsarEngine.executeExporter(config, false); return { logger, result, success: true, }; } catch (error) { return { logger, result: error, success: false, }; } } async run() { const { flags } = await this.parse(RunLocalExporter); const { version } = await getWritableVersion(flags); const result = await this.executeExporter(flags, version.id); if (flags.log) { this.logRun(result.logger); } if (result.success) { await this.writeToBuildPath(result.result, flags); this.log("Export finished successfully".green); } else { this.error(`Export failed: ${result.result.message}`.red, { code: "ERR_EXPORT_FAILED", }); } } async downloadFileToMemory(fileUrl) { const response = await axios({ method: "get", responseType: "arraybuffer", url: fileUrl, }); return Buffer.from(response.data); } ensureDirectoryExists(filePath, forceLastFragmentIsDirectory = false) { if (forceLastFragmentIsDirectory && !filePath.endsWith("/")) { filePath += "/"; } if (fs.existsSync(filePath)) { return; } fs.mkdirSync(filePath, { recursive: true }); } logRun(logger) { for (const log of logger.logs) { let message = log.message.trim(); if (message.startsWith('"')) { message = message.slice(1); } if (message.endsWith('"')) { message = message.slice(0, Math.max(0, message.length - 1)); } console.log(`[user]`.gray + message.white); } } async writeToBuildPath(result, flags) { if (!fs.existsSync(flags.outputDir)) { this.ensureDirectoryExists(flags.outputDir); } if (!flags.allowOverridingOutput) { for (const file of result.emittedFiles) { const destination = path.join(flags.outputDir, file.path); if (fs.existsSync(destination)) { throw new Error(`Exporter produced file for destination ${destination} but that file already exists. Enable --allowOverridingOutput option to allow overriding`); } } } const filesToWrite = []; const processFile = async (file) => { const filePath = path.join(flags.outputDir, ...file.path.split("/")); const fileDirectory = path.dirname(filePath); this.ensureDirectoryExists(fileDirectory); switch (file.type) { case "copy_file": { const fileContent = fs.readFileSync(file.content); filesToWrite.push({ content: fileContent, filePath }); break; } case "copy_file_remote": { const fileContent = await this.downloadFileToMemory(file.content); filesToWrite.push({ content: fileContent, filePath }); break; } case "string": { filesToWrite.push({ content: file.content, filePath }); break; } } }; const chunkSize = 4; for (let i = 0; i < result.emittedFiles.length; i += chunkSize) { const chunk = result.emittedFiles.slice(i, i + chunkSize); await Promise.all(chunk.map(file => processFile(file))); } for (const { content, filePath } of filesToWrite) { fs.writeFileSync(filePath, content); } } } __decorate([ SentryTraced(), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, String]), __metadata("design:returntype", Promise) ], RunLocalExporter.prototype, "executeExporter", null); __decorate([ SentryTraced(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], RunLocalExporter.prototype, "run", null); __decorate([ SentryTraced(), __metadata("design:type", Function), __metadata("design:paramtypes", [String]), __metadata("design:returntype", Promise) ], RunLocalExporter.prototype, "downloadFileToMemory", null); __decorate([ SentryTraced(), __metadata("design:type", Function), __metadata("design:paramtypes", [String, Boolean]), __metadata("design:returntype", void 0) ], RunLocalExporter.prototype, "ensureDirectoryExists", null); __decorate([ SentryTraced(), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], RunLocalExporter.prototype, "writeToBuildPath", null); //# sourceMappingURL=run-local-exporter.js.map //# debugId=a8c4f73e-02e8-52a9-8859-155cc944878f