@supernovaio/cli 2.0.16 → 2.0.17
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/template-upload.d.ts +9 -0
- package/dist/commands/template-upload.d.ts.map +1 -1
- package/dist/commands/template-upload.js +134 -83
- package/dist/commands/template-upload.js.map +1 -1
- package/oclif.manifest.json +3 -36
- package/package.json +1 -1
- package/dist/commands/template-upload-docker.d.ts +0 -27
- package/dist/commands/template-upload-docker.d.ts.map +0 -1
- package/dist/commands/template-upload-docker.js +0 -208
- package/dist/commands/template-upload-docker.js.map +0 -1
|
@@ -8,11 +8,20 @@ export default class TemplateUpload extends SentryCommand<TemplateUploadConfig>
|
|
|
8
8
|
static examples: string[];
|
|
9
9
|
static hidden: boolean;
|
|
10
10
|
static flags: {
|
|
11
|
+
from: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
12
|
workspaceId: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
designSystemId: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
14
|
};
|
|
13
15
|
get commandId(): string;
|
|
14
16
|
get configSchema(): ZodType<TemplateUploadConfig>;
|
|
15
17
|
run(): Promise<void>;
|
|
18
|
+
private validateDockerDaemon;
|
|
19
|
+
private createBuildDir;
|
|
20
|
+
private deleteBuildDir;
|
|
21
|
+
private prepareBuildFolder;
|
|
22
|
+
private buildDockerImage;
|
|
23
|
+
private pushDockerImage;
|
|
24
|
+
private remoteTemplateBuild;
|
|
16
25
|
}
|
|
17
26
|
export {};
|
|
18
27
|
//# 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":"
|
|
1
|
+
{"version":3,"file":"template-upload.d.ts","sourceRoot":"","sources":["../../src/commands/template-upload.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAGhC,OAAO,EAAe,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAQ9D,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,SAAiD;IAC5E,OAAgB,QAAQ,WAA0D;IAClF,OAAgB,MAAM,EAAE,OAAO,CAAO;IACtC,OAAgB,KAAK;;;;MAapB;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,YAAY,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAEhD;IAGY,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YAqDnB,oBAAoB;IAMlC,OAAO,CAAC,cAAc;YAIR,cAAc;YAId,kBAAkB;YAclB,gBAAgB;YAchB,eAAe;YAQf,mBAAmB;CA0BlC"}
|
|
@@ -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]="d3e55359-6715-5b2e-a858-ae6306d18841")}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);
|
|
@@ -12,15 +12,15 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
12
12
|
import { Flags } from "@oclif/core";
|
|
13
13
|
import { action } from "@oclif/core/ux";
|
|
14
14
|
import { SentryTraced } from "@sentry/nestjs";
|
|
15
|
-
import fetch from "node-fetch";
|
|
16
15
|
import { exec as execCallback } from "node:child_process";
|
|
17
|
-
import { createHash, randomUUID } from "node:crypto";
|
|
18
|
-
import { createReadStream } from "node:fs";
|
|
19
16
|
import * as fs from "node:fs/promises";
|
|
20
17
|
import path from "node:path";
|
|
21
18
|
import { promisify } from "node:util";
|
|
22
19
|
import { z } from "zod";
|
|
20
|
+
import fsx from "fs-extra";
|
|
23
21
|
import { commonFlags, SentryCommand } from "../types/index.js";
|
|
22
|
+
import { sleep } from "../utils/common.js";
|
|
23
|
+
import { tmpdir } from "node:os";
|
|
24
24
|
const exec = promisify(execCallback);
|
|
25
25
|
const TemplateUploadConfig = z.object({});
|
|
26
26
|
async function fileExists(p) {
|
|
@@ -32,19 +32,17 @@ async function fileExists(p) {
|
|
|
32
32
|
return false;
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
});
|
|
47
|
-
}
|
|
35
|
+
const dockerfile = `
|
|
36
|
+
FROM node:22-slim
|
|
37
|
+
|
|
38
|
+
RUN apt-get update && apt-get install -y curl && apt-get clean && rm -rf /var/lib/apt/lists/*
|
|
39
|
+
|
|
40
|
+
WORKDIR /home/user
|
|
41
|
+
|
|
42
|
+
COPY . .
|
|
43
|
+
RUN npm i && rm .npmrc
|
|
44
|
+
RUN node docker-scripts/extract-private-packages.js
|
|
45
|
+
`;
|
|
48
46
|
export default class TemplateUpload extends SentryCommand {
|
|
49
47
|
static args = {};
|
|
50
48
|
static description = "Upload custom prototype app sandbox template";
|
|
@@ -52,7 +50,17 @@ export default class TemplateUpload extends SentryCommand {
|
|
|
52
50
|
static hidden = true;
|
|
53
51
|
static flags = {
|
|
54
52
|
...commonFlags,
|
|
53
|
+
from: Flags.string({
|
|
54
|
+
char: "f",
|
|
55
|
+
description: "Directory to upload template from, defaults to the current directory",
|
|
56
|
+
required: false,
|
|
57
|
+
}),
|
|
55
58
|
workspaceId: Flags.string({ char: "w", description: "Workspace ID to upload the template to", required: true }),
|
|
59
|
+
designSystemId: Flags.string({
|
|
60
|
+
char: "d",
|
|
61
|
+
description: "Design system ID to upload the template to",
|
|
62
|
+
required: true,
|
|
63
|
+
}),
|
|
56
64
|
};
|
|
57
65
|
get commandId() {
|
|
58
66
|
return TemplateUpload.id;
|
|
@@ -63,19 +71,9 @@ export default class TemplateUpload extends SentryCommand {
|
|
|
63
71
|
async run() {
|
|
64
72
|
const apiClient = await this.apiClient();
|
|
65
73
|
const { flags } = await this.parse();
|
|
66
|
-
const cwd = process.cwd();
|
|
67
|
-
const pkgPath = path.join(cwd, "package.json");
|
|
68
|
-
const modulesPath = path.join(cwd, "node_modules");
|
|
69
|
-
const zipPath = path.join(cwd, ".supernova-upload.zip");
|
|
70
|
-
if (!(await fileExists(pkgPath)))
|
|
71
|
-
this.error("package.json not found in current directory.");
|
|
72
|
-
if (!(await fileExists(modulesPath)) || !(await fs.stat(modulesPath)).isDirectory()) {
|
|
73
|
-
this.error(`node_modules directory not found in the current directory`);
|
|
74
|
-
}
|
|
75
74
|
let pkg;
|
|
76
75
|
try {
|
|
77
|
-
|
|
78
|
-
pkg = JSON.parse(raw);
|
|
76
|
+
pkg = await readPackageJson();
|
|
79
77
|
}
|
|
80
78
|
catch (error) {
|
|
81
79
|
if (error instanceof Error)
|
|
@@ -83,68 +81,89 @@ export default class TemplateUpload extends SentryCommand {
|
|
|
83
81
|
else
|
|
84
82
|
throw error;
|
|
85
83
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
missing.push(name);
|
|
84
|
+
if (pkg.supernova?.privateDependencies) {
|
|
85
|
+
this.log(`Following packages will be linked as private dependencies: ${pkg.supernova.privateDependencies}`);
|
|
86
|
+
if (!(await fileExists(path.join(process.cwd(), ".npmrc")))) {
|
|
87
|
+
this.error(`CLI needs private NPM registry access to be able to bundle private dependencies.\n` +
|
|
88
|
+
`Please provide .npmrc file in the root directory and include neccessary access tokens.`);
|
|
92
89
|
}
|
|
93
|
-
}));
|
|
94
|
-
if (missing.length > 0) {
|
|
95
|
-
this.error(`Some dependencies were not found in current node modules: [${missing.join(", ")}]`);
|
|
96
|
-
}
|
|
97
|
-
try {
|
|
98
|
-
await exec(`zip -9 -q -r "${zipPath}" . -x "*.zip"`);
|
|
99
90
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
else
|
|
104
|
-
throw error;
|
|
91
|
+
else {
|
|
92
|
+
this.warn(`package.json doesn't contain 'supernova.privateDependencies' declaration.`);
|
|
93
|
+
this.warn(`Dependencies coming from private registries will fail`);
|
|
105
94
|
}
|
|
106
|
-
|
|
107
|
-
this.error(`Upload zip was not produced`);
|
|
108
|
-
const stat = await fs.stat(zipPath);
|
|
109
|
-
const checksum = await computeChecksum(zipPath);
|
|
110
|
-
action.start(`Uploading ${(stat.size / 1000 / 1000).toFixed(2)}MB`);
|
|
111
|
-
const uploadResponse = await apiClient.files.upload({
|
|
112
|
-
ownerType: "Workspace",
|
|
95
|
+
const buildData = await apiClient.sandboxes.builds.start({
|
|
113
96
|
workspaceId: flags.workspaceId,
|
|
114
|
-
|
|
97
|
+
designSystemId: flags.designSystemId,
|
|
98
|
+
name: pkg.name,
|
|
99
|
+
version: pkg.version,
|
|
115
100
|
});
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
headers: {
|
|
126
|
-
"Content-Type": "contentType",
|
|
127
|
-
"Content-Length": stat.size.toString(),
|
|
128
|
-
},
|
|
129
|
-
body: createReadStream(zipPath),
|
|
130
|
-
});
|
|
131
|
-
if (!s3UploadResponse.ok) {
|
|
132
|
-
const text = await s3UploadResponse.text();
|
|
133
|
-
throw new Error(`Upload failed with status ${s3UploadResponse.status}: ${text}`);
|
|
134
|
-
}
|
|
135
|
-
const finalizeResponse = await apiClient.files.finalizeUpload({
|
|
136
|
-
ownerType: "Workspace",
|
|
137
|
-
workspaceId: flags.workspaceId,
|
|
138
|
-
fileIds: [uploadResponse.files[0].id],
|
|
139
|
-
});
|
|
140
|
-
file = finalizeResponse.files[0];
|
|
101
|
+
const url = imageUrl(buildData);
|
|
102
|
+
await this.validateDockerDaemon();
|
|
103
|
+
const buildDir = await this.createBuildDir();
|
|
104
|
+
try {
|
|
105
|
+
await this.prepareBuildFolder(buildDir);
|
|
106
|
+
await this.buildDockerImage(buildDir, url);
|
|
107
|
+
await this.pushDockerImage(buildDir, url);
|
|
108
|
+
await this.remoteTemplateBuild(apiClient, buildData.build.id);
|
|
109
|
+
this.log(`✅ Template has been successfully uploaded`);
|
|
141
110
|
}
|
|
142
|
-
|
|
143
|
-
this.
|
|
111
|
+
finally {
|
|
112
|
+
await this.deleteBuildDir(buildDir);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async validateDockerDaemon() {
|
|
116
|
+
await exec("docker info").catch(() => {
|
|
117
|
+
this.error(`Docker is not available, please start docker daemon and try again`);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
createBuildDir() {
|
|
121
|
+
return fs.mkdtemp(path.join(tmpdir(), "supernova-template-bundle-"));
|
|
122
|
+
}
|
|
123
|
+
async deleteBuildDir(buildDir) {
|
|
124
|
+
await fs.rm(buildDir, { recursive: true, force: true });
|
|
125
|
+
}
|
|
126
|
+
async prepareBuildFolder(buildDir) {
|
|
127
|
+
await fsx.copy(process.cwd(), buildDir, {
|
|
128
|
+
filter(src) {
|
|
129
|
+
return !src.includes("node_modules/") && !src.includes(".git/") && !src.includes(".out/");
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
const cliSrcPath = path.resolve(path.dirname(new URL(import.meta.url).pathname), "..");
|
|
133
|
+
await fsx.copy(path.join(cliSrcPath, "docker-scripts"), path.join(buildDir, "docker-scripts"));
|
|
134
|
+
}
|
|
135
|
+
async buildDockerImage(buildDir, imageUrl) {
|
|
136
|
+
action.start("🔨 Building docker image");
|
|
137
|
+
const process = exec(`docker build --progress=plain -t ${imageUrl} --pull --platform linux/amd64 -f - .`, {
|
|
138
|
+
cwd: buildDir,
|
|
139
|
+
});
|
|
140
|
+
process.child.stdin.write(dockerfile);
|
|
141
|
+
process.child.stdin.end();
|
|
142
|
+
await process;
|
|
143
|
+
action.stop("done");
|
|
144
|
+
}
|
|
145
|
+
async pushDockerImage(buildDir, imageUrl) {
|
|
146
|
+
action.start("⬆️ Uploading docker image to Supernova");
|
|
147
|
+
await exec(`docker push ${imageUrl}`, {
|
|
148
|
+
cwd: buildDir,
|
|
149
|
+
});
|
|
150
|
+
action.stop("done");
|
|
151
|
+
}
|
|
152
|
+
async remoteTemplateBuild(client, buildId) {
|
|
153
|
+
action.start("📦 Creating template with the image");
|
|
154
|
+
await client.sandboxes.builds.finalize(buildId);
|
|
155
|
+
const pollIntervalMs = 2000;
|
|
156
|
+
const timeoutMs = 5 * 60 * 1000;
|
|
157
|
+
const startTime = Date.now();
|
|
158
|
+
let build;
|
|
159
|
+
do {
|
|
160
|
+
await sleep(pollIntervalMs);
|
|
161
|
+
build = (await client.sandboxes.builds.get(buildId)).build;
|
|
162
|
+
} while (build.state === "Building" && Date.now() - startTime < timeoutMs);
|
|
163
|
+
if (build.state !== "Success") {
|
|
164
|
+
this.error(`Template creation failed`);
|
|
144
165
|
}
|
|
145
|
-
await fs.unlink(zipPath);
|
|
146
166
|
action.stop("done");
|
|
147
|
-
this.log(`✅ Template has been uploaded, checksum: ${file.deduplicationKey}`);
|
|
148
167
|
}
|
|
149
168
|
}
|
|
150
169
|
__decorate([
|
|
@@ -153,5 +172,37 @@ __decorate([
|
|
|
153
172
|
__metadata("design:paramtypes", []),
|
|
154
173
|
__metadata("design:returntype", Promise)
|
|
155
174
|
], TemplateUpload.prototype, "run", null);
|
|
175
|
+
async function readPackageJson() {
|
|
176
|
+
const pkgPath = path.join(process.cwd(), "package.json");
|
|
177
|
+
if (!(await fileExists(pkgPath)))
|
|
178
|
+
throw new Error(`package.json file was not found in the current directory`);
|
|
179
|
+
const raw = await fs.readFile(pkgPath, "utf8");
|
|
180
|
+
const pkg = JSON.parse(raw);
|
|
181
|
+
if (typeof pkg !== "object" || pkg === null)
|
|
182
|
+
throw new Error(`Error parsing package.json: not a json`);
|
|
183
|
+
if (typeof pkg.name !== "string")
|
|
184
|
+
throw new Error(`Error parsing package.json: 'name' must be defined`);
|
|
185
|
+
if (typeof pkg.version !== "string")
|
|
186
|
+
throw new Error(`Error parsing package.json: 'version' must be defined`);
|
|
187
|
+
if (typeof pkg.dependencies !== "object" || pkg.dependencies === null)
|
|
188
|
+
throw new Error(`Error parsing package.json: 'dependencies' must be defined`);
|
|
189
|
+
if (pkg.supernova?.privateDependencies) {
|
|
190
|
+
const privateDependencies = pkg.supernova?.privateDependencies;
|
|
191
|
+
if (!Array.isArray(privateDependencies))
|
|
192
|
+
throw new TypeError(`supernova.privateDependencies must be an array`);
|
|
193
|
+
for (const [i, d] of privateDependencies.entries()) {
|
|
194
|
+
if (typeof d !== "string") {
|
|
195
|
+
throw new TypeError(`supernova.privateDependencies[${i}] must be a string`);
|
|
196
|
+
}
|
|
197
|
+
if (!pkg.dependencies[d]) {
|
|
198
|
+
throw new Error(`Private dependency ${d} is not listed in 'dependencies'`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return pkg;
|
|
203
|
+
}
|
|
204
|
+
function imageUrl(build) {
|
|
205
|
+
return `${build.dockerRegistryDomain}${build.build.dockerImagePath}`;
|
|
206
|
+
}
|
|
156
207
|
//# sourceMappingURL=template-upload.js.map
|
|
157
|
-
//# debugId=
|
|
208
|
+
//# debugId=d3e55359-6715-5b2e-a858-ae6306d18841
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template-upload.js","sources":["../../src/commands/template-upload.ts"],"sourceRoot":"","sourcesContent":["import { Flags } from \"@oclif/core\"\nimport { action } from \"@oclif/core/ux\"\nimport { SentryTraced } from \"@sentry/nestjs\"\nimport fetch from \"node-fetch\"\nimport { exec as execCallback } from \"node:child_process\"\nimport { createHash, randomUUID } from \"node:crypto\"\nimport { createReadStream } from \"node:fs\"\nimport * as fs from \"node:fs/promises\"\nimport path from \"node:path\"\nimport { promisify } from \"node:util\"\nimport { z, ZodType } from \"zod\"\n\nimport { commonFlags, SentryCommand } from \"../types/index.js\"\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\nasync function computeChecksum(filePath: string) {\n return new Promise<string>((resolve, reject) => {\n const hash = createHash(\"sha256\")\n const stream = createReadStream(filePath)\n\n stream.on(\"error\", reject)\n hash.on(\"error\", reject)\n\n stream.on(\"data\", chunk => hash.update(chunk))\n stream.on(\"end\", () => {\n const digest = hash.digest(\"hex\")\n resolve(digest)\n })\n })\n}\n\nexport default class TemplateUpload extends SentryCommand<TemplateUploadConfig> {\n static override args = {}\n static override description = \"Upload custom prototype app sandbox template\"\n static override examples = [\"<%= config.bin %> <%= command.id %> TemplateUpload \"]\n static override hidden: boolean = true\n static override flags = {\n ...commonFlags,\n workspaceId: Flags.string({ char: \"w\", description: \"Workspace ID to upload the template to\", required: true }),\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 const cwd = process.cwd()\n const pkgPath = path.join(cwd, \"package.json\")\n const modulesPath = path.join(cwd, \"node_modules\")\n const zipPath = path.join(cwd, \".supernova-upload.zip\")\n\n // Validate package json\n if (!(await fileExists(pkgPath))) this.error(\"package.json not found in current directory.\")\n\n // Validate node modules\n if (!(await fileExists(modulesPath)) || !(await fs.stat(modulesPath)).isDirectory()) {\n this.error(`node_modules directory not found in the current directory`)\n }\n\n // Read package json\n let pkg\n try {\n const raw = await fs.readFile(pkgPath, \"utf8\")\n pkg = JSON.parse(raw) as { dependencies: Record<string, string> }\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 // Validate dependencies are present\n const depNames = Object.keys(pkg.dependencies)\n const missing: string[] = []\n\n await Promise.all(\n depNames.map(async name => {\n const depDir = path.join(modulesPath, ...name.split(\"/\"))\n if (!(await fileExists(depDir))) {\n missing.push(name)\n }\n }),\n )\n\n if (missing.length > 0) {\n this.error(`Some dependencies were not found in current node modules: [${missing.join(\", \")}]`)\n }\n\n // 6) Create ZIP of current directory\n try {\n await exec(`zip -9 -q -r \"${zipPath}\" . -x \"*.zip\"`)\n } catch (error) {\n if (error instanceof Error) this.error(`Failed to create zip archive: ${error.message}`)\n else throw error\n }\n\n if (!(await fileExists(zipPath))) this.error(`Upload zip was not produced`)\n\n const stat = await fs.stat(zipPath)\n const checksum = await computeChecksum(zipPath)\n\n action.start(`Uploading ${(stat.size / 1000 / 1000).toFixed(2)}MB`)\n\n const uploadResponse = await apiClient.files.upload({\n ownerType: \"Workspace\",\n workspaceId: flags.workspaceId,\n files: [{ checksum, name: `${randomUUID()}.zip`, size: stat.size }],\n })\n\n if (uploadResponse.files.length === 0) this.error(`Upload endpoint returned no files`)\n\n let file = uploadResponse.files[0]\n if (file.pendingUpload) {\n const [uploadUrl] = uploadResponse.uploadUrls\n if (!uploadUrl) this.error(`File is pending upload, but no upload URL was provided`)\n\n const s3UploadResponse = await fetch(uploadUrl.uploadUrl, {\n method: \"PUT\",\n headers: {\n \"Content-Type\": \"contentType\",\n \"Content-Length\": stat.size.toString(),\n },\n body: createReadStream(zipPath),\n })\n\n if (!s3UploadResponse.ok) {\n const text = await s3UploadResponse.text()\n throw new Error(`Upload failed with status ${s3UploadResponse.status}: ${text}`)\n }\n\n const finalizeResponse = await apiClient.files.finalizeUpload({\n ownerType: \"Workspace\",\n workspaceId: flags.workspaceId,\n fileIds: [uploadResponse.files[0].id],\n })\n\n file = finalizeResponse.files[0]\n } else {\n this.log(`Already uploaded, skipping upload...`)\n }\n\n await fs.unlink(zipPath)\n\n action.stop(\"done\")\n this.log(`✅ Template has been uploaded, checksum: ${file.deduplicationKey}`)\n }\n}\n"],"names":[],"mappings":"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","debug_id":"5ee66120-d90c-524e-bbfc-dc8d227ecaf3"}
|
|
1
|
+
{"version":3,"file":"template-upload.js","sources":["../../src/commands/template-upload.ts"],"sourceRoot":"","sourcesContent":["import { 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 dockerfile = `\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 npm i && rm .npmrc\nRUN node docker-scripts/extract-private-packages.js\n`\n\nexport default class TemplateUpload extends SentryCommand<TemplateUploadConfig> {\n static override args = {}\n static override description = \"Upload custom prototype app sandbox template\"\n static override examples = [\"<%= config.bin %> <%= command.id %> TemplateUpload \"]\n static override hidden: boolean = true\n static override flags = {\n ...commonFlags,\n from: Flags.string({\n char: \"f\",\n description: \"Directory to upload template from, defaults to the current directory\",\n required: false,\n }),\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 }\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 })\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)\n await this.pushDockerImage(buildDir, 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) {\n action.start(\"🔨 Building docker image\")\n\n const process = exec(`docker build --progress=plain -t ${imageUrl} --pull --platform linux/amd64 -f - .`, {\n cwd: buildDir,\n })\n process.child.stdin!.write(dockerfile)\n process.child.stdin!.end()\n\n await process\n\n action.stop(\"done\")\n }\n\n private async pushDockerImage(buildDir: string, imageUrl: string) {\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 // Poll every 2 seconds for roughly 5 minutes\n action.start(\"📦 Creating template with the image\")\n\n // Trigger remote build phase\n await client.sandboxes.builds.finalize(buildId)\n\n // Await remote build\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":";;;;;;;;;;;AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,IAAI,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,CAAC,EAAW,MAAM,KAAK,CAAA;AAChC,OAAO,GAAG,MAAM,UAAU,CAAA;AAE1B,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAG9D,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAEhC,MAAM,IAAI,GAAG,SAAS,CAAC,YAAY,CAAC,CAAA;AAEpC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AAIzC,KAAK,UAAU,UAAU,CAAC,CAAS;IACjC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QAClB,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,GAAG;;;;;;;;;;CAUlB,CAAA;AAED,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,aAAmC;IAC7E,MAAM,CAAU,IAAI,GAAG,EAAE,CAAA;IACzB,MAAM,CAAU,WAAW,GAAG,8CAA8C,CAAA;IAC5E,MAAM,CAAU,QAAQ,GAAG,CAAC,qDAAqD,CAAC,CAAA;IAClF,MAAM,CAAU,MAAM,GAAY,IAAI,CAAA;IACtC,MAAM,CAAU,KAAK,GAAG;QACtB,GAAG,WAAW;QACd,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;YACjB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,sEAAsE;YACnF,QAAQ,EAAE,KAAK;SAChB,CAAC;QACF,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,wCAAwC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC/G,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC;YAC3B,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,4CAA4C;YACzD,QAAQ,EAAE,IAAI;SACf,CAAC;KACH,CAAA;IAED,IAAI,SAAS;QACX,OAAO,cAAc,CAAC,EAAE,CAAA;IAC1B,CAAC;IAED,IAAI,YAAY;QACd,OAAO,oBAAoB,CAAA;IAC7B,CAAC;IAGY,AAAN,KAAK,CAAC,GAAG;QACd,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAA;QACxC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAA;QAGpC,IAAI,GAAG,CAAA;QACP,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,eAAe,EAAE,CAAA;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK;gBAAE,IAAI,CAAC,KAAK,CAAC,yCAAyC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;;gBAC3F,MAAM,KAAK,CAAA;QAClB,CAAC;QAED,IAAI,GAAG,CAAC,SAAS,EAAE,mBAAmB,EAAE,CAAC;YACvC,IAAI,CAAC,GAAG,CAAC,8DAA8D,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAC,CAAA;YAE3G,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5D,IAAI,CAAC,KAAK,CACR,oFAAoF;oBAClF,wFAAwF,CAC3F,CAAA;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAA;YACtF,IAAI,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAA;QACpE,CAAC;QAGD,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC;YACvD,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,OAAO,EAAE,GAAG,CAAC,OAAO;SACrB,CAAC,CAAA;QAGF,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAA;QAE/B,MAAM,IAAI,CAAC,oBAAoB,EAAE,CAAA;QACjC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAA;QAE5C,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAA;YACvC,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;YAC1C,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;YACzC,MAAM,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;YAE7D,IAAI,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAA;QACvD,CAAC;gBAAS,CAAC;YACT,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAA;QACrC,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,oBAAoB;QAChC,MAAM,IAAI,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACnC,IAAI,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAA;QACjF,CAAC,CAAC,CAAA;IACJ,CAAC;IAEO,cAAc;QACpB,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,4BAA4B,CAAC,CAAC,CAAA;IACtE,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,QAAgB;QAC3C,MAAM,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IACzD,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAC,QAAgB;QAE/C,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE;YACtC,MAAM,CAAC,GAAG;gBACR,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;YAC3F,CAAC;SACF,CAAC,CAAA;QAGF,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAA;QAEtF,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,gBAAgB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAA;IAChG,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,QAAgB,EAAE,QAAgB;QAC/D,MAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAA;QAExC,MAAM,OAAO,GAAG,IAAI,CAAC,oCAAoC,QAAQ,uCAAuC,EAAE;YACxG,GAAG,EAAE,QAAQ;SACd,CAAC,CAAA;QACF,OAAO,CAAC,KAAK,CAAC,KAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;QACtC,OAAO,CAAC,KAAK,CAAC,KAAM,CAAC,GAAG,EAAE,CAAA;QAE1B,MAAM,OAAO,CAAA;QAEb,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACrB,CAAC;IAEO,KAAK,CAAC,eAAe,CAAC,QAAgB,EAAE,QAAgB;QAC9D,MAAM,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAA;QACtD,MAAM,IAAI,CAAC,eAAe,QAAQ,EAAE,EAAE;YACpC,GAAG,EAAE,QAAQ;SACd,CAAC,CAAA;QACF,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACrB,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAAC,MAA0B,EAAE,OAAe;QAE3E,MAAM,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAA;QAGnD,MAAM,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAG/C,MAAM,cAAc,GAAG,IAAI,CAAA;QAC3B,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAA;QAE/B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAE5B,IAAI,KAAK,CAAA;QACT,GAAG,CAAC;YACF,MAAM,KAAK,CAAC,cAAc,CAAC,CAAA;YAC3B,KAAK,GAAG,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAA;QAC5D,CAAC,QAAQ,KAAK,CAAC,KAAK,KAAK,UAAU,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,SAAS,EAAC;QAG1E,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC9B,IAAI,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAA;QACxC,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACrB,CAAC;;AAhIY;IADZ,YAAY,EAAE;;;;yCAoDd;AA2FH,KAAK,UAAU,eAAe;IAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAA;IAExD,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAA;IAE7G,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAE3B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;IAEtG,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAA;IACvG,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAA;IAC7G,IAAI,OAAO,GAAG,CAAC,YAAY,KAAK,QAAQ,IAAI,GAAG,CAAC,YAAY,KAAK,IAAI;QACnE,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAA;IAE/E,IAAI,GAAG,CAAC,SAAS,EAAE,mBAAmB,EAAE,CAAC;QACvC,MAAM,mBAAmB,GAAG,GAAG,CAAC,SAAS,EAAE,mBAAmB,CAAA;QAC9D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,mBAAmB,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,gDAAgD,CAAC,CAAA;QAE9G,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,mBAAmB,CAAC,OAAO,EAAE,EAAE,CAAC;YACnD,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAC1B,MAAM,IAAI,SAAS,CAAC,iCAAiC,CAAC,oBAAoB,CAAC,CAAA;YAC7E,CAAC;YAED,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,kCAAkC,CAAC,CAAA;YAC5E,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,SAAS,QAAQ,CAAC,KAA4C;IAC5D,OAAO,GAAG,KAAK,CAAC,oBAAoB,GAAG,KAAK,CAAC,KAAK,CAAC,eAAe,EAAE,CAAA;AACtE,CAAC","debug_id":"d3e55359-6715-5b2e-a858-ae6306d18841"}
|
package/oclif.manifest.json
CHANGED
|
@@ -501,12 +501,12 @@
|
|
|
501
501
|
"sync-tokens.js"
|
|
502
502
|
]
|
|
503
503
|
},
|
|
504
|
-
"template-upload
|
|
504
|
+
"template-upload": {
|
|
505
505
|
"aliases": [],
|
|
506
506
|
"args": {},
|
|
507
507
|
"description": "Upload custom prototype app sandbox template",
|
|
508
508
|
"examples": [
|
|
509
|
-
"<%= config.bin %> <%= command.id %>
|
|
509
|
+
"<%= config.bin %> <%= command.id %> TemplateUpload "
|
|
510
510
|
],
|
|
511
511
|
"flags": {
|
|
512
512
|
"from": {
|
|
@@ -540,39 +540,6 @@
|
|
|
540
540
|
"hasDynamicHelp": false,
|
|
541
541
|
"hidden": true,
|
|
542
542
|
"hiddenAliases": [],
|
|
543
|
-
"id": "template-upload-docker",
|
|
544
|
-
"pluginAlias": "@supernovaio/cli",
|
|
545
|
-
"pluginName": "@supernovaio/cli",
|
|
546
|
-
"pluginType": "core",
|
|
547
|
-
"strict": true,
|
|
548
|
-
"isESM": true,
|
|
549
|
-
"relativePath": [
|
|
550
|
-
"dist",
|
|
551
|
-
"commands",
|
|
552
|
-
"template-upload-docker.js"
|
|
553
|
-
]
|
|
554
|
-
},
|
|
555
|
-
"template-upload": {
|
|
556
|
-
"aliases": [],
|
|
557
|
-
"args": {},
|
|
558
|
-
"description": "Upload custom prototype app sandbox template",
|
|
559
|
-
"examples": [
|
|
560
|
-
"<%= config.bin %> <%= command.id %> TemplateUpload "
|
|
561
|
-
],
|
|
562
|
-
"flags": {
|
|
563
|
-
"workspaceId": {
|
|
564
|
-
"char": "w",
|
|
565
|
-
"description": "Workspace ID to upload the template to",
|
|
566
|
-
"name": "workspaceId",
|
|
567
|
-
"required": true,
|
|
568
|
-
"hasDynamicHelp": false,
|
|
569
|
-
"multiple": false,
|
|
570
|
-
"type": "option"
|
|
571
|
-
}
|
|
572
|
-
},
|
|
573
|
-
"hasDynamicHelp": false,
|
|
574
|
-
"hidden": true,
|
|
575
|
-
"hiddenAliases": [],
|
|
576
543
|
"id": "template-upload",
|
|
577
544
|
"pluginAlias": "@supernovaio/cli",
|
|
578
545
|
"pluginName": "@supernovaio/cli",
|
|
@@ -608,5 +575,5 @@
|
|
|
608
575
|
]
|
|
609
576
|
}
|
|
610
577
|
},
|
|
611
|
-
"version": "2.0.
|
|
578
|
+
"version": "2.0.17"
|
|
612
579
|
}
|
package/package.json
CHANGED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { z, ZodType } from "zod";
|
|
2
|
-
import { SentryCommand } from "../types/index.js";
|
|
3
|
-
declare const TemplateUploadConfig: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
|
4
|
-
type TemplateUploadConfig = z.infer<typeof TemplateUploadConfig>;
|
|
5
|
-
export default class TemplateUploadDocker extends SentryCommand<TemplateUploadConfig> {
|
|
6
|
-
static args: {};
|
|
7
|
-
static description: string;
|
|
8
|
-
static examples: string[];
|
|
9
|
-
static hidden: boolean;
|
|
10
|
-
static flags: {
|
|
11
|
-
from: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
-
workspaceId: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
-
designSystemId: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
-
};
|
|
15
|
-
get commandId(): string;
|
|
16
|
-
get configSchema(): ZodType<TemplateUploadConfig>;
|
|
17
|
-
run(): Promise<void>;
|
|
18
|
-
private validateDockerDaemon;
|
|
19
|
-
private createBuildDir;
|
|
20
|
-
private deleteBuildDir;
|
|
21
|
-
private prepareBuildFolder;
|
|
22
|
-
private buildDockerImage;
|
|
23
|
-
private pushDockerImage;
|
|
24
|
-
private remoteTemplateBuild;
|
|
25
|
-
}
|
|
26
|
-
export {};
|
|
27
|
-
//# sourceMappingURL=template-upload-docker.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"template-upload-docker.d.ts","sourceRoot":"","sources":["../../src/commands/template-upload-docker.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAGhC,OAAO,EAAe,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAQ9D,QAAA,MAAM,oBAAoB,gDAAe,CAAA;AAEzC,KAAK,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAuBhE,MAAM,CAAC,OAAO,OAAO,oBAAqB,SAAQ,aAAa,CAAC,oBAAoB,CAAC;IACnF,OAAgB,IAAI,KAAK;IACzB,OAAgB,WAAW,SAAiD;IAC5E,OAAgB,QAAQ,WAAgE;IACxF,OAAgB,MAAM,EAAE,OAAO,CAAO;IACtC,OAAgB,KAAK;;;;MAapB;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,YAAY,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAEhD;IAGY,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YAqDnB,oBAAoB;IAMlC,OAAO,CAAC,cAAc;YAIR,cAAc;YAId,kBAAkB;YAclB,gBAAgB;YAchB,eAAe;YAQf,mBAAmB;CA0BlC"}
|
|
@@ -1,208 +0,0 @@
|
|
|
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]="74258b89-1bcd-5ade-b708-d120c59a1edb")}catch(e){}}();
|
|
3
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
4
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
5
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6
|
-
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;
|
|
7
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
8
|
-
};
|
|
9
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
10
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
11
|
-
};
|
|
12
|
-
import { Flags } from "@oclif/core";
|
|
13
|
-
import { action } from "@oclif/core/ux";
|
|
14
|
-
import { SentryTraced } from "@sentry/nestjs";
|
|
15
|
-
import { exec as execCallback } from "node:child_process";
|
|
16
|
-
import * as fs from "node:fs/promises";
|
|
17
|
-
import path from "node:path";
|
|
18
|
-
import { promisify } from "node:util";
|
|
19
|
-
import { z } from "zod";
|
|
20
|
-
import fsx from "fs-extra";
|
|
21
|
-
import { commonFlags, SentryCommand } from "../types/index.js";
|
|
22
|
-
import { sleep } from "../utils/common.js";
|
|
23
|
-
import { tmpdir } from "node:os";
|
|
24
|
-
const exec = promisify(execCallback);
|
|
25
|
-
const TemplateUploadConfig = z.object({});
|
|
26
|
-
async function fileExists(p) {
|
|
27
|
-
try {
|
|
28
|
-
await fs.access(p);
|
|
29
|
-
return true;
|
|
30
|
-
}
|
|
31
|
-
catch {
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
const dockerfile = `
|
|
36
|
-
FROM node:22-slim
|
|
37
|
-
|
|
38
|
-
RUN apt-get update && apt-get install -y curl && apt-get clean && rm -rf /var/lib/apt/lists/*
|
|
39
|
-
|
|
40
|
-
WORKDIR /home/user
|
|
41
|
-
|
|
42
|
-
COPY . .
|
|
43
|
-
RUN npm i && rm .npmrc
|
|
44
|
-
RUN node docker-scripts/extract-private-packages.js
|
|
45
|
-
`;
|
|
46
|
-
export default class TemplateUploadDocker extends SentryCommand {
|
|
47
|
-
static args = {};
|
|
48
|
-
static description = "Upload custom prototype app sandbox template";
|
|
49
|
-
static examples = ["<%= config.bin %> <%= command.id %> TemplateUploadDocker "];
|
|
50
|
-
static hidden = true;
|
|
51
|
-
static flags = {
|
|
52
|
-
...commonFlags,
|
|
53
|
-
from: Flags.string({
|
|
54
|
-
char: "f",
|
|
55
|
-
description: "Directory to upload template from, defaults to the current directory",
|
|
56
|
-
required: false,
|
|
57
|
-
}),
|
|
58
|
-
workspaceId: Flags.string({ char: "w", description: "Workspace ID to upload the template to", required: true }),
|
|
59
|
-
designSystemId: Flags.string({
|
|
60
|
-
char: "d",
|
|
61
|
-
description: "Design system ID to upload the template to",
|
|
62
|
-
required: true,
|
|
63
|
-
}),
|
|
64
|
-
};
|
|
65
|
-
get commandId() {
|
|
66
|
-
return TemplateUploadDocker.id;
|
|
67
|
-
}
|
|
68
|
-
get configSchema() {
|
|
69
|
-
return TemplateUploadConfig;
|
|
70
|
-
}
|
|
71
|
-
async run() {
|
|
72
|
-
const apiClient = await this.apiClient();
|
|
73
|
-
const { flags } = await this.parse();
|
|
74
|
-
let pkg;
|
|
75
|
-
try {
|
|
76
|
-
pkg = await readPackageJson();
|
|
77
|
-
}
|
|
78
|
-
catch (error) {
|
|
79
|
-
if (error instanceof Error)
|
|
80
|
-
this.error(`Failed to read or parse package.json: ${error.message}`);
|
|
81
|
-
else
|
|
82
|
-
throw error;
|
|
83
|
-
}
|
|
84
|
-
if (pkg.supernova?.privateDependencies) {
|
|
85
|
-
this.log(`Following packages will be linked as private dependencies: ${pkg.supernova.privateDependencies}`);
|
|
86
|
-
if (!(await fileExists(path.join(process.cwd(), ".npmrc")))) {
|
|
87
|
-
this.error(`CLI needs private NPM registry access to be able to bundle private dependencies.\n` +
|
|
88
|
-
`Please provide .npmrc file in the root directory and include neccessary access tokens.`);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
this.warn(`package.json doesn't contain 'supernova.privateDependencies' declaration.`);
|
|
93
|
-
this.warn(`Dependencies coming from private registries will fail`);
|
|
94
|
-
}
|
|
95
|
-
const buildData = await apiClient.sandboxes.builds.start({
|
|
96
|
-
workspaceId: flags.workspaceId,
|
|
97
|
-
designSystemId: flags.designSystemId,
|
|
98
|
-
name: pkg.name,
|
|
99
|
-
version: pkg.version,
|
|
100
|
-
});
|
|
101
|
-
const url = imageUrl(buildData);
|
|
102
|
-
await this.validateDockerDaemon();
|
|
103
|
-
const buildDir = await this.createBuildDir();
|
|
104
|
-
try {
|
|
105
|
-
await this.prepareBuildFolder(buildDir);
|
|
106
|
-
await this.buildDockerImage(buildDir, url);
|
|
107
|
-
await this.pushDockerImage(buildDir, url);
|
|
108
|
-
await this.remoteTemplateBuild(apiClient, buildData.build.id);
|
|
109
|
-
this.log(`✅ Template has been successfully uploaded`);
|
|
110
|
-
}
|
|
111
|
-
finally {
|
|
112
|
-
await this.deleteBuildDir(buildDir);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
async validateDockerDaemon() {
|
|
116
|
-
await exec("docker info").catch(() => {
|
|
117
|
-
this.error(`Docker is not available, please start docker daemon and try again`);
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
createBuildDir() {
|
|
121
|
-
return fs.mkdtemp(path.join(tmpdir(), "supernova-template-bundle-"));
|
|
122
|
-
}
|
|
123
|
-
async deleteBuildDir(buildDir) {
|
|
124
|
-
await fs.rm(buildDir, { recursive: true, force: true });
|
|
125
|
-
}
|
|
126
|
-
async prepareBuildFolder(buildDir) {
|
|
127
|
-
await fsx.copy(process.cwd(), buildDir, {
|
|
128
|
-
filter(src) {
|
|
129
|
-
return !src.includes("node_modules/") && !src.includes(".git/") && !src.includes(".out/");
|
|
130
|
-
},
|
|
131
|
-
});
|
|
132
|
-
const cliSrcPath = path.resolve(path.dirname(new URL(import.meta.url).pathname), "..");
|
|
133
|
-
await fsx.copy(path.join(cliSrcPath, "docker-scripts"), path.join(buildDir, "docker-scripts"));
|
|
134
|
-
}
|
|
135
|
-
async buildDockerImage(buildDir, imageUrl) {
|
|
136
|
-
action.start("🔨 Building docker image");
|
|
137
|
-
const process = exec(`docker build --progress=plain -t ${imageUrl} --pull --platform linux/amd64 -f - .`, {
|
|
138
|
-
cwd: buildDir,
|
|
139
|
-
});
|
|
140
|
-
process.child.stdin.write(dockerfile);
|
|
141
|
-
process.child.stdin.end();
|
|
142
|
-
await process;
|
|
143
|
-
action.stop("done");
|
|
144
|
-
}
|
|
145
|
-
async pushDockerImage(buildDir, imageUrl) {
|
|
146
|
-
action.start("⬆️ Uploading docker image to Supernova");
|
|
147
|
-
await exec(`docker push ${imageUrl}`, {
|
|
148
|
-
cwd: buildDir,
|
|
149
|
-
});
|
|
150
|
-
action.stop("done");
|
|
151
|
-
}
|
|
152
|
-
async remoteTemplateBuild(client, buildId) {
|
|
153
|
-
action.start("📦 Creating template with the image");
|
|
154
|
-
await client.sandboxes.builds.finalize(buildId);
|
|
155
|
-
const pollIntervalMs = 2000;
|
|
156
|
-
const timeoutMs = 5 * 60 * 1000;
|
|
157
|
-
const startTime = Date.now();
|
|
158
|
-
let build;
|
|
159
|
-
do {
|
|
160
|
-
await sleep(pollIntervalMs);
|
|
161
|
-
build = (await client.sandboxes.builds.get(buildId)).build;
|
|
162
|
-
} while (build.state === "Building" && Date.now() - startTime < timeoutMs);
|
|
163
|
-
if (build.state !== "Success") {
|
|
164
|
-
this.error(`Template creation failed`);
|
|
165
|
-
}
|
|
166
|
-
action.stop("done");
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
__decorate([
|
|
170
|
-
SentryTraced(),
|
|
171
|
-
__metadata("design:type", Function),
|
|
172
|
-
__metadata("design:paramtypes", []),
|
|
173
|
-
__metadata("design:returntype", Promise)
|
|
174
|
-
], TemplateUploadDocker.prototype, "run", null);
|
|
175
|
-
async function readPackageJson() {
|
|
176
|
-
const pkgPath = path.join(process.cwd(), "package.json");
|
|
177
|
-
if (!(await fileExists(pkgPath)))
|
|
178
|
-
throw new Error(`package.json file was not found in the current directory`);
|
|
179
|
-
const raw = await fs.readFile(pkgPath, "utf8");
|
|
180
|
-
const pkg = JSON.parse(raw);
|
|
181
|
-
if (typeof pkg !== "object" || pkg === null)
|
|
182
|
-
throw new Error(`Error parsing package.json: not a json`);
|
|
183
|
-
if (typeof pkg.name !== "string")
|
|
184
|
-
throw new Error(`Error parsing package.json: 'name' must be defined`);
|
|
185
|
-
if (typeof pkg.version !== "string")
|
|
186
|
-
throw new Error(`Error parsing package.json: 'version' must be defined`);
|
|
187
|
-
if (typeof pkg.dependencies !== "object" || pkg.dependencies === null)
|
|
188
|
-
throw new Error(`Error parsing package.json: 'dependencies' must be defined`);
|
|
189
|
-
if (pkg.supernova?.privateDependencies) {
|
|
190
|
-
const privateDependencies = pkg.supernova?.privateDependencies;
|
|
191
|
-
if (!Array.isArray(privateDependencies))
|
|
192
|
-
throw new TypeError(`supernova.privateDependencies must be an array`);
|
|
193
|
-
for (const [i, d] of privateDependencies.entries()) {
|
|
194
|
-
if (typeof d !== "string") {
|
|
195
|
-
throw new TypeError(`supernova.privateDependencies[${i}] must be a string`);
|
|
196
|
-
}
|
|
197
|
-
if (!pkg.dependencies[d]) {
|
|
198
|
-
throw new Error(`Private dependency ${d} is not listed in 'dependencies'`);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
return pkg;
|
|
203
|
-
}
|
|
204
|
-
function imageUrl(build) {
|
|
205
|
-
return `${build.dockerRegistryDomain}${build.build.dockerImagePath}`;
|
|
206
|
-
}
|
|
207
|
-
//# sourceMappingURL=template-upload-docker.js.map
|
|
208
|
-
//# debugId=74258b89-1bcd-5ade-b708-d120c59a1edb
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"template-upload-docker.js","sources":["../../src/commands/template-upload-docker.ts"],"sourceRoot":"","sourcesContent":["import { 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 dockerfile = `\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 npm i && rm .npmrc\nRUN node docker-scripts/extract-private-packages.js\n`\n\nexport default class TemplateUploadDocker extends SentryCommand<TemplateUploadConfig> {\n static override args = {}\n static override description = \"Upload custom prototype app sandbox template\"\n static override examples = [\"<%= config.bin %> <%= command.id %> TemplateUploadDocker \"]\n static override hidden: boolean = true\n static override flags = {\n ...commonFlags,\n from: Flags.string({\n char: \"f\",\n description: \"Directory to upload template from, defaults to the current directory\",\n required: false,\n }),\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 }\n\n get commandId(): string {\n return TemplateUploadDocker.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 })\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)\n await this.pushDockerImage(buildDir, 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) {\n action.start(\"🔨 Building docker image\")\n\n const process = exec(`docker build --progress=plain -t ${imageUrl} --pull --platform linux/amd64 -f - .`, {\n cwd: buildDir,\n })\n process.child.stdin!.write(dockerfile)\n process.child.stdin!.end()\n\n await process\n\n action.stop(\"done\")\n }\n\n private async pushDockerImage(buildDir: string, imageUrl: string) {\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 // Poll every 2 seconds for roughly 5 minutes\n action.start(\"📦 Creating template with the image\")\n\n // Trigger remote build phase\n await client.sandboxes.builds.finalize(buildId)\n\n // Await remote build\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":"74258b89-1bcd-5ade-b708-d120c59a1edb"}
|