@supernovaio/cli 2.0.35 → 2.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/components-import.js +5 -5
- package/dist/commands/components-import.js.map +1 -1
- package/dist/commands/describe-design-system.js +5 -5
- package/dist/commands/describe-design-system.js.map +1 -1
- package/dist/commands/describe-workspaces.js +7 -7
- package/dist/commands/describe-workspaces.js.map +1 -1
- package/dist/commands/login.js +5 -5
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/publish-documentation.js +5 -5
- package/dist/commands/publish-documentation.js.map +1 -1
- package/dist/commands/run-local-exporter.d.ts +0 -1
- package/dist/commands/run-local-exporter.d.ts.map +1 -1
- package/dist/commands/run-local-exporter.js +5 -6
- package/dist/commands/run-local-exporter.js.map +1 -1
- package/dist/commands/sync-tokens.d.ts +0 -1
- package/dist/commands/sync-tokens.d.ts.map +1 -1
- package/dist/commands/sync-tokens.js +3 -4
- package/dist/commands/sync-tokens.js.map +1 -1
- package/dist/commands/template-upload.d.ts +1 -0
- package/dist/commands/template-upload.d.ts.map +1 -1
- package/dist/commands/template-upload.js +128 -2
- package/dist/commands/template-upload.js.map +1 -1
- package/dist/services/user.service.d.ts +16 -16
- package/dist/services/user.service.d.ts.map +1 -1
- package/dist/services/vault.service.d.ts.map +1 -1
- package/dist/services/vault.service.js +9 -6
- package/dist/services/vault.service.js.map +1 -1
- package/dist/utils/sdk.d.ts +0 -1
- package/dist/utils/sdk.d.ts.map +1 -1
- package/dist/utils/sdk.js +4 -7
- package/dist/utils/sdk.js.map +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-tokens.js","sources":["../../src/commands/sync-tokens.ts"],"sourceRoot":"","sourcesContent":["//\n// sync-tokens.ts\n// Supernova CLI\n//\n// Created by Jiri Trecak.\n// Copyright © Supernova.io. All rights reserved.\n//\n\n// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n// MARK: - Imports\n\nimport { Flags } from \"@oclif/core\"\nimport { SentryTraced } from \"@sentry/nestjs\"\nimport { z, ZodType } from \"zod\"\n\nimport { SentryCommand } from \"../types/index.js\"\n\
|
|
1
|
+
{"version":3,"file":"sync-tokens.js","sources":["../../src/commands/sync-tokens.ts"],"sourceRoot":"","sourcesContent":["//\n// sync-tokens.ts\n// Supernova CLI\n//\n// Created by Jiri Trecak.\n// Copyright © Supernova.io. All rights reserved.\n//\n\n// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n// MARK: - Imports\n\nimport { Flags } from \"@oclif/core\"\nimport { SentryTraced } from \"@sentry/nestjs\"\nimport { z, ZodType } from \"zod\"\n\nimport { SentryCommand } from \"../types/index.js\"\n\nimport { FigmaTokensDataLoader } from \"../utils/figma-tokens-data-loader.js\"\nimport { getWritableVersion } from \"../utils/sdk.js\"\n\n// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n// MARK: - Definition\n\n// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n// MARK: - Configuration\n\nconst SyncDesignTokensConfigSchema = z.object({\n apiKey: z.string(),\n apiUrl: z.string().url().optional(),\n configFilePath: z.string(),\n designSystemId: z.string(),\n proxyUrl: z.string().url().optional(),\n tokenDirPath: z.string().optional(),\n tokenFilePath: z.string().optional(),\n})\n\ntype SyncDesignTokensConfig = z.infer<typeof SyncDesignTokensConfigSchema>\n\n// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n// MARK: - Tool implementation\n\n/** Command that handles synchronization with design tokens plugin */\nexport class SyncDesignTokens extends SentryCommand<SyncDesignTokensConfig> {\n // --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n // MARK: - Command configuration\n\n // How this command can be run\n static aliases = [\"sync-tokens\"]\n // Command help description\n static description = \"Synchronize tokens from Figma Tokens plugin to Supernova workspaces\"\n // Examples how to use the command\n static examples = [\n `$ @supernovaio/cli sync-tokens --apiKey=\"{xxx-xxx-xxx}\" --designSystemId={1234} --tokenFilePath \"/path/to/tokens.json\" --configFilePath \"/path/to/config.json\"`,\n `$ @supernovaio/cli sync-tokens --apiKey=\"{xxx-xxx-xxx}\" --designSystemId={1234} --tokenDirPath \"/path/to/tokens/\" --configFilePath \"/path/to/config.json\"`,\n ]\n // Static flags to enable / disable features\n static flags = {\n apiKey: Flags.string({ description: \"API key to use for accessing Supernova instance\", required: true }),\n apiUrl: Flags.string({\n description: \"API url to use for accessing Supernova instance, would ignore defaults\",\n hidden: true,\n }),\n configFilePath: Flags.string({ description: \"Path to configuration JSON file\", exclusive: [], required: true }),\n designSystemId: Flags.string({ description: \"Design System to synchronize contents with\", required: true }),\n proxyUrl: Flags.string({\n description: \"When set, CLI will use provided proxy URL for all requests\",\n hidden: true,\n required: false,\n }),\n tokenDirPath: Flags.string({\n description: \"Path to directory of JSON files containing token definitions\",\n exactlyOne: [\"tokenDirPath\", \"tokenFilePath\"],\n }),\n tokenFilePath: Flags.string({\n description: \"Path to JSON file containing token definitions\",\n exactlyOne: [\"tokenDirPath\", \"tokenFilePath\"],\n }),\n }\n\n // --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n // MARK: - Command runtime\n\n get commandId(): string {\n return SyncDesignTokens.id\n }\n\n get configSchema(): ZodType<SyncDesignTokensConfig> {\n return SyncDesignTokensConfigSchema\n }\n\n @SentryTraced()\n async run(): Promise<void> {\n const { flags } = await this.parse(SyncDesignTokens)\n\n // Get workspace -> design system –> version\n const { id, instance } = await getWritableVersion(flags)\n const dataLoader = new FigmaTokensDataLoader()\n const configDefinition = dataLoader.loadConfigFromPath(flags.configFilePath)\n const { settings } = configDefinition\n if (flags.dry) {\n settings.dryRun = true\n }\n\n const buildData = (payload: unknown) => ({\n connection: { name: \"CLI\" },\n ...dataLoader.loadConfigFromPathAsIs(flags.configFilePath),\n payload,\n })\n\n if (!flags.tokenFilePath && !flags.tokenDirPath) {\n throw new Error(`Either tokenFilePath or tokenDirPath must be provided`)\n }\n\n const tokenDefinition = flags.tokenDirPath\n ? await dataLoader.loadTokensFromDirectory(flags.tokenDirPath, flags.configFilePath)\n : await dataLoader.loadTokensFromPath(flags.tokenFilePath!)\n const response = (await instance.versions.writeTokenStudioData(id, buildData(tokenDefinition))) as {\n result: { logs: string[] }\n }\n if (response?.result?.logs && response.result.logs.length > 0) {\n for (const log of response.result.logs) {\n this.log(log)\n }\n }\n\n this.log(`\\nTokens synchronized`)\n }\n}\n"],"names":[],"mappings":"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","debug_id":"00776725-3ce8-5b09-99b1-8e3e148ce98e"}
|
|
@@ -23,6 +23,7 @@ export default class TemplateUpload extends SentryCommand<TemplateUploadConfig>
|
|
|
23
23
|
private buildDockerImage;
|
|
24
24
|
private pushDockerImage;
|
|
25
25
|
private remoteTemplateBuild;
|
|
26
|
+
private uploadThumbnailsAndBuildTemplates;
|
|
26
27
|
}
|
|
27
28
|
export {};
|
|
28
29
|
//# sourceMappingURL=template-upload.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template-upload.d.ts","sourceRoot":"","sources":["../../src/commands/template-upload.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"template-upload.d.ts","sourceRoot":"","sources":["../../src/commands/template-upload.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAIhC,OAAO,EAAe,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAY9D,QAAA,MAAM,oBAAoB,gDAAe,CAAA;AAEzC,KAAK,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAuBhE,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,aAAa,CAAC,oBAAoB,CAAC;IAC7E,OAAgB,IAAI,KAAK;IACzB,OAAgB,WAAW,SAAqD;IAChF,OAAgB,QAAQ,WAA0D;IAClF,OAAgB,MAAM,EAAE,OAAO,CAAQ;IACvC,OAAgB,KAAK;;;;;MAmBpB;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,YAAY,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAEhD;IAGY,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YA2DnB,oBAAoB;IAMlC,OAAO,CAAC,cAAc;YAIR,cAAc;YAId,kBAAkB;YAclB,gBAAgB;YAyBhB,eAAe;YAkBf,mBAAmB;YA0BnB,iCAAiC;CA8FhD"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!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]="
|
|
2
|
+
!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]="3a01607f-c974-5086-8482-944a26462fb3")}catch(e){}}();
|
|
3
3
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
4
4
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
5
5
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -19,6 +19,7 @@ import path from "node:path";
|
|
|
19
19
|
import { promisify } from "node:util";
|
|
20
20
|
import { z } from "zod";
|
|
21
21
|
import fsx from "fs-extra";
|
|
22
|
+
import crypto from "node:crypto";
|
|
22
23
|
import { commonFlags, SentryCommand } from "../types/index.js";
|
|
23
24
|
import { sleep } from "../utils/common.js";
|
|
24
25
|
import { tmpdir } from "node:os";
|
|
@@ -97,12 +98,16 @@ export default class TemplateUpload extends SentryCommand {
|
|
|
97
98
|
this.warn(`package.json doesn't contain 'supernova.privateDependencies' declaration.`);
|
|
98
99
|
this.warn(`Dependencies coming from private registries will fail`);
|
|
99
100
|
}
|
|
101
|
+
const templatesWithThumbnailUrls = pkg.supernova?.templates
|
|
102
|
+
? await this.uploadThumbnailsAndBuildTemplates(apiClient, flags.workspaceId, pkg.supernova.templates)
|
|
103
|
+
: undefined;
|
|
100
104
|
const buildData = await apiClient.sandboxes.builds.start({
|
|
101
105
|
workspaceId: flags.workspaceId,
|
|
102
106
|
designSystemId: flags.designSystemId,
|
|
103
107
|
name: pkg.name,
|
|
104
108
|
version: pkg.version,
|
|
105
109
|
isExistingVersionUpdateAllowed: flags.force ?? false,
|
|
110
|
+
templates: templatesWithThumbnailUrls,
|
|
106
111
|
});
|
|
107
112
|
const url = imageUrl(buildData);
|
|
108
113
|
await this.validateDockerDaemon();
|
|
@@ -185,6 +190,70 @@ export default class TemplateUpload extends SentryCommand {
|
|
|
185
190
|
}
|
|
186
191
|
action.stop("done");
|
|
187
192
|
}
|
|
193
|
+
async uploadThumbnailsAndBuildTemplates(apiClient, workspaceId, templates) {
|
|
194
|
+
const templateNames = Object.values(templates).map(t => t.name);
|
|
195
|
+
const duplicateNames = templateNames.filter((name, index) => templateNames.indexOf(name) !== index);
|
|
196
|
+
if (duplicateNames.length > 0) {
|
|
197
|
+
throw new Error(`Duplicate template names found: ${[...new Set(duplicateNames)].join(", ")}. Each template must have a unique name.`);
|
|
198
|
+
}
|
|
199
|
+
const templateCount = Object.keys(templates).length;
|
|
200
|
+
action.start(`📸 Processing ${templateCount} template(s)`);
|
|
201
|
+
const thumbnailFiles = [];
|
|
202
|
+
for (const [templateId, template] of Object.entries(templates)) {
|
|
203
|
+
if (!template.thumbnail)
|
|
204
|
+
continue;
|
|
205
|
+
const validation = await validateThumbnailFile(templateId, template.thumbnail, this);
|
|
206
|
+
if (!validation)
|
|
207
|
+
continue;
|
|
208
|
+
try {
|
|
209
|
+
const checksum = await calculateFileChecksum(validation.fullPath);
|
|
210
|
+
thumbnailFiles.push({
|
|
211
|
+
name: validation.name,
|
|
212
|
+
size: validation.size,
|
|
213
|
+
checksum,
|
|
214
|
+
originalPath: validation.fullPath,
|
|
215
|
+
templateId,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
this.warn(`Failed to calculate checksum for ${validation.fullPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
let thumbnailUrlMap = {};
|
|
224
|
+
if (thumbnailFiles.length > 0) {
|
|
225
|
+
try {
|
|
226
|
+
const uploadResponse = await apiClient.files.upload({
|
|
227
|
+
ownerType: "Workspace",
|
|
228
|
+
workspaceId,
|
|
229
|
+
files: thumbnailFiles.map(({ name, size, checksum }) => ({ name, size, checksum })),
|
|
230
|
+
});
|
|
231
|
+
await uploadFilesToUrls(uploadResponse.uploadUrls, uploadResponse.files, thumbnailFiles);
|
|
232
|
+
await apiClient.files.finalizeUpload({
|
|
233
|
+
ownerType: "Workspace",
|
|
234
|
+
workspaceId,
|
|
235
|
+
fileIds: uploadResponse.uploadUrls.map(f => f.fileId),
|
|
236
|
+
});
|
|
237
|
+
thumbnailUrlMap = buildTemplateUrlMap(thumbnailFiles, uploadResponse.files);
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
this.warn(`Failed to upload thumbnails: ${error instanceof Error ? error.message : String(error)}`);
|
|
241
|
+
this.warn("Continuing without uploaded thumbnails...");
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
const message = thumbnailFiles.length > 0 ? `uploaded ${thumbnailFiles.length} thumbnail(s)` : "no thumbnails to upload";
|
|
245
|
+
action.stop(message);
|
|
246
|
+
const templatesWithUrls = Object.entries(templates).map(([id, template]) => {
|
|
247
|
+
return {
|
|
248
|
+
id,
|
|
249
|
+
name: template.name,
|
|
250
|
+
description: template.description,
|
|
251
|
+
thumbnailUrl: thumbnailUrlMap[id],
|
|
252
|
+
files: template.files,
|
|
253
|
+
};
|
|
254
|
+
});
|
|
255
|
+
return templatesWithUrls;
|
|
256
|
+
}
|
|
188
257
|
}
|
|
189
258
|
__decorate([
|
|
190
259
|
SentryTraced(),
|
|
@@ -224,5 +293,62 @@ async function readPackageJson() {
|
|
|
224
293
|
function imageUrl(build) {
|
|
225
294
|
return `${build.dockerRegistryDomain}${build.build.dockerImagePath}`;
|
|
226
295
|
}
|
|
296
|
+
async function validateThumbnailFile(templateId, thumbnailPath, logger) {
|
|
297
|
+
const allowedExtensions = [".png", ".jpg", ".jpeg", ".svg", ".webp"];
|
|
298
|
+
const maxFileSize = 10 * 1024 * 1024;
|
|
299
|
+
const fullPath = path.resolve(thumbnailPath);
|
|
300
|
+
const name = path.basename(thumbnailPath);
|
|
301
|
+
if (!(await fileExists(fullPath))) {
|
|
302
|
+
logger.warn(`Thumbnail file not found for template ${templateId}: ${thumbnailPath}`);
|
|
303
|
+
return undefined;
|
|
304
|
+
}
|
|
305
|
+
const extension = path.extname(thumbnailPath).toLowerCase();
|
|
306
|
+
if (!allowedExtensions.includes(extension)) {
|
|
307
|
+
logger.warn(`Thumbnail file ${name} for template ${templateId} has unsupported format. Allowed formats: ${allowedExtensions.join(", ")}`);
|
|
308
|
+
return undefined;
|
|
309
|
+
}
|
|
310
|
+
const size = await getFileSize(fullPath);
|
|
311
|
+
if (size > maxFileSize) {
|
|
312
|
+
logger.warn(`Thumbnail file ${name} for template ${templateId} is too large (${(size / 1024 / 1024).toFixed(2)}MB). Maximum size is 10MB.`);
|
|
313
|
+
return undefined;
|
|
314
|
+
}
|
|
315
|
+
return { name, size, fullPath };
|
|
316
|
+
}
|
|
317
|
+
async function uploadFilesToUrls(uploadUrls, fileResponses, thumbnailFiles) {
|
|
318
|
+
const uploadTasks = uploadUrls.map(async (uploadUrl) => {
|
|
319
|
+
const fileResponse = fileResponses.find(f => f.id === uploadUrl.fileId);
|
|
320
|
+
const thumbnailFile = thumbnailFiles.find(f => f.name === fileResponse?.name && f.size === fileResponse?.size);
|
|
321
|
+
if (thumbnailFile) {
|
|
322
|
+
const fileBuffer = await fs.readFile(thumbnailFile.originalPath);
|
|
323
|
+
await fetch(uploadUrl.uploadUrl, {
|
|
324
|
+
method: "PUT",
|
|
325
|
+
body: fileBuffer,
|
|
326
|
+
headers: {
|
|
327
|
+
"Content-Type": "application/octet-stream",
|
|
328
|
+
},
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
await Promise.all(uploadTasks);
|
|
333
|
+
}
|
|
334
|
+
function buildTemplateUrlMap(thumbnailFiles, fileResponses) {
|
|
335
|
+
const thumbnailUrlMap = {};
|
|
336
|
+
for (const thumbnailFile of thumbnailFiles) {
|
|
337
|
+
const fileResponse = fileResponses.find(f => f.name === thumbnailFile.name && f.size === thumbnailFile.size);
|
|
338
|
+
if (fileResponse) {
|
|
339
|
+
thumbnailUrlMap[thumbnailFile.templateId] = fileResponse.url;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return thumbnailUrlMap;
|
|
343
|
+
}
|
|
344
|
+
async function calculateFileChecksum(filePath) {
|
|
345
|
+
const fileBuffer = await fs.readFile(filePath);
|
|
346
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", fileBuffer);
|
|
347
|
+
return Buffer.from(hashBuffer).toString("hex");
|
|
348
|
+
}
|
|
349
|
+
async function getFileSize(filePath) {
|
|
350
|
+
const stats = await fs.stat(filePath);
|
|
351
|
+
return stats.size;
|
|
352
|
+
}
|
|
227
353
|
//# sourceMappingURL=template-upload.js.map
|
|
228
|
-
//# debugId=
|
|
354
|
+
//# debugId=3a01607f-c974-5086-8482-944a26462fb3
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template-upload.js","sources":["../../src/commands/template-upload.ts"],"sourceRoot":"","sourcesContent":["import fetch from \"node-fetch\"\nimport { Flags } from \"@oclif/core\"\nimport { action } from \"@oclif/core/ux\"\nimport { SentryTraced } from \"@sentry/nestjs\"\nimport { exec as execCallback } from \"node:child_process\"\nimport * as fs from \"node:fs/promises\"\nimport path from \"node:path\"\nimport { promisify } from \"node:util\"\nimport { z, ZodType } from \"zod\"\nimport fsx from \"fs-extra\"\n\nimport { commonFlags, SentryCommand } from \"../types/index.js\"\n\nimport { DTOSandboxTemplateBuildCreateResponse, SupernovaApiClient } from \"@supernova-studio/client\"\nimport { sleep } from \"../utils/common.js\"\nimport { tmpdir } from \"node:os\"\n\nconst exec = promisify(execCallback)\n\nconst TemplateUploadConfig = z.object({})\n\ntype TemplateUploadConfig = z.infer<typeof TemplateUploadConfig>\n\nasync function fileExists(p: string) {\n try {\n await fs.access(p)\n return true\n } catch {\n return false\n }\n}\n\nconst dockerfileTemplate = `\nFROM node:22-slim\n\nRUN apt-get update && apt-get install -y curl && apt-get clean && rm -rf /var/lib/apt/lists/*\n\nWORKDIR /home/user\n\nCOPY . .\nRUN {{ npmTokenSecretMount }} npm i && truncate -s 0 .npmrc\nRUN node docker-scripts/extract-private-packages.js\n`\nexport default class TemplateUpload extends SentryCommand<TemplateUploadConfig> {\n static override args = {}\n static override description = \"Upload component container template to Supernova\"\n static override examples = [\"<%= config.bin %> <%= command.id %> TemplateUpload \"]\n static override hidden: boolean = false\n static override flags = {\n ...commonFlags,\n workspaceId: Flags.string({ char: \"w\", description: \"Workspace ID to upload the template to\", required: true }),\n designSystemId: Flags.string({\n char: \"d\",\n description: \"Design system ID to upload the template to\",\n required: true,\n }),\n force: Flags.boolean({\n char: \"f\",\n description:\n \"Allows overwriting already published version of this template if it exists. This flag has no effect on new versions.\",\n required: false,\n }),\n npmToken: Flags.string({\n description:\n \"Allows passing NPM token as a Docker secret. The token will be available as a NPM_TOKEN env variable\",\n required: false,\n }),\n }\n\n get commandId(): string {\n return TemplateUpload.id\n }\n\n get configSchema(): ZodType<TemplateUploadConfig> {\n return TemplateUploadConfig\n }\n\n @SentryTraced()\n public async run(): Promise<void> {\n const apiClient = await this.apiClient()\n const { flags } = await this.parse()\n\n // Read package json\n let pkg\n try {\n pkg = await readPackageJson()\n } catch (error) {\n if (error instanceof Error) this.error(`Failed to read or parse package.json: ${error.message}`)\n else throw error\n }\n\n if (pkg.supernova?.privateDependencies) {\n this.log(`Following packages will be linked as private dependencies: ${pkg.supernova.privateDependencies}`)\n\n if (!(await fileExists(path.join(process.cwd(), \".npmrc\")))) {\n this.error(\n `CLI needs private NPM registry access to be able to bundle private dependencies.\\n` +\n `Please provide .npmrc file in the root directory and include neccessary access tokens.`,\n )\n }\n } else {\n this.warn(`package.json doesn't contain 'supernova.privateDependencies' declaration.`)\n this.warn(`Dependencies coming from private registries will fail`)\n }\n\n // Request build\n const buildData = await apiClient.sandboxes.builds.start({\n workspaceId: flags.workspaceId,\n designSystemId: flags.designSystemId,\n name: pkg.name,\n version: pkg.version,\n isExistingVersionUpdateAllowed: flags.force ?? false,\n })\n\n // Build image\n const url = imageUrl(buildData)\n\n await this.validateDockerDaemon()\n const buildDir = await this.createBuildDir()\n\n try {\n await this.prepareBuildFolder(buildDir)\n await this.buildDockerImage(buildDir, url, flags.npmToken)\n await this.pushDockerImage(buildDir, buildData.dockerRegistryDomain, url)\n await this.remoteTemplateBuild(apiClient, buildData.build.id)\n\n this.log(`✅ Template has been successfully uploaded`)\n } finally {\n await this.deleteBuildDir(buildDir)\n }\n }\n\n private async validateDockerDaemon() {\n await exec(\"docker info\").catch(() => {\n this.error(`Docker is not available, please start docker daemon and try again`)\n })\n }\n\n private createBuildDir(): Promise<string> {\n return fs.mkdtemp(path.join(tmpdir(), \"supernova-template-bundle-\"))\n }\n\n private async deleteBuildDir(buildDir: string) {\n await fs.rm(buildDir, { recursive: true, force: true })\n }\n\n private async prepareBuildFolder(buildDir: string) {\n // Move working directory to temp folder from where it will be built\n await fsx.copy(process.cwd(), buildDir, {\n filter(src) {\n return !src.includes(\"node_modules/\") && !src.includes(\".git/\") && !src.includes(\".out/\")\n },\n })\n\n // Inject Supernova scripts\n const cliSrcPath = path.resolve(path.dirname(new URL(import.meta.url).pathname), \"..\")\n\n await fsx.copy(path.join(cliSrcPath, \"docker-scripts\"), path.join(buildDir, \"docker-scripts\"))\n }\n\n private async buildDockerImage(buildDir: string, imageUrl: string, npmToken: string | undefined) {\n action.start(\"🔨 Building docker image\")\n\n let cmd = `docker build -t ${imageUrl} --pull --platform linux/amd64`\n if (npmToken) cmd += ` --secret id=NPM_TOKEN`\n cmd += \" -f - .\"\n\n const dockerfile = dockerfileTemplate.replace(\n \"{{ npmTokenSecretMount }}\",\n npmToken ? `--mount=type=secret,id=NPM_TOKEN NPM_TOKEN=\"$(cat /run/secrets/NPM_TOKEN)\"` : \"\",\n )\n\n const subprocess = exec(cmd, {\n env: npmToken ? { ...process.env, NPM_TOKEN: npmToken } : process.env,\n cwd: buildDir,\n })\n\n subprocess.child.stdin!.write(dockerfile)\n subprocess.child.stdin!.end()\n\n await subprocess\n\n action.stop(\"done\")\n }\n\n private async pushDockerImage(buildDir: string, dockerHost: string, imageUrl: string) {\n const response = await fetch(`https://${dockerHost}/v2/`)\n if (response.status === 401) {\n // Requires auth\n const { accessToken } = (await this.apiClient()).config\n const loginProcess = exec(`docker login ${dockerHost} -u cli --password-stdin`)\n loginProcess.child.stdin!.write(accessToken)\n loginProcess.child.stdin!.end()\n await loginProcess\n }\n\n action.start(\"⬆️ Uploading docker image to Supernova\")\n await exec(`docker push ${imageUrl}`, {\n cwd: buildDir,\n })\n action.stop(\"done\")\n }\n\n private async remoteTemplateBuild(client: SupernovaApiClient, buildId: string) {\n action.start(\"📦 Creating template with the image\")\n\n // Trigger remote build phase\n await client.sandboxes.builds.finalize(buildId)\n\n // Poll every 2 seconds for roughly 5 minutes\n const pollIntervalMs = 2000\n const timeoutMs = 5 * 60 * 1000\n\n const startTime = Date.now()\n\n let build\n do {\n await sleep(pollIntervalMs)\n build = (await client.sandboxes.builds.get(buildId)).build\n } while (build.state === \"Building\" && Date.now() - startTime < timeoutMs)\n\n // Verify build state\n if (build.state !== \"Success\") {\n this.error(`Template creation failed`)\n }\n\n action.stop(\"done\")\n }\n}\n\ntype PackageJson = {\n name: string\n version: string\n dependencies: Record<string, string>\n supernova:\n | {\n privateDependencies: string[] | undefined\n }\n | undefined\n}\n\nasync function readPackageJson(): Promise<PackageJson> {\n const pkgPath = path.join(process.cwd(), \"package.json\")\n\n if (!(await fileExists(pkgPath))) throw new Error(`package.json file was not found in the current directory`)\n\n const raw = await fs.readFile(pkgPath, \"utf8\")\n const pkg = JSON.parse(raw)\n\n if (typeof pkg !== \"object\" || pkg === null) throw new Error(`Error parsing package.json: not a json`)\n\n if (typeof pkg.name !== \"string\") throw new Error(`Error parsing package.json: 'name' must be defined`)\n if (typeof pkg.version !== \"string\") throw new Error(`Error parsing package.json: 'version' must be defined`)\n if (typeof pkg.dependencies !== \"object\" || pkg.dependencies === null)\n throw new Error(`Error parsing package.json: 'dependencies' must be defined`)\n\n if (pkg.supernova?.privateDependencies) {\n const privateDependencies = pkg.supernova?.privateDependencies\n if (!Array.isArray(privateDependencies)) throw new TypeError(`supernova.privateDependencies must be an array`)\n\n for (const [i, d] of privateDependencies.entries()) {\n if (typeof d !== \"string\") {\n throw new TypeError(`supernova.privateDependencies[${i}] must be a string`)\n }\n\n if (!pkg.dependencies[d]) {\n throw new Error(`Private dependency ${d} is not listed in 'dependencies'`)\n }\n }\n }\n\n return pkg\n}\n\nfunction imageUrl(build: DTOSandboxTemplateBuildCreateResponse) {\n return `${build.dockerRegistryDomain}${build.build.dockerImagePath}`\n}\n"],"names":[],"mappings":"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","debug_id":"b3e738c6-f18f-53bb-a79a-4efaf7dd269b"}
|
|
1
|
+
{"version":3,"file":"template-upload.js","sources":["../../src/commands/template-upload.ts"],"sourceRoot":"","sourcesContent":["import fetch from \"node-fetch\"\nimport { Flags } from \"@oclif/core\"\nimport { action } from \"@oclif/core/ux\"\nimport { SentryTraced } from \"@sentry/nestjs\"\nimport { exec as execCallback } from \"node:child_process\"\nimport * as fs from \"node:fs/promises\"\nimport path from \"node:path\"\nimport { promisify } from \"node:util\"\nimport { z, ZodType } from \"zod\"\nimport fsx from \"fs-extra\"\nimport crypto from \"node:crypto\"\n\nimport { commonFlags, SentryCommand } from \"../types/index.js\"\n\nimport {\n DTOSandboxTemplateBuildCreateResponse,\n DTOSandboxTemplateBuildCreateInput,\n SupernovaApiClient,\n} from \"@supernova-studio/client\"\nimport { sleep } from \"../utils/common.js\"\nimport { tmpdir } from \"node:os\"\n\nconst exec = promisify(execCallback)\n\nconst TemplateUploadConfig = z.object({})\n\ntype TemplateUploadConfig = z.infer<typeof TemplateUploadConfig>\ntype TemplatePreset = { name: string; description: string; thumbnail?: string; files?: string[] }\n\nasync function fileExists(p: string) {\n try {\n await fs.access(p)\n return true\n } catch {\n return false\n }\n}\n\nconst dockerfileTemplate = `\nFROM node:22-slim\n\nRUN apt-get update && apt-get install -y curl && apt-get clean && rm -rf /var/lib/apt/lists/*\n\nWORKDIR /home/user\n\nCOPY . .\nRUN {{ npmTokenSecretMount }} npm i && truncate -s 0 .npmrc\nRUN node docker-scripts/extract-private-packages.js\n`\nexport default class TemplateUpload extends SentryCommand<TemplateUploadConfig> {\n static override args = {}\n static override description = \"Upload component container template to Supernova\"\n static override examples = [\"<%= config.bin %> <%= command.id %> TemplateUpload \"]\n static override hidden: boolean = false\n static override flags = {\n ...commonFlags,\n workspaceId: Flags.string({ char: \"w\", description: \"Workspace ID to upload the template to\", required: true }),\n designSystemId: Flags.string({\n char: \"d\",\n description: \"Design system ID to upload the template to\",\n required: true,\n }),\n force: Flags.boolean({\n char: \"f\",\n description:\n \"Allows overwriting already published version of this template if it exists. This flag has no effect on new versions.\",\n required: false,\n }),\n npmToken: Flags.string({\n description:\n \"Allows passing NPM token as a Docker secret. The token will be available as a NPM_TOKEN env variable\",\n required: false,\n }),\n }\n\n get commandId(): string {\n return TemplateUpload.id\n }\n\n get configSchema(): ZodType<TemplateUploadConfig> {\n return TemplateUploadConfig\n }\n\n @SentryTraced()\n public async run(): Promise<void> {\n const apiClient = await this.apiClient()\n const { flags } = await this.parse()\n\n // Read package json\n let pkg\n try {\n pkg = await readPackageJson()\n } catch (error) {\n if (error instanceof Error) this.error(`Failed to read or parse package.json: ${error.message}`)\n else throw error\n }\n\n if (pkg.supernova?.privateDependencies) {\n this.log(`Following packages will be linked as private dependencies: ${pkg.supernova.privateDependencies}`)\n\n if (!(await fileExists(path.join(process.cwd(), \".npmrc\")))) {\n this.error(\n `CLI needs private NPM registry access to be able to bundle private dependencies.\\n` +\n `Please provide .npmrc file in the root directory and include neccessary access tokens.`,\n )\n }\n } else {\n this.warn(`package.json doesn't contain 'supernova.privateDependencies' declaration.`)\n this.warn(`Dependencies coming from private registries will fail`)\n }\n\n const templatesWithThumbnailUrls = pkg.supernova?.templates\n ? await this.uploadThumbnailsAndBuildTemplates(apiClient, flags.workspaceId, pkg.supernova.templates)\n : undefined\n\n // Request build\n const buildData = await apiClient.sandboxes.builds.start({\n workspaceId: flags.workspaceId,\n designSystemId: flags.designSystemId,\n name: pkg.name,\n version: pkg.version,\n isExistingVersionUpdateAllowed: flags.force ?? false,\n templates: templatesWithThumbnailUrls,\n })\n\n // Build image\n const url = imageUrl(buildData)\n\n await this.validateDockerDaemon()\n const buildDir = await this.createBuildDir()\n\n try {\n await this.prepareBuildFolder(buildDir)\n await this.buildDockerImage(buildDir, url, flags.npmToken)\n await this.pushDockerImage(buildDir, buildData.dockerRegistryDomain, url)\n await this.remoteTemplateBuild(apiClient, buildData.build.id)\n\n this.log(`✅ Template has been successfully uploaded`)\n } finally {\n await this.deleteBuildDir(buildDir)\n }\n }\n\n private async validateDockerDaemon() {\n await exec(\"docker info\").catch(() => {\n this.error(`Docker is not available, please start docker daemon and try again`)\n })\n }\n\n private createBuildDir(): Promise<string> {\n return fs.mkdtemp(path.join(tmpdir(), \"supernova-template-bundle-\"))\n }\n\n private async deleteBuildDir(buildDir: string) {\n await fs.rm(buildDir, { recursive: true, force: true })\n }\n\n private async prepareBuildFolder(buildDir: string) {\n // Move working directory to temp folder from where it will be built\n await fsx.copy(process.cwd(), buildDir, {\n filter(src) {\n return !src.includes(\"node_modules/\") && !src.includes(\".git/\") && !src.includes(\".out/\")\n },\n })\n\n // Inject Supernova scripts\n const cliSrcPath = path.resolve(path.dirname(new URL(import.meta.url).pathname), \"..\")\n\n await fsx.copy(path.join(cliSrcPath, \"docker-scripts\"), path.join(buildDir, \"docker-scripts\"))\n }\n\n private async buildDockerImage(buildDir: string, imageUrl: string, npmToken: string | undefined) {\n action.start(\"🔨 Building docker image\")\n\n let cmd = `docker build -t ${imageUrl} --pull --platform linux/amd64`\n if (npmToken) cmd += ` --secret id=NPM_TOKEN`\n cmd += \" -f - .\"\n\n const dockerfile = dockerfileTemplate.replace(\n \"{{ npmTokenSecretMount }}\",\n npmToken ? `--mount=type=secret,id=NPM_TOKEN NPM_TOKEN=\"$(cat /run/secrets/NPM_TOKEN)\"` : \"\",\n )\n\n const subprocess = exec(cmd, {\n env: npmToken ? { ...process.env, NPM_TOKEN: npmToken } : process.env,\n cwd: buildDir,\n })\n\n subprocess.child.stdin!.write(dockerfile)\n subprocess.child.stdin!.end()\n\n await subprocess\n\n action.stop(\"done\")\n }\n\n private async pushDockerImage(buildDir: string, dockerHost: string, imageUrl: string) {\n const response = await fetch(`https://${dockerHost}/v2/`)\n if (response.status === 401) {\n // Requires auth\n const { accessToken } = (await this.apiClient()).config\n const loginProcess = exec(`docker login ${dockerHost} -u cli --password-stdin`)\n loginProcess.child.stdin!.write(accessToken)\n loginProcess.child.stdin!.end()\n await loginProcess\n }\n\n action.start(\"⬆️ Uploading docker image to Supernova\")\n await exec(`docker push ${imageUrl}`, {\n cwd: buildDir,\n })\n action.stop(\"done\")\n }\n\n private async remoteTemplateBuild(client: SupernovaApiClient, buildId: string) {\n action.start(\"📦 Creating template with the image\")\n\n // Trigger remote build phase\n await client.sandboxes.builds.finalize(buildId)\n\n // Poll every 2 seconds for roughly 5 minutes\n const pollIntervalMs = 2000\n const timeoutMs = 5 * 60 * 1000\n\n const startTime = Date.now()\n\n let build\n do {\n await sleep(pollIntervalMs)\n build = (await client.sandboxes.builds.get(buildId)).build\n } while (build.state === \"Building\" && Date.now() - startTime < timeoutMs)\n\n // Verify build state\n if (build.state !== \"Success\") {\n this.error(`Template creation failed`)\n }\n\n action.stop(\"done\")\n }\n\n private async uploadThumbnailsAndBuildTemplates(\n apiClient: SupernovaApiClient,\n workspaceId: string,\n templates: { [key: string]: TemplatePreset },\n ): Promise<DTOSandboxTemplateBuildCreateInput[\"templates\"]> {\n // Validate template names are unique\n const templateNames = Object.values(templates).map(t => t.name)\n const duplicateNames = templateNames.filter((name, index) => templateNames.indexOf(name) !== index)\n if (duplicateNames.length > 0) {\n throw new Error(\n `Duplicate template names found: ${[...new Set(duplicateNames)].join(\", \")}. Each template must have a unique name.`,\n )\n }\n\n const templateCount = Object.keys(templates).length\n action.start(`📸 Processing ${templateCount} template(s)`)\n\n const thumbnailFiles: Array<{\n name: string\n size: number\n checksum: string\n originalPath: string\n templateId: string\n }> = []\n\n // Validate thumbnail files\n for (const [templateId, template] of Object.entries(templates)) {\n if (!template.thumbnail) continue\n\n const validation = await validateThumbnailFile(templateId, template.thumbnail, this)\n if (!validation) continue\n\n try {\n const checksum = await calculateFileChecksum(validation.fullPath)\n thumbnailFiles.push({\n name: validation.name,\n size: validation.size,\n checksum,\n originalPath: validation.fullPath,\n templateId,\n })\n } catch (error) {\n this.warn(\n `Failed to calculate checksum for ${validation.fullPath}: ${error instanceof Error ? error.message : String(error)}`,\n )\n continue\n }\n }\n\n let thumbnailUrlMap: { [templateId: string]: string } = {}\n\n if (thumbnailFiles.length > 0) {\n try {\n // Request upload URLs from API\n const uploadResponse = await apiClient.files.upload({\n ownerType: \"Workspace\",\n workspaceId,\n files: thumbnailFiles.map(({ name, size, checksum }) => ({ name, size, checksum })),\n })\n\n // Upload files to signed URLs\n await uploadFilesToUrls(uploadResponse.uploadUrls, uploadResponse.files, thumbnailFiles)\n\n await apiClient.files.finalizeUpload({\n ownerType: \"Workspace\",\n workspaceId,\n fileIds: uploadResponse.uploadUrls.map(f => f.fileId),\n })\n\n // Map template IDs to their uploaded thumbnail URLs\n thumbnailUrlMap = buildTemplateUrlMap(thumbnailFiles, uploadResponse.files)\n } catch (error) {\n this.warn(`Failed to upload thumbnails: ${error instanceof Error ? error.message : String(error)}`)\n this.warn(\"Continuing without uploaded thumbnails...\")\n // Don't error out completely, just continue without uploaded thumbnails\n }\n }\n\n const message =\n thumbnailFiles.length > 0 ? `uploaded ${thumbnailFiles.length} thumbnail(s)` : \"no thumbnails to upload\"\n action.stop(message)\n\n const templatesWithUrls = Object.entries(templates).map(([id, template]) => {\n return {\n id,\n name: template.name,\n description: template.description,\n thumbnailUrl: thumbnailUrlMap[id],\n files: template.files,\n }\n })\n\n return templatesWithUrls\n }\n}\n\ntype PackageJson = {\n name: string\n version: string\n dependencies: Record<string, string>\n supernova:\n | {\n privateDependencies: string[] | undefined\n templates?: {\n [key: string]: TemplatePreset\n }\n }\n | undefined\n}\n\nasync function readPackageJson(): Promise<PackageJson> {\n const pkgPath = path.join(process.cwd(), \"package.json\")\n\n if (!(await fileExists(pkgPath))) throw new Error(`package.json file was not found in the current directory`)\n\n const raw = await fs.readFile(pkgPath, \"utf8\")\n const pkg = JSON.parse(raw)\n\n if (typeof pkg !== \"object\" || pkg === null) throw new Error(`Error parsing package.json: not a json`)\n\n if (typeof pkg.name !== \"string\") throw new Error(`Error parsing package.json: 'name' must be defined`)\n if (typeof pkg.version !== \"string\") throw new Error(`Error parsing package.json: 'version' must be defined`)\n if (typeof pkg.dependencies !== \"object\" || pkg.dependencies === null)\n throw new Error(`Error parsing package.json: 'dependencies' must be defined`)\n\n if (pkg.supernova?.privateDependencies) {\n const privateDependencies = pkg.supernova?.privateDependencies\n if (!Array.isArray(privateDependencies)) throw new TypeError(`supernova.privateDependencies must be an array`)\n\n for (const [i, d] of privateDependencies.entries()) {\n if (typeof d !== \"string\") {\n throw new TypeError(`supernova.privateDependencies[${i}] must be a string`)\n }\n\n if (!pkg.dependencies[d]) {\n throw new Error(`Private dependency ${d} is not listed in 'dependencies'`)\n }\n }\n }\n\n return pkg\n}\n\nfunction imageUrl(build: DTOSandboxTemplateBuildCreateResponse) {\n return `${build.dockerRegistryDomain}${build.build.dockerImagePath}`\n}\n\nasync function validateThumbnailFile(\n templateId: string,\n thumbnailPath: string,\n logger: { warn: (msg: string) => void },\n): Promise<{ name: string; size: number; fullPath: string } | undefined> {\n const allowedExtensions = [\".png\", \".jpg\", \".jpeg\", \".svg\", \".webp\"]\n const maxFileSize = 10 * 1024 * 1024 // 10 MB in bytes\n\n const fullPath = path.resolve(thumbnailPath)\n const name = path.basename(thumbnailPath)\n\n if (!(await fileExists(fullPath))) {\n logger.warn(`Thumbnail file not found for template ${templateId}: ${thumbnailPath}`)\n return undefined\n }\n\n const extension = path.extname(thumbnailPath).toLowerCase()\n if (!allowedExtensions.includes(extension)) {\n logger.warn(\n `Thumbnail file ${name} for template ${templateId} has unsupported format. Allowed formats: ${allowedExtensions.join(\", \")}`,\n )\n return undefined\n }\n\n const size = await getFileSize(fullPath)\n if (size > maxFileSize) {\n logger.warn(\n `Thumbnail file ${name} for template ${templateId} is too large (${(size / 1024 / 1024).toFixed(2)}MB). Maximum size is 10MB.`,\n )\n return undefined\n }\n\n return { name, size, fullPath }\n}\n\nasync function uploadFilesToUrls(\n uploadUrls: Array<{ fileId: string; uploadUrl: string }>,\n fileResponses: Array<{ id: string; name: string; size: number }>,\n thumbnailFiles: Array<{ name: string; size: number; originalPath: string; templateId: string }>,\n): Promise<void> {\n const uploadTasks = uploadUrls.map(async uploadUrl => {\n const fileResponse = fileResponses.find(f => f.id === uploadUrl.fileId)\n const thumbnailFile = thumbnailFiles.find(f => f.name === fileResponse?.name && f.size === fileResponse?.size)\n\n if (thumbnailFile) {\n const fileBuffer = await fs.readFile(thumbnailFile.originalPath)\n await fetch(uploadUrl.uploadUrl, {\n method: \"PUT\",\n body: fileBuffer,\n headers: {\n \"Content-Type\": \"application/octet-stream\",\n },\n })\n }\n })\n\n await Promise.all(uploadTasks)\n}\n\nfunction buildTemplateUrlMap(\n thumbnailFiles: Array<{ templateId: string; name: string; size: number }>,\n fileResponses: Array<{ name: string; size: number; url: string }>,\n): { [templateId: string]: string } {\n const thumbnailUrlMap: { [templateId: string]: string } = {}\n\n for (const thumbnailFile of thumbnailFiles) {\n const fileResponse = fileResponses.find(f => f.name === thumbnailFile.name && f.size === thumbnailFile.size)\n if (fileResponse) {\n thumbnailUrlMap[thumbnailFile.templateId] = fileResponse.url\n }\n }\n\n return thumbnailUrlMap\n}\n\nasync function calculateFileChecksum(filePath: string): Promise<string> {\n const fileBuffer = await fs.readFile(filePath)\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", fileBuffer)\n return Buffer.from(hashBuffer).toString(\"hex\")\n}\n\nasync function getFileSize(filePath: string): Promise<number> {\n const stats = await fs.stat(filePath)\n return stats.size\n}\n"],"names":[],"mappings":"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","debug_id":"3a01607f-c974-5086-8482-944a26462fb3"}
|
|
@@ -4,37 +4,36 @@ export declare class UserService {
|
|
|
4
4
|
constructor(client: SupernovaApiClient);
|
|
5
5
|
getMe(): Promise<{
|
|
6
6
|
user: {
|
|
7
|
-
id: string;
|
|
8
|
-
createdAt: Date;
|
|
9
7
|
email: string;
|
|
8
|
+
id: string;
|
|
10
9
|
profile: {
|
|
11
10
|
name: string;
|
|
12
|
-
nickname?: string | undefined;
|
|
13
11
|
avatar?: string | undefined;
|
|
12
|
+
nickname?: string | undefined;
|
|
13
|
+
theme?: {
|
|
14
|
+
backgroundColor?: string | undefined;
|
|
15
|
+
accentColor?: string | undefined;
|
|
16
|
+
contrast?: number | undefined;
|
|
17
|
+
isSecondaryEnabled?: boolean | undefined;
|
|
18
|
+
secondaryBackgroundColor?: string | undefined;
|
|
19
|
+
secondaryContrast?: number | undefined;
|
|
20
|
+
isEditorWhite?: boolean | undefined;
|
|
21
|
+
preset?: "Custom" | "Default" | "HighContrast" | "DefaultDark" | "HighContrastDark" | "SpaceBlue" | "DarkGrey" | "SystemPreference" | "Sepia" | undefined;
|
|
22
|
+
} | undefined;
|
|
14
23
|
onboarding?: {
|
|
15
24
|
companyName?: string | undefined;
|
|
16
25
|
numberOfPeopleInOrg?: string | undefined;
|
|
17
26
|
numberOfPeopleInDesignTeam?: string | undefined;
|
|
18
|
-
department?: "
|
|
27
|
+
department?: "Other" | "Design" | "Engineering" | "Product" | "Brand" | undefined;
|
|
19
28
|
jobTitle?: string | undefined;
|
|
20
29
|
phase?: string | undefined;
|
|
21
30
|
jobLevel?: "Other" | "Executive" | "Manager" | "IndividualContributor" | undefined;
|
|
22
31
|
designSystemName?: string | undefined;
|
|
23
32
|
defaultDestination?: string | undefined;
|
|
24
|
-
isPageDraftOnboardingFinished?: boolean | undefined;
|
|
25
33
|
figmaUrl?: string | undefined;
|
|
34
|
+
isPageDraftOnboardingFinished?: boolean | undefined;
|
|
26
35
|
isApprovalsOnboardingFinished?: boolean | undefined;
|
|
27
36
|
} | undefined;
|
|
28
|
-
theme?: {
|
|
29
|
-
backgroundColor?: string | undefined;
|
|
30
|
-
accentColor?: string | undefined;
|
|
31
|
-
contrast?: number | undefined;
|
|
32
|
-
isSecondaryEnabled?: boolean | undefined;
|
|
33
|
-
secondaryBackgroundColor?: string | undefined;
|
|
34
|
-
secondaryContrast?: number | undefined;
|
|
35
|
-
isEditorWhite?: boolean | undefined;
|
|
36
|
-
preset?: "Custom" | "Default" | "HighContrast" | "DefaultDark" | "HighContrastDark" | "SpaceBlue" | "DarkGrey" | "SystemPreference" | "Sepia" | undefined;
|
|
37
|
-
} | undefined;
|
|
38
37
|
portalTheme?: {
|
|
39
38
|
backgroundColor?: string | undefined;
|
|
40
39
|
accentColor?: string | undefined;
|
|
@@ -46,11 +45,12 @@ export declare class UserService {
|
|
|
46
45
|
preset?: "Custom" | "Default" | "HighContrast" | "DefaultDark" | "HighContrastDark" | "SpaceBlue" | "DarkGrey" | "SystemPreference" | "Sepia" | "DefaultPortal" | undefined;
|
|
47
46
|
} | undefined;
|
|
48
47
|
};
|
|
48
|
+
createdAt: Date;
|
|
49
49
|
emailSettings: {
|
|
50
50
|
marketingEmails: boolean;
|
|
51
51
|
};
|
|
52
|
-
loggedOutAt?: Date | undefined;
|
|
53
52
|
source?: "SignUp" | "Invite" | "SSO" | "Google" | undefined;
|
|
53
|
+
loggedOutAt?: Date | undefined;
|
|
54
54
|
};
|
|
55
55
|
}>;
|
|
56
56
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.service.d.ts","sourceRoot":"","sources":["../../src/services/user.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAE7D,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,kBAAkB;IAEvD,KAAK
|
|
1
|
+
{"version":3,"file":"user.service.d.ts","sourceRoot":"","sources":["../../src/services/user.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAE7D,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,kBAAkB;IAEvD,KAAK;;;;;;sBAI2013f,CAAC;wBAA8C,CAAC;qBAA2C,CAAC;mCAAuC,CAAC;+BAAqD,CAAC;4BAAkD,CAAC;sCAA4D,CAAC;4CAAmE,CAAC;qCAA2D,CAAC;iCAAuD,CAAC;0BAAiD,CAAC;;0BAA6M,CAAC;+BAAmC,CAAC;uCAA6D,CAAC;8CAAoE,CAAC;8BAAoD,CAAC;4BAAoG,CAAC;yBAA+C,CAAC;4BAAkD,CAAC;oCAA+G,CAAC;sCAA4D,CAAC;4BAAkD,CAAC;iDAAuE,CAAC;iDAAwE,CAAC;;2BAAiF,CAAC;mCAAuC,CAAC;+BAAqD,CAAC;4BAAkD,CAAC;sCAA4D,CAAC;4CAAmE,CAAC;qCAA2D,CAAC;iCAAuD,CAAC;0BAAiD,CAAC;;;;;;;kBAAyV,CAAC;uBAA6E,CAAC;;;CAD1v63f"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vault.service.d.ts","sourceRoot":"","sources":["../../src/services/vault.service.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACnD,OAAO,EAA8B,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAEtE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAU/C,MAAM,WAAW,MAAM;IACrB,cAAc,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACvE,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,CAAA;IAC7E,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACvF;AAED,qBAAa,WAAY,YAAW,MAAM;IAClC,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"vault.service.d.ts","sourceRoot":"","sources":["../../src/services/vault.service.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACnD,OAAO,EAA8B,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAEtE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAU/C,MAAM,WAAW,MAAM;IACrB,cAAc,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACvE,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,CAAA;IAC7E,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACvF;AAED,qBAAa,WAAY,YAAW,MAAM;IAClC,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnE,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC;IAKzE,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAIzF;AAED,qBAAa,YAAY;IAIrB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK;IAJxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;gBAGvB,WAAW,GAAE,WAA+B,EAC5C,KAAK,GAAE,MAA0B;IAIvC,qBAAqB,CAAC,GAAG,EAAE,SAAS;IAUpC,kBAAkB,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IASrE,iBAAiB,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS;IAa/C,qBAAqB,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IA+B7D,kBAAkB,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAOnD,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAkB3G,iBAAiB,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,GAAG,MAAM;IAqBjD,kBAAkB,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS;IAW9E,YAAY,IAAI,MAAM;IAKtB,cAAc,IAAI,MAAM;CAIhC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!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]="
|
|
2
|
+
!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]="1ae5b45e-6c76-59ae-8787-71b5df4c3714")}catch(e){}}();
|
|
3
3
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
4
4
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
5
5
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -22,18 +22,21 @@ let _keytarCache;
|
|
|
22
22
|
async function importKeytar() {
|
|
23
23
|
if (_keytarCache)
|
|
24
24
|
return _keytarCache;
|
|
25
|
-
_keytarCache = await import("keytar");
|
|
25
|
+
_keytarCache = (await import("keytar")).default;
|
|
26
26
|
return _keytarCache;
|
|
27
27
|
}
|
|
28
28
|
export class KeytarVault {
|
|
29
29
|
async deletePassword(serviceName, account) {
|
|
30
|
-
|
|
30
|
+
const kt = await importKeytar();
|
|
31
|
+
await kt.deletePassword(serviceName, account);
|
|
31
32
|
}
|
|
32
33
|
async getPassword(serviceName, account) {
|
|
33
|
-
|
|
34
|
+
const kt = await importKeytar();
|
|
35
|
+
return kt.getPassword(serviceName, account);
|
|
34
36
|
}
|
|
35
37
|
async setPassword(serviceName, account, password) {
|
|
36
|
-
|
|
38
|
+
const kt = await importKeytar();
|
|
39
|
+
await kt.setPassword(serviceName, account, password);
|
|
37
40
|
}
|
|
38
41
|
}
|
|
39
42
|
export class VaultService {
|
|
@@ -201,4 +204,4 @@ __decorate([
|
|
|
201
204
|
__metadata("design:returntype", Promise)
|
|
202
205
|
], VaultService.prototype, "storeTokensToVault", null);
|
|
203
206
|
//# sourceMappingURL=vault.service.js.map
|
|
204
|
-
//# debugId=
|
|
207
|
+
//# debugId=1ae5b45e-6c76-59ae-8787-71b5df4c3714
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vault.service.js","sources":["../../src/services/vault.service.ts"],"sourceRoot":"","sourcesContent":["import { SentryTraced } from \"@sentry/nestjs\"\nimport { jwtDecode } from \"jwt-decode\"\nimport * as fs from \"node:fs\"\nimport * as os from \"node:os\"\nimport path from \"node:path\"\nimport type _keytar from \"keytar\"\nimport { TargetEnv } from \"../types/environment.js\"\nimport { EnvTokens, EnvTokensSchema, Tokens } from \"../types/login.js\"\nimport { NotAuthorizedError } from \"../types/not-authorized.error.js\"\nimport { AuthService } from \"./auth.service.js\"\n\nlet _keytarCache: typeof _keytar | undefined\n\nasync function importKeytar() {\n if (_keytarCache) return _keytarCache\n _keytarCache = await import(\"keytar\")\n return _keytarCache\n}\n\nexport interface IVault {\n deletePassword: (serviceName: string, account: string) => Promise<void>\n getPassword: (serviceName: string, account: string) => Promise<null | string>\n setPassword: (serviceName: string, account: string, password: string) => Promise<void>\n}\n\nexport class KeytarVault implements IVault {\n async deletePassword(serviceName: string, account: string): Promise<void> {\n await (await importKeytar()).deletePassword(serviceName, account)\n }\n\n async getPassword(serviceName: string, account: string): Promise<null | string> {\n return (await importKeytar()).getPassword(serviceName, account)\n }\n\n async setPassword(serviceName: string, account: string, password: string): Promise<void> {\n await (await importKeytar()).setPassword(serviceName, account, password)\n }\n}\n\nexport class VaultService {\n private readonly serviceName = \"Supernova\"\n\n constructor(\n private readonly authService: AuthService = new AuthService(),\n private readonly vault: IVault = new KeytarVault(),\n ) {}\n\n @SentryTraced()\n public async deleteTokensFromVault(env: TargetEnv) {\n try {\n await this.vault.deletePassword(this.serviceName, `${env}_access_token`)\n await this.vault.deletePassword(this.serviceName, `${env}_refresh_token`)\n } catch {\n this.storeTokensInFile(env, null)\n }\n }\n\n @SentryTraced()\n public async getLoggedInUserSub(env: TargetEnv): Promise<string | undefined> {\n const tokens = await this.tryGetTokensFromVault(env)\n if (!tokens) return undefined\n\n const decoded = jwtDecode<{ sub?: string }>(tokens.accessToken)\n return decoded.sub\n }\n\n @SentryTraced()\n public getTokensFromFile(env: TargetEnv): Tokens | undefined {\n const filePath = this.tokensFilePath()\n\n if (!fs.existsSync(filePath)) {\n return undefined\n }\n\n const fileContent = fs.readFileSync(filePath, \"utf8\")\n const data = JSON.parse(fileContent)\n return data[env] ?? {}\n }\n\n @SentryTraced()\n public async tryGetTokensFromVault(env: TargetEnv): Promise<Tokens | null> {\n if (process.env.SUPERNOVA_TOKEN) {\n return { accessToken: process.env.SUPERNOVA_TOKEN }\n }\n\n let accessToken: string | undefined\n let refreshToken: string | undefined\n try {\n accessToken = (await this.vault.getPassword(this.serviceName, `${env}_access_token`)) ?? undefined\n refreshToken = (await this.vault.getPassword(this.serviceName, `${env}_refresh_token`)) ?? undefined\n } catch {\n const tokens = this.getTokensFromFile(env)\n if (tokens) {\n accessToken = tokens.accessToken\n refreshToken = tokens.refreshToken\n }\n }\n\n if (!accessToken) {\n return null\n }\n\n const freshTokens = refreshToken ? await this.refreshTokens(env, accessToken, refreshToken) : undefined\n if (freshTokens) {\n return freshTokens\n }\n\n return { accessToken, refreshToken }\n }\n\n @SentryTraced()\n public async getTokensFromVault(env: TargetEnv): Promise<Tokens> {\n const tokens = await this.tryGetTokensFromVault(env)\n if (!tokens) throw new NotAuthorizedError()\n return tokens\n }\n\n @SentryTraced()\n public async refreshTokens(env: TargetEnv, accessToken: string, refreshToken: string): Promise<Tokens | undefined> {\n const decoded = jwtDecode<{ exp?: number }>(accessToken)\n const currentTime = Math.floor(Date.now() / 1000)\n if (decoded.exp && decoded.exp < currentTime + 300) {\n const freshTokens = await this.authService.refreshToken(env, refreshToken)\n if (!freshTokens) {\n await this.deleteTokensFromVault(env)\n throw new NotAuthorizedError()\n }\n\n await this.storeTokensToVault(freshTokens, env)\n return freshTokens\n }\n\n return undefined\n }\n\n @SentryTraced()\n public storeTokensInFile(env: TargetEnv, tokens: null | Tokens) {\n const supernovaDir = this.supernovaDir()\n const filePath = path.join(supernovaDir, \"tokens.json\")\n\n if (!fs.existsSync(supernovaDir)) {\n fs.mkdirSync(supernovaDir, { recursive: true })\n }\n\n let data: EnvTokens = {}\n if (fs.existsSync(filePath)) {\n const fileContent = fs.readFileSync(filePath, \"utf8\")\n data = EnvTokensSchema.parse(JSON.parse(fileContent))\n }\n\n if (tokens) data[env] = tokens\n else delete data[env]\n\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2), \"utf8\")\n }\n\n @SentryTraced()\n public async storeTokensToVault({ accessToken, refreshToken }: Tokens, env: TargetEnv) {\n try {\n await this.vault.setPassword(this.serviceName, `${env}_access_token`, accessToken)\n if (refreshToken) {\n await this.vault.setPassword(this.serviceName, `${env}_refresh_token`, refreshToken)\n }\n } catch {\n this.storeTokensInFile(env, { accessToken, refreshToken })\n }\n }\n\n public supernovaDir(): string {\n const homeDir = os.homedir()\n return path.join(homeDir, \".supernova\")\n }\n\n public tokensFilePath(): string {\n const homeDir = this.supernovaDir()\n return path.join(homeDir, \"tokens.json\")\n }\n}\n"],"names":[],"mappings":"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","debug_id":"5be19fa8-abc9-564e-bdba-3cfd37703c9b"}
|
|
1
|
+
{"version":3,"file":"vault.service.js","sources":["../../src/services/vault.service.ts"],"sourceRoot":"","sourcesContent":["import { SentryTraced } from \"@sentry/nestjs\"\nimport { jwtDecode } from \"jwt-decode\"\nimport * as fs from \"node:fs\"\nimport * as os from \"node:os\"\nimport path from \"node:path\"\nimport type _keytar from \"keytar\"\nimport { TargetEnv } from \"../types/environment.js\"\nimport { EnvTokens, EnvTokensSchema, Tokens } from \"../types/login.js\"\nimport { NotAuthorizedError } from \"../types/not-authorized.error.js\"\nimport { AuthService } from \"./auth.service.js\"\n\nlet _keytarCache: typeof _keytar | undefined\n\nasync function importKeytar() {\n if (_keytarCache) return _keytarCache\n _keytarCache = (await import(\"keytar\")).default\n return _keytarCache\n}\n\nexport interface IVault {\n deletePassword: (serviceName: string, account: string) => Promise<void>\n getPassword: (serviceName: string, account: string) => Promise<null | string>\n setPassword: (serviceName: string, account: string, password: string) => Promise<void>\n}\n\nexport class KeytarVault implements IVault {\n async deletePassword(serviceName: string, account: string): Promise<void> {\n const kt = await importKeytar()\n await kt.deletePassword(serviceName, account)\n }\n\n async getPassword(serviceName: string, account: string): Promise<null | string> {\n const kt = await importKeytar()\n return kt.getPassword(serviceName, account)\n }\n\n async setPassword(serviceName: string, account: string, password: string): Promise<void> {\n const kt = await importKeytar()\n await kt.setPassword(serviceName, account, password)\n }\n}\n\nexport class VaultService {\n private readonly serviceName = \"Supernova\"\n\n constructor(\n private readonly authService: AuthService = new AuthService(),\n private readonly vault: IVault = new KeytarVault(),\n ) {}\n\n @SentryTraced()\n public async deleteTokensFromVault(env: TargetEnv) {\n try {\n await this.vault.deletePassword(this.serviceName, `${env}_access_token`)\n await this.vault.deletePassword(this.serviceName, `${env}_refresh_token`)\n } catch {\n this.storeTokensInFile(env, null)\n }\n }\n\n @SentryTraced()\n public async getLoggedInUserSub(env: TargetEnv): Promise<string | undefined> {\n const tokens = await this.tryGetTokensFromVault(env)\n if (!tokens) return undefined\n\n const decoded = jwtDecode<{ sub?: string }>(tokens.accessToken)\n return decoded.sub\n }\n\n @SentryTraced()\n public getTokensFromFile(env: TargetEnv): Tokens | undefined {\n const filePath = this.tokensFilePath()\n\n if (!fs.existsSync(filePath)) {\n return undefined\n }\n\n const fileContent = fs.readFileSync(filePath, \"utf8\")\n const data = JSON.parse(fileContent)\n return data[env] ?? {}\n }\n\n @SentryTraced()\n public async tryGetTokensFromVault(env: TargetEnv): Promise<Tokens | null> {\n if (process.env.SUPERNOVA_TOKEN) {\n return { accessToken: process.env.SUPERNOVA_TOKEN }\n }\n\n let accessToken: string | undefined\n let refreshToken: string | undefined\n try {\n accessToken = (await this.vault.getPassword(this.serviceName, `${env}_access_token`)) ?? undefined\n refreshToken = (await this.vault.getPassword(this.serviceName, `${env}_refresh_token`)) ?? undefined\n } catch {\n const tokens = this.getTokensFromFile(env)\n if (tokens) {\n accessToken = tokens.accessToken\n refreshToken = tokens.refreshToken\n }\n }\n\n if (!accessToken) {\n return null\n }\n\n const freshTokens = refreshToken ? await this.refreshTokens(env, accessToken, refreshToken) : undefined\n if (freshTokens) {\n return freshTokens\n }\n\n return { accessToken, refreshToken }\n }\n\n @SentryTraced()\n public async getTokensFromVault(env: TargetEnv): Promise<Tokens> {\n const tokens = await this.tryGetTokensFromVault(env)\n if (!tokens) throw new NotAuthorizedError()\n return tokens\n }\n\n @SentryTraced()\n public async refreshTokens(env: TargetEnv, accessToken: string, refreshToken: string): Promise<Tokens | undefined> {\n const decoded = jwtDecode<{ exp?: number }>(accessToken)\n const currentTime = Math.floor(Date.now() / 1000)\n if (decoded.exp && decoded.exp < currentTime + 300) {\n const freshTokens = await this.authService.refreshToken(env, refreshToken)\n if (!freshTokens) {\n await this.deleteTokensFromVault(env)\n throw new NotAuthorizedError()\n }\n\n await this.storeTokensToVault(freshTokens, env)\n return freshTokens\n }\n\n return undefined\n }\n\n @SentryTraced()\n public storeTokensInFile(env: TargetEnv, tokens: null | Tokens) {\n const supernovaDir = this.supernovaDir()\n const filePath = path.join(supernovaDir, \"tokens.json\")\n\n if (!fs.existsSync(supernovaDir)) {\n fs.mkdirSync(supernovaDir, { recursive: true })\n }\n\n let data: EnvTokens = {}\n if (fs.existsSync(filePath)) {\n const fileContent = fs.readFileSync(filePath, \"utf8\")\n data = EnvTokensSchema.parse(JSON.parse(fileContent))\n }\n\n if (tokens) data[env] = tokens\n else delete data[env]\n\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2), \"utf8\")\n }\n\n @SentryTraced()\n public async storeTokensToVault({ accessToken, refreshToken }: Tokens, env: TargetEnv) {\n try {\n await this.vault.setPassword(this.serviceName, `${env}_access_token`, accessToken)\n if (refreshToken) {\n await this.vault.setPassword(this.serviceName, `${env}_refresh_token`, refreshToken)\n }\n } catch {\n this.storeTokensInFile(env, { accessToken, refreshToken })\n }\n }\n\n public supernovaDir(): string {\n const homeDir = os.homedir()\n return path.join(homeDir, \".supernova\")\n }\n\n public tokensFilePath(): string {\n const homeDir = this.supernovaDir()\n return path.join(homeDir, \"tokens.json\")\n }\n}\n"],"names":[],"mappings":"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","debug_id":"1ae5b45e-6c76-59ae-8787-71b5df4c3714"}
|
package/dist/utils/sdk.d.ts
CHANGED
package/dist/utils/sdk.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/utils/sdk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/utils/sdk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAA;AAS5C,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC;IACjF,KAAK,EAAE,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAA;IAC5B,YAAY,EAAE,QAAQ,CAAC,YAAY,CAAA;IACnC,EAAE,EAAE,QAAQ,CAAC,gCAAgC,CAAA;IAC7C,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAA;IAC5B,KAAK,EAAE,IAAI,GAAG,QAAQ,CAAC,UAAU,CAAA;IACjC,OAAO,EAAE,QAAQ,CAAC,mBAAmB,CAAA;CACtC,CAAC,CAqDD"}
|
package/dist/utils/sdk.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
!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]="
|
|
2
|
+
!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]="2e4ad83e-2d39-52ed-98f7-417ef8624e3b")}catch(e){}}();
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
|
-
import { HttpsProxyAgent } from
|
|
4
|
+
import { HttpsProxyAgent } from "https-proxy-agent";
|
|
5
5
|
import { apiUrlForEnvironment, getTargetEnv } from "../types/environment.js";
|
|
6
|
-
import "colors";
|
|
7
6
|
const require = createRequire(import.meta.url);
|
|
8
7
|
const sdkProvider = require("@supernovaio/sdk");
|
|
9
8
|
export async function getWritableVersion(flags) {
|
|
@@ -16,9 +15,7 @@ export async function getWritableVersion(flags) {
|
|
|
16
15
|
const apiUrl = flags.apiUrl && flags.apiUrl.length > 0 ? flags.apiUrl : apiUrlForEnvironment(getTargetEnv());
|
|
17
16
|
const instance = new sdkProvider.Supernova(flags.apiKey, {
|
|
18
17
|
apiUrl,
|
|
19
|
-
customProxyLib: flags.proxyUrl
|
|
20
|
-
? new HttpsProxyAgent(flags.proxyUrl)
|
|
21
|
-
: null,
|
|
18
|
+
customProxyLib: flags.proxyUrl ? new HttpsProxyAgent(flags.proxyUrl) : null,
|
|
22
19
|
});
|
|
23
20
|
const designSystem = await instance.designSystems.designSystem(flags.designSystemId);
|
|
24
21
|
if (!designSystem) {
|
|
@@ -52,4 +49,4 @@ export async function getWritableVersion(flags) {
|
|
|
52
49
|
return { brand, designSystem, id, instance, theme, version };
|
|
53
50
|
}
|
|
54
51
|
//# sourceMappingURL=sdk.js.map
|
|
55
|
-
//# debugId=
|
|
52
|
+
//# debugId=2e4ad83e-2d39-52ed-98f7-417ef8624e3b
|
package/dist/utils/sdk.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.js","sources":["../../src/utils/sdk.ts"],"sourceRoot":"","sourcesContent":["import * as sdkTypes from \"@supernovaio/sdk\"\nimport { createRequire } from \"node:module\"\nimport { HttpsProxyAgent } from
|
|
1
|
+
{"version":3,"file":"sdk.js","sources":["../../src/utils/sdk.ts"],"sourceRoot":"","sourcesContent":["import * as sdkTypes from \"@supernovaio/sdk\"\nimport { createRequire } from \"node:module\"\nimport { HttpsProxyAgent } from \"https-proxy-agent\"\n\nimport { apiUrlForEnvironment, getTargetEnv } from \"../types/environment.js\"\n\nconst require = createRequire(import.meta.url)\nconst sdkProvider = require(\"@supernovaio/sdk\") as typeof sdkTypes\n\nexport interface DefaultDesignSystemFlags {\n apiKey: string\n apiUrl?: string\n brandId?: string\n designSystemId: string\n proxyUrl?: string\n themeId?: string\n}\n\nexport async function getWritableVersion(flags: DefaultDesignSystemFlags): Promise<{\n brand: null | sdkTypes.Brand\n designSystem: sdkTypes.DesignSystem\n id: sdkTypes.RemoteWorkspaceVersionIdentifier\n instance: sdkTypes.Supernova\n theme: null | sdkTypes.TokenTheme\n version: sdkTypes.DesignSystemVersion\n}> {\n if (!flags.apiKey || flags.apiKey.length === 0) {\n throw new Error(`API key must not be empty`)\n }\n\n if (!flags.designSystemId || flags.designSystemId.length === 0) {\n throw new Error(`Design System ID must not be empty`)\n }\n\n // Create instance for prod / dev\n const apiUrl = flags.apiUrl && flags.apiUrl.length > 0 ? flags.apiUrl : apiUrlForEnvironment(getTargetEnv())\n const instance = new sdkProvider.Supernova(flags.apiKey, {\n apiUrl,\n customProxyLib: flags.proxyUrl ? new HttpsProxyAgent(flags.proxyUrl) : null,\n })\n\n const designSystem = await instance.designSystems.designSystem(flags.designSystemId)\n if (!designSystem) {\n throw new Error(`Design system ${flags.designSystemId} not found or not available under provided API key`)\n }\n\n const version = await instance.versions.getActiveVersion(flags.designSystemId)\n if (!version) {\n throw new Error(\n `Design system ${flags.designSystemId} writable version not found or not available under provided API key`,\n )\n }\n\n const id: sdkTypes.RemoteWorkspaceVersionIdentifier = {\n designSystemId: flags.designSystemId,\n versionId: version.id,\n workspaceId: designSystem.workspaceId,\n }\n\n let brand: null | sdkTypes.Brand = null\n if (flags.brandId) {\n const brands = await instance.brands.getBrands(id)\n brand = brands.find(brand => brand.id === flags.brandId || brand.idInVersion === flags.brandId) ?? null\n if (!brand) {\n throw new Error(`Brand ${flags.brandId} not found in specified design system`)\n }\n }\n\n let theme: null | sdkTypes.TokenTheme = null\n if (flags.themeId) {\n const themes = await instance.tokens.getTokenThemes(id)\n theme = themes.find(theme => theme.id === flags.themeId || theme.idInVersion === flags.themeId) ?? null\n if (!theme) {\n throw new Error(`Theme ${flags.themeId} not found in specified brand`)\n }\n }\n\n return { brand, designSystem, id, instance, theme, version }\n}\n"],"names":[],"mappings":"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","debug_id":"2e4ad83e-2d39-52ed-98f7-417ef8624e3b"}
|
package/oclif.manifest.json
CHANGED