@yorozu/build 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/LICENSE +21 -0
- package/README.md +38 -0
- package/chunks/21EFCjEU.js +19160 -0
- package/chunks/CMapqBQB.js +2620 -0
- package/chunks/CYSd7-PF.js +623 -0
- package/chunks/Cr5v7tI0.js +1824 -0
- package/ci/github-actions.d.ts +3 -0
- package/ci/index.d.ts +1 -0
- package/cli/commands/_utils.d.ts +8 -0
- package/cli/commands/build.d.ts +40 -0
- package/cli/commands/bump-version.d.ts +27 -0
- package/cli/commands/cr.d.ts +27 -0
- package/cli/commands/docs.d.ts +9 -0
- package/cli/commands/find-changed-packages.d.ts +10 -0
- package/cli/commands/gen-changelog.d.ts +10 -0
- package/cli/commands/gen-deps-graph.d.ts +15 -0
- package/cli/commands/jsr.d.ts +6 -0
- package/cli/commands/lint/config.d.ts +1 -0
- package/cli/commands/lint/index.d.ts +11 -0
- package/cli/commands/lint/validate-workspace-deps.d.ts +23 -0
- package/cli/commands/publish.d.ts +62 -0
- package/cli/commands/release.d.ts +45 -0
- package/cli/index.d.ts +8 -0
- package/cli/log.d.ts +3 -0
- package/cli/main.d.ts +2 -0
- package/config.d.ts +57 -0
- package/git/github.d.ts +15 -0
- package/git/index.d.ts +2 -0
- package/git/utils.d.ts +38 -0
- package/index.d.ts +8 -0
- package/index.js +26 -0
- package/jsr/_deno-directives.d.ts +1 -0
- package/jsr/config.d.ts +1 -0
- package/jsr/create-packages.d.ts +8 -0
- package/jsr/deno-json.d.ts +19 -0
- package/jsr/generate-workspace.d.ts +9 -0
- package/jsr/index.d.ts +6 -0
- package/jsr/populate.d.ts +10 -0
- package/jsr/utils/external-libs.d.ts +8 -0
- package/jsr/utils/index.d.ts +4 -0
- package/jsr/utils/jsr-api.d.ts +23 -0
- package/jsr/utils/jsr-json.d.ts +10 -0
- package/jsr/utils/jsr.d.ts +10 -0
- package/jsr.d.ts +1 -0
- package/jsr.js +2 -0
- package/misc/_config.d.ts +2 -0
- package/misc/exec.d.ts +15 -0
- package/misc/fs.d.ts +4 -0
- package/misc/index.d.ts +6 -0
- package/misc/path.d.ts +1 -0
- package/misc/publish-order.d.ts +3 -0
- package/misc/tsconfig.d.ts +2 -0
- package/npm/index.d.ts +1 -0
- package/npm/npm-api.d.ts +6 -0
- package/package-json/collect-package-jsons.d.ts +9 -0
- package/package-json/find-package-json.d.ts +1 -0
- package/package-json/index.d.ts +6 -0
- package/package-json/parse.d.ts +11 -0
- package/package-json/process-package-json.d.ts +20 -0
- package/package-json/types.d.ts +39 -0
- package/package-json/utils.d.ts +4 -0
- package/package.json +59 -0
- package/versioning/bump-version.d.ts +31 -0
- package/versioning/collect-files.d.ts +21 -0
- package/versioning/generate-changelog.d.ts +8 -0
- package/versioning/index.d.ts +4 -0
- package/versioning/types.d.ts +21 -0
- package/vite/build-plugin.d.ts +73 -0
- package/vite/config.d.ts +47 -0
- package/vite/index.d.ts +2 -0
- package/vite.d.ts +1 -0
- package/vite.js +184 -0
- package/yorozu-build.d.ts +1 -0
- package/yorozu-build.js +527 -0
|
@@ -0,0 +1,623 @@
|
|
|
1
|
+
import { __toESM, asNonNull, asyncPool, collectPackageJsons, collectVersions, directoryExists, fileExists, filterPackageJsonsForPublish, findRootPackage, glob, info, loadBuildConfig, normalizeFilePath, object, processPackageJson, record, require_picomatch, string, tryCopy, unknown } from "./21EFCjEU.js";
|
|
2
|
+
import { determinePublishOrder, exec, require_semver } from "./Cr5v7tI0.js";
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import process from "node:process";
|
|
5
|
+
import { dirname, join, relative, resolve } from "node:path";
|
|
6
|
+
import * as fsp from "node:fs/promises";
|
|
7
|
+
import ts, { parseConfigFileTextToJson } from "typescript";
|
|
8
|
+
//#region src/jsr/utils/jsr-api.ts
|
|
9
|
+
var USER_AGENT$1 = "@yorozu/build";
|
|
10
|
+
var REQUEST_TIMEOUT_MS$1 = 15e3;
|
|
11
|
+
var MAX_RETRIES = 3;
|
|
12
|
+
function joinRegistryUrl$1(registry, path) {
|
|
13
|
+
return `${registry.replace(/\/$/, "")}/${path.replace(/^\//, "")}`;
|
|
14
|
+
}
|
|
15
|
+
async function readErrorBody(res) {
|
|
16
|
+
try {
|
|
17
|
+
return await res.text();
|
|
18
|
+
} catch {
|
|
19
|
+
return "";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async function jsrFetch$1(url, init = {}) {
|
|
23
|
+
let lastError;
|
|
24
|
+
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) try {
|
|
25
|
+
return await fetch(url, {
|
|
26
|
+
...init,
|
|
27
|
+
headers: {
|
|
28
|
+
"User-Agent": USER_AGENT$1,
|
|
29
|
+
...init.headers
|
|
30
|
+
},
|
|
31
|
+
signal: init.signal ?? AbortSignal.timeout(REQUEST_TIMEOUT_MS$1)
|
|
32
|
+
});
|
|
33
|
+
} catch (err) {
|
|
34
|
+
lastError = err;
|
|
35
|
+
}
|
|
36
|
+
throw lastError instanceof Error ? lastError : new Error(String(lastError));
|
|
37
|
+
}
|
|
38
|
+
function jsonInit(token, body) {
|
|
39
|
+
return {
|
|
40
|
+
headers: {
|
|
41
|
+
Cookie: `token=${token}`,
|
|
42
|
+
"Content-Type": "application/json"
|
|
43
|
+
},
|
|
44
|
+
body: JSON.stringify(body)
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
async function jsrGetScopeInfo(params) {
|
|
48
|
+
let { scope, registry } = params;
|
|
49
|
+
let res = await jsrFetch$1(joinRegistryUrl$1(registry, `/api/scopes/${scope}`));
|
|
50
|
+
if (res.status === 404) {
|
|
51
|
+
if (res.body) res.body.cancel();
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
if (res.status !== 200) throw new Error(`Failed to get scope info: ${res.status} ${await readErrorBody(res)}`);
|
|
55
|
+
return res.json();
|
|
56
|
+
}
|
|
57
|
+
async function jsrCreateScope(params) {
|
|
58
|
+
let { name, registry, token, quiet } = params;
|
|
59
|
+
let create = await jsrFetch$1(joinRegistryUrl$1(registry, "/api/scopes"), {
|
|
60
|
+
method: "POST",
|
|
61
|
+
...jsonInit(token, { scope: name })
|
|
62
|
+
});
|
|
63
|
+
if (create.status !== 200) throw new Error(`Failed to create scope: ${create.status} ${await create.text()}`);
|
|
64
|
+
if (create.body) create.body.cancel();
|
|
65
|
+
if (!quiet) info(`Created scope @${name}`);
|
|
66
|
+
}
|
|
67
|
+
async function jsrMaybeCreatePackage(params) {
|
|
68
|
+
let { name, registry, token, quiet } = params;
|
|
69
|
+
let [scopeWithAt, packageName] = name.split("/");
|
|
70
|
+
if (!packageName || !scopeWithAt || !scopeWithAt.startsWith("@")) throw new Error("Invalid package name");
|
|
71
|
+
let scope = scopeWithAt.slice(1);
|
|
72
|
+
let packageMeta = await jsrFetch$1(joinRegistryUrl$1(registry, `/api/scopes/${scope}/packages/${packageName}`));
|
|
73
|
+
if (packageMeta.status === 200) {
|
|
74
|
+
if (packageMeta.body) packageMeta.body.cancel();
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (packageMeta.status !== 404) throw new Error(`Failed to check package: ${packageMeta.status} ${await packageMeta.text()}`);
|
|
78
|
+
if (packageMeta.body) packageMeta.body.cancel();
|
|
79
|
+
if (!quiet) info(`${name} does not exist, creating..`);
|
|
80
|
+
let create = await jsrFetch$1(joinRegistryUrl$1(registry, `/api/scopes/${scope}/packages`), {
|
|
81
|
+
method: "POST",
|
|
82
|
+
...jsonInit(token, { package: packageName })
|
|
83
|
+
});
|
|
84
|
+
if (create.status !== 200) {
|
|
85
|
+
let text = await create.text();
|
|
86
|
+
if (create.status === 403) try {
|
|
87
|
+
if (JSON.parse(text).code === "actorNotScopeMember") {
|
|
88
|
+
if (await jsrGetScopeInfo({
|
|
89
|
+
scope,
|
|
90
|
+
registry
|
|
91
|
+
}) === null) {
|
|
92
|
+
await jsrCreateScope({
|
|
93
|
+
name: scope,
|
|
94
|
+
registry,
|
|
95
|
+
token,
|
|
96
|
+
quiet
|
|
97
|
+
});
|
|
98
|
+
return jsrMaybeCreatePackage({
|
|
99
|
+
...params,
|
|
100
|
+
quiet: true
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
} catch (err) {
|
|
105
|
+
if (err instanceof Error && err.message.startsWith("Failed to")) throw err;
|
|
106
|
+
}
|
|
107
|
+
throw new Error(`Failed to create package: ${create.status} ${text}`);
|
|
108
|
+
}
|
|
109
|
+
if (create.body) create.body.cancel();
|
|
110
|
+
}
|
|
111
|
+
async function jsrSetGithubRepo(params) {
|
|
112
|
+
let { registry, name, token, owner, repo } = params;
|
|
113
|
+
let [scopeWithAt, packageName] = name.split("/");
|
|
114
|
+
if (!packageName || !scopeWithAt || !scopeWithAt.startsWith("@")) throw new Error("Invalid package name");
|
|
115
|
+
let res = await jsrFetch$1(joinRegistryUrl$1(registry, `/api/scopes/${scopeWithAt.slice(1)}/packages/${packageName}`), {
|
|
116
|
+
method: "PATCH",
|
|
117
|
+
...jsonInit(token, { githubRepository: {
|
|
118
|
+
owner,
|
|
119
|
+
name: repo
|
|
120
|
+
} })
|
|
121
|
+
});
|
|
122
|
+
if (res.status !== 200) throw new Error(`Failed to set github repo: ${await res.text()}`);
|
|
123
|
+
if (res.body) res.body.cancel();
|
|
124
|
+
}
|
|
125
|
+
//#endregion
|
|
126
|
+
//#region src/jsr/utils/external-libs.ts
|
|
127
|
+
var import_semver = /* @__PURE__ */ __toESM(require_semver(), 1);
|
|
128
|
+
var _cacheDir;
|
|
129
|
+
function getModuleCacheDirectory() {
|
|
130
|
+
if (process.env.JSR_CACHE_DIR != null) return process.env.JSR_CACHE_DIR;
|
|
131
|
+
if (_cacheDir != null) return _cacheDir;
|
|
132
|
+
switch (process.platform) {
|
|
133
|
+
case "win32": return _cacheDir = join(process.env.LOCALAPPDATA ?? process.env.APPDATA ?? "C:", "jsr-cache");
|
|
134
|
+
case "darwin": return _cacheDir = join(process.env.HOME ?? "/tmp", "Library", "Caches", "jsr");
|
|
135
|
+
default: return _cacheDir = join(process.env.XDG_CACHE_HOME ?? process.env.HOME ?? "/tmp", ".cache", "jsr");
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function parseImportSpecifier(importSpecifier) {
|
|
139
|
+
let [registry, specifier] = importSpecifier.split(":");
|
|
140
|
+
if (registry !== "npm" && registry !== "jsr") throw new Error(`Invalid import specifier: ${importSpecifier}`);
|
|
141
|
+
if (registry === "jsr" && specifier[0] === "/") specifier = specifier.slice(1);
|
|
142
|
+
if (specifier.startsWith("@")) {
|
|
143
|
+
let [pkg, version] = specifier.slice(1).split("@");
|
|
144
|
+
return {
|
|
145
|
+
registry,
|
|
146
|
+
packageName: `@${pkg}`,
|
|
147
|
+
version: version.split("/")[0]
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
let [pkg, version] = specifier.split("@");
|
|
151
|
+
return {
|
|
152
|
+
registry,
|
|
153
|
+
packageName: pkg,
|
|
154
|
+
version: version.split("/")[0]
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function splitImportRequest(request) {
|
|
158
|
+
if (request.startsWith("jsr:/")) request = `jsr:${request.slice(5)}`;
|
|
159
|
+
let parts = request.split("/");
|
|
160
|
+
if (parts[0].match(/^(?:npm:|jsr:)?@/)) return [parts.slice(0, 2).join("/"), parts.slice(2).join("/")];
|
|
161
|
+
return [parts[0], parts.slice(1).join("/")];
|
|
162
|
+
}
|
|
163
|
+
//#endregion
|
|
164
|
+
//#region src/jsr/utils/jsr.ts
|
|
165
|
+
var USER_AGENT = "@yorozu/build";
|
|
166
|
+
var REQUEST_TIMEOUT_MS = 3e4;
|
|
167
|
+
var DEFAULT_REGISTRY = process.env.JSR_URL ?? "https://jsr.io";
|
|
168
|
+
function joinRegistryUrl(registry, path) {
|
|
169
|
+
return `${registry.replace(/\/$/, "")}/${path.replace(/^\//, "")}`;
|
|
170
|
+
}
|
|
171
|
+
async function jsrFetch(url, init = {}) {
|
|
172
|
+
return fetch(url, {
|
|
173
|
+
...init,
|
|
174
|
+
headers: {
|
|
175
|
+
"User-Agent": USER_AGENT,
|
|
176
|
+
...init.headers
|
|
177
|
+
},
|
|
178
|
+
signal: init.signal ?? AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
async function jsrCheckVersion(params) {
|
|
182
|
+
let { registry = DEFAULT_REGISTRY, package: packageName, version } = params;
|
|
183
|
+
let res = await jsrFetch(joinRegistryUrl(registry, `/${packageName}/meta${version != null ? `_${version}` : ""}.json`));
|
|
184
|
+
if (res.body) res.body.cancel();
|
|
185
|
+
return res.status === 200;
|
|
186
|
+
}
|
|
187
|
+
var MetaSchema = object({ versions: record(string(), unknown()) });
|
|
188
|
+
var VersionMetaSchema = object({ manifest: record(string(), unknown()) });
|
|
189
|
+
async function downloadJsrPackage(specifier, params) {
|
|
190
|
+
if (specifier.registry !== "jsr") throw new Error("Invalid registry");
|
|
191
|
+
let registry = params?.registry ?? DEFAULT_REGISTRY;
|
|
192
|
+
let targetDir = `${specifier.packageName.replace(/\//g, "+")}@${specifier.version}`;
|
|
193
|
+
let registryHost = new URL(registry).host;
|
|
194
|
+
let cacheDir = join(getModuleCacheDirectory(), "jsr", registryHost, targetDir);
|
|
195
|
+
if (await directoryExists(cacheDir)) if (params?.force) await fsp.rm(cacheDir, { recursive: true });
|
|
196
|
+
else return cacheDir;
|
|
197
|
+
let metaRes = await jsrFetch(joinRegistryUrl(registry, `${specifier.packageName}/meta.json`));
|
|
198
|
+
if (!metaRes.ok) throw new Error(`Failed to fetch jsr meta for ${specifier.packageName}: ${metaRes.status}`);
|
|
199
|
+
let meta = MetaSchema.parse(await metaRes.json());
|
|
200
|
+
let availableVersions = Object.keys(meta.versions);
|
|
201
|
+
let version = import_semver.default.maxSatisfying(availableVersions, specifier.version);
|
|
202
|
+
if (version == null) throw new Error(`No matching version for ${specifier.packageName}@${specifier.version}`);
|
|
203
|
+
await fsp.mkdir(cacheDir, { recursive: true });
|
|
204
|
+
let versionMetaRes = await jsrFetch(joinRegistryUrl(registry, `${specifier.packageName}/${version}_meta.json`));
|
|
205
|
+
if (!versionMetaRes.ok) throw new Error(`Failed to fetch jsr version meta for ${specifier.packageName}@${version}: ${versionMetaRes.status}`);
|
|
206
|
+
let versionMeta = VersionMetaSchema.parse(await versionMetaRes.json());
|
|
207
|
+
await asyncPool(Object.keys(versionMeta.manifest), async (file) => {
|
|
208
|
+
let relative = file.replace(/^\//, "");
|
|
209
|
+
let filePath = join(cacheDir, relative);
|
|
210
|
+
await fsp.mkdir(join(filePath, ".."), { recursive: true });
|
|
211
|
+
let res = await jsrFetch(joinRegistryUrl(registry, `${specifier.packageName}/${version}/${relative}`));
|
|
212
|
+
if (!res.ok) throw new Error(`Failed to download ${specifier.packageName}@${version}/${relative}: ${res.status}`);
|
|
213
|
+
await fsp.writeFile(filePath, Buffer.from(await res.arrayBuffer()));
|
|
214
|
+
});
|
|
215
|
+
return cacheDir;
|
|
216
|
+
}
|
|
217
|
+
//#endregion
|
|
218
|
+
//#region src/jsr/create-packages.ts
|
|
219
|
+
async function jsrCreatePackages(params) {
|
|
220
|
+
let { workspaceRoot, registry = process.env.JSR_URL ?? "https://jsr.io", token, githubRepo } = params;
|
|
221
|
+
let workspace = filterPackageJsonsForPublish(params.workspacePackages ?? await collectPackageJsons(workspaceRoot, false), "jsr");
|
|
222
|
+
let hasFailed = false;
|
|
223
|
+
for (let pkg of workspace) {
|
|
224
|
+
if (pkg.json.name == null) continue;
|
|
225
|
+
if (await jsrCheckVersion({
|
|
226
|
+
registry,
|
|
227
|
+
package: pkg.json.name
|
|
228
|
+
})) continue;
|
|
229
|
+
let [scope_, packageName] = pkg.json.name.split("/");
|
|
230
|
+
let scope = scope_.startsWith("@") ? scope_.slice(1) : scope_;
|
|
231
|
+
if (token == null) {
|
|
232
|
+
info(`to create ${pkg.json.name} follow this link: ${new URL(`/create?scope=${scope}&package=${packageName}`, registry).href}`);
|
|
233
|
+
hasFailed = true;
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
await jsrMaybeCreatePackage({
|
|
237
|
+
name: pkg.json.name,
|
|
238
|
+
registry,
|
|
239
|
+
token
|
|
240
|
+
});
|
|
241
|
+
if (githubRepo != null) {
|
|
242
|
+
let [owner, repo] = githubRepo.split("/");
|
|
243
|
+
await jsrSetGithubRepo({
|
|
244
|
+
registry,
|
|
245
|
+
name: pkg.json.name,
|
|
246
|
+
token,
|
|
247
|
+
owner,
|
|
248
|
+
repo
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return hasFailed;
|
|
253
|
+
}
|
|
254
|
+
//#endregion
|
|
255
|
+
//#region src/jsr/deno-json.ts
|
|
256
|
+
var import_picomatch = /* @__PURE__ */ __toESM(require_picomatch(), 1);
|
|
257
|
+
function packageJsonToDeno({ packageJson, packageJsonOrig, workspaceVersions, exclude, buildDirName, baseDir }) {
|
|
258
|
+
let importMap = {};
|
|
259
|
+
let exports = {};
|
|
260
|
+
for (let field of [
|
|
261
|
+
"dependencies",
|
|
262
|
+
"peerDependencies",
|
|
263
|
+
"optionalDependencies"
|
|
264
|
+
]) {
|
|
265
|
+
let deps = packageJson[field];
|
|
266
|
+
if (deps == null) continue;
|
|
267
|
+
for (let [name, version] of Object.entries(deps)) {
|
|
268
|
+
if (typeof version !== "string") continue;
|
|
269
|
+
if (workspaceVersions.has(name)) continue;
|
|
270
|
+
else if (version.startsWith("npm:@jsr/")) {
|
|
271
|
+
let rest = version.slice(9);
|
|
272
|
+
importMap[name] = `jsr:@${rest.split("@")[0].replace("__", "/")}@${rest.split("@")[1]}`;
|
|
273
|
+
} else if (version.startsWith("jsr:")) importMap[name] = version;
|
|
274
|
+
else if (name) {
|
|
275
|
+
let packageName = name;
|
|
276
|
+
let packageVersion = version;
|
|
277
|
+
if (version.startsWith("npm:")) {
|
|
278
|
+
let npmValue = version.slice(4);
|
|
279
|
+
let idx = npmValue.lastIndexOf("@");
|
|
280
|
+
if (idx <= 0) throw new Error(`Invalid npm dependency: ${name}@${version}`);
|
|
281
|
+
packageName = npmValue.slice(0, idx);
|
|
282
|
+
packageVersion = npmValue.slice(idx + 1);
|
|
283
|
+
} else if (version.match(/\|\||&&|:/)) throw new Error(`Invalid npm dependency (not supported by JSR): ${name}@${version}`);
|
|
284
|
+
importMap[name] = `npm:${packageName}@${packageVersion}`;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
if (packageJsonOrig.exports != null) {
|
|
289
|
+
let tmpExports;
|
|
290
|
+
if (typeof packageJsonOrig.exports === "string") tmpExports = { ".": packageJsonOrig.exports };
|
|
291
|
+
else if (typeof packageJsonOrig.exports !== "object") throw new TypeError("package.json exports must be an object");
|
|
292
|
+
else tmpExports = packageJsonOrig.exports;
|
|
293
|
+
for (let [name, value] of Object.entries(tmpExports)) {
|
|
294
|
+
if (typeof value !== "string") throw new TypeError(`package.json exports value must be a string: ${name}`);
|
|
295
|
+
if (value.endsWith(".wasm")) continue;
|
|
296
|
+
if (baseDir != null && baseDir !== ".") {
|
|
297
|
+
if (!value.startsWith(`./${baseDir}`)) throw new Error(`Invalid export value: ${value} (must be inside ./${baseDir})`);
|
|
298
|
+
exports[name] = `./${value.slice(baseDir.length + 3)}`;
|
|
299
|
+
} else exports[name] = value;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return {
|
|
303
|
+
name: asNonNull(packageJson.name),
|
|
304
|
+
version: asNonNull(packageJson.version),
|
|
305
|
+
exports,
|
|
306
|
+
exclude,
|
|
307
|
+
imports: importMap,
|
|
308
|
+
publish: { exclude: [`!../${buildDirName}`] },
|
|
309
|
+
...packageJson.denoJson != null && typeof packageJson.denoJson === "object" ? packageJson.denoJson : {}
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
//#endregion
|
|
313
|
+
//#region src/jsr/_deno-directives.ts
|
|
314
|
+
function applyDenoDirectives(code) {
|
|
315
|
+
if (!code.match("<deno-(insert|remove|tsignore)>")) return code;
|
|
316
|
+
let insertContent = code.match(/\/\/\s*<deno-insert>(.*?)<\/deno-insert>/s);
|
|
317
|
+
while (insertContent) {
|
|
318
|
+
code = code.slice(0, insertContent.index) + insertContent[1].replace(/\/\/\s*/g, "") + code.slice(asNonNull(insertContent.index) + insertContent[0].length);
|
|
319
|
+
insertContent = code.match(/\/\/\s*<deno-insert>(.*?)<\/deno-insert>/s);
|
|
320
|
+
}
|
|
321
|
+
let removeContent = code.match(/\/\/\s*<deno-remove>(.*?)<\/deno-remove>/s);
|
|
322
|
+
while (removeContent) {
|
|
323
|
+
code = code.slice(0, removeContent.index) + code.slice(asNonNull(removeContent.index) + removeContent[0].length);
|
|
324
|
+
removeContent = code.match(/\/\/\s*<deno-remove>(.*?)<\/deno-remove>/s);
|
|
325
|
+
}
|
|
326
|
+
let tsIgnoreContent = code.match(/\/\/\s*<deno-tsignore>/);
|
|
327
|
+
while (tsIgnoreContent) {
|
|
328
|
+
code = `${code.slice(0, tsIgnoreContent.index)}/* @ts-ignore */${code.slice(asNonNull(tsIgnoreContent.index) + tsIgnoreContent[0].length)}`;
|
|
329
|
+
tsIgnoreContent = code.match(/\/\/\s*<deno-tsignore>/);
|
|
330
|
+
}
|
|
331
|
+
return code;
|
|
332
|
+
}
|
|
333
|
+
//#endregion
|
|
334
|
+
//#region src/jsr/generate-workspace.ts
|
|
335
|
+
function mergeArrays(a, b, defaultValue = []) {
|
|
336
|
+
if (!a) return b ?? defaultValue;
|
|
337
|
+
if (!b) return a;
|
|
338
|
+
return [...a, ...b];
|
|
339
|
+
}
|
|
340
|
+
function shouldCopySource(source, srcDir, excludeFilesPico) {
|
|
341
|
+
let rel = relative(srcDir, source);
|
|
342
|
+
if (rel === "") return true;
|
|
343
|
+
if (rel.split(/[\\/]/).some((part) => part === "node_modules" || part === ".git" || part === "dist")) return false;
|
|
344
|
+
if (excludeFilesPico(rel)) return false;
|
|
345
|
+
return true;
|
|
346
|
+
}
|
|
347
|
+
async function generateDenoWorkspace(params) {
|
|
348
|
+
let { workspaceRoot: workspaceRoot_, workspacePackages = await collectPackageJsons(workspaceRoot_, true), rootConfig, withDryRun = false, fixedVersion } = params;
|
|
349
|
+
let workspaceRoot = normalizeFilePath(workspaceRoot_);
|
|
350
|
+
let rootPackage = findRootPackage(workspacePackages);
|
|
351
|
+
let outDir = join(workspaceRoot, rootConfig?.outputDir ?? "dist/jsr");
|
|
352
|
+
await fsp.rm(outDir, {
|
|
353
|
+
recursive: true,
|
|
354
|
+
force: true
|
|
355
|
+
});
|
|
356
|
+
await fsp.mkdir(outDir, { recursive: true });
|
|
357
|
+
let rootDenoJson = { workspace: [] };
|
|
358
|
+
for (let pkg of filterPackageJsonsForPublish(workspacePackages, "jsr")) {
|
|
359
|
+
if (pkg.json.name == null) continue;
|
|
360
|
+
if (rootConfig?.includePackage != null && !rootConfig.includePackage(pkg)) continue;
|
|
361
|
+
let packageRoot = pkg.path;
|
|
362
|
+
let packageDirName = pkg.json.name.replace(/\//g, "__");
|
|
363
|
+
let packageOutRoot = join(outDir, packageDirName);
|
|
364
|
+
rootDenoJson.workspace.push(`./${packageDirName}`);
|
|
365
|
+
await fsp.mkdir(packageOutRoot, { recursive: true });
|
|
366
|
+
if (pkg.json.scripts?.["build:jsr"] != null) {
|
|
367
|
+
await exec([
|
|
368
|
+
"npm",
|
|
369
|
+
"run",
|
|
370
|
+
"build:jsr"
|
|
371
|
+
], {
|
|
372
|
+
env: {
|
|
373
|
+
...process.env,
|
|
374
|
+
YOROZU_BUILD_SRC: packageRoot,
|
|
375
|
+
YOROZU_BUILD_OUT: packageOutRoot
|
|
376
|
+
},
|
|
377
|
+
cwd: packageRoot,
|
|
378
|
+
stdio: "inherit",
|
|
379
|
+
throwOnError: true
|
|
380
|
+
});
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
let packageConfig = await loadBuildConfig(pkg.path);
|
|
384
|
+
let packageConfigJsr = packageConfig?.jsr;
|
|
385
|
+
let srcDir = join(packageRoot, normalizeFilePath(packageConfigJsr?.sourceDir ?? rootConfig?.sourceDir ?? ""));
|
|
386
|
+
let excludeFiles = mergeArrays(rootConfig?.exclude, packageConfigJsr?.exclude);
|
|
387
|
+
let excludeFilesPico = (0, import_picomatch.default)(excludeFiles);
|
|
388
|
+
await fsp.cp(srcDir, packageOutRoot, {
|
|
389
|
+
recursive: true,
|
|
390
|
+
filter(source) {
|
|
391
|
+
return shouldCopySource(source, srcDir, excludeFilesPico);
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
let printer = ts.createPrinter();
|
|
395
|
+
await asyncPool(await glob("**/*.ts", { cwd: packageOutRoot }), async (filename) => {
|
|
396
|
+
let fullFilePath = join(packageOutRoot, filename);
|
|
397
|
+
let fileContent = await fsp.readFile(fullFilePath, "utf8");
|
|
398
|
+
let changed = false;
|
|
399
|
+
let file = ts.createSourceFile(filename, fileContent, ts.ScriptTarget.ESNext, true);
|
|
400
|
+
let changedTs = false;
|
|
401
|
+
for (let imp of file.statements) {
|
|
402
|
+
if (!ts.isImportDeclaration(imp) && !ts.isExportDeclaration(imp)) continue;
|
|
403
|
+
if (!imp.moduleSpecifier || !ts.isStringLiteral(imp.moduleSpecifier)) continue;
|
|
404
|
+
let mod = imp.moduleSpecifier.text;
|
|
405
|
+
if (mod[0] !== ".") continue;
|
|
406
|
+
if (mod.endsWith(".js") || mod.endsWith(".jsx")) {
|
|
407
|
+
let newMod = mod.replace(/\.js(x?)$/, ".ts$1");
|
|
408
|
+
let fullPathOld = join(dirname(fullFilePath), mod);
|
|
409
|
+
let fullPathNew = join(dirname(fullFilePath), newMod);
|
|
410
|
+
if (!await fileExists(fullPathOld) && await fileExists(fullPathNew)) {
|
|
411
|
+
changedTs = true;
|
|
412
|
+
imp.moduleSpecifier = ts.factory.createStringLiteral(newMod);
|
|
413
|
+
}
|
|
414
|
+
} else throw new Error(`Invalid import specifier: ${mod} at ${join(srcDir, filename)}`);
|
|
415
|
+
}
|
|
416
|
+
if (rootConfig?.transformAst?.(file)) changedTs = true;
|
|
417
|
+
if (packageConfigJsr?.transformAst?.(file)) changedTs = true;
|
|
418
|
+
if (changedTs) {
|
|
419
|
+
fileContent = printer.printFile(file);
|
|
420
|
+
changed = true;
|
|
421
|
+
}
|
|
422
|
+
if (rootConfig?.enableDenoDirectives) fileContent = applyDenoDirectives(fileContent);
|
|
423
|
+
if (rootConfig?.transformCode || packageConfigJsr?.transformCode) {
|
|
424
|
+
let origFileContent = fileContent;
|
|
425
|
+
if (rootConfig?.transformCode) fileContent = rootConfig.transformCode(filename, fileContent);
|
|
426
|
+
if (packageConfigJsr?.transformCode) fileContent = packageConfigJsr.transformCode(filename, fileContent);
|
|
427
|
+
if (fileContent !== origFileContent) changed = true;
|
|
428
|
+
}
|
|
429
|
+
if (changed) await fsp.writeFile(fullFilePath, fileContent);
|
|
430
|
+
});
|
|
431
|
+
let hookContext = {
|
|
432
|
+
outDir: packageOutRoot,
|
|
433
|
+
packageDir: packageOutRoot,
|
|
434
|
+
packageName: pkg.json.name,
|
|
435
|
+
packageJson: pkg.json,
|
|
436
|
+
jsr: true,
|
|
437
|
+
typedoc: false
|
|
438
|
+
};
|
|
439
|
+
packageConfig?.preparePackageJson?.(hookContext);
|
|
440
|
+
let workspaceVersions = collectVersions(workspacePackages);
|
|
441
|
+
let { packageJson, packageJsonOriginal } = processPackageJson({
|
|
442
|
+
packageJson: pkg.json,
|
|
443
|
+
rootPackageJson: rootPackage.json,
|
|
444
|
+
workspaceVersions,
|
|
445
|
+
bundledWorkspaceDeps: [],
|
|
446
|
+
rootFieldsToCopy: new Set(["license"])
|
|
447
|
+
});
|
|
448
|
+
if (fixedVersion != null) {
|
|
449
|
+
packageJson.version = fixedVersion;
|
|
450
|
+
packageJsonOriginal.version = fixedVersion;
|
|
451
|
+
}
|
|
452
|
+
hookContext.packageJson = packageJson;
|
|
453
|
+
await packageConfig?.finalizePackageJson?.(hookContext);
|
|
454
|
+
let denoJson = packageJsonToDeno({
|
|
455
|
+
packageJson,
|
|
456
|
+
packageJsonOrig: packageJsonOriginal,
|
|
457
|
+
workspaceVersions,
|
|
458
|
+
buildDirName: relative(packageOutRoot, outDir),
|
|
459
|
+
baseDir: relative(packageRoot, srcDir),
|
|
460
|
+
exclude: excludeFiles
|
|
461
|
+
});
|
|
462
|
+
packageConfig?.jsr?.finalizeDenoJson?.(hookContext, denoJson);
|
|
463
|
+
rootConfig?.finalizeDenoJson?.(hookContext, denoJson);
|
|
464
|
+
await fsp.writeFile(join(packageOutRoot, "deno.json"), JSON.stringify(denoJson, null, 4));
|
|
465
|
+
for (let file of mergeArrays(rootConfig?.copyRootFiles, packageConfig?.jsr?.copyRootFiles, ["LICENSE"])) await tryCopy(join(workspaceRoot, file), join(packageOutRoot, file), { recursive: true });
|
|
466
|
+
for (let file of mergeArrays(rootConfig?.copyPackageFiles, packageConfig?.jsr?.copyPackageFiles, ["README.md"])) await tryCopy(join(packageRoot, file), join(packageOutRoot, file), { recursive: true });
|
|
467
|
+
await packageConfig?.jsr?.finalize?.(hookContext);
|
|
468
|
+
}
|
|
469
|
+
await fsp.writeFile(join(outDir, "deno.json"), JSON.stringify(rootDenoJson, null, 4));
|
|
470
|
+
await rootConfig?.finalize?.({
|
|
471
|
+
outDir,
|
|
472
|
+
packageDir: outDir,
|
|
473
|
+
packageName: "<jsr-root>",
|
|
474
|
+
packageJson: {},
|
|
475
|
+
jsr: true,
|
|
476
|
+
typedoc: false
|
|
477
|
+
});
|
|
478
|
+
if (rootConfig?.dryRun === true || withDryRun) await exec([
|
|
479
|
+
"deno",
|
|
480
|
+
"publish",
|
|
481
|
+
"--dry-run",
|
|
482
|
+
"-q",
|
|
483
|
+
"--allow-dirty"
|
|
484
|
+
], {
|
|
485
|
+
cwd: outDir,
|
|
486
|
+
stdio: "inherit",
|
|
487
|
+
throwOnError: true
|
|
488
|
+
});
|
|
489
|
+
return outDir;
|
|
490
|
+
}
|
|
491
|
+
//#endregion
|
|
492
|
+
//#region src/jsr/utils/jsr-json.ts
|
|
493
|
+
function parseJsrJson(json) {
|
|
494
|
+
let res = parseConfigFileTextToJson("jsr.json", json);
|
|
495
|
+
if (res.error) throw new Error(res.error.messageText.toString());
|
|
496
|
+
let obj = res.config;
|
|
497
|
+
if (typeof obj !== "object" || obj === null) throw new Error("Expected object");
|
|
498
|
+
if (typeof obj.name !== "string") throw new TypeError("Expected \"name\" to be a string");
|
|
499
|
+
if (typeof obj.version !== "string") throw new TypeError("Expected \"version\" to be a string");
|
|
500
|
+
if (typeof obj.exports !== "string" && (typeof obj.exports !== "object" || obj.exports === null)) throw new TypeError("Expected \"exports\" to be a string or an object");
|
|
501
|
+
if (typeof obj.exports !== "string") for (let key in obj.exports) {
|
|
502
|
+
if (typeof key !== "string") throw new TypeError("exports: Expected key to be a string");
|
|
503
|
+
if (typeof obj.exports[key] !== "string") throw new TypeError("exports: Expected value to be a string");
|
|
504
|
+
}
|
|
505
|
+
if (obj.imports !== void 0) {
|
|
506
|
+
if (typeof obj.imports !== "object" || obj.imports === null) throw new TypeError("Expected \"imports\" to be an object");
|
|
507
|
+
let imports = obj.imports;
|
|
508
|
+
for (let key in imports) {
|
|
509
|
+
if (typeof key !== "string") throw new TypeError("imports: Expected key to be a string");
|
|
510
|
+
if (typeof imports[key] !== "string") throw new TypeError("imports: Expected value to be a string");
|
|
511
|
+
imports[key] = parseImportSpecifier(imports[key]);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
if (obj.compilerOptions !== void 0) {
|
|
515
|
+
if (typeof obj.compilerOptions !== "object" || obj.compilerOptions === null) throw new TypeError("Expected \"compilerOptions\" to be an object");
|
|
516
|
+
}
|
|
517
|
+
return obj;
|
|
518
|
+
}
|
|
519
|
+
var _findClosestJsrJsonCache = /* @__PURE__ */ new Map();
|
|
520
|
+
function findClosestJsrJson(path) {
|
|
521
|
+
while (true) {
|
|
522
|
+
if (_findClosestJsrJsonCache.has(path)) return _findClosestJsrJsonCache.get(path) ?? null;
|
|
523
|
+
for (let file of [
|
|
524
|
+
"jsr.json",
|
|
525
|
+
"deno.json",
|
|
526
|
+
"jsr.jsonc",
|
|
527
|
+
"deno.jsonc"
|
|
528
|
+
]) if (existsSync(join(path, file))) {
|
|
529
|
+
_findClosestJsrJsonCache.set(path, join(path, file));
|
|
530
|
+
return join(path, file);
|
|
531
|
+
}
|
|
532
|
+
if (existsSync(join(path, "package.json"))) {
|
|
533
|
+
_findClosestJsrJsonCache.set(path, null);
|
|
534
|
+
return null;
|
|
535
|
+
}
|
|
536
|
+
let parent = join(path, "..");
|
|
537
|
+
if (parent === path) return null;
|
|
538
|
+
path = parent;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
//#endregion
|
|
542
|
+
//#region src/jsr/populate.ts
|
|
543
|
+
async function findPackageDependencies(packagePath) {
|
|
544
|
+
let jsrJsonPath = findClosestJsrJson(packagePath);
|
|
545
|
+
if (jsrJsonPath == null) throw new Error(`Could not find jsr.json for package at ${packagePath}`);
|
|
546
|
+
let jsrJson = parseJsrJson(await fsp.readFile(jsrJsonPath, "utf8"));
|
|
547
|
+
let entrypoints = typeof jsrJson.exports === "string" ? [jsrJson.exports] : Object.values(jsrJson.exports);
|
|
548
|
+
let visited = /* @__PURE__ */ new Set();
|
|
549
|
+
let dependencies = /* @__PURE__ */ new Set();
|
|
550
|
+
let queue = [...entrypoints];
|
|
551
|
+
while (queue.length > 0) {
|
|
552
|
+
let file = queue.shift();
|
|
553
|
+
if (file == null || visited.has(file)) continue;
|
|
554
|
+
visited.add(file);
|
|
555
|
+
const handleSpecifier = (specifier) => {
|
|
556
|
+
if (specifier.startsWith("jsr:")) {
|
|
557
|
+
let parsed = parseImportSpecifier(specifier);
|
|
558
|
+
dependencies.add(`${parsed.packageName}@${parsed.version}`);
|
|
559
|
+
} else if (specifier.startsWith(".")) {
|
|
560
|
+
let relative = resolve(dirname(join(packagePath, file)), specifier).slice(packagePath.length + 1);
|
|
561
|
+
if (!relative.startsWith(".")) relative = `./${relative}`;
|
|
562
|
+
queue.push(relative);
|
|
563
|
+
}
|
|
564
|
+
};
|
|
565
|
+
let content = await fsp.readFile(join(packagePath, file), "utf8");
|
|
566
|
+
let source = ts.createSourceFile(file, content, ts.ScriptTarget.ESNext, true);
|
|
567
|
+
for (let node of source.statements) if (ts.isImportDeclaration(node)) handleSpecifier(node.moduleSpecifier.getText().slice(1, -1));
|
|
568
|
+
else if (ts.isExportDeclaration(node) && node.moduleSpecifier) handleSpecifier(node.moduleSpecifier.getText().slice(1, -1));
|
|
569
|
+
}
|
|
570
|
+
return Array.from(dependencies);
|
|
571
|
+
}
|
|
572
|
+
async function populateFromUpstream(params) {
|
|
573
|
+
let { upstream = "https://jsr.io", downstream, packages, token, createViaApi = false, deno = "deno", quiet = false, publishArgs: _publishArgs } = params;
|
|
574
|
+
let publishArgs = typeof _publishArgs === "function" ? _publishArgs : () => _publishArgs || [];
|
|
575
|
+
if (createViaApi && token == null) throw new Error("createViaApi requires a token");
|
|
576
|
+
let depsMap = /* @__PURE__ */ new Map();
|
|
577
|
+
let nameToPath = /* @__PURE__ */ new Map();
|
|
578
|
+
let pending = [...packages];
|
|
579
|
+
let seen = /* @__PURE__ */ new Set();
|
|
580
|
+
while (pending.length > 0) {
|
|
581
|
+
let batch = pending.splice(0, pending.length).filter((pkg) => !seen.has(pkg));
|
|
582
|
+
for (let pkg of batch) seen.add(pkg);
|
|
583
|
+
if (batch.length === 0) break;
|
|
584
|
+
await asyncPool(batch, async (pkg) => {
|
|
585
|
+
if (!quiet) info(`Downloading ${pkg}...`);
|
|
586
|
+
let path = await downloadJsrPackage(parseImportSpecifier(`jsr:${pkg}`), { registry: upstream });
|
|
587
|
+
nameToPath.set(pkg, path);
|
|
588
|
+
let deps = await findPackageDependencies(path);
|
|
589
|
+
depsMap.set(pkg, deps);
|
|
590
|
+
for (let dep of deps) if (!seen.has(dep)) pending.push(dep);
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
let order = determinePublishOrder(Object.fromEntries(depsMap));
|
|
594
|
+
for (let item of order) {
|
|
595
|
+
let spec = parseImportSpecifier(`jsr:${item}`);
|
|
596
|
+
let path = nameToPath.get(item);
|
|
597
|
+
if (path == null) throw new Error(`Missing downloaded package path for ${item}`);
|
|
598
|
+
if (createViaApi) await jsrMaybeCreatePackage({
|
|
599
|
+
name: spec.packageName,
|
|
600
|
+
registry: downstream,
|
|
601
|
+
token,
|
|
602
|
+
quiet
|
|
603
|
+
});
|
|
604
|
+
if (!quiet) info(`Publishing ${item}...`);
|
|
605
|
+
await exec([
|
|
606
|
+
deno,
|
|
607
|
+
"publish",
|
|
608
|
+
"--quiet",
|
|
609
|
+
...token != null ? ["--token", token] : [],
|
|
610
|
+
...publishArgs(item)
|
|
611
|
+
], {
|
|
612
|
+
env: {
|
|
613
|
+
...process.env,
|
|
614
|
+
JSR_URL: downstream
|
|
615
|
+
},
|
|
616
|
+
cwd: path,
|
|
617
|
+
stdio: "inherit",
|
|
618
|
+
throwOnError: true
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
//#endregion
|
|
623
|
+
export { downloadJsrPackage, findClosestJsrJson, generateDenoWorkspace, getModuleCacheDirectory, jsrCheckVersion, jsrCreatePackages, jsrCreateScope, jsrGetScopeInfo, jsrMaybeCreatePackage, jsrSetGithubRepo, packageJsonToDeno, parseImportSpecifier, parseJsrJson, populateFromUpstream, splitImportRequest };
|