@proliferate_ai/cli 0.1.0

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.
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/index.js ADDED
@@ -0,0 +1,295 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
25
+
26
+ // src/index.ts
27
+ var import_commander = require("commander");
28
+ var fs = __toESM(require("fs"));
29
+ var path = __toESM(require("path"));
30
+ var import_child_process = require("child_process");
31
+ var import_glob = require("glob");
32
+ var import_form_data = __toESM(require("form-data"));
33
+ var program = new import_commander.Command();
34
+ program.name("proliferate").description("Proliferate CLI for source map management").version("0.1.0");
35
+ function detectRelease() {
36
+ const envVars = [
37
+ "PROLIFERATE_RELEASE",
38
+ "GITHUB_SHA",
39
+ "VERCEL_GIT_COMMIT_SHA",
40
+ "CF_PAGES_COMMIT_SHA",
41
+ "RENDER_GIT_COMMIT",
42
+ "RAILWAY_GIT_COMMIT_SHA",
43
+ "GITLAB_CI_COMMIT_SHA",
44
+ "CIRCLE_SHA1",
45
+ "COMMIT_SHA",
46
+ "GIT_COMMIT",
47
+ "BITBUCKET_COMMIT",
48
+ "DRONE_COMMIT_SHA",
49
+ "TRAVIS_COMMIT"
50
+ ];
51
+ for (const envVar of envVars) {
52
+ const value = process.env[envVar];
53
+ if (value) {
54
+ return value;
55
+ }
56
+ }
57
+ try {
58
+ const sha = (0, import_child_process.execSync)("git rev-parse HEAD", {
59
+ encoding: "utf8",
60
+ stdio: ["pipe", "pipe", "pipe"]
61
+ }).trim();
62
+ return sha;
63
+ } catch {
64
+ }
65
+ return `build-${Date.now()}`;
66
+ }
67
+ function log(options, message) {
68
+ if (!options.silent) {
69
+ console.log(`[Proliferate] ${message}`);
70
+ }
71
+ }
72
+ function warn(options, message) {
73
+ if (!options.silent) {
74
+ console.warn(`[Proliferate] Warning: ${message}`);
75
+ }
76
+ }
77
+ function error(message) {
78
+ console.error(`[Proliferate] Error: ${message}`);
79
+ }
80
+ async function createRelease(options) {
81
+ const form = new import_form_data.default();
82
+ form.append("version", options.release);
83
+ form.append("url_prefix", options.urlPrefix);
84
+ const response = await fetch(`${options.endpoint}/releases`, {
85
+ method: "POST",
86
+ headers: {
87
+ Authorization: `Bearer ${options.apiKey}`
88
+ },
89
+ body: form
90
+ });
91
+ if (!response.ok) {
92
+ const text = await response.text();
93
+ throw new Error(`Failed to create release: ${response.status} ${text}`);
94
+ }
95
+ }
96
+ async function uploadSourceMap(options, url, content) {
97
+ const form = new import_form_data.default();
98
+ form.append("release", options.release);
99
+ form.append("url", url);
100
+ form.append("url_prefix", options.urlPrefix);
101
+ form.append("sourcemap", content, {
102
+ filename: "sourcemap.map",
103
+ contentType: "application/json"
104
+ });
105
+ const response = await fetch(`${options.endpoint}/sourcemaps`, {
106
+ method: "POST",
107
+ headers: {
108
+ Authorization: `Bearer ${options.apiKey}`
109
+ },
110
+ body: form
111
+ });
112
+ if (!response.ok) {
113
+ const text = await response.text();
114
+ throw new Error(`${response.status} ${text}`);
115
+ }
116
+ }
117
+ async function finalizeRelease(options) {
118
+ const response = await fetch(
119
+ `${options.endpoint}/releases/${encodeURIComponent(options.release)}/finalize`,
120
+ {
121
+ method: "POST",
122
+ headers: {
123
+ Authorization: `Bearer ${options.apiKey}`
124
+ }
125
+ }
126
+ );
127
+ if (!response.ok) {
128
+ const text = await response.text();
129
+ warn(options, `Failed to finalize release: ${response.status} ${text}`);
130
+ }
131
+ }
132
+ program.command("upload-sourcemaps").description("Upload source maps from a build directory").requiredOption(
133
+ "--api-key <key>",
134
+ "API key (or set PROLIFERATE_API_KEY env var)"
135
+ ).requiredOption(
136
+ "--endpoint <url>",
137
+ "API endpoint (or set PROLIFERATE_ENDPOINT env var)"
138
+ ).option(
139
+ "--release <version>",
140
+ "Release version (auto-detected from git/CI if not specified)"
141
+ ).option("--directory <dir>", "Directory containing source maps", "./dist").option("--url-prefix <prefix>", "URL prefix for source map URLs", "~/").option("--include <pattern>", "Glob pattern for files", "**/*.map").option("--exclude <patterns...>", "Patterns to exclude", ["node_modules"]).option("--delete-after-upload", "Delete source maps after upload", false).option("--dry-run", "Show what would be uploaded without uploading", false).option("--silent", "Suppress output", false).action(async (cmdOptions) => {
142
+ const apiKey = cmdOptions.apiKey || process.env.PROLIFERATE_API_KEY;
143
+ const endpoint = cmdOptions.endpoint || process.env.PROLIFERATE_ENDPOINT;
144
+ if (!apiKey) {
145
+ error("API key is required. Use --api-key or set PROLIFERATE_API_KEY");
146
+ process.exit(1);
147
+ }
148
+ if (!endpoint) {
149
+ error("Endpoint is required. Use --endpoint or set PROLIFERATE_ENDPOINT");
150
+ process.exit(1);
151
+ }
152
+ const release = cmdOptions.release || detectRelease();
153
+ const directory = path.resolve(process.cwd(), cmdOptions.directory);
154
+ const options = {
155
+ apiKey,
156
+ endpoint,
157
+ release,
158
+ urlPrefix: cmdOptions.urlPrefix,
159
+ deleteAfterUpload: cmdOptions.deleteAfterUpload,
160
+ silent: cmdOptions.silent,
161
+ dryRun: cmdOptions.dryRun
162
+ };
163
+ if (!fs.existsSync(directory)) {
164
+ error(`Directory not found: ${directory}`);
165
+ process.exit(1);
166
+ }
167
+ const pattern = path.join(directory, cmdOptions.include);
168
+ const ignorePatterns = cmdOptions.exclude.map(
169
+ (p) => path.join(directory, "**", p, "**")
170
+ );
171
+ const mapFiles = await (0, import_glob.glob)(pattern, {
172
+ ignore: ignorePatterns,
173
+ nodir: true
174
+ });
175
+ if (mapFiles.length === 0) {
176
+ warn(options, "No source maps found to upload");
177
+ warn(options, `Looked in: ${directory}`);
178
+ warn(options, `Pattern: ${cmdOptions.include}`);
179
+ process.exit(0);
180
+ }
181
+ log(options, `Found ${mapFiles.length} source map(s) to upload`);
182
+ log(options, `Release: ${release}`);
183
+ log(options, `Directory: ${directory}`);
184
+ if (!options.dryRun) {
185
+ try {
186
+ await createRelease(options);
187
+ log(options, "Created release");
188
+ } catch (err) {
189
+ error(`Failed to create release: ${err}`);
190
+ process.exit(1);
191
+ }
192
+ }
193
+ let uploaded = 0;
194
+ let failed = 0;
195
+ for (const mapPath of mapFiles) {
196
+ const relativePath = path.relative(directory, mapPath);
197
+ const minifiedFilename = relativePath.replace(".map", "");
198
+ const url = options.urlPrefix + minifiedFilename;
199
+ if (options.dryRun) {
200
+ log(options, `[Dry Run] Would upload: ${url}`);
201
+ uploaded++;
202
+ continue;
203
+ }
204
+ try {
205
+ const mapContent = fs.readFileSync(mapPath);
206
+ await uploadSourceMap(options, url, mapContent);
207
+ log(options, `Uploaded: ${url}`);
208
+ uploaded++;
209
+ if (options.deleteAfterUpload) {
210
+ fs.unlinkSync(mapPath);
211
+ log(options, `Deleted: ${relativePath}`);
212
+ }
213
+ } catch (err) {
214
+ warn(options, `Failed to upload ${relativePath}: ${err}`);
215
+ failed++;
216
+ }
217
+ }
218
+ if (!options.dryRun && uploaded > 0) {
219
+ await finalizeRelease(options);
220
+ log(options, "Finalized release");
221
+ }
222
+ log(
223
+ options,
224
+ `Source map upload complete: ${uploaded} uploaded, ${failed} failed`
225
+ );
226
+ if (failed > 0) {
227
+ process.exit(1);
228
+ }
229
+ });
230
+ program.command("upload").description("Upload a single source map file").requiredOption(
231
+ "--api-key <key>",
232
+ "API key (or set PROLIFERATE_API_KEY env var)"
233
+ ).requiredOption(
234
+ "--endpoint <url>",
235
+ "API endpoint (or set PROLIFERATE_ENDPOINT env var)"
236
+ ).requiredOption("--file <path>", "Path to the source map file").requiredOption("--url <url>", "URL of the minified JavaScript file").option(
237
+ "--release <version>",
238
+ "Release version (auto-detected from git/CI if not specified)"
239
+ ).option("--url-prefix <prefix>", "URL prefix", "~/").option("--delete-after-upload", "Delete source map after upload", false).option("--dry-run", "Show what would be uploaded without uploading", false).option("--silent", "Suppress output", false).action(async (cmdOptions) => {
240
+ const apiKey = cmdOptions.apiKey || process.env.PROLIFERATE_API_KEY;
241
+ const endpoint = cmdOptions.endpoint || process.env.PROLIFERATE_ENDPOINT;
242
+ if (!apiKey) {
243
+ error("API key is required. Use --api-key or set PROLIFERATE_API_KEY");
244
+ process.exit(1);
245
+ }
246
+ if (!endpoint) {
247
+ error("Endpoint is required. Use --endpoint or set PROLIFERATE_ENDPOINT");
248
+ process.exit(1);
249
+ }
250
+ const release = cmdOptions.release || detectRelease();
251
+ const filePath = path.resolve(process.cwd(), cmdOptions.file);
252
+ const options = {
253
+ apiKey,
254
+ endpoint,
255
+ release,
256
+ urlPrefix: cmdOptions.urlPrefix,
257
+ deleteAfterUpload: cmdOptions.deleteAfterUpload,
258
+ silent: cmdOptions.silent,
259
+ dryRun: cmdOptions.dryRun
260
+ };
261
+ if (!fs.existsSync(filePath)) {
262
+ error(`File not found: ${filePath}`);
263
+ process.exit(1);
264
+ }
265
+ log(options, `Release: ${release}`);
266
+ if (options.dryRun) {
267
+ log(options, `[Dry Run] Would upload: ${cmdOptions.url}`);
268
+ process.exit(0);
269
+ }
270
+ try {
271
+ await createRelease(options);
272
+ log(options, "Created release");
273
+ } catch (err) {
274
+ error(`Failed to create release: ${err}`);
275
+ process.exit(1);
276
+ }
277
+ try {
278
+ const content = fs.readFileSync(filePath);
279
+ await uploadSourceMap(options, cmdOptions.url, content);
280
+ log(options, `Uploaded: ${cmdOptions.url}`);
281
+ if (options.deleteAfterUpload) {
282
+ fs.unlinkSync(filePath);
283
+ log(options, `Deleted: ${cmdOptions.file}`);
284
+ }
285
+ } catch (err) {
286
+ error(`Failed to upload: ${err}`);
287
+ process.exit(1);
288
+ }
289
+ await finalizeRelease(options);
290
+ log(options, "Finalized release");
291
+ });
292
+ program.command("detect-release").description("Detect and print the release version from git/CI environment").action(() => {
293
+ console.log(detectRelease());
294
+ });
295
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@proliferate_ai/cli",
3
+ "version": "0.1.0",
4
+ "description": "CLI for Proliferate - upload source maps from any build system",
5
+ "bin": {
6
+ "proliferate": "./dist/index.js"
7
+ },
8
+ "main": "dist/index.js",
9
+ "types": "dist/index.d.ts",
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsup src/index.ts --format cjs --dts --clean",
15
+ "dev": "tsup src/index.ts --format cjs --dts --watch",
16
+ "typecheck": "tsc --noEmit",
17
+ "test": "vitest",
18
+ "test:run": "vitest run"
19
+ },
20
+ "keywords": [
21
+ "cli",
22
+ "sourcemap",
23
+ "source-map",
24
+ "error-monitoring",
25
+ "proliferate"
26
+ ],
27
+ "author": "",
28
+ "license": "MIT",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/YOUR_ORG/proliferation.git",
32
+ "directory": "sdks/cli"
33
+ },
34
+ "publishConfig": {
35
+ "access": "public",
36
+ "provenance": true
37
+ },
38
+ "dependencies": {
39
+ "commander": "^12.0.0",
40
+ "form-data": "^4.0.0",
41
+ "glob": "^10.0.0"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^20.0.0",
45
+ "tsup": "^8.0.0",
46
+ "typescript": "^5.0.0",
47
+ "vitest": "^2.0.0"
48
+ },
49
+ "engines": {
50
+ "node": ">=18"
51
+ }
52
+ }