@proliferate_ai/nextjs-plugin 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.
- package/dist/chunk-PPXY4MSU.mjs +187 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +340 -0
- package/dist/cli.mjs +136 -0
- package/dist/index.d.mts +150 -0
- package/dist/index.d.ts +150 -0
- package/dist/index.js +291 -0
- package/dist/index.mjs +73 -0
- package/package.json +62 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
// src/sourcemap-uploader.ts
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import { execSync } from "child_process";
|
|
5
|
+
import FormData from "form-data";
|
|
6
|
+
function log(options, message) {
|
|
7
|
+
if (!options.silent) {
|
|
8
|
+
console.log(`[Proliferate] ${message}`);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function warn(options, message) {
|
|
12
|
+
if (!options.silent) {
|
|
13
|
+
console.warn(`[Proliferate] ${message}`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function detectRelease() {
|
|
17
|
+
const envVars = [
|
|
18
|
+
"PROLIFERATE_RELEASE",
|
|
19
|
+
"GITHUB_SHA",
|
|
20
|
+
"VERCEL_GIT_COMMIT_SHA",
|
|
21
|
+
"CF_PAGES_COMMIT_SHA",
|
|
22
|
+
"RENDER_GIT_COMMIT",
|
|
23
|
+
"RAILWAY_GIT_COMMIT_SHA",
|
|
24
|
+
"GITLAB_CI_COMMIT_SHA",
|
|
25
|
+
"CIRCLE_SHA1",
|
|
26
|
+
"COMMIT_SHA",
|
|
27
|
+
"GIT_COMMIT"
|
|
28
|
+
];
|
|
29
|
+
for (const envVar of envVars) {
|
|
30
|
+
const value = process.env[envVar];
|
|
31
|
+
if (value) {
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const sha = execSync("git rev-parse HEAD", { encoding: "utf8" }).trim();
|
|
37
|
+
return sha;
|
|
38
|
+
} catch {
|
|
39
|
+
}
|
|
40
|
+
return `build-${Date.now()}`;
|
|
41
|
+
}
|
|
42
|
+
async function createRelease(options) {
|
|
43
|
+
const form = new FormData();
|
|
44
|
+
form.append("version", options.release);
|
|
45
|
+
form.append("url_prefix", options.urlPrefix || "~/_next/");
|
|
46
|
+
const response = await fetch(`${options.endpoint}/releases`, {
|
|
47
|
+
method: "POST",
|
|
48
|
+
headers: {
|
|
49
|
+
Authorization: `Bearer ${options.apiKey}`
|
|
50
|
+
},
|
|
51
|
+
body: form
|
|
52
|
+
});
|
|
53
|
+
if (!response.ok) {
|
|
54
|
+
const text = await response.text();
|
|
55
|
+
throw new Error(`Failed to create release: ${response.status} ${text}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function uploadSourceMap(options, url, content) {
|
|
59
|
+
const form = new FormData();
|
|
60
|
+
form.append("release", options.release);
|
|
61
|
+
form.append("url", url);
|
|
62
|
+
form.append("url_prefix", options.urlPrefix || "~/_next/");
|
|
63
|
+
form.append("sourcemap", Buffer.from(content), {
|
|
64
|
+
filename: "sourcemap.map",
|
|
65
|
+
contentType: "application/json"
|
|
66
|
+
});
|
|
67
|
+
const response = await fetch(`${options.endpoint}/sourcemaps`, {
|
|
68
|
+
method: "POST",
|
|
69
|
+
headers: {
|
|
70
|
+
Authorization: `Bearer ${options.apiKey}`
|
|
71
|
+
},
|
|
72
|
+
body: form
|
|
73
|
+
});
|
|
74
|
+
if (!response.ok) {
|
|
75
|
+
const text = await response.text();
|
|
76
|
+
throw new Error(`${response.status} ${text}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async function finalizeRelease(options) {
|
|
80
|
+
const response = await fetch(
|
|
81
|
+
`${options.endpoint}/releases/${encodeURIComponent(options.release)}/finalize`,
|
|
82
|
+
{
|
|
83
|
+
method: "POST",
|
|
84
|
+
headers: {
|
|
85
|
+
Authorization: `Bearer ${options.apiKey}`
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
if (!response.ok) {
|
|
90
|
+
const text = await response.text();
|
|
91
|
+
warn(options, `Failed to finalize release: ${response.status} ${text}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function findMapFiles(dir, exclude = ["node_modules"]) {
|
|
95
|
+
const mapFiles = [];
|
|
96
|
+
function scan(currentDir) {
|
|
97
|
+
if (!fs.existsSync(currentDir)) return;
|
|
98
|
+
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
99
|
+
for (const entry of entries) {
|
|
100
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
101
|
+
if (entry.isDirectory()) {
|
|
102
|
+
const shouldExclude = exclude.some((pattern) => {
|
|
103
|
+
if (pattern.includes("*")) {
|
|
104
|
+
const regex = new RegExp(pattern.replace(/\*/g, ".*"));
|
|
105
|
+
return regex.test(entry.name);
|
|
106
|
+
}
|
|
107
|
+
return entry.name === pattern || fullPath.includes(pattern);
|
|
108
|
+
});
|
|
109
|
+
if (!shouldExclude) {
|
|
110
|
+
scan(fullPath);
|
|
111
|
+
}
|
|
112
|
+
} else if (entry.name.endsWith(".map")) {
|
|
113
|
+
mapFiles.push(fullPath);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
scan(dir);
|
|
118
|
+
return mapFiles;
|
|
119
|
+
}
|
|
120
|
+
async function uploadSourceMaps(options) {
|
|
121
|
+
const release = options.release || detectRelease();
|
|
122
|
+
const outDir = options.outDir || ".next";
|
|
123
|
+
const urlPrefix = options.urlPrefix || "~/_next/";
|
|
124
|
+
const exclude = options.exclude || ["node_modules"];
|
|
125
|
+
const fullOptions = { ...options, release, urlPrefix };
|
|
126
|
+
const outputPath = path.resolve(process.cwd(), outDir);
|
|
127
|
+
const staticDir = path.join(outputPath, "static");
|
|
128
|
+
const mapFiles = findMapFiles(staticDir, exclude);
|
|
129
|
+
if (mapFiles.length === 0) {
|
|
130
|
+
warn(fullOptions, "No source maps found to upload");
|
|
131
|
+
warn(fullOptions, `Looked in: ${staticDir}`);
|
|
132
|
+
warn(
|
|
133
|
+
fullOptions,
|
|
134
|
+
"Make sure productionBrowserSourceMaps is enabled in next.config.js"
|
|
135
|
+
);
|
|
136
|
+
return { uploaded: 0, failed: 0 };
|
|
137
|
+
}
|
|
138
|
+
log(fullOptions, `Found ${mapFiles.length} source map(s) to upload`);
|
|
139
|
+
log(fullOptions, `Release: ${release}`);
|
|
140
|
+
if (!options.dryRun) {
|
|
141
|
+
try {
|
|
142
|
+
await createRelease(fullOptions);
|
|
143
|
+
log(fullOptions, "Created release");
|
|
144
|
+
} catch (error) {
|
|
145
|
+
warn(fullOptions, `Failed to create release: ${error}`);
|
|
146
|
+
return { uploaded: 0, failed: mapFiles.length };
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
let uploaded = 0;
|
|
150
|
+
let failed = 0;
|
|
151
|
+
for (const mapPath of mapFiles) {
|
|
152
|
+
const relativePath = path.relative(staticDir, mapPath);
|
|
153
|
+
const minifiedFilename = relativePath.replace(".map", "");
|
|
154
|
+
const url = urlPrefix + "static/" + minifiedFilename;
|
|
155
|
+
if (options.dryRun) {
|
|
156
|
+
log(fullOptions, `[Dry Run] Would upload: ${url}`);
|
|
157
|
+
uploaded++;
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
try {
|
|
161
|
+
const mapContent = fs.readFileSync(mapPath, "utf8");
|
|
162
|
+
await uploadSourceMap(fullOptions, url, mapContent);
|
|
163
|
+
log(fullOptions, `Uploaded: ${url}`);
|
|
164
|
+
uploaded++;
|
|
165
|
+
if (options.deleteAfterUpload) {
|
|
166
|
+
fs.unlinkSync(mapPath);
|
|
167
|
+
log(fullOptions, `Deleted: ${relativePath}`);
|
|
168
|
+
}
|
|
169
|
+
} catch (error) {
|
|
170
|
+
warn(fullOptions, `Failed to upload ${relativePath}: ${error}`);
|
|
171
|
+
failed++;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (!options.dryRun && uploaded > 0) {
|
|
175
|
+
await finalizeRelease(fullOptions);
|
|
176
|
+
log(fullOptions, "Finalized release");
|
|
177
|
+
}
|
|
178
|
+
log(
|
|
179
|
+
fullOptions,
|
|
180
|
+
`Source map upload complete: ${uploaded} uploaded, ${failed} failed`
|
|
181
|
+
);
|
|
182
|
+
return { uploaded, failed };
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export {
|
|
186
|
+
uploadSourceMaps
|
|
187
|
+
};
|
package/dist/cli.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
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/sourcemap-uploader.ts
|
|
27
|
+
var fs = __toESM(require("fs"));
|
|
28
|
+
var path = __toESM(require("path"));
|
|
29
|
+
var import_child_process = require("child_process");
|
|
30
|
+
var import_form_data = __toESM(require("form-data"));
|
|
31
|
+
function log(options, message) {
|
|
32
|
+
if (!options.silent) {
|
|
33
|
+
console.log(`[Proliferate] ${message}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function warn(options, message) {
|
|
37
|
+
if (!options.silent) {
|
|
38
|
+
console.warn(`[Proliferate] ${message}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function detectRelease() {
|
|
42
|
+
const envVars = [
|
|
43
|
+
"PROLIFERATE_RELEASE",
|
|
44
|
+
"GITHUB_SHA",
|
|
45
|
+
"VERCEL_GIT_COMMIT_SHA",
|
|
46
|
+
"CF_PAGES_COMMIT_SHA",
|
|
47
|
+
"RENDER_GIT_COMMIT",
|
|
48
|
+
"RAILWAY_GIT_COMMIT_SHA",
|
|
49
|
+
"GITLAB_CI_COMMIT_SHA",
|
|
50
|
+
"CIRCLE_SHA1",
|
|
51
|
+
"COMMIT_SHA",
|
|
52
|
+
"GIT_COMMIT"
|
|
53
|
+
];
|
|
54
|
+
for (const envVar of envVars) {
|
|
55
|
+
const value = process.env[envVar];
|
|
56
|
+
if (value) {
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
const sha = (0, import_child_process.execSync)("git rev-parse HEAD", { encoding: "utf8" }).trim();
|
|
62
|
+
return sha;
|
|
63
|
+
} catch {
|
|
64
|
+
}
|
|
65
|
+
return `build-${Date.now()}`;
|
|
66
|
+
}
|
|
67
|
+
async function createRelease(options) {
|
|
68
|
+
const form = new import_form_data.default();
|
|
69
|
+
form.append("version", options.release);
|
|
70
|
+
form.append("url_prefix", options.urlPrefix || "~/_next/");
|
|
71
|
+
const response = await fetch(`${options.endpoint}/releases`, {
|
|
72
|
+
method: "POST",
|
|
73
|
+
headers: {
|
|
74
|
+
Authorization: `Bearer ${options.apiKey}`
|
|
75
|
+
},
|
|
76
|
+
body: form
|
|
77
|
+
});
|
|
78
|
+
if (!response.ok) {
|
|
79
|
+
const text = await response.text();
|
|
80
|
+
throw new Error(`Failed to create release: ${response.status} ${text}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async function uploadSourceMap(options, url, content) {
|
|
84
|
+
const form = new import_form_data.default();
|
|
85
|
+
form.append("release", options.release);
|
|
86
|
+
form.append("url", url);
|
|
87
|
+
form.append("url_prefix", options.urlPrefix || "~/_next/");
|
|
88
|
+
form.append("sourcemap", Buffer.from(content), {
|
|
89
|
+
filename: "sourcemap.map",
|
|
90
|
+
contentType: "application/json"
|
|
91
|
+
});
|
|
92
|
+
const response = await fetch(`${options.endpoint}/sourcemaps`, {
|
|
93
|
+
method: "POST",
|
|
94
|
+
headers: {
|
|
95
|
+
Authorization: `Bearer ${options.apiKey}`
|
|
96
|
+
},
|
|
97
|
+
body: form
|
|
98
|
+
});
|
|
99
|
+
if (!response.ok) {
|
|
100
|
+
const text = await response.text();
|
|
101
|
+
throw new Error(`${response.status} ${text}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async function finalizeRelease(options) {
|
|
105
|
+
const response = await fetch(
|
|
106
|
+
`${options.endpoint}/releases/${encodeURIComponent(options.release)}/finalize`,
|
|
107
|
+
{
|
|
108
|
+
method: "POST",
|
|
109
|
+
headers: {
|
|
110
|
+
Authorization: `Bearer ${options.apiKey}`
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
);
|
|
114
|
+
if (!response.ok) {
|
|
115
|
+
const text = await response.text();
|
|
116
|
+
warn(options, `Failed to finalize release: ${response.status} ${text}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function findMapFiles(dir, exclude = ["node_modules"]) {
|
|
120
|
+
const mapFiles = [];
|
|
121
|
+
function scan(currentDir) {
|
|
122
|
+
if (!fs.existsSync(currentDir)) return;
|
|
123
|
+
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
124
|
+
for (const entry of entries) {
|
|
125
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
126
|
+
if (entry.isDirectory()) {
|
|
127
|
+
const shouldExclude = exclude.some((pattern) => {
|
|
128
|
+
if (pattern.includes("*")) {
|
|
129
|
+
const regex = new RegExp(pattern.replace(/\*/g, ".*"));
|
|
130
|
+
return regex.test(entry.name);
|
|
131
|
+
}
|
|
132
|
+
return entry.name === pattern || fullPath.includes(pattern);
|
|
133
|
+
});
|
|
134
|
+
if (!shouldExclude) {
|
|
135
|
+
scan(fullPath);
|
|
136
|
+
}
|
|
137
|
+
} else if (entry.name.endsWith(".map")) {
|
|
138
|
+
mapFiles.push(fullPath);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
scan(dir);
|
|
143
|
+
return mapFiles;
|
|
144
|
+
}
|
|
145
|
+
async function uploadSourceMaps(options) {
|
|
146
|
+
const release = options.release || detectRelease();
|
|
147
|
+
const outDir = options.outDir || ".next";
|
|
148
|
+
const urlPrefix = options.urlPrefix || "~/_next/";
|
|
149
|
+
const exclude = options.exclude || ["node_modules"];
|
|
150
|
+
const fullOptions = { ...options, release, urlPrefix };
|
|
151
|
+
const outputPath = path.resolve(process.cwd(), outDir);
|
|
152
|
+
const staticDir = path.join(outputPath, "static");
|
|
153
|
+
const mapFiles = findMapFiles(staticDir, exclude);
|
|
154
|
+
if (mapFiles.length === 0) {
|
|
155
|
+
warn(fullOptions, "No source maps found to upload");
|
|
156
|
+
warn(fullOptions, `Looked in: ${staticDir}`);
|
|
157
|
+
warn(
|
|
158
|
+
fullOptions,
|
|
159
|
+
"Make sure productionBrowserSourceMaps is enabled in next.config.js"
|
|
160
|
+
);
|
|
161
|
+
return { uploaded: 0, failed: 0 };
|
|
162
|
+
}
|
|
163
|
+
log(fullOptions, `Found ${mapFiles.length} source map(s) to upload`);
|
|
164
|
+
log(fullOptions, `Release: ${release}`);
|
|
165
|
+
if (!options.dryRun) {
|
|
166
|
+
try {
|
|
167
|
+
await createRelease(fullOptions);
|
|
168
|
+
log(fullOptions, "Created release");
|
|
169
|
+
} catch (error) {
|
|
170
|
+
warn(fullOptions, `Failed to create release: ${error}`);
|
|
171
|
+
return { uploaded: 0, failed: mapFiles.length };
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
let uploaded = 0;
|
|
175
|
+
let failed = 0;
|
|
176
|
+
for (const mapPath of mapFiles) {
|
|
177
|
+
const relativePath = path.relative(staticDir, mapPath);
|
|
178
|
+
const minifiedFilename = relativePath.replace(".map", "");
|
|
179
|
+
const url = urlPrefix + "static/" + minifiedFilename;
|
|
180
|
+
if (options.dryRun) {
|
|
181
|
+
log(fullOptions, `[Dry Run] Would upload: ${url}`);
|
|
182
|
+
uploaded++;
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
try {
|
|
186
|
+
const mapContent = fs.readFileSync(mapPath, "utf8");
|
|
187
|
+
await uploadSourceMap(fullOptions, url, mapContent);
|
|
188
|
+
log(fullOptions, `Uploaded: ${url}`);
|
|
189
|
+
uploaded++;
|
|
190
|
+
if (options.deleteAfterUpload) {
|
|
191
|
+
fs.unlinkSync(mapPath);
|
|
192
|
+
log(fullOptions, `Deleted: ${relativePath}`);
|
|
193
|
+
}
|
|
194
|
+
} catch (error) {
|
|
195
|
+
warn(fullOptions, `Failed to upload ${relativePath}: ${error}`);
|
|
196
|
+
failed++;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (!options.dryRun && uploaded > 0) {
|
|
200
|
+
await finalizeRelease(fullOptions);
|
|
201
|
+
log(fullOptions, "Finalized release");
|
|
202
|
+
}
|
|
203
|
+
log(
|
|
204
|
+
fullOptions,
|
|
205
|
+
`Source map upload complete: ${uploaded} uploaded, ${failed} failed`
|
|
206
|
+
);
|
|
207
|
+
return { uploaded, failed };
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// src/cli.ts
|
|
211
|
+
function parseArgs(args) {
|
|
212
|
+
const result = {
|
|
213
|
+
command: "",
|
|
214
|
+
deleteAfterUpload: false,
|
|
215
|
+
dryRun: false,
|
|
216
|
+
silent: false,
|
|
217
|
+
help: false
|
|
218
|
+
};
|
|
219
|
+
for (let i = 0; i < args.length; i++) {
|
|
220
|
+
const arg = args[i];
|
|
221
|
+
if (arg === "upload") {
|
|
222
|
+
result.command = "upload";
|
|
223
|
+
} else if (arg === "--help" || arg === "-h") {
|
|
224
|
+
result.help = true;
|
|
225
|
+
} else if (arg === "--dry-run") {
|
|
226
|
+
result.dryRun = true;
|
|
227
|
+
} else if (arg === "--silent") {
|
|
228
|
+
result.silent = true;
|
|
229
|
+
} else if (arg === "--delete-after-upload") {
|
|
230
|
+
result.deleteAfterUpload = true;
|
|
231
|
+
} else if (arg.startsWith("--api-key=")) {
|
|
232
|
+
result.apiKey = arg.split("=")[1];
|
|
233
|
+
} else if (arg === "--api-key" && args[i + 1]) {
|
|
234
|
+
result.apiKey = args[++i];
|
|
235
|
+
} else if (arg.startsWith("--endpoint=")) {
|
|
236
|
+
result.endpoint = arg.split("=")[1];
|
|
237
|
+
} else if (arg === "--endpoint" && args[i + 1]) {
|
|
238
|
+
result.endpoint = args[++i];
|
|
239
|
+
} else if (arg.startsWith("--release=")) {
|
|
240
|
+
result.release = arg.split("=")[1];
|
|
241
|
+
} else if (arg === "--release" && args[i + 1]) {
|
|
242
|
+
result.release = args[++i];
|
|
243
|
+
} else if (arg.startsWith("--url-prefix=")) {
|
|
244
|
+
result.urlPrefix = arg.split("=")[1];
|
|
245
|
+
} else if (arg === "--url-prefix" && args[i + 1]) {
|
|
246
|
+
result.urlPrefix = args[++i];
|
|
247
|
+
} else if (arg.startsWith("--out-dir=")) {
|
|
248
|
+
result.outDir = arg.split("=")[1];
|
|
249
|
+
} else if (arg === "--out-dir" && args[i + 1]) {
|
|
250
|
+
result.outDir = args[++i];
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
result.apiKey = result.apiKey || process.env.PROLIFERATE_API_KEY;
|
|
254
|
+
result.endpoint = result.endpoint || process.env.PROLIFERATE_ENDPOINT;
|
|
255
|
+
result.release = result.release || process.env.PROLIFERATE_RELEASE;
|
|
256
|
+
return result;
|
|
257
|
+
}
|
|
258
|
+
function printHelp() {
|
|
259
|
+
console.log(`
|
|
260
|
+
@proliferate/nextjs-plugin - Upload Next.js source maps to Proliferate
|
|
261
|
+
|
|
262
|
+
USAGE:
|
|
263
|
+
npx @proliferate/nextjs-plugin upload [options]
|
|
264
|
+
|
|
265
|
+
COMMANDS:
|
|
266
|
+
upload Upload source maps to Proliferate
|
|
267
|
+
|
|
268
|
+
OPTIONS:
|
|
269
|
+
--api-key=KEY Proliferate API key (or PROLIFERATE_API_KEY env var)
|
|
270
|
+
--endpoint=URL Proliferate API endpoint (or PROLIFERATE_ENDPOINT env var)
|
|
271
|
+
--release=VERSION Release version (auto-detected from git/CI if not specified)
|
|
272
|
+
--url-prefix=PREFIX URL prefix for source maps (default: ~/_next/)
|
|
273
|
+
--out-dir=DIR Next.js output directory (default: .next)
|
|
274
|
+
--delete-after-upload Delete source maps after uploading
|
|
275
|
+
--dry-run Show what would be uploaded without actually uploading
|
|
276
|
+
--silent Suppress log output
|
|
277
|
+
--help, -h Show this help message
|
|
278
|
+
|
|
279
|
+
EXAMPLES:
|
|
280
|
+
# Basic upload
|
|
281
|
+
npx @proliferate/nextjs-plugin upload \\
|
|
282
|
+
--api-key=$PROLIFERATE_API_KEY \\
|
|
283
|
+
--endpoint=https://api.proliferate.com
|
|
284
|
+
|
|
285
|
+
# Dry run to see what would be uploaded
|
|
286
|
+
npx @proliferate/nextjs-plugin upload --dry-run
|
|
287
|
+
|
|
288
|
+
# Upload and delete source maps afterward (for security)
|
|
289
|
+
npx @proliferate/nextjs-plugin upload --delete-after-upload
|
|
290
|
+
|
|
291
|
+
ENVIRONMENT VARIABLES:
|
|
292
|
+
PROLIFERATE_API_KEY API key (alternative to --api-key)
|
|
293
|
+
PROLIFERATE_ENDPOINT API endpoint (alternative to --endpoint)
|
|
294
|
+
PROLIFERATE_RELEASE Release version (alternative to --release)
|
|
295
|
+
`);
|
|
296
|
+
}
|
|
297
|
+
async function main() {
|
|
298
|
+
const args = parseArgs(process.argv.slice(2));
|
|
299
|
+
if (args.help || !args.command) {
|
|
300
|
+
printHelp();
|
|
301
|
+
process.exit(args.help ? 0 : 1);
|
|
302
|
+
}
|
|
303
|
+
if (args.command === "upload") {
|
|
304
|
+
if (!args.apiKey) {
|
|
305
|
+
console.error(
|
|
306
|
+
"Error: API key is required. Use --api-key or set PROLIFERATE_API_KEY environment variable."
|
|
307
|
+
);
|
|
308
|
+
process.exit(1);
|
|
309
|
+
}
|
|
310
|
+
if (!args.endpoint) {
|
|
311
|
+
console.error(
|
|
312
|
+
"Error: Endpoint is required. Use --endpoint or set PROLIFERATE_ENDPOINT environment variable."
|
|
313
|
+
);
|
|
314
|
+
process.exit(1);
|
|
315
|
+
}
|
|
316
|
+
try {
|
|
317
|
+
const result = await uploadSourceMaps({
|
|
318
|
+
apiKey: args.apiKey,
|
|
319
|
+
endpoint: args.endpoint,
|
|
320
|
+
release: args.release,
|
|
321
|
+
urlPrefix: args.urlPrefix,
|
|
322
|
+
outDir: args.outDir,
|
|
323
|
+
deleteAfterUpload: args.deleteAfterUpload,
|
|
324
|
+
dryRun: args.dryRun,
|
|
325
|
+
silent: args.silent
|
|
326
|
+
});
|
|
327
|
+
if (result.failed > 0) {
|
|
328
|
+
process.exit(1);
|
|
329
|
+
}
|
|
330
|
+
} catch (error) {
|
|
331
|
+
console.error("Error:", error);
|
|
332
|
+
process.exit(1);
|
|
333
|
+
}
|
|
334
|
+
} else {
|
|
335
|
+
console.error(`Unknown command: ${args.command}`);
|
|
336
|
+
printHelp();
|
|
337
|
+
process.exit(1);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
main();
|
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
uploadSourceMaps
|
|
4
|
+
} from "./chunk-PPXY4MSU.mjs";
|
|
5
|
+
|
|
6
|
+
// src/cli.ts
|
|
7
|
+
function parseArgs(args) {
|
|
8
|
+
const result = {
|
|
9
|
+
command: "",
|
|
10
|
+
deleteAfterUpload: false,
|
|
11
|
+
dryRun: false,
|
|
12
|
+
silent: false,
|
|
13
|
+
help: false
|
|
14
|
+
};
|
|
15
|
+
for (let i = 0; i < args.length; i++) {
|
|
16
|
+
const arg = args[i];
|
|
17
|
+
if (arg === "upload") {
|
|
18
|
+
result.command = "upload";
|
|
19
|
+
} else if (arg === "--help" || arg === "-h") {
|
|
20
|
+
result.help = true;
|
|
21
|
+
} else if (arg === "--dry-run") {
|
|
22
|
+
result.dryRun = true;
|
|
23
|
+
} else if (arg === "--silent") {
|
|
24
|
+
result.silent = true;
|
|
25
|
+
} else if (arg === "--delete-after-upload") {
|
|
26
|
+
result.deleteAfterUpload = true;
|
|
27
|
+
} else if (arg.startsWith("--api-key=")) {
|
|
28
|
+
result.apiKey = arg.split("=")[1];
|
|
29
|
+
} else if (arg === "--api-key" && args[i + 1]) {
|
|
30
|
+
result.apiKey = args[++i];
|
|
31
|
+
} else if (arg.startsWith("--endpoint=")) {
|
|
32
|
+
result.endpoint = arg.split("=")[1];
|
|
33
|
+
} else if (arg === "--endpoint" && args[i + 1]) {
|
|
34
|
+
result.endpoint = args[++i];
|
|
35
|
+
} else if (arg.startsWith("--release=")) {
|
|
36
|
+
result.release = arg.split("=")[1];
|
|
37
|
+
} else if (arg === "--release" && args[i + 1]) {
|
|
38
|
+
result.release = args[++i];
|
|
39
|
+
} else if (arg.startsWith("--url-prefix=")) {
|
|
40
|
+
result.urlPrefix = arg.split("=")[1];
|
|
41
|
+
} else if (arg === "--url-prefix" && args[i + 1]) {
|
|
42
|
+
result.urlPrefix = args[++i];
|
|
43
|
+
} else if (arg.startsWith("--out-dir=")) {
|
|
44
|
+
result.outDir = arg.split("=")[1];
|
|
45
|
+
} else if (arg === "--out-dir" && args[i + 1]) {
|
|
46
|
+
result.outDir = args[++i];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
result.apiKey = result.apiKey || process.env.PROLIFERATE_API_KEY;
|
|
50
|
+
result.endpoint = result.endpoint || process.env.PROLIFERATE_ENDPOINT;
|
|
51
|
+
result.release = result.release || process.env.PROLIFERATE_RELEASE;
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
function printHelp() {
|
|
55
|
+
console.log(`
|
|
56
|
+
@proliferate/nextjs-plugin - Upload Next.js source maps to Proliferate
|
|
57
|
+
|
|
58
|
+
USAGE:
|
|
59
|
+
npx @proliferate/nextjs-plugin upload [options]
|
|
60
|
+
|
|
61
|
+
COMMANDS:
|
|
62
|
+
upload Upload source maps to Proliferate
|
|
63
|
+
|
|
64
|
+
OPTIONS:
|
|
65
|
+
--api-key=KEY Proliferate API key (or PROLIFERATE_API_KEY env var)
|
|
66
|
+
--endpoint=URL Proliferate API endpoint (or PROLIFERATE_ENDPOINT env var)
|
|
67
|
+
--release=VERSION Release version (auto-detected from git/CI if not specified)
|
|
68
|
+
--url-prefix=PREFIX URL prefix for source maps (default: ~/_next/)
|
|
69
|
+
--out-dir=DIR Next.js output directory (default: .next)
|
|
70
|
+
--delete-after-upload Delete source maps after uploading
|
|
71
|
+
--dry-run Show what would be uploaded without actually uploading
|
|
72
|
+
--silent Suppress log output
|
|
73
|
+
--help, -h Show this help message
|
|
74
|
+
|
|
75
|
+
EXAMPLES:
|
|
76
|
+
# Basic upload
|
|
77
|
+
npx @proliferate/nextjs-plugin upload \\
|
|
78
|
+
--api-key=$PROLIFERATE_API_KEY \\
|
|
79
|
+
--endpoint=https://api.proliferate.com
|
|
80
|
+
|
|
81
|
+
# Dry run to see what would be uploaded
|
|
82
|
+
npx @proliferate/nextjs-plugin upload --dry-run
|
|
83
|
+
|
|
84
|
+
# Upload and delete source maps afterward (for security)
|
|
85
|
+
npx @proliferate/nextjs-plugin upload --delete-after-upload
|
|
86
|
+
|
|
87
|
+
ENVIRONMENT VARIABLES:
|
|
88
|
+
PROLIFERATE_API_KEY API key (alternative to --api-key)
|
|
89
|
+
PROLIFERATE_ENDPOINT API endpoint (alternative to --endpoint)
|
|
90
|
+
PROLIFERATE_RELEASE Release version (alternative to --release)
|
|
91
|
+
`);
|
|
92
|
+
}
|
|
93
|
+
async function main() {
|
|
94
|
+
const args = parseArgs(process.argv.slice(2));
|
|
95
|
+
if (args.help || !args.command) {
|
|
96
|
+
printHelp();
|
|
97
|
+
process.exit(args.help ? 0 : 1);
|
|
98
|
+
}
|
|
99
|
+
if (args.command === "upload") {
|
|
100
|
+
if (!args.apiKey) {
|
|
101
|
+
console.error(
|
|
102
|
+
"Error: API key is required. Use --api-key or set PROLIFERATE_API_KEY environment variable."
|
|
103
|
+
);
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
if (!args.endpoint) {
|
|
107
|
+
console.error(
|
|
108
|
+
"Error: Endpoint is required. Use --endpoint or set PROLIFERATE_ENDPOINT environment variable."
|
|
109
|
+
);
|
|
110
|
+
process.exit(1);
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
const result = await uploadSourceMaps({
|
|
114
|
+
apiKey: args.apiKey,
|
|
115
|
+
endpoint: args.endpoint,
|
|
116
|
+
release: args.release,
|
|
117
|
+
urlPrefix: args.urlPrefix,
|
|
118
|
+
outDir: args.outDir,
|
|
119
|
+
deleteAfterUpload: args.deleteAfterUpload,
|
|
120
|
+
dryRun: args.dryRun,
|
|
121
|
+
silent: args.silent
|
|
122
|
+
});
|
|
123
|
+
if (result.failed > 0) {
|
|
124
|
+
process.exit(1);
|
|
125
|
+
}
|
|
126
|
+
} catch (error) {
|
|
127
|
+
console.error("Error:", error);
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
} else {
|
|
131
|
+
console.error(`Unknown command: ${args.command}`);
|
|
132
|
+
printHelp();
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
main();
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { NextConfig } from 'next';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Source map upload utilities for Proliferate.
|
|
5
|
+
*
|
|
6
|
+
* This module handles uploading source maps to the Proliferate API.
|
|
7
|
+
* Used by both the Next.js plugin and the CLI.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Options for uploading source maps.
|
|
11
|
+
*/
|
|
12
|
+
interface UploadOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Your Proliferate API key.
|
|
15
|
+
*/
|
|
16
|
+
apiKey: string;
|
|
17
|
+
/**
|
|
18
|
+
* The Proliferate API endpoint.
|
|
19
|
+
*/
|
|
20
|
+
endpoint: string;
|
|
21
|
+
/**
|
|
22
|
+
* Release version.
|
|
23
|
+
*/
|
|
24
|
+
release: string;
|
|
25
|
+
/**
|
|
26
|
+
* URL prefix for source map URLs. Defaults to '~/_next/'.
|
|
27
|
+
*/
|
|
28
|
+
urlPrefix?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Patterns to exclude from upload. Defaults to ['node_modules'].
|
|
31
|
+
*/
|
|
32
|
+
exclude?: string[];
|
|
33
|
+
/**
|
|
34
|
+
* Delete source maps after upload. Defaults to false.
|
|
35
|
+
*/
|
|
36
|
+
deleteAfterUpload?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Suppress log output.
|
|
39
|
+
*/
|
|
40
|
+
silent?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Dry run mode - log what would be uploaded without actually uploading.
|
|
43
|
+
*/
|
|
44
|
+
dryRun?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Output directory to scan for source maps. Defaults to '.next'.
|
|
47
|
+
*/
|
|
48
|
+
outDir?: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Upload source maps to the Proliferate API.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```javascript
|
|
55
|
+
* const { uploadSourceMaps } = require('@proliferate/nextjs-plugin');
|
|
56
|
+
*
|
|
57
|
+
* await uploadSourceMaps({
|
|
58
|
+
* apiKey: process.env.PROLIFERATE_API_KEY,
|
|
59
|
+
* endpoint: 'https://api.proliferate.com',
|
|
60
|
+
* release: process.env.VERCEL_GIT_COMMIT_SHA,
|
|
61
|
+
* });
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
declare function uploadSourceMaps(options: Omit<UploadOptions, 'release'> & {
|
|
65
|
+
release?: string;
|
|
66
|
+
}): Promise<{
|
|
67
|
+
uploaded: number;
|
|
68
|
+
failed: number;
|
|
69
|
+
}>;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Proliferate Next.js Plugin
|
|
73
|
+
*
|
|
74
|
+
* Integrates Proliferate error monitoring with Next.js applications by:
|
|
75
|
+
* 1. Injecting the release version into the build
|
|
76
|
+
* 2. Enabling production source maps
|
|
77
|
+
* 3. Providing a CLI for uploading source maps
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```javascript
|
|
81
|
+
* // next.config.js
|
|
82
|
+
* const { withProliferate } = require('@proliferate/nextjs-plugin');
|
|
83
|
+
*
|
|
84
|
+
* module.exports = withProliferate({
|
|
85
|
+
* // your Next.js config
|
|
86
|
+
* }, {
|
|
87
|
+
* apiKey: process.env.PROLIFERATE_API_KEY,
|
|
88
|
+
* endpoint: 'https://api.proliferate.com',
|
|
89
|
+
* });
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Configuration options for the Proliferate Next.js plugin.
|
|
95
|
+
*/
|
|
96
|
+
interface ProliferateNextOptions {
|
|
97
|
+
/**
|
|
98
|
+
* Your Proliferate API key.
|
|
99
|
+
* Can also be set via PROLIFERATE_API_KEY environment variable.
|
|
100
|
+
*/
|
|
101
|
+
apiKey?: string;
|
|
102
|
+
/**
|
|
103
|
+
* The Proliferate API endpoint.
|
|
104
|
+
* Can also be set via PROLIFERATE_ENDPOINT environment variable.
|
|
105
|
+
*/
|
|
106
|
+
endpoint?: string;
|
|
107
|
+
/**
|
|
108
|
+
* Release version. Auto-detected from git SHA or CI environment variables if not provided.
|
|
109
|
+
* Can also be set via PROLIFERATE_RELEASE environment variable.
|
|
110
|
+
*/
|
|
111
|
+
release?: string;
|
|
112
|
+
/**
|
|
113
|
+
* URL prefix for source map URLs. Defaults to '~/'.
|
|
114
|
+
*/
|
|
115
|
+
urlPrefix?: string;
|
|
116
|
+
/**
|
|
117
|
+
* Suppress log output.
|
|
118
|
+
*/
|
|
119
|
+
silent?: boolean;
|
|
120
|
+
/**
|
|
121
|
+
* Enable production source maps. Defaults to true.
|
|
122
|
+
* Set to false if you want to handle source map generation yourself.
|
|
123
|
+
*/
|
|
124
|
+
enableSourceMaps?: boolean;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Wrap your Next.js config with Proliferate integration.
|
|
128
|
+
*
|
|
129
|
+
* This HOC:
|
|
130
|
+
* - Injects `__PROLIFERATE_RELEASE__` global variable at build time
|
|
131
|
+
* - Sets `NEXT_PUBLIC_PROLIFERATE_RELEASE` environment variable
|
|
132
|
+
* - Enables production source maps (configurable)
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```javascript
|
|
136
|
+
* // next.config.js
|
|
137
|
+
* const { withProliferate } = require('@proliferate/nextjs-plugin');
|
|
138
|
+
*
|
|
139
|
+
* module.exports = withProliferate({
|
|
140
|
+
* reactStrictMode: true,
|
|
141
|
+
* // ... other Next.js config
|
|
142
|
+
* }, {
|
|
143
|
+
* apiKey: process.env.PROLIFERATE_API_KEY,
|
|
144
|
+
* endpoint: 'https://api.proliferate.com',
|
|
145
|
+
* });
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
declare function withProliferate(nextConfig?: NextConfig, options?: ProliferateNextOptions): NextConfig;
|
|
149
|
+
|
|
150
|
+
export { type ProliferateNextOptions, type UploadOptions, withProliferate as default, uploadSourceMaps, withProliferate };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { NextConfig } from 'next';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Source map upload utilities for Proliferate.
|
|
5
|
+
*
|
|
6
|
+
* This module handles uploading source maps to the Proliferate API.
|
|
7
|
+
* Used by both the Next.js plugin and the CLI.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Options for uploading source maps.
|
|
11
|
+
*/
|
|
12
|
+
interface UploadOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Your Proliferate API key.
|
|
15
|
+
*/
|
|
16
|
+
apiKey: string;
|
|
17
|
+
/**
|
|
18
|
+
* The Proliferate API endpoint.
|
|
19
|
+
*/
|
|
20
|
+
endpoint: string;
|
|
21
|
+
/**
|
|
22
|
+
* Release version.
|
|
23
|
+
*/
|
|
24
|
+
release: string;
|
|
25
|
+
/**
|
|
26
|
+
* URL prefix for source map URLs. Defaults to '~/_next/'.
|
|
27
|
+
*/
|
|
28
|
+
urlPrefix?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Patterns to exclude from upload. Defaults to ['node_modules'].
|
|
31
|
+
*/
|
|
32
|
+
exclude?: string[];
|
|
33
|
+
/**
|
|
34
|
+
* Delete source maps after upload. Defaults to false.
|
|
35
|
+
*/
|
|
36
|
+
deleteAfterUpload?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Suppress log output.
|
|
39
|
+
*/
|
|
40
|
+
silent?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Dry run mode - log what would be uploaded without actually uploading.
|
|
43
|
+
*/
|
|
44
|
+
dryRun?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Output directory to scan for source maps. Defaults to '.next'.
|
|
47
|
+
*/
|
|
48
|
+
outDir?: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Upload source maps to the Proliferate API.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```javascript
|
|
55
|
+
* const { uploadSourceMaps } = require('@proliferate/nextjs-plugin');
|
|
56
|
+
*
|
|
57
|
+
* await uploadSourceMaps({
|
|
58
|
+
* apiKey: process.env.PROLIFERATE_API_KEY,
|
|
59
|
+
* endpoint: 'https://api.proliferate.com',
|
|
60
|
+
* release: process.env.VERCEL_GIT_COMMIT_SHA,
|
|
61
|
+
* });
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
declare function uploadSourceMaps(options: Omit<UploadOptions, 'release'> & {
|
|
65
|
+
release?: string;
|
|
66
|
+
}): Promise<{
|
|
67
|
+
uploaded: number;
|
|
68
|
+
failed: number;
|
|
69
|
+
}>;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Proliferate Next.js Plugin
|
|
73
|
+
*
|
|
74
|
+
* Integrates Proliferate error monitoring with Next.js applications by:
|
|
75
|
+
* 1. Injecting the release version into the build
|
|
76
|
+
* 2. Enabling production source maps
|
|
77
|
+
* 3. Providing a CLI for uploading source maps
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```javascript
|
|
81
|
+
* // next.config.js
|
|
82
|
+
* const { withProliferate } = require('@proliferate/nextjs-plugin');
|
|
83
|
+
*
|
|
84
|
+
* module.exports = withProliferate({
|
|
85
|
+
* // your Next.js config
|
|
86
|
+
* }, {
|
|
87
|
+
* apiKey: process.env.PROLIFERATE_API_KEY,
|
|
88
|
+
* endpoint: 'https://api.proliferate.com',
|
|
89
|
+
* });
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Configuration options for the Proliferate Next.js plugin.
|
|
95
|
+
*/
|
|
96
|
+
interface ProliferateNextOptions {
|
|
97
|
+
/**
|
|
98
|
+
* Your Proliferate API key.
|
|
99
|
+
* Can also be set via PROLIFERATE_API_KEY environment variable.
|
|
100
|
+
*/
|
|
101
|
+
apiKey?: string;
|
|
102
|
+
/**
|
|
103
|
+
* The Proliferate API endpoint.
|
|
104
|
+
* Can also be set via PROLIFERATE_ENDPOINT environment variable.
|
|
105
|
+
*/
|
|
106
|
+
endpoint?: string;
|
|
107
|
+
/**
|
|
108
|
+
* Release version. Auto-detected from git SHA or CI environment variables if not provided.
|
|
109
|
+
* Can also be set via PROLIFERATE_RELEASE environment variable.
|
|
110
|
+
*/
|
|
111
|
+
release?: string;
|
|
112
|
+
/**
|
|
113
|
+
* URL prefix for source map URLs. Defaults to '~/'.
|
|
114
|
+
*/
|
|
115
|
+
urlPrefix?: string;
|
|
116
|
+
/**
|
|
117
|
+
* Suppress log output.
|
|
118
|
+
*/
|
|
119
|
+
silent?: boolean;
|
|
120
|
+
/**
|
|
121
|
+
* Enable production source maps. Defaults to true.
|
|
122
|
+
* Set to false if you want to handle source map generation yourself.
|
|
123
|
+
*/
|
|
124
|
+
enableSourceMaps?: boolean;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Wrap your Next.js config with Proliferate integration.
|
|
128
|
+
*
|
|
129
|
+
* This HOC:
|
|
130
|
+
* - Injects `__PROLIFERATE_RELEASE__` global variable at build time
|
|
131
|
+
* - Sets `NEXT_PUBLIC_PROLIFERATE_RELEASE` environment variable
|
|
132
|
+
* - Enables production source maps (configurable)
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```javascript
|
|
136
|
+
* // next.config.js
|
|
137
|
+
* const { withProliferate } = require('@proliferate/nextjs-plugin');
|
|
138
|
+
*
|
|
139
|
+
* module.exports = withProliferate({
|
|
140
|
+
* reactStrictMode: true,
|
|
141
|
+
* // ... other Next.js config
|
|
142
|
+
* }, {
|
|
143
|
+
* apiKey: process.env.PROLIFERATE_API_KEY,
|
|
144
|
+
* endpoint: 'https://api.proliferate.com',
|
|
145
|
+
* });
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
declare function withProliferate(nextConfig?: NextConfig, options?: ProliferateNextOptions): NextConfig;
|
|
149
|
+
|
|
150
|
+
export { type ProliferateNextOptions, type UploadOptions, withProliferate as default, uploadSourceMaps, withProliferate };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
default: () => index_default,
|
|
34
|
+
uploadSourceMaps: () => uploadSourceMaps,
|
|
35
|
+
withProliferate: () => withProliferate
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(index_exports);
|
|
38
|
+
var import_child_process2 = require("child_process");
|
|
39
|
+
|
|
40
|
+
// src/sourcemap-uploader.ts
|
|
41
|
+
var fs = __toESM(require("fs"));
|
|
42
|
+
var path = __toESM(require("path"));
|
|
43
|
+
var import_child_process = require("child_process");
|
|
44
|
+
var import_form_data = __toESM(require("form-data"));
|
|
45
|
+
function log(options, message) {
|
|
46
|
+
if (!options.silent) {
|
|
47
|
+
console.log(`[Proliferate] ${message}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function warn(options, message) {
|
|
51
|
+
if (!options.silent) {
|
|
52
|
+
console.warn(`[Proliferate] ${message}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function detectRelease() {
|
|
56
|
+
const envVars = [
|
|
57
|
+
"PROLIFERATE_RELEASE",
|
|
58
|
+
"GITHUB_SHA",
|
|
59
|
+
"VERCEL_GIT_COMMIT_SHA",
|
|
60
|
+
"CF_PAGES_COMMIT_SHA",
|
|
61
|
+
"RENDER_GIT_COMMIT",
|
|
62
|
+
"RAILWAY_GIT_COMMIT_SHA",
|
|
63
|
+
"GITLAB_CI_COMMIT_SHA",
|
|
64
|
+
"CIRCLE_SHA1",
|
|
65
|
+
"COMMIT_SHA",
|
|
66
|
+
"GIT_COMMIT"
|
|
67
|
+
];
|
|
68
|
+
for (const envVar of envVars) {
|
|
69
|
+
const value = process.env[envVar];
|
|
70
|
+
if (value) {
|
|
71
|
+
return value;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
const sha = (0, import_child_process.execSync)("git rev-parse HEAD", { encoding: "utf8" }).trim();
|
|
76
|
+
return sha;
|
|
77
|
+
} catch {
|
|
78
|
+
}
|
|
79
|
+
return `build-${Date.now()}`;
|
|
80
|
+
}
|
|
81
|
+
async function createRelease(options) {
|
|
82
|
+
const form = new import_form_data.default();
|
|
83
|
+
form.append("version", options.release);
|
|
84
|
+
form.append("url_prefix", options.urlPrefix || "~/_next/");
|
|
85
|
+
const response = await fetch(`${options.endpoint}/releases`, {
|
|
86
|
+
method: "POST",
|
|
87
|
+
headers: {
|
|
88
|
+
Authorization: `Bearer ${options.apiKey}`
|
|
89
|
+
},
|
|
90
|
+
body: form
|
|
91
|
+
});
|
|
92
|
+
if (!response.ok) {
|
|
93
|
+
const text = await response.text();
|
|
94
|
+
throw new Error(`Failed to create release: ${response.status} ${text}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async function uploadSourceMap(options, url, content) {
|
|
98
|
+
const form = new import_form_data.default();
|
|
99
|
+
form.append("release", options.release);
|
|
100
|
+
form.append("url", url);
|
|
101
|
+
form.append("url_prefix", options.urlPrefix || "~/_next/");
|
|
102
|
+
form.append("sourcemap", Buffer.from(content), {
|
|
103
|
+
filename: "sourcemap.map",
|
|
104
|
+
contentType: "application/json"
|
|
105
|
+
});
|
|
106
|
+
const response = await fetch(`${options.endpoint}/sourcemaps`, {
|
|
107
|
+
method: "POST",
|
|
108
|
+
headers: {
|
|
109
|
+
Authorization: `Bearer ${options.apiKey}`
|
|
110
|
+
},
|
|
111
|
+
body: form
|
|
112
|
+
});
|
|
113
|
+
if (!response.ok) {
|
|
114
|
+
const text = await response.text();
|
|
115
|
+
throw new Error(`${response.status} ${text}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async function finalizeRelease(options) {
|
|
119
|
+
const response = await fetch(
|
|
120
|
+
`${options.endpoint}/releases/${encodeURIComponent(options.release)}/finalize`,
|
|
121
|
+
{
|
|
122
|
+
method: "POST",
|
|
123
|
+
headers: {
|
|
124
|
+
Authorization: `Bearer ${options.apiKey}`
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
);
|
|
128
|
+
if (!response.ok) {
|
|
129
|
+
const text = await response.text();
|
|
130
|
+
warn(options, `Failed to finalize release: ${response.status} ${text}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function findMapFiles(dir, exclude = ["node_modules"]) {
|
|
134
|
+
const mapFiles = [];
|
|
135
|
+
function scan(currentDir) {
|
|
136
|
+
if (!fs.existsSync(currentDir)) return;
|
|
137
|
+
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
138
|
+
for (const entry of entries) {
|
|
139
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
140
|
+
if (entry.isDirectory()) {
|
|
141
|
+
const shouldExclude = exclude.some((pattern) => {
|
|
142
|
+
if (pattern.includes("*")) {
|
|
143
|
+
const regex = new RegExp(pattern.replace(/\*/g, ".*"));
|
|
144
|
+
return regex.test(entry.name);
|
|
145
|
+
}
|
|
146
|
+
return entry.name === pattern || fullPath.includes(pattern);
|
|
147
|
+
});
|
|
148
|
+
if (!shouldExclude) {
|
|
149
|
+
scan(fullPath);
|
|
150
|
+
}
|
|
151
|
+
} else if (entry.name.endsWith(".map")) {
|
|
152
|
+
mapFiles.push(fullPath);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
scan(dir);
|
|
157
|
+
return mapFiles;
|
|
158
|
+
}
|
|
159
|
+
async function uploadSourceMaps(options) {
|
|
160
|
+
const release = options.release || detectRelease();
|
|
161
|
+
const outDir = options.outDir || ".next";
|
|
162
|
+
const urlPrefix = options.urlPrefix || "~/_next/";
|
|
163
|
+
const exclude = options.exclude || ["node_modules"];
|
|
164
|
+
const fullOptions = { ...options, release, urlPrefix };
|
|
165
|
+
const outputPath = path.resolve(process.cwd(), outDir);
|
|
166
|
+
const staticDir = path.join(outputPath, "static");
|
|
167
|
+
const mapFiles = findMapFiles(staticDir, exclude);
|
|
168
|
+
if (mapFiles.length === 0) {
|
|
169
|
+
warn(fullOptions, "No source maps found to upload");
|
|
170
|
+
warn(fullOptions, `Looked in: ${staticDir}`);
|
|
171
|
+
warn(
|
|
172
|
+
fullOptions,
|
|
173
|
+
"Make sure productionBrowserSourceMaps is enabled in next.config.js"
|
|
174
|
+
);
|
|
175
|
+
return { uploaded: 0, failed: 0 };
|
|
176
|
+
}
|
|
177
|
+
log(fullOptions, `Found ${mapFiles.length} source map(s) to upload`);
|
|
178
|
+
log(fullOptions, `Release: ${release}`);
|
|
179
|
+
if (!options.dryRun) {
|
|
180
|
+
try {
|
|
181
|
+
await createRelease(fullOptions);
|
|
182
|
+
log(fullOptions, "Created release");
|
|
183
|
+
} catch (error) {
|
|
184
|
+
warn(fullOptions, `Failed to create release: ${error}`);
|
|
185
|
+
return { uploaded: 0, failed: mapFiles.length };
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
let uploaded = 0;
|
|
189
|
+
let failed = 0;
|
|
190
|
+
for (const mapPath of mapFiles) {
|
|
191
|
+
const relativePath = path.relative(staticDir, mapPath);
|
|
192
|
+
const minifiedFilename = relativePath.replace(".map", "");
|
|
193
|
+
const url = urlPrefix + "static/" + minifiedFilename;
|
|
194
|
+
if (options.dryRun) {
|
|
195
|
+
log(fullOptions, `[Dry Run] Would upload: ${url}`);
|
|
196
|
+
uploaded++;
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
try {
|
|
200
|
+
const mapContent = fs.readFileSync(mapPath, "utf8");
|
|
201
|
+
await uploadSourceMap(fullOptions, url, mapContent);
|
|
202
|
+
log(fullOptions, `Uploaded: ${url}`);
|
|
203
|
+
uploaded++;
|
|
204
|
+
if (options.deleteAfterUpload) {
|
|
205
|
+
fs.unlinkSync(mapPath);
|
|
206
|
+
log(fullOptions, `Deleted: ${relativePath}`);
|
|
207
|
+
}
|
|
208
|
+
} catch (error) {
|
|
209
|
+
warn(fullOptions, `Failed to upload ${relativePath}: ${error}`);
|
|
210
|
+
failed++;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (!options.dryRun && uploaded > 0) {
|
|
214
|
+
await finalizeRelease(fullOptions);
|
|
215
|
+
log(fullOptions, "Finalized release");
|
|
216
|
+
}
|
|
217
|
+
log(
|
|
218
|
+
fullOptions,
|
|
219
|
+
`Source map upload complete: ${uploaded} uploaded, ${failed} failed`
|
|
220
|
+
);
|
|
221
|
+
return { uploaded, failed };
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// src/index.ts
|
|
225
|
+
function detectRelease2() {
|
|
226
|
+
const envVars = [
|
|
227
|
+
"PROLIFERATE_RELEASE",
|
|
228
|
+
"GITHUB_SHA",
|
|
229
|
+
"VERCEL_GIT_COMMIT_SHA",
|
|
230
|
+
"CF_PAGES_COMMIT_SHA",
|
|
231
|
+
"RENDER_GIT_COMMIT",
|
|
232
|
+
"RAILWAY_GIT_COMMIT_SHA",
|
|
233
|
+
"GITLAB_CI_COMMIT_SHA",
|
|
234
|
+
"CIRCLE_SHA1",
|
|
235
|
+
"COMMIT_SHA",
|
|
236
|
+
"GIT_COMMIT"
|
|
237
|
+
];
|
|
238
|
+
for (const envVar of envVars) {
|
|
239
|
+
const value = process.env[envVar];
|
|
240
|
+
if (value) {
|
|
241
|
+
return value;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
try {
|
|
245
|
+
const sha = (0, import_child_process2.execSync)("git rev-parse HEAD", { encoding: "utf8" }).trim();
|
|
246
|
+
return sha;
|
|
247
|
+
} catch {
|
|
248
|
+
}
|
|
249
|
+
return `build-${Date.now()}`;
|
|
250
|
+
}
|
|
251
|
+
function log2(options, message) {
|
|
252
|
+
if (!options.silent) {
|
|
253
|
+
console.log(`[Proliferate] ${message}`);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
function withProliferate(nextConfig = {}, options = {}) {
|
|
257
|
+
const release = options.release || process.env.PROLIFERATE_RELEASE || detectRelease2();
|
|
258
|
+
const enableSourceMaps = options.enableSourceMaps !== false;
|
|
259
|
+
log2(options, `Using release: ${release}`);
|
|
260
|
+
return {
|
|
261
|
+
...nextConfig,
|
|
262
|
+
// Inject release as public environment variable
|
|
263
|
+
env: {
|
|
264
|
+
...nextConfig.env,
|
|
265
|
+
NEXT_PUBLIC_PROLIFERATE_RELEASE: release
|
|
266
|
+
},
|
|
267
|
+
// Enable source maps in production builds
|
|
268
|
+
...enableSourceMaps && {
|
|
269
|
+
productionBrowserSourceMaps: true
|
|
270
|
+
},
|
|
271
|
+
// Extend webpack config
|
|
272
|
+
webpack(config, context) {
|
|
273
|
+
const { webpack } = context;
|
|
274
|
+
config.plugins.push(
|
|
275
|
+
new webpack.DefinePlugin({
|
|
276
|
+
__PROLIFERATE_RELEASE__: JSON.stringify(release)
|
|
277
|
+
})
|
|
278
|
+
);
|
|
279
|
+
if (typeof nextConfig.webpack === "function") {
|
|
280
|
+
return nextConfig.webpack(config, context);
|
|
281
|
+
}
|
|
282
|
+
return config;
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
var index_default = withProliferate;
|
|
287
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
288
|
+
0 && (module.exports = {
|
|
289
|
+
uploadSourceMaps,
|
|
290
|
+
withProliferate
|
|
291
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {
|
|
2
|
+
uploadSourceMaps
|
|
3
|
+
} from "./chunk-PPXY4MSU.mjs";
|
|
4
|
+
|
|
5
|
+
// src/index.ts
|
|
6
|
+
import { execSync } from "child_process";
|
|
7
|
+
function detectRelease() {
|
|
8
|
+
const envVars = [
|
|
9
|
+
"PROLIFERATE_RELEASE",
|
|
10
|
+
"GITHUB_SHA",
|
|
11
|
+
"VERCEL_GIT_COMMIT_SHA",
|
|
12
|
+
"CF_PAGES_COMMIT_SHA",
|
|
13
|
+
"RENDER_GIT_COMMIT",
|
|
14
|
+
"RAILWAY_GIT_COMMIT_SHA",
|
|
15
|
+
"GITLAB_CI_COMMIT_SHA",
|
|
16
|
+
"CIRCLE_SHA1",
|
|
17
|
+
"COMMIT_SHA",
|
|
18
|
+
"GIT_COMMIT"
|
|
19
|
+
];
|
|
20
|
+
for (const envVar of envVars) {
|
|
21
|
+
const value = process.env[envVar];
|
|
22
|
+
if (value) {
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const sha = execSync("git rev-parse HEAD", { encoding: "utf8" }).trim();
|
|
28
|
+
return sha;
|
|
29
|
+
} catch {
|
|
30
|
+
}
|
|
31
|
+
return `build-${Date.now()}`;
|
|
32
|
+
}
|
|
33
|
+
function log(options, message) {
|
|
34
|
+
if (!options.silent) {
|
|
35
|
+
console.log(`[Proliferate] ${message}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function withProliferate(nextConfig = {}, options = {}) {
|
|
39
|
+
const release = options.release || process.env.PROLIFERATE_RELEASE || detectRelease();
|
|
40
|
+
const enableSourceMaps = options.enableSourceMaps !== false;
|
|
41
|
+
log(options, `Using release: ${release}`);
|
|
42
|
+
return {
|
|
43
|
+
...nextConfig,
|
|
44
|
+
// Inject release as public environment variable
|
|
45
|
+
env: {
|
|
46
|
+
...nextConfig.env,
|
|
47
|
+
NEXT_PUBLIC_PROLIFERATE_RELEASE: release
|
|
48
|
+
},
|
|
49
|
+
// Enable source maps in production builds
|
|
50
|
+
...enableSourceMaps && {
|
|
51
|
+
productionBrowserSourceMaps: true
|
|
52
|
+
},
|
|
53
|
+
// Extend webpack config
|
|
54
|
+
webpack(config, context) {
|
|
55
|
+
const { webpack } = context;
|
|
56
|
+
config.plugins.push(
|
|
57
|
+
new webpack.DefinePlugin({
|
|
58
|
+
__PROLIFERATE_RELEASE__: JSON.stringify(release)
|
|
59
|
+
})
|
|
60
|
+
);
|
|
61
|
+
if (typeof nextConfig.webpack === "function") {
|
|
62
|
+
return nextConfig.webpack(config, context);
|
|
63
|
+
}
|
|
64
|
+
return config;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
var index_default = withProliferate;
|
|
69
|
+
export {
|
|
70
|
+
index_default as default,
|
|
71
|
+
uploadSourceMaps,
|
|
72
|
+
withProliferate
|
|
73
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@proliferate_ai/nextjs-plugin",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Proliferate integration for Next.js - source map upload and release tracking",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"proliferate-nextjs": "./dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.mjs",
|
|
15
|
+
"require": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsup src/index.ts src/cli.ts --format cjs,esm --dts --clean",
|
|
23
|
+
"dev": "tsup src/index.ts src/cli.ts --format cjs,esm --dts --watch",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"test:watch": "vitest",
|
|
26
|
+
"typecheck": "tsc --noEmit"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"nextjs",
|
|
30
|
+
"next",
|
|
31
|
+
"sourcemaps",
|
|
32
|
+
"error-monitoring",
|
|
33
|
+
"proliferate"
|
|
34
|
+
],
|
|
35
|
+
"author": "",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "https://github.com/YOUR_ORG/proliferation.git",
|
|
40
|
+
"directory": "sdks/nextjs-plugin"
|
|
41
|
+
},
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public",
|
|
44
|
+
"provenance": true
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"form-data": "^4.0.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/node": "^20.19.27",
|
|
51
|
+
"next": "^14.0.0 || ^15.0.0",
|
|
52
|
+
"tsup": "^8.0.0",
|
|
53
|
+
"typescript": "^5.0.0",
|
|
54
|
+
"vitest": "^4.0.16"
|
|
55
|
+
},
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"next": ">=12.0.0"
|
|
58
|
+
},
|
|
59
|
+
"engines": {
|
|
60
|
+
"node": ">=18"
|
|
61
|
+
}
|
|
62
|
+
}
|