@utoo/pack 0.0.1-alpha.1 → 0.0.1-alpha.13
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/cjs/binding.d.ts +153 -100
- package/cjs/build.d.ts +2 -0
- package/cjs/build.js +53 -0
- package/cjs/dev.d.ts +42 -0
- package/cjs/dev.js +355 -0
- package/cjs/hmr.d.ts +80 -0
- package/cjs/hmr.js +285 -0
- package/cjs/index.d.ts +2 -1
- package/cjs/index.js +5 -73
- package/cjs/mkcert.d.ts +7 -0
- package/cjs/mkcert.js +183 -0
- package/cjs/project.d.ts +3 -3
- package/cjs/project.js +4 -11
- package/cjs/types.d.ts +16 -2
- package/cjs/util.d.ts +12 -1
- package/cjs/util.js +102 -1
- package/config_schema.json +710 -0
- package/esm/binding.d.ts +153 -100
- package/esm/build.d.ts +2 -0
- package/esm/build.js +50 -0
- package/esm/dev.d.ts +42 -0
- package/esm/dev.js +339 -0
- package/esm/hmr.d.ts +80 -0
- package/esm/hmr.js +278 -0
- package/esm/index.d.ts +2 -1
- package/esm/index.js +2 -69
- package/esm/mkcert.d.ts +7 -0
- package/esm/mkcert.js +176 -0
- package/esm/project.d.ts +3 -3
- package/esm/project.js +2 -9
- package/esm/types.d.ts +16 -2
- package/esm/util.d.ts +12 -1
- package/esm/util.js +98 -1
- package/package.json +38 -23
- package/bin/cli.js +0 -9
- package/global.d.ts +0 -10
package/cjs/hmr.js
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.FAST_REFRESH_RUNTIME_RELOAD = void 0;
|
|
7
|
+
exports.createHotReloader = createHotReloader;
|
|
8
|
+
const nanoid_1 = require("nanoid");
|
|
9
|
+
const ws_1 = __importDefault(require("ws"));
|
|
10
|
+
const project_1 = require("./project");
|
|
11
|
+
const util_1 = require("./util");
|
|
12
|
+
const wsServer = new ws_1.default.Server({ noServer: true });
|
|
13
|
+
const sessionId = Math.floor(Number.MAX_SAFE_INTEGER * Math.random());
|
|
14
|
+
exports.FAST_REFRESH_RUNTIME_RELOAD = "Fast Refresh had to perform a full reload due to a runtime error.";
|
|
15
|
+
async function createHotReloader(bundleOptions, projectPath, rootPath) {
|
|
16
|
+
var _a;
|
|
17
|
+
const createProject = (0, project_1.projectFactory)();
|
|
18
|
+
const project = await createProject({
|
|
19
|
+
processEnv: (_a = bundleOptions.processEnv) !== null && _a !== void 0 ? _a : {},
|
|
20
|
+
processDefineEnv: (0, util_1.createDefineEnv)({
|
|
21
|
+
config: bundleOptions.config,
|
|
22
|
+
dev: true,
|
|
23
|
+
optionDefineEnv: bundleOptions.processDefineEnv,
|
|
24
|
+
}),
|
|
25
|
+
watch: {
|
|
26
|
+
enable: true,
|
|
27
|
+
},
|
|
28
|
+
dev: true,
|
|
29
|
+
buildId: (0, nanoid_1.nanoid)(),
|
|
30
|
+
config: {
|
|
31
|
+
...bundleOptions.config,
|
|
32
|
+
mode: "development",
|
|
33
|
+
optimization: {
|
|
34
|
+
...bundleOptions.config.optimization,
|
|
35
|
+
minify: false,
|
|
36
|
+
moduleIds: "named",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
projectPath: projectPath || process.cwd(),
|
|
40
|
+
rootPath: rootPath || projectPath || process.cwd(),
|
|
41
|
+
}, {
|
|
42
|
+
persistentCaching: true,
|
|
43
|
+
});
|
|
44
|
+
const entrypointsSubscription = project.entrypointsSubscribe();
|
|
45
|
+
let currentEntriesHandlingResolve;
|
|
46
|
+
let currentEntriesHandling = new Promise((resolve) => (currentEntriesHandlingResolve = resolve));
|
|
47
|
+
let hmrEventHappened = false;
|
|
48
|
+
let hmrHash = 0;
|
|
49
|
+
const clients = new Set();
|
|
50
|
+
const clientStates = new WeakMap();
|
|
51
|
+
function sendToClient(client, payload) {
|
|
52
|
+
client.send(JSON.stringify(payload));
|
|
53
|
+
}
|
|
54
|
+
function sendEnqueuedMessages() {
|
|
55
|
+
for (const client of clients) {
|
|
56
|
+
const state = clientStates.get(client);
|
|
57
|
+
if (!state) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
for (const payload of state.hmrPayloads.values()) {
|
|
61
|
+
sendToClient(client, payload);
|
|
62
|
+
}
|
|
63
|
+
state.hmrPayloads.clear();
|
|
64
|
+
if (state.turbopackUpdates.length > 0) {
|
|
65
|
+
sendToClient(client, {
|
|
66
|
+
action: "turbopack-message" /* HMR_ACTIONS_SENT_TO_BROWSER.TURBOPACK_MESSAGE */,
|
|
67
|
+
data: state.turbopackUpdates,
|
|
68
|
+
});
|
|
69
|
+
state.turbopackUpdates.length = 0;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const sendEnqueuedMessagesDebounce = (0, util_1.debounce)(sendEnqueuedMessages, 2);
|
|
74
|
+
function sendTurbopackMessage(payload) {
|
|
75
|
+
var _a;
|
|
76
|
+
payload.diagnostics = [];
|
|
77
|
+
payload.issues = [];
|
|
78
|
+
for (const client of clients) {
|
|
79
|
+
(_a = clientStates.get(client)) === null || _a === void 0 ? void 0 : _a.turbopackUpdates.push(payload);
|
|
80
|
+
}
|
|
81
|
+
hmrEventHappened = true;
|
|
82
|
+
sendEnqueuedMessagesDebounce();
|
|
83
|
+
}
|
|
84
|
+
async function subscribeToHmrEvents(client, id) {
|
|
85
|
+
const state = clientStates.get(client);
|
|
86
|
+
if (!state || state.subscriptions.has(id)) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const subscription = project.hmrEvents(id);
|
|
90
|
+
state.subscriptions.set(id, subscription);
|
|
91
|
+
// The subscription will always emit once, which is the initial
|
|
92
|
+
// computation. This is not a change, so swallow it.
|
|
93
|
+
try {
|
|
94
|
+
await subscription.next();
|
|
95
|
+
for await (const data of subscription) {
|
|
96
|
+
(0, util_1.processIssues)(data, true, true);
|
|
97
|
+
if (data.type !== "issues") {
|
|
98
|
+
sendTurbopackMessage(data);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
// The client might be using an HMR session from a previous server, tell them
|
|
104
|
+
// to fully reload the page to resolve the issue. We can't use
|
|
105
|
+
// `hotReloader.send` since that would force every connected client to
|
|
106
|
+
// reload, only this client is out of date.
|
|
107
|
+
const reloadAction = {
|
|
108
|
+
action: "reload" /* HMR_ACTIONS_SENT_TO_BROWSER.RELOAD */,
|
|
109
|
+
data: `error in HMR event subscription for ${id}: ${e}`,
|
|
110
|
+
};
|
|
111
|
+
sendToClient(client, reloadAction);
|
|
112
|
+
client.close();
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function unsubscribeFromHmrEvents(client, id) {
|
|
117
|
+
const state = clientStates.get(client);
|
|
118
|
+
if (!state) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const subscription = state.subscriptions.get(id);
|
|
122
|
+
subscription === null || subscription === void 0 ? void 0 : subscription.return();
|
|
123
|
+
}
|
|
124
|
+
async function handleEntrypointsSubscription() {
|
|
125
|
+
for await (const entrypoints of entrypointsSubscription) {
|
|
126
|
+
if (!currentEntriesHandlingResolve) {
|
|
127
|
+
currentEntriesHandling = new Promise(
|
|
128
|
+
// eslint-disable-next-line no-loop-func
|
|
129
|
+
(resolve) => (currentEntriesHandlingResolve = resolve));
|
|
130
|
+
}
|
|
131
|
+
await Promise.all(entrypoints.apps.map((l) => l.writeToDisk().then((res) => (0, util_1.processIssues)(res, true, true))));
|
|
132
|
+
currentEntriesHandlingResolve();
|
|
133
|
+
currentEntriesHandlingResolve = undefined;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const hotReloader = {
|
|
137
|
+
turbopackProject: project,
|
|
138
|
+
serverStats: null,
|
|
139
|
+
onHMR(req, socket, head, onUpgrade) {
|
|
140
|
+
wsServer.handleUpgrade(req, socket, head, (client) => {
|
|
141
|
+
onUpgrade === null || onUpgrade === void 0 ? void 0 : onUpgrade(client);
|
|
142
|
+
const subscriptions = new Map();
|
|
143
|
+
clients.add(client);
|
|
144
|
+
clientStates.set(client, {
|
|
145
|
+
hmrPayloads: new Map(),
|
|
146
|
+
turbopackUpdates: [],
|
|
147
|
+
subscriptions,
|
|
148
|
+
});
|
|
149
|
+
client.on("close", () => {
|
|
150
|
+
var _a;
|
|
151
|
+
// Remove active subscriptions
|
|
152
|
+
for (const subscription of subscriptions.values()) {
|
|
153
|
+
(_a = subscription.return) === null || _a === void 0 ? void 0 : _a.call(subscription);
|
|
154
|
+
}
|
|
155
|
+
clientStates.delete(client);
|
|
156
|
+
clients.delete(client);
|
|
157
|
+
});
|
|
158
|
+
client.addEventListener("message", ({ data }) => {
|
|
159
|
+
const parsedData = JSON.parse(typeof data !== "string" ? data.toString() : data);
|
|
160
|
+
// messages
|
|
161
|
+
switch (parsedData.event) {
|
|
162
|
+
case "client-error": // { errorCount, clientId }
|
|
163
|
+
case "client-warning": // { warningCount, clientId }
|
|
164
|
+
case "client-success": // { clientId }
|
|
165
|
+
case "client-full-reload": // { stackTrace, hadRuntimeError }
|
|
166
|
+
const { hadRuntimeError, dependencyChain } = parsedData;
|
|
167
|
+
if (hadRuntimeError) {
|
|
168
|
+
console.warn(exports.FAST_REFRESH_RUNTIME_RELOAD);
|
|
169
|
+
}
|
|
170
|
+
if (Array.isArray(dependencyChain) &&
|
|
171
|
+
typeof dependencyChain[0] === "string") {
|
|
172
|
+
const cleanedModulePath = dependencyChain[0]
|
|
173
|
+
.replace(/^\[project\]/, ".")
|
|
174
|
+
.replace(/ \[.*\] \(.*\)$/, "");
|
|
175
|
+
console.warn(`Fast Refresh had to perform a full reload when ${cleanedModulePath} changed.`);
|
|
176
|
+
}
|
|
177
|
+
break;
|
|
178
|
+
default:
|
|
179
|
+
// Might be a Turbopack message...
|
|
180
|
+
if (!parsedData.type) {
|
|
181
|
+
throw new Error(`unrecognized HMR message "${data}"`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// Turbopack messages
|
|
185
|
+
switch (parsedData.type) {
|
|
186
|
+
case "turbopack-subscribe":
|
|
187
|
+
subscribeToHmrEvents(client, parsedData.path);
|
|
188
|
+
break;
|
|
189
|
+
case "turbopack-unsubscribe":
|
|
190
|
+
unsubscribeFromHmrEvents(client, parsedData.path);
|
|
191
|
+
break;
|
|
192
|
+
default:
|
|
193
|
+
if (!parsedData.event) {
|
|
194
|
+
throw new Error(`unrecognized Turbopack HMR message "${data}"`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
const turbopackConnected = {
|
|
199
|
+
action: "turbopack-connected" /* HMR_ACTIONS_SENT_TO_BROWSER.TURBOPACK_CONNECTED */,
|
|
200
|
+
data: { sessionId },
|
|
201
|
+
};
|
|
202
|
+
sendToClient(client, turbopackConnected);
|
|
203
|
+
const errors = [];
|
|
204
|
+
(async function () {
|
|
205
|
+
const sync = {
|
|
206
|
+
action: "sync" /* HMR_ACTIONS_SENT_TO_BROWSER.SYNC */,
|
|
207
|
+
errors,
|
|
208
|
+
warnings: [],
|
|
209
|
+
hash: "",
|
|
210
|
+
};
|
|
211
|
+
sendToClient(client, sync);
|
|
212
|
+
})();
|
|
213
|
+
});
|
|
214
|
+
},
|
|
215
|
+
send(action) {
|
|
216
|
+
const payload = JSON.stringify(action);
|
|
217
|
+
for (const client of clients) {
|
|
218
|
+
client.send(payload);
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
setHmrServerError(_error) {
|
|
222
|
+
// Not implemented yet.
|
|
223
|
+
},
|
|
224
|
+
clearHmrServerError() {
|
|
225
|
+
// Not implemented yet.
|
|
226
|
+
},
|
|
227
|
+
async start() { },
|
|
228
|
+
async buildFallbackError() {
|
|
229
|
+
// Not implemented yet.
|
|
230
|
+
},
|
|
231
|
+
close() {
|
|
232
|
+
for (const wsClient of clients) {
|
|
233
|
+
// it's okay to not cleanly close these websocket connections, this is dev
|
|
234
|
+
wsClient.terminate();
|
|
235
|
+
}
|
|
236
|
+
clients.clear();
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
handleEntrypointsSubscription().catch((err) => {
|
|
240
|
+
console.error(err);
|
|
241
|
+
process.exit(1);
|
|
242
|
+
});
|
|
243
|
+
// Write empty manifests
|
|
244
|
+
await currentEntriesHandling;
|
|
245
|
+
async function handleProjectUpdates() {
|
|
246
|
+
for await (const updateMessage of project.updateInfoSubscribe(30)) {
|
|
247
|
+
switch (updateMessage.updateType) {
|
|
248
|
+
case "start": {
|
|
249
|
+
hotReloader.send({ action: "building" /* HMR_ACTIONS_SENT_TO_BROWSER.BUILDING */ });
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
case "end": {
|
|
253
|
+
sendEnqueuedMessages();
|
|
254
|
+
const errors = new Map();
|
|
255
|
+
for (const client of clients) {
|
|
256
|
+
const state = clientStates.get(client);
|
|
257
|
+
if (!state) {
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
const clientErrors = new Map(errors);
|
|
261
|
+
sendToClient(client, {
|
|
262
|
+
action: "built" /* HMR_ACTIONS_SENT_TO_BROWSER.BUILT */,
|
|
263
|
+
hash: String(++hmrHash),
|
|
264
|
+
errors: [...clientErrors.values()],
|
|
265
|
+
warnings: [],
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
if (hmrEventHappened) {
|
|
269
|
+
const time = updateMessage.value.duration;
|
|
270
|
+
const timeMessage = time > 2000 ? `${Math.round(time / 100) / 10}s` : `${time}ms`;
|
|
271
|
+
console.log(`Compiled in ${timeMessage}`);
|
|
272
|
+
hmrEventHappened = false;
|
|
273
|
+
}
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
default:
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
handleProjectUpdates().catch((err) => {
|
|
281
|
+
console.error(err);
|
|
282
|
+
process.exit(1);
|
|
283
|
+
});
|
|
284
|
+
return hotReloader;
|
|
285
|
+
}
|
package/cjs/index.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { build } from "./build";
|
|
2
|
+
export { serve } from "./dev";
|
package/cjs/index.js
CHANGED
|
@@ -1,75 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.build =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const util_1 = require("./util");
|
|
12
|
-
const xcodeProfile_1 = require("./xcodeProfile");
|
|
13
|
-
// ref:
|
|
14
|
-
// https://github.com/vercel/next.js/pull/51883
|
|
15
|
-
function blockStdout() {
|
|
16
|
-
// rust needs stdout to be blocking, otherwise it will throw an error (on macOS at least) when writing a lot of data (logs) to it
|
|
17
|
-
// see https://github.com/napi-rs/napi-rs/issues/1630
|
|
18
|
-
// and https://github.com/nodejs/node/blob/main/doc/api/process.md#a-note-on-process-io
|
|
19
|
-
if (process.stdout._handle != null) {
|
|
20
|
-
process.stdout._handle.setBlocking(true);
|
|
21
|
-
}
|
|
22
|
-
if (process.stderr._handle != null) {
|
|
23
|
-
process.stderr._handle.setBlocking(true);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
async function build(dir) {
|
|
27
|
-
var _a, _b, _c, _d;
|
|
28
|
-
blockStdout();
|
|
29
|
-
if (process.env.XCODE_PROFILE) {
|
|
30
|
-
await (0, xcodeProfile_1.xcodeProfilingReady)();
|
|
31
|
-
}
|
|
32
|
-
const cwd = dir || process.cwd();
|
|
33
|
-
const projectOptions = JSON.parse(fs_1.default.readFileSync(path_1.default.join(cwd, "project_options.json"), {
|
|
34
|
-
encoding: "utf-8",
|
|
35
|
-
}));
|
|
36
|
-
const createProject = (0, project_1.projectFactory)();
|
|
37
|
-
const project = await createProject({
|
|
38
|
-
processEnv: (_a = projectOptions.processEnv) !== null && _a !== void 0 ? _a : {},
|
|
39
|
-
processDefineEnv: (_b = projectOptions.processDefineEnv) !== null && _b !== void 0 ? _b : {
|
|
40
|
-
client: [],
|
|
41
|
-
nodejs: [],
|
|
42
|
-
edge: [],
|
|
43
|
-
},
|
|
44
|
-
watch: (_c = projectOptions.watch) !== null && _c !== void 0 ? _c : {
|
|
45
|
-
enable: false,
|
|
46
|
-
},
|
|
47
|
-
dev: (_d = projectOptions.dev) !== null && _d !== void 0 ? _d : false,
|
|
48
|
-
buildId: (0, nanoid_1.nanoid)(),
|
|
49
|
-
config: projectOptions.config,
|
|
50
|
-
rootPath: path_1.default.resolve(cwd, projectOptions.rootPath),
|
|
51
|
-
projectPath: path_1.default.resolve(cwd, projectOptions.projectPath),
|
|
52
|
-
}, {
|
|
53
|
-
persistentCaching: false,
|
|
54
|
-
});
|
|
55
|
-
const entrypoints = await project.writeAllEntrypointsToDisk();
|
|
56
|
-
const topLevelErrors = [];
|
|
57
|
-
const topLevelWarnings = [];
|
|
58
|
-
for (const issue of entrypoints.issues) {
|
|
59
|
-
if (issue.severity === "error" || issue.severity === "fatal") {
|
|
60
|
-
topLevelErrors.push((0, util_1.formatIssue)(issue));
|
|
61
|
-
}
|
|
62
|
-
else if ((0, util_1.isRelevantWarning)(issue)) {
|
|
63
|
-
topLevelWarnings.push((0, util_1.formatIssue)(issue));
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
if (topLevelWarnings.length > 0) {
|
|
67
|
-
console.warn(`Turbopack build encountered ${topLevelWarnings.length} warnings:\n${topLevelWarnings.join("\n")}`);
|
|
68
|
-
}
|
|
69
|
-
if (topLevelErrors.length > 0) {
|
|
70
|
-
throw new Error(`Turbopack build failed with ${topLevelErrors.length} errors:\n${topLevelErrors.join("\n")}`);
|
|
71
|
-
}
|
|
72
|
-
await project.shutdown();
|
|
73
|
-
// TODO: Maybe run tasks in worker is a better way, see
|
|
74
|
-
// https://github.com/vercel/next.js/blob/512d8283054407ab92b2583ecce3b253c3be7b85/packages/next/src/lib/worker.ts
|
|
75
|
-
}
|
|
3
|
+
exports.serve = exports.build = void 0;
|
|
4
|
+
var build_1 = require("./build");
|
|
5
|
+
Object.defineProperty(exports, "build", { enumerable: true, get: function () { return build_1.build; } });
|
|
6
|
+
var dev_1 = require("./dev");
|
|
7
|
+
Object.defineProperty(exports, "serve", { enumerable: true, get: function () { return dev_1.serve; } });
|
package/cjs/mkcert.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface SelfSignedCertificate {
|
|
2
|
+
key: string;
|
|
3
|
+
cert: string;
|
|
4
|
+
rootCA?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function createSelfSignedCertificate(host?: string, certDir?: string): Promise<SelfSignedCertificate | undefined>;
|
|
7
|
+
export declare function getCacheDirectory(fileDirectory: string, envPath?: string): string;
|
package/cjs/mkcert.js
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createSelfSignedCertificate = createSelfSignedCertificate;
|
|
7
|
+
exports.getCacheDirectory = getCacheDirectory;
|
|
8
|
+
const node_child_process_1 = require("node:child_process");
|
|
9
|
+
const node_crypto_1 = require("node:crypto");
|
|
10
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
11
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
+
const os_1 = __importDefault(require("os"));
|
|
13
|
+
const { WritableStream } = require("node:stream/web");
|
|
14
|
+
const MKCERT_VERSION = "v1.4.4";
|
|
15
|
+
function getBinaryName() {
|
|
16
|
+
const platform = process.platform;
|
|
17
|
+
const arch = process.arch === "x64" ? "amd64" : process.arch;
|
|
18
|
+
if (platform === "win32") {
|
|
19
|
+
return `mkcert-${MKCERT_VERSION}-windows-${arch}.exe`;
|
|
20
|
+
}
|
|
21
|
+
if (platform === "darwin") {
|
|
22
|
+
return `mkcert-${MKCERT_VERSION}-darwin-${arch}`;
|
|
23
|
+
}
|
|
24
|
+
if (platform === "linux") {
|
|
25
|
+
return `mkcert-${MKCERT_VERSION}-linux-${arch}`;
|
|
26
|
+
}
|
|
27
|
+
throw new Error(`Unsupported platform: ${platform}`);
|
|
28
|
+
}
|
|
29
|
+
async function downloadBinary() {
|
|
30
|
+
try {
|
|
31
|
+
const binaryName = getBinaryName();
|
|
32
|
+
const cacheDirectory = getCacheDirectory("mkcert");
|
|
33
|
+
const binaryPath = node_path_1.default.join(cacheDirectory, binaryName);
|
|
34
|
+
if (node_fs_1.default.existsSync(binaryPath)) {
|
|
35
|
+
return binaryPath;
|
|
36
|
+
}
|
|
37
|
+
const downloadUrl = `https://github.com/FiloSottile/mkcert/releases/download/${MKCERT_VERSION}/${binaryName}`;
|
|
38
|
+
await node_fs_1.default.promises.mkdir(cacheDirectory, { recursive: true });
|
|
39
|
+
console.log(`Downloading mkcert package...`);
|
|
40
|
+
const response = await fetch(downloadUrl);
|
|
41
|
+
if (!response.ok || !response.body) {
|
|
42
|
+
throw new Error(`request failed with status ${response.status}`);
|
|
43
|
+
}
|
|
44
|
+
console.log(`Download response was successful, writing to disk`);
|
|
45
|
+
const binaryWriteStream = node_fs_1.default.createWriteStream(binaryPath);
|
|
46
|
+
await response.body.pipeTo(new WritableStream({
|
|
47
|
+
write(chunk) {
|
|
48
|
+
return new Promise((resolve, reject) => {
|
|
49
|
+
binaryWriteStream.write(chunk, (error) => {
|
|
50
|
+
if (error) {
|
|
51
|
+
reject(error);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
resolve();
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
close() {
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
binaryWriteStream.close((error) => {
|
|
61
|
+
if (error) {
|
|
62
|
+
reject(error);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
resolve();
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
}));
|
|
70
|
+
await node_fs_1.default.promises.chmod(binaryPath, 0o755);
|
|
71
|
+
return binaryPath;
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
console.error("Error downloading mkcert:", err);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async function createSelfSignedCertificate(host, certDir = "certificates") {
|
|
78
|
+
try {
|
|
79
|
+
const binaryPath = await downloadBinary();
|
|
80
|
+
if (!binaryPath)
|
|
81
|
+
throw new Error("missing mkcert binary");
|
|
82
|
+
const resolvedCertDir = node_path_1.default.resolve(process.cwd(), `./${certDir}`);
|
|
83
|
+
await node_fs_1.default.promises.mkdir(resolvedCertDir, {
|
|
84
|
+
recursive: true,
|
|
85
|
+
});
|
|
86
|
+
const keyPath = node_path_1.default.resolve(resolvedCertDir, "localhost-key.pem");
|
|
87
|
+
const certPath = node_path_1.default.resolve(resolvedCertDir, "localhost.pem");
|
|
88
|
+
if (node_fs_1.default.existsSync(keyPath) && node_fs_1.default.existsSync(certPath)) {
|
|
89
|
+
const cert = new node_crypto_1.X509Certificate(node_fs_1.default.readFileSync(certPath));
|
|
90
|
+
const key = node_fs_1.default.readFileSync(keyPath);
|
|
91
|
+
if (cert.checkHost(host !== null && host !== void 0 ? host : "localhost") &&
|
|
92
|
+
cert.checkPrivateKey((0, node_crypto_1.createPrivateKey)(key))) {
|
|
93
|
+
console.log("Using already generated self signed certificate");
|
|
94
|
+
const caLocation = (0, node_child_process_1.execSync)(`"${binaryPath}" -CAROOT`)
|
|
95
|
+
.toString()
|
|
96
|
+
.trim();
|
|
97
|
+
return {
|
|
98
|
+
key: keyPath,
|
|
99
|
+
cert: certPath,
|
|
100
|
+
rootCA: `${caLocation}/rootCA.pem`,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
console.log("Attempting to generate self signed certificate. This may prompt for your password");
|
|
105
|
+
const defaultHosts = ["localhost", "127.0.0.1", "::1"];
|
|
106
|
+
const hosts = host && !defaultHosts.includes(host)
|
|
107
|
+
? [...defaultHosts, host]
|
|
108
|
+
: defaultHosts;
|
|
109
|
+
(0, node_child_process_1.execSync)(`"${binaryPath}" -install -key-file "${keyPath}" -cert-file "${certPath}" ${hosts.join(" ")}`, { stdio: "ignore" });
|
|
110
|
+
const caLocation = (0, node_child_process_1.execSync)(`"${binaryPath}" -CAROOT`).toString().trim();
|
|
111
|
+
if (!node_fs_1.default.existsSync(keyPath) || !node_fs_1.default.existsSync(certPath)) {
|
|
112
|
+
throw new Error("Certificate files not found");
|
|
113
|
+
}
|
|
114
|
+
console.log(`CA Root certificate created in ${caLocation}`);
|
|
115
|
+
console.log(`Certificates created in ${resolvedCertDir}`);
|
|
116
|
+
const gitignorePath = node_path_1.default.resolve(process.cwd(), "./.gitignore");
|
|
117
|
+
if (node_fs_1.default.existsSync(gitignorePath)) {
|
|
118
|
+
const gitignore = await node_fs_1.default.promises.readFile(gitignorePath, "utf8");
|
|
119
|
+
if (!gitignore.includes(certDir)) {
|
|
120
|
+
console.log("Adding certificates to .gitignore");
|
|
121
|
+
await node_fs_1.default.promises.appendFile(gitignorePath, `\n${certDir}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
key: keyPath,
|
|
126
|
+
cert: certPath,
|
|
127
|
+
rootCA: `${caLocation}/rootCA.pem`,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
console.error("Failed to generate self-signed certificate. Falling back to http.", err);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// get platform specific cache directory adapted from playwright's handling
|
|
135
|
+
// https://github.com/microsoft/playwright/blob/7d924470d397975a74a19184c136b3573a974e13/packages/playwright-core/src/utils/registry.ts#L141
|
|
136
|
+
function getCacheDirectory(fileDirectory, envPath) {
|
|
137
|
+
let result;
|
|
138
|
+
if (envPath) {
|
|
139
|
+
result = envPath;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
let systemCacheDirectory;
|
|
143
|
+
if (process.platform === "linux") {
|
|
144
|
+
systemCacheDirectory =
|
|
145
|
+
process.env.XDG_CACHE_HOME || node_path_1.default.join(os_1.default.homedir(), ".cache");
|
|
146
|
+
}
|
|
147
|
+
else if (process.platform === "darwin") {
|
|
148
|
+
systemCacheDirectory = node_path_1.default.join(os_1.default.homedir(), "Library", "Caches");
|
|
149
|
+
}
|
|
150
|
+
else if (process.platform === "win32") {
|
|
151
|
+
systemCacheDirectory =
|
|
152
|
+
process.env.LOCALAPPDATA || node_path_1.default.join(os_1.default.homedir(), "AppData", "Local");
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
/// Attempt to use generic tmp location for un-handled platform
|
|
156
|
+
if (!systemCacheDirectory) {
|
|
157
|
+
for (const dir of [
|
|
158
|
+
node_path_1.default.join(os_1.default.homedir(), ".cache"),
|
|
159
|
+
node_path_1.default.join(os_1.default.tmpdir()),
|
|
160
|
+
]) {
|
|
161
|
+
if (node_fs_1.default.existsSync(dir)) {
|
|
162
|
+
systemCacheDirectory = dir;
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (!systemCacheDirectory) {
|
|
168
|
+
console.error(new Error("Unsupported platform: " + process.platform));
|
|
169
|
+
process.exit(0);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
result = node_path_1.default.join(systemCacheDirectory, fileDirectory);
|
|
173
|
+
}
|
|
174
|
+
if (!node_path_1.default.isAbsolute(result)) {
|
|
175
|
+
// It is important to resolve to the absolute path:
|
|
176
|
+
// - for unzipping to work correctly;
|
|
177
|
+
// - so that registry directory matches between installation and execution.
|
|
178
|
+
// INIT_CWD points to the root of `npm/yarn install` and is probably what
|
|
179
|
+
// the user meant when typing the relative path.
|
|
180
|
+
result = node_path_1.default.resolve(process.env["INIT_CWD"] || process.cwd(), result);
|
|
181
|
+
}
|
|
182
|
+
return result;
|
|
183
|
+
}
|
package/cjs/project.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { HmrIdentifiers, NapiUpdateMessage, NapiWrittenEndpoint, StackFrame } from "./binding";
|
|
1
2
|
import * as binding from "./binding";
|
|
2
|
-
import type { NapiWrittenEndpoint, StackFrame } from "./binding";
|
|
3
3
|
import { ProjectOptions, RawEntrypoints, Update } from "./types";
|
|
4
4
|
export declare class TurbopackInternalError extends Error {
|
|
5
5
|
name: string;
|
|
@@ -32,12 +32,12 @@ export declare function projectFactory(): (options: ProjectOptions, turboEngineO
|
|
|
32
32
|
diagnostics: binding.NapiDiagnostic[];
|
|
33
33
|
}, void, unknown>;
|
|
34
34
|
hmrEvents(identifier: string): AsyncIterableIterator<TurbopackResult<Update>>;
|
|
35
|
-
hmrIdentifiersSubscribe(): AsyncIterableIterator<TurbopackResult<
|
|
35
|
+
hmrIdentifiersSubscribe(): AsyncIterableIterator<TurbopackResult<HmrIdentifiers>>;
|
|
36
36
|
traceSource(stackFrame: StackFrame, currentDirectoryFileUrl: string): Promise<StackFrame | null>;
|
|
37
37
|
getSourceForAsset(filePath: string): Promise<string | null>;
|
|
38
38
|
getSourceMap(filePath: string): Promise<string | null>;
|
|
39
39
|
getSourceMapSync(filePath: string): string | null;
|
|
40
|
-
updateInfoSubscribe(aggregationMs: number): AsyncIterableIterator<TurbopackResult<
|
|
40
|
+
updateInfoSubscribe(aggregationMs: number): AsyncIterableIterator<TurbopackResult<NapiUpdateMessage>>;
|
|
41
41
|
shutdown(): Promise<void>;
|
|
42
42
|
onExit(): Promise<void>;
|
|
43
43
|
}>;
|
package/cjs/project.js
CHANGED
|
@@ -35,9 +35,10 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.TurbopackInternalError = void 0;
|
|
37
37
|
exports.projectFactory = projectFactory;
|
|
38
|
+
const nanoid_1 = require("nanoid");
|
|
38
39
|
const util_1 = require("util");
|
|
39
40
|
const binding = __importStar(require("./binding"));
|
|
40
|
-
const
|
|
41
|
+
const util_2 = require("./util");
|
|
41
42
|
class TurbopackInternalError extends Error {
|
|
42
43
|
constructor(cause) {
|
|
43
44
|
super(cause.message);
|
|
@@ -114,19 +115,11 @@ async function serializeConfig(config) {
|
|
|
114
115
|
}
|
|
115
116
|
return JSON.stringify(configSerializable, null, 2);
|
|
116
117
|
}
|
|
117
|
-
function rustifyEnv(env) {
|
|
118
|
-
return Object.entries(env)
|
|
119
|
-
.filter(([_, value]) => value != null)
|
|
120
|
-
.map(([name, value]) => ({
|
|
121
|
-
name,
|
|
122
|
-
value,
|
|
123
|
-
}));
|
|
124
|
-
}
|
|
125
118
|
async function rustifyPartialProjectOptions(options) {
|
|
126
119
|
return {
|
|
127
120
|
...options,
|
|
128
121
|
config: options.config && (await serializeConfig(options.config)),
|
|
129
|
-
processEnv: options.processEnv && rustifyEnv(options.processEnv),
|
|
122
|
+
processEnv: options.processEnv && (0, util_2.rustifyEnv)(options.processEnv),
|
|
130
123
|
};
|
|
131
124
|
}
|
|
132
125
|
async function rustifyProjectOptions(options) {
|
|
@@ -134,7 +127,7 @@ async function rustifyProjectOptions(options) {
|
|
|
134
127
|
return {
|
|
135
128
|
...options,
|
|
136
129
|
config: await serializeConfig(options.config),
|
|
137
|
-
processEnv: rustifyEnv((_a = options.processEnv) !== null && _a !== void 0 ? _a : {}),
|
|
130
|
+
processEnv: (0, util_2.rustifyEnv)((_a = options.processEnv) !== null && _a !== void 0 ? _a : {}),
|
|
138
131
|
};
|
|
139
132
|
}
|
|
140
133
|
function projectFactory() {
|
package/cjs/types.d.ts
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
import { HmrIdentifiers, NapiIssue, NapiUpdateMessage, NapiWrittenEndpoint, StackFrame } from "./binding";
|
|
1
|
+
import { HmrIdentifiers, NapiDiagnostic, NapiIssue, NapiUpdateMessage, NapiWrittenEndpoint, StackFrame } from "./binding";
|
|
2
|
+
declare global {
|
|
3
|
+
export type TurbopackResult<T = {}> = T & {
|
|
4
|
+
issues: NapiIssue[];
|
|
5
|
+
diagnostics: NapiDiagnostic[];
|
|
6
|
+
};
|
|
7
|
+
export type RefCell = {
|
|
8
|
+
readonly __tag: unique symbol;
|
|
9
|
+
};
|
|
10
|
+
export type ExternalEndpoint = {
|
|
11
|
+
readonly __tag: unique symbol;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
2
14
|
export interface BaseUpdate {
|
|
3
15
|
resource: {
|
|
4
16
|
headers: unknown;
|
|
@@ -93,6 +105,7 @@ export interface ConfigComplete {
|
|
|
93
105
|
type?: "standalone" | "export";
|
|
94
106
|
filename?: string;
|
|
95
107
|
chunkFilename?: string;
|
|
108
|
+
clean?: boolean;
|
|
96
109
|
};
|
|
97
110
|
target?: string;
|
|
98
111
|
sourceMaps?: boolean;
|
|
@@ -202,7 +215,7 @@ export interface ProjectOptions {
|
|
|
202
215
|
pollIntervalMs?: number;
|
|
203
216
|
};
|
|
204
217
|
/**
|
|
205
|
-
* The mode
|
|
218
|
+
* The mode of utoo-pack.
|
|
206
219
|
*/
|
|
207
220
|
dev: boolean;
|
|
208
221
|
/**
|
|
@@ -210,6 +223,7 @@ export interface ProjectOptions {
|
|
|
210
223
|
*/
|
|
211
224
|
buildId: string;
|
|
212
225
|
}
|
|
226
|
+
export type BundleOptions = Omit<ProjectOptions, "rootPath" | "projectPath">;
|
|
213
227
|
export interface Project {
|
|
214
228
|
update(options: Partial<ProjectOptions>): Promise<void>;
|
|
215
229
|
entrypointsSubscribe(): AsyncIterableIterator<TurbopackResult<RawEntrypoints>>;
|