@utoo/pack 1.1.3 → 1.1.4
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/commands/build.d.ts +3 -0
- package/cjs/commands/build.js +165 -0
- package/cjs/commands/dev.d.ts +44 -0
- package/cjs/commands/dev.js +387 -0
- package/cjs/config/readWebpackConfig.d.ts +1 -0
- package/cjs/config/readWebpackConfig.js +14 -0
- package/cjs/config/types.d.ts +1 -0
- package/cjs/config/types.js +17 -0
- package/cjs/config/webpackCompat.d.ts +2 -0
- package/cjs/config/webpackCompat.js +7 -0
- package/cjs/core/hmr.d.ts +80 -0
- package/cjs/core/hmr.js +341 -0
- package/cjs/core/loaderWorkerPool.d.ts +1 -0
- package/cjs/core/loaderWorkerPool.js +35 -0
- package/cjs/core/project.d.ts +43 -0
- package/cjs/core/project.js +291 -0
- package/cjs/core/types.d.ts +94 -0
- package/cjs/core/types.js +2 -0
- package/cjs/plugins/HtmlPlugin.d.ts +9 -0
- package/cjs/plugins/HtmlPlugin.js +116 -0
- package/cjs/utils/common.d.ts +3 -0
- package/cjs/utils/common.js +32 -0
- package/cjs/utils/find-root.d.ts +4 -0
- package/cjs/utils/find-root.js +75 -0
- package/cjs/utils/html-entry.d.ts +2 -0
- package/cjs/utils/html-entry.js +47 -0
- package/cjs/utils/mkcert.d.ts +7 -0
- package/cjs/utils/mkcert.js +183 -0
- package/cjs/utils/print-server-info.d.ts +1 -0
- package/cjs/utils/print-server-info.js +50 -0
- package/cjs/utils/xcodeProfile.d.ts +1 -0
- package/cjs/utils/xcodeProfile.js +16 -0
- package/esm/commands/build.d.ts +3 -0
- package/esm/commands/build.js +129 -0
- package/esm/commands/dev.d.ts +44 -0
- package/esm/commands/dev.js +371 -0
- package/esm/config/readWebpackConfig.d.ts +1 -0
- package/esm/config/readWebpackConfig.js +8 -0
- package/esm/config/types.d.ts +1 -0
- package/esm/config/types.js +1 -0
- package/esm/config/webpackCompat.d.ts +2 -0
- package/esm/config/webpackCompat.js +2 -0
- package/esm/core/hmr.d.ts +80 -0
- package/esm/core/hmr.js +334 -0
- package/esm/core/loaderWorkerPool.d.ts +1 -0
- package/esm/core/loaderWorkerPool.js +32 -0
- package/esm/core/project.d.ts +43 -0
- package/esm/core/project.js +253 -0
- package/esm/core/types.d.ts +94 -0
- package/esm/core/types.js +1 -0
- package/esm/plugins/HtmlPlugin.d.ts +9 -0
- package/esm/plugins/HtmlPlugin.js +109 -0
- package/esm/utils/common.d.ts +3 -0
- package/esm/utils/common.js +18 -0
- package/esm/utils/find-root.d.ts +4 -0
- package/esm/utils/find-root.js +66 -0
- package/esm/utils/html-entry.d.ts +2 -0
- package/esm/utils/html-entry.js +41 -0
- package/esm/utils/mkcert.d.ts +7 -0
- package/esm/utils/mkcert.js +176 -0
- package/esm/utils/print-server-info.d.ts +1 -0
- package/esm/utils/print-server-info.js +44 -0
- package/esm/utils/xcodeProfile.d.ts +1 -0
- package/esm/utils/xcodeProfile.js +13 -0
- package/package.json +12 -14
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { HmrIdentifiers, NapiDiagnostic, NapiIssue, NapiUpdateMessage, NapiWrittenEndpoint, StackFrame } from "../binding";
|
|
2
|
+
import { BundleOptions } from "../config/types";
|
|
3
|
+
declare global {
|
|
4
|
+
export type TurbopackResult<T = {}> = T & {
|
|
5
|
+
issues: NapiIssue[];
|
|
6
|
+
diagnostics: NapiDiagnostic[];
|
|
7
|
+
};
|
|
8
|
+
export type RefCell = {
|
|
9
|
+
readonly __tag: unique symbol;
|
|
10
|
+
};
|
|
11
|
+
export type ExternalEndpoint = {
|
|
12
|
+
readonly __tag: unique symbol;
|
|
13
|
+
};
|
|
14
|
+
export type RcStr = string;
|
|
15
|
+
}
|
|
16
|
+
export interface BaseUpdate {
|
|
17
|
+
resource: {
|
|
18
|
+
headers: unknown;
|
|
19
|
+
path: string;
|
|
20
|
+
};
|
|
21
|
+
diagnostics: unknown[];
|
|
22
|
+
issues: NapiIssue[];
|
|
23
|
+
}
|
|
24
|
+
export interface IssuesUpdate extends BaseUpdate {
|
|
25
|
+
type: "issues";
|
|
26
|
+
}
|
|
27
|
+
export interface EcmascriptMergedUpdate {
|
|
28
|
+
type: "EcmascriptMergedUpdate";
|
|
29
|
+
chunks: {
|
|
30
|
+
[moduleName: string]: {
|
|
31
|
+
type: "partial";
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
entries: {
|
|
35
|
+
[moduleName: string]: {
|
|
36
|
+
code: string;
|
|
37
|
+
map: string;
|
|
38
|
+
url: string;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export interface PartialUpdate extends BaseUpdate {
|
|
43
|
+
type: "partial";
|
|
44
|
+
instruction: {
|
|
45
|
+
type: "ChunkListUpdate";
|
|
46
|
+
merged: EcmascriptMergedUpdate[] | undefined;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export type Update = IssuesUpdate | PartialUpdate;
|
|
50
|
+
export interface ProjectOptions extends BundleOptions {
|
|
51
|
+
/**
|
|
52
|
+
* A root path from which all files must be nested under. Trying to access
|
|
53
|
+
* a file outside this root will fail. Think of this as a chroot.
|
|
54
|
+
*/
|
|
55
|
+
rootPath: string;
|
|
56
|
+
/**
|
|
57
|
+
* A path inside the root_path which contains the app/pages directories.
|
|
58
|
+
*/
|
|
59
|
+
projectPath: string;
|
|
60
|
+
}
|
|
61
|
+
export { BundleOptions };
|
|
62
|
+
export interface Project {
|
|
63
|
+
update(options: Partial<ProjectOptions>): Promise<void>;
|
|
64
|
+
entrypointsSubscribe(): AsyncIterableIterator<TurbopackResult<RawEntrypoints>>;
|
|
65
|
+
hmrEvents(identifier: string): AsyncIterableIterator<TurbopackResult<Update>>;
|
|
66
|
+
hmrIdentifiersSubscribe(): AsyncIterableIterator<TurbopackResult<HmrIdentifiers>>;
|
|
67
|
+
getSourceForAsset(filePath: string): Promise<string | null>;
|
|
68
|
+
getSourceMap(filePath: string): Promise<string | null>;
|
|
69
|
+
getSourceMapSync(filePath: string): string | null;
|
|
70
|
+
traceSource(stackFrame: StackFrame, currentDirectoryFileUrl: string): Promise<StackFrame | null>;
|
|
71
|
+
updateInfoSubscribe(aggregationMs: number): AsyncIterableIterator<TurbopackResult<NapiUpdateMessage>>;
|
|
72
|
+
shutdown(): Promise<void>;
|
|
73
|
+
onExit(): Promise<void>;
|
|
74
|
+
}
|
|
75
|
+
export interface RawEntrypoints {
|
|
76
|
+
apps?: Endpoint[];
|
|
77
|
+
libraries?: Endpoint[];
|
|
78
|
+
}
|
|
79
|
+
export interface Endpoint {
|
|
80
|
+
/** Write files for the endpoint to disk. */
|
|
81
|
+
writeToDisk(): Promise<TurbopackResult<NapiWrittenEndpoint>>;
|
|
82
|
+
/**
|
|
83
|
+
* Listen to client-side changes to the endpoint.
|
|
84
|
+
* After clientChanged() has been awaited it will listen to changes.
|
|
85
|
+
* The async iterator will yield for each change.
|
|
86
|
+
*/
|
|
87
|
+
clientChanged(): Promise<AsyncIterableIterator<TurbopackResult>>;
|
|
88
|
+
/**
|
|
89
|
+
* Listen to server-side changes to the endpoint.
|
|
90
|
+
* After serverChanged() has been awaited it will listen to changes.
|
|
91
|
+
* The async iterator will yield for each change.
|
|
92
|
+
*/
|
|
93
|
+
serverChanged(includeIssues: boolean): Promise<AsyncIterableIterator<TurbopackResult>>;
|
|
94
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { DOMParser } from "domparser-rs";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
export class HtmlPlugin {
|
|
5
|
+
constructor(config) {
|
|
6
|
+
this.config = config;
|
|
7
|
+
}
|
|
8
|
+
async generate(outputDir, assets, globalPublicPath) {
|
|
9
|
+
const templatePath = this.config.template
|
|
10
|
+
? path.resolve(process.cwd(), this.config.template)
|
|
11
|
+
: undefined;
|
|
12
|
+
const publicPath = globalPublicPath || "";
|
|
13
|
+
let htmlContent = "";
|
|
14
|
+
if (this.config.templateContent) {
|
|
15
|
+
htmlContent = this.config.templateContent;
|
|
16
|
+
}
|
|
17
|
+
else if (templatePath && fs.existsSync(templatePath)) {
|
|
18
|
+
htmlContent = fs.readFileSync(templatePath, "utf-8");
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
htmlContent = `<!DOCTYPE html>
|
|
22
|
+
<html>
|
|
23
|
+
<head>
|
|
24
|
+
<meta charset="utf-8">
|
|
25
|
+
<title>${this.config.title || "Utoo App"}</title>
|
|
26
|
+
</head>
|
|
27
|
+
<body>
|
|
28
|
+
<div id="root"></div>
|
|
29
|
+
</body>
|
|
30
|
+
</html>`;
|
|
31
|
+
}
|
|
32
|
+
const parser = new DOMParser();
|
|
33
|
+
const doc = parser.parseFromString(htmlContent, "text/html");
|
|
34
|
+
if (this.config.title) {
|
|
35
|
+
const title = doc.querySelector("title");
|
|
36
|
+
if (title) {
|
|
37
|
+
title.textContent = this.config.title;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
const head = doc.querySelector("head");
|
|
41
|
+
if (head) {
|
|
42
|
+
const titleNode = doc.createElement("title");
|
|
43
|
+
titleNode.textContent = this.config.title;
|
|
44
|
+
head.appendChild(titleNode);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Inject meta
|
|
49
|
+
if (this.config.meta) {
|
|
50
|
+
const head = doc.querySelector("head");
|
|
51
|
+
if (head) {
|
|
52
|
+
Object.entries(this.config.meta).forEach(([name, value]) => {
|
|
53
|
+
const meta = doc.createElement("meta");
|
|
54
|
+
if (typeof value === "string") {
|
|
55
|
+
meta.setAttribute("name", name);
|
|
56
|
+
meta.setAttribute("content", value);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
Object.entries(value).forEach(([k, v]) => {
|
|
60
|
+
meta.setAttribute(k, v);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
head.appendChild(meta);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const head = doc.querySelector("head");
|
|
68
|
+
const body = doc.querySelector("body");
|
|
69
|
+
// Inject CSS
|
|
70
|
+
assets.css.forEach((cssFile) => {
|
|
71
|
+
const link = doc.createElement("link");
|
|
72
|
+
link.setAttribute("rel", "stylesheet");
|
|
73
|
+
link.setAttribute("href", publicPath
|
|
74
|
+
? publicPath.endsWith("/")
|
|
75
|
+
? publicPath + cssFile
|
|
76
|
+
: publicPath + "/" + cssFile
|
|
77
|
+
: cssFile);
|
|
78
|
+
if (head)
|
|
79
|
+
head.appendChild(link);
|
|
80
|
+
});
|
|
81
|
+
// Inject JS
|
|
82
|
+
assets.js.forEach((jsFile) => {
|
|
83
|
+
const script = doc.createElement("script");
|
|
84
|
+
script.setAttribute("src", publicPath
|
|
85
|
+
? publicPath.endsWith("/")
|
|
86
|
+
? publicPath + jsFile
|
|
87
|
+
: publicPath + "/" + jsFile
|
|
88
|
+
: jsFile);
|
|
89
|
+
if (this.config.scriptLoading === "defer") {
|
|
90
|
+
script.setAttribute("defer", "");
|
|
91
|
+
}
|
|
92
|
+
else if (this.config.scriptLoading === "module") {
|
|
93
|
+
script.setAttribute("type", "module");
|
|
94
|
+
}
|
|
95
|
+
if (this.config.inject === "head" && head) {
|
|
96
|
+
head.appendChild(script);
|
|
97
|
+
}
|
|
98
|
+
else if (body) {
|
|
99
|
+
body.appendChild(script);
|
|
100
|
+
}
|
|
101
|
+
else if (head) {
|
|
102
|
+
head.appendChild(script); // Fallback
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
const finalHtml = doc.outerHTML;
|
|
106
|
+
const filename = this.config.filename || "index.html";
|
|
107
|
+
fs.writeFileSync(path.join(outputDir, filename), finalHtml);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
export { createDefineEnv, debounce, isWellKnownError, ModuleBuildError, processIssues, rustifyEnv, } from "@utoo/pack-shared";
|
|
3
|
+
// ref:
|
|
4
|
+
// https://github.com/vercel/next.js/pull/51883
|
|
5
|
+
export function blockStdout() {
|
|
6
|
+
// 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
|
|
7
|
+
// see https://github.com/napi-rs/napi-rs/issues/1630
|
|
8
|
+
// and https://github.com/nodejs/node/blob/main/doc/api/process.md#a-note-on-process-io
|
|
9
|
+
if (process.stdout._handle != null) {
|
|
10
|
+
process.stdout._handle.setBlocking(true);
|
|
11
|
+
}
|
|
12
|
+
if (process.stderr._handle != null) {
|
|
13
|
+
process.stderr._handle.setBlocking(true);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function getPackPath() {
|
|
17
|
+
return path.resolve(__dirname, "..");
|
|
18
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function findRootLockFile(cwd: string): string | undefined;
|
|
2
|
+
export declare function findPackageJson(cwd: string): string | undefined;
|
|
3
|
+
export declare function findWorkspacesRoot(cwd: string): string;
|
|
4
|
+
export declare function findRootDir(cwd: string): string;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import findUp from "find-up";
|
|
2
|
+
import { readFileSync } from "fs";
|
|
3
|
+
import { dirname } from "path";
|
|
4
|
+
export function findRootLockFile(cwd) {
|
|
5
|
+
return findUp.sync([
|
|
6
|
+
"pnpm-lock.yaml",
|
|
7
|
+
"package-lock.json",
|
|
8
|
+
"yarn.lock",
|
|
9
|
+
"bun.lock",
|
|
10
|
+
"bun.lockb",
|
|
11
|
+
], {
|
|
12
|
+
cwd,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
// compatible with tnpm
|
|
16
|
+
export function findPackageJson(cwd) {
|
|
17
|
+
return findUp.sync(["package.json"], {
|
|
18
|
+
cwd,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function isWorkspaceRoot(pkgPath) {
|
|
22
|
+
const pkgJson = readFileSync(pkgPath, "utf-8");
|
|
23
|
+
const pkgJsonContent = JSON.parse(pkgJson);
|
|
24
|
+
return Boolean(pkgJsonContent.workspaces);
|
|
25
|
+
}
|
|
26
|
+
// refer from: https://github.com/umijs/mako/blob/next/crates/pm/src/helper/workspace.rs#L153
|
|
27
|
+
// TODO: 这块逻辑后续跟 utoo-pkg 使用一套方法
|
|
28
|
+
export function findWorkspacesRoot(cwd) {
|
|
29
|
+
const pkgJson = findPackageJson(cwd);
|
|
30
|
+
if (!pkgJson)
|
|
31
|
+
return cwd;
|
|
32
|
+
const pkgJsonFiles = [pkgJson];
|
|
33
|
+
while (true) {
|
|
34
|
+
const lastPkgJson = pkgJsonFiles[pkgJsonFiles.length - 1];
|
|
35
|
+
const currentDir = dirname(lastPkgJson);
|
|
36
|
+
const parentDir = dirname(currentDir);
|
|
37
|
+
if (parentDir === currentDir)
|
|
38
|
+
break;
|
|
39
|
+
if (isWorkspaceRoot(lastPkgJson))
|
|
40
|
+
break;
|
|
41
|
+
const newPkgJson = findPackageJson(parentDir);
|
|
42
|
+
if (!newPkgJson)
|
|
43
|
+
break;
|
|
44
|
+
pkgJsonFiles.push(newPkgJson);
|
|
45
|
+
}
|
|
46
|
+
return dirname(pkgJsonFiles[pkgJsonFiles.length - 1]);
|
|
47
|
+
}
|
|
48
|
+
export function findRootDir(cwd) {
|
|
49
|
+
const lockFile = findRootLockFile(cwd);
|
|
50
|
+
if (!lockFile)
|
|
51
|
+
return findWorkspacesRoot(cwd);
|
|
52
|
+
const lockFiles = [lockFile];
|
|
53
|
+
while (true) {
|
|
54
|
+
const lastLockFile = lockFiles[lockFiles.length - 1];
|
|
55
|
+
const currentDir = dirname(lastLockFile);
|
|
56
|
+
const parentDir = dirname(currentDir);
|
|
57
|
+
// dirname('/')==='/' so if we happen to reach the FS root (as might happen in a container we need to quit to avoid looping forever
|
|
58
|
+
if (parentDir === currentDir)
|
|
59
|
+
break;
|
|
60
|
+
const newLockFile = findRootLockFile(parentDir);
|
|
61
|
+
if (!newLockFile)
|
|
62
|
+
break;
|
|
63
|
+
lockFiles.push(newLockFile);
|
|
64
|
+
}
|
|
65
|
+
return dirname(lockFiles[lockFiles.length - 1]);
|
|
66
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { DOMParser } from "domparser-rs";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
export function processHtmlEntry(config, projectPath) {
|
|
5
|
+
if (!config.entry)
|
|
6
|
+
return;
|
|
7
|
+
const newEntries = [];
|
|
8
|
+
config.entry = config.entry.filter((entry) => {
|
|
9
|
+
if (entry.import.endsWith(".html")) {
|
|
10
|
+
const htmlPath = path.resolve(projectPath, entry.import);
|
|
11
|
+
if (fs.existsSync(htmlPath)) {
|
|
12
|
+
const content = fs.readFileSync(htmlPath, "utf-8");
|
|
13
|
+
const parser = new DOMParser();
|
|
14
|
+
const doc = parser.parseFromString(content, "text/html");
|
|
15
|
+
const scripts = doc.querySelectorAll("script");
|
|
16
|
+
scripts.forEach((script) => {
|
|
17
|
+
const src = script.getAttribute("src");
|
|
18
|
+
if (src && !src.startsWith("http") && !src.startsWith("//")) {
|
|
19
|
+
const scriptPath = path.join(path.dirname(entry.import), src);
|
|
20
|
+
newEntries.push({
|
|
21
|
+
import: scriptPath,
|
|
22
|
+
html: {
|
|
23
|
+
template: entry.import,
|
|
24
|
+
templateContent: doc.outerHTML,
|
|
25
|
+
filename: path.basename(entry.import),
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
// Remove the script tag from the DOM
|
|
29
|
+
if (script.parentNode) {
|
|
30
|
+
script.parentNode.removeChild(script);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
});
|
|
39
|
+
// Add new script entries
|
|
40
|
+
config.entry.push(...newEntries);
|
|
41
|
+
}
|
|
@@ -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;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { createPrivateKey, X509Certificate } from "node:crypto";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import os from "os";
|
|
6
|
+
const { WritableStream } = require("node:stream/web");
|
|
7
|
+
const MKCERT_VERSION = "v1.4.4";
|
|
8
|
+
function getBinaryName() {
|
|
9
|
+
const platform = process.platform;
|
|
10
|
+
const arch = process.arch === "x64" ? "amd64" : process.arch;
|
|
11
|
+
if (platform === "win32") {
|
|
12
|
+
return `mkcert-${MKCERT_VERSION}-windows-${arch}.exe`;
|
|
13
|
+
}
|
|
14
|
+
if (platform === "darwin") {
|
|
15
|
+
return `mkcert-${MKCERT_VERSION}-darwin-${arch}`;
|
|
16
|
+
}
|
|
17
|
+
if (platform === "linux") {
|
|
18
|
+
return `mkcert-${MKCERT_VERSION}-linux-${arch}`;
|
|
19
|
+
}
|
|
20
|
+
throw new Error(`Unsupported platform: ${platform}`);
|
|
21
|
+
}
|
|
22
|
+
async function downloadBinary() {
|
|
23
|
+
try {
|
|
24
|
+
const binaryName = getBinaryName();
|
|
25
|
+
const cacheDirectory = getCacheDirectory("mkcert");
|
|
26
|
+
const binaryPath = path.join(cacheDirectory, binaryName);
|
|
27
|
+
if (fs.existsSync(binaryPath)) {
|
|
28
|
+
return binaryPath;
|
|
29
|
+
}
|
|
30
|
+
const downloadUrl = `https://github.com/FiloSottile/mkcert/releases/download/${MKCERT_VERSION}/${binaryName}`;
|
|
31
|
+
await fs.promises.mkdir(cacheDirectory, { recursive: true });
|
|
32
|
+
console.log(`Downloading mkcert package...`);
|
|
33
|
+
const response = await fetch(downloadUrl);
|
|
34
|
+
if (!response.ok || !response.body) {
|
|
35
|
+
throw new Error(`request failed with status ${response.status}`);
|
|
36
|
+
}
|
|
37
|
+
console.log(`Download response was successful, writing to disk`);
|
|
38
|
+
const binaryWriteStream = fs.createWriteStream(binaryPath);
|
|
39
|
+
await response.body.pipeTo(new WritableStream({
|
|
40
|
+
write(chunk) {
|
|
41
|
+
return new Promise((resolve, reject) => {
|
|
42
|
+
binaryWriteStream.write(chunk, (error) => {
|
|
43
|
+
if (error) {
|
|
44
|
+
reject(error);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
resolve();
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
},
|
|
51
|
+
close() {
|
|
52
|
+
return new Promise((resolve, reject) => {
|
|
53
|
+
binaryWriteStream.close((error) => {
|
|
54
|
+
if (error) {
|
|
55
|
+
reject(error);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
resolve();
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
}));
|
|
63
|
+
await fs.promises.chmod(binaryPath, 0o755);
|
|
64
|
+
return binaryPath;
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
console.error("Error downloading mkcert:", err);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export async function createSelfSignedCertificate(host, certDir = "certificates") {
|
|
71
|
+
try {
|
|
72
|
+
const binaryPath = await downloadBinary();
|
|
73
|
+
if (!binaryPath)
|
|
74
|
+
throw new Error("missing mkcert binary");
|
|
75
|
+
const resolvedCertDir = path.resolve(process.cwd(), `./${certDir}`);
|
|
76
|
+
await fs.promises.mkdir(resolvedCertDir, {
|
|
77
|
+
recursive: true,
|
|
78
|
+
});
|
|
79
|
+
const keyPath = path.resolve(resolvedCertDir, "localhost-key.pem");
|
|
80
|
+
const certPath = path.resolve(resolvedCertDir, "localhost.pem");
|
|
81
|
+
if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
|
|
82
|
+
const cert = new X509Certificate(fs.readFileSync(certPath));
|
|
83
|
+
const key = fs.readFileSync(keyPath);
|
|
84
|
+
if (cert.checkHost(host !== null && host !== void 0 ? host : "localhost") &&
|
|
85
|
+
cert.checkPrivateKey(createPrivateKey(key))) {
|
|
86
|
+
console.log("Using already generated self signed certificate");
|
|
87
|
+
const caLocation = execSync(`"${binaryPath}" -CAROOT`)
|
|
88
|
+
.toString()
|
|
89
|
+
.trim();
|
|
90
|
+
return {
|
|
91
|
+
key: keyPath,
|
|
92
|
+
cert: certPath,
|
|
93
|
+
rootCA: `${caLocation}/rootCA.pem`,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
console.log("Attempting to generate self signed certificate. This may prompt for your password");
|
|
98
|
+
const defaultHosts = ["localhost", "127.0.0.1", "::1"];
|
|
99
|
+
const hosts = host && !defaultHosts.includes(host)
|
|
100
|
+
? [...defaultHosts, host]
|
|
101
|
+
: defaultHosts;
|
|
102
|
+
execSync(`"${binaryPath}" -install -key-file "${keyPath}" -cert-file "${certPath}" ${hosts.join(" ")}`, { stdio: "ignore" });
|
|
103
|
+
const caLocation = execSync(`"${binaryPath}" -CAROOT`).toString().trim();
|
|
104
|
+
if (!fs.existsSync(keyPath) || !fs.existsSync(certPath)) {
|
|
105
|
+
throw new Error("Certificate files not found");
|
|
106
|
+
}
|
|
107
|
+
console.log(`CA Root certificate created in ${caLocation}`);
|
|
108
|
+
console.log(`Certificates created in ${resolvedCertDir}`);
|
|
109
|
+
const gitignorePath = path.resolve(process.cwd(), "./.gitignore");
|
|
110
|
+
if (fs.existsSync(gitignorePath)) {
|
|
111
|
+
const gitignore = await fs.promises.readFile(gitignorePath, "utf8");
|
|
112
|
+
if (!gitignore.includes(certDir)) {
|
|
113
|
+
console.log("Adding certificates to .gitignore");
|
|
114
|
+
await fs.promises.appendFile(gitignorePath, `\n${certDir}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
key: keyPath,
|
|
119
|
+
cert: certPath,
|
|
120
|
+
rootCA: `${caLocation}/rootCA.pem`,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
console.error("Failed to generate self-signed certificate. Falling back to http.", err);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// get platform specific cache directory adapted from playwright's handling
|
|
128
|
+
// https://github.com/microsoft/playwright/blob/7d924470d397975a74a19184c136b3573a974e13/packages/playwright-core/src/utils/registry.ts#L141
|
|
129
|
+
export function getCacheDirectory(fileDirectory, envPath) {
|
|
130
|
+
let result;
|
|
131
|
+
if (envPath) {
|
|
132
|
+
result = envPath;
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
let systemCacheDirectory;
|
|
136
|
+
if (process.platform === "linux") {
|
|
137
|
+
systemCacheDirectory =
|
|
138
|
+
process.env.XDG_CACHE_HOME || path.join(os.homedir(), ".cache");
|
|
139
|
+
}
|
|
140
|
+
else if (process.platform === "darwin") {
|
|
141
|
+
systemCacheDirectory = path.join(os.homedir(), "Library", "Caches");
|
|
142
|
+
}
|
|
143
|
+
else if (process.platform === "win32") {
|
|
144
|
+
systemCacheDirectory =
|
|
145
|
+
process.env.LOCALAPPDATA || path.join(os.homedir(), "AppData", "Local");
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
/// Attempt to use generic tmp location for un-handled platform
|
|
149
|
+
if (!systemCacheDirectory) {
|
|
150
|
+
for (const dir of [
|
|
151
|
+
path.join(os.homedir(), ".cache"),
|
|
152
|
+
path.join(os.tmpdir()),
|
|
153
|
+
]) {
|
|
154
|
+
if (fs.existsSync(dir)) {
|
|
155
|
+
systemCacheDirectory = dir;
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (!systemCacheDirectory) {
|
|
161
|
+
console.error(new Error("Unsupported platform: " + process.platform));
|
|
162
|
+
process.exit(0);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
result = path.join(systemCacheDirectory, fileDirectory);
|
|
166
|
+
}
|
|
167
|
+
if (!path.isAbsolute(result)) {
|
|
168
|
+
// It is important to resolve to the absolute path:
|
|
169
|
+
// - for unzipping to work correctly;
|
|
170
|
+
// - so that registry directory matches between installation and execution.
|
|
171
|
+
// INIT_CWD points to the root of `npm/yarn install` and is probably what
|
|
172
|
+
// the user meant when typing the relative path.
|
|
173
|
+
result = path.resolve(process.env["INIT_CWD"] || process.cwd(), result);
|
|
174
|
+
}
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function printServerInfo(protocol: "http" | "https", hostname: string, port: number): void;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import os from "os";
|
|
2
|
+
import pc from "picocolors";
|
|
3
|
+
export function printServerInfo(protocol, hostname, port) {
|
|
4
|
+
const localUrl = `${protocol}://localhost:${port}`;
|
|
5
|
+
const networkAddress = getNetworkAddress();
|
|
6
|
+
const networkUrl = networkAddress
|
|
7
|
+
? `${protocol}://${networkAddress}:${port}`
|
|
8
|
+
: null;
|
|
9
|
+
console.log();
|
|
10
|
+
console.log(pc.green(" ┌──────────────────────────────────────────────────┐"));
|
|
11
|
+
console.log(pc.green(" │ │"));
|
|
12
|
+
console.log(pc.green(" │ ") +
|
|
13
|
+
pc.bold("Serving!") +
|
|
14
|
+
pc.green(" │"));
|
|
15
|
+
console.log(pc.green(" │ │"));
|
|
16
|
+
const localLabel = " │ - Local: ";
|
|
17
|
+
const localPadding = 50 - 15 - localUrl.length; // 15 is " - Local: ".length
|
|
18
|
+
console.log(pc.green(localLabel) +
|
|
19
|
+
pc.cyan(localUrl) +
|
|
20
|
+
pc.green(" ".repeat(Math.max(0, localPadding)) + "│"));
|
|
21
|
+
if (networkUrl) {
|
|
22
|
+
const netLabel = " │ - Network: ";
|
|
23
|
+
const netPadding = 50 - 17 - networkUrl.length; // 17 is " - Network: ".length
|
|
24
|
+
console.log(pc.green(netLabel) +
|
|
25
|
+
pc.cyan(networkUrl) +
|
|
26
|
+
pc.green(" ".repeat(Math.max(0, netPadding)) + "│"));
|
|
27
|
+
}
|
|
28
|
+
console.log(pc.green(" │ │"));
|
|
29
|
+
console.log(pc.green(" │ Copied local address to clipboard! │"));
|
|
30
|
+
console.log(pc.green(" │ │"));
|
|
31
|
+
console.log(pc.green(" └──────────────────────────────────────────────────┘"));
|
|
32
|
+
console.log();
|
|
33
|
+
}
|
|
34
|
+
function getNetworkAddress() {
|
|
35
|
+
const interfaces = os.networkInterfaces();
|
|
36
|
+
for (const name of Object.keys(interfaces)) {
|
|
37
|
+
for (const iface of interfaces[name]) {
|
|
38
|
+
if (iface.family === "IPv4" && !iface.internal) {
|
|
39
|
+
return iface.address;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function xcodeProfilingReady(): Promise<void>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export async function xcodeProfilingReady() {
|
|
2
|
+
await new Promise((resolve) => {
|
|
3
|
+
const readline = require("readline");
|
|
4
|
+
const rl = readline.createInterface({
|
|
5
|
+
input: process.stdin,
|
|
6
|
+
output: process.stdout,
|
|
7
|
+
});
|
|
8
|
+
rl.question(`Xcode profile enabled. Current process ${process.title} (${process.pid}) . Press Enter to continue...\n`, () => {
|
|
9
|
+
rl.close();
|
|
10
|
+
resolve();
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@utoo/pack",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"main": "cjs/index.js",
|
|
5
5
|
"module": "esm/index.js",
|
|
6
6
|
"types": "esm/index.d.ts",
|
|
@@ -16,11 +16,9 @@
|
|
|
16
16
|
"./package.json": "./package.json"
|
|
17
17
|
},
|
|
18
18
|
"files": [
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"./esm/*.d.ts",
|
|
23
|
-
"./config_schema.json"
|
|
19
|
+
"cjs",
|
|
20
|
+
"esm",
|
|
21
|
+
"config_schema.json"
|
|
24
22
|
],
|
|
25
23
|
"napi": {
|
|
26
24
|
"name": "pack",
|
|
@@ -84,18 +82,18 @@
|
|
|
84
82
|
"build:binding": "napi build src --platform --release -p pack-napi --cargo-cwd ../../ --cargo-name pack_napi --features plugin --js binding.js --dts binding.d.ts",
|
|
85
83
|
"build:binding:local": "napi build src --platform --profile release-local -p pack-napi --cargo-cwd ../../ --cargo-name pack_napi --features plugin --js binding.js --dts binding.d.ts",
|
|
86
84
|
"clean": "rm -rf cjs esm",
|
|
87
|
-
"prepublishOnly": "
|
|
85
|
+
"prepublishOnly": "npm run build:js && napi prepublish -t npm --skip-gh-release",
|
|
88
86
|
"version": "napi version",
|
|
89
87
|
"generate-features-list": "node ./scripts/generate-feature-list.js"
|
|
90
88
|
},
|
|
91
89
|
"repository": "git@github.com:utooland/utoo.git",
|
|
92
90
|
"optionalDependencies": {
|
|
93
|
-
"@utoo/pack-darwin-arm64": "1.1.
|
|
94
|
-
"@utoo/pack-darwin-x64": "1.1.
|
|
95
|
-
"@utoo/pack-linux-arm64-gnu": "1.1.
|
|
96
|
-
"@utoo/pack-linux-arm64-musl": "1.1.
|
|
97
|
-
"@utoo/pack-linux-x64-gnu": "1.1.
|
|
98
|
-
"@utoo/pack-linux-x64-musl": "1.1.
|
|
99
|
-
"@utoo/pack-win32-x64-msvc": "1.1.
|
|
91
|
+
"@utoo/pack-darwin-arm64": "1.1.4",
|
|
92
|
+
"@utoo/pack-darwin-x64": "1.1.4",
|
|
93
|
+
"@utoo/pack-linux-arm64-gnu": "1.1.4",
|
|
94
|
+
"@utoo/pack-linux-arm64-musl": "1.1.4",
|
|
95
|
+
"@utoo/pack-linux-x64-gnu": "1.1.4",
|
|
96
|
+
"@utoo/pack-linux-x64-musl": "1.1.4",
|
|
97
|
+
"@utoo/pack-win32-x64-msvc": "1.1.4"
|
|
100
98
|
}
|
|
101
99
|
}
|