pkg-pr-new 0.0.7 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +123 -50
- package/index.ts +76 -52
- package/package.json +2 -2
- package/template.ts +54 -0
package/index.ts
CHANGED
|
@@ -6,21 +6,27 @@ import { createHash } from "node:crypto";
|
|
|
6
6
|
import { hash } from "ohash";
|
|
7
7
|
import fsSync from "fs";
|
|
8
8
|
import fs from "fs/promises";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
9
|
+
import { getPackageManifest, type PackageManifest } from "query-registry";
|
|
10
|
+
import type { Comment } from "@pkg-pr-new/utils";
|
|
11
|
+
import {
|
|
12
|
+
abbreviateCommitHash,
|
|
13
|
+
extractOwnerAndRepo,
|
|
14
|
+
extractRepository,
|
|
15
|
+
} from "@pkg-pr-new/utils";
|
|
12
16
|
import fg from "fast-glob";
|
|
13
17
|
import ignore from "ignore";
|
|
14
18
|
import "./environments";
|
|
15
19
|
import pkg from "./package.json" with { type: "json" };
|
|
16
20
|
import { isBinaryFile } from "isbinaryfile";
|
|
17
21
|
import { readPackageJSON, writePackageJSON } from "pkg-types";
|
|
22
|
+
import { createDefaultTemplate } from "./template";
|
|
18
23
|
|
|
19
24
|
declare global {
|
|
20
25
|
var API_URL: string;
|
|
21
26
|
}
|
|
22
27
|
|
|
23
|
-
const
|
|
28
|
+
const apiUrl = process.env.API_URL ?? API_URL;
|
|
29
|
+
const publishUrl = new URL("/publish", apiUrl);
|
|
24
30
|
|
|
25
31
|
const main = defineCommand({
|
|
26
32
|
meta: {
|
|
@@ -46,6 +52,11 @@ const main = defineCommand({
|
|
|
46
52
|
description:
|
|
47
53
|
"generate stackblitz templates out of directories in the current repo with the new built packages",
|
|
48
54
|
},
|
|
55
|
+
comment: {
|
|
56
|
+
type: "string", // "off", "create", "update" (default)
|
|
57
|
+
description: `"off" for no comments (silent mode). "create" for comment on each publish. "update" for one comment across the pull request with edits on each publish (default)`,
|
|
58
|
+
default: "update",
|
|
59
|
+
},
|
|
49
60
|
},
|
|
50
61
|
run: async ({ args }) => {
|
|
51
62
|
const paths = (args._.length ? args._ : ["."])
|
|
@@ -55,7 +66,7 @@ const main = defineCommand({
|
|
|
55
66
|
const templates = (
|
|
56
67
|
typeof args.template === "string"
|
|
57
68
|
? [args.template]
|
|
58
|
-
: ([...(args.template
|
|
69
|
+
: ([...(args.template || [])] as string[])
|
|
59
70
|
)
|
|
60
71
|
.flatMap((p) => (fg.isDynamicPattern(p) ? fg.sync(p) : p))
|
|
61
72
|
.map((p) => path.resolve(p));
|
|
@@ -65,6 +76,8 @@ const main = defineCommand({
|
|
|
65
76
|
const isCompact = !!args.compact;
|
|
66
77
|
const isPnpm = !!args.pnpm;
|
|
67
78
|
|
|
79
|
+
const comment: Comment = args.comment as Comment;
|
|
80
|
+
|
|
68
81
|
if (!process.env.TEST && process.env.GITHUB_ACTIONS !== "true") {
|
|
69
82
|
console.error(
|
|
70
83
|
"Continuous Releases are only available in Github Actions.",
|
|
@@ -72,14 +85,11 @@ const main = defineCommand({
|
|
|
72
85
|
process.exit(1);
|
|
73
86
|
}
|
|
74
87
|
|
|
75
|
-
new Octokit(); // gh authentication
|
|
76
|
-
|
|
77
88
|
const {
|
|
78
89
|
GITHUB_REPOSITORY,
|
|
79
90
|
GITHUB_RUN_ID,
|
|
80
91
|
GITHUB_RUN_ATTEMPT,
|
|
81
92
|
GITHUB_ACTOR_ID,
|
|
82
|
-
GITHUB_JOB
|
|
83
93
|
} = process.env;
|
|
84
94
|
|
|
85
95
|
const [owner, repo] = GITHUB_REPOSITORY.split("/");
|
|
@@ -87,15 +97,14 @@ const main = defineCommand({
|
|
|
87
97
|
const metadata = {
|
|
88
98
|
owner,
|
|
89
99
|
repo,
|
|
90
|
-
|
|
91
|
-
runId: Number(GITHUB_RUN_ID),
|
|
100
|
+
run: Number(GITHUB_RUN_ID),
|
|
92
101
|
attempt: Number(GITHUB_RUN_ATTEMPT),
|
|
93
102
|
actor: Number(GITHUB_ACTOR_ID),
|
|
94
103
|
};
|
|
95
104
|
|
|
96
105
|
const key = hash(metadata);
|
|
97
106
|
|
|
98
|
-
const checkResponse = await fetch(new URL("/check",
|
|
107
|
+
const checkResponse = await fetch(new URL("/check", apiUrl), {
|
|
99
108
|
method: "POST",
|
|
100
109
|
body: JSON.stringify({
|
|
101
110
|
owner,
|
|
@@ -110,6 +119,7 @@ const main = defineCommand({
|
|
|
110
119
|
}
|
|
111
120
|
|
|
112
121
|
const { sha } = await checkResponse.json();
|
|
122
|
+
const abbreviatedSha = abbreviateCommitHash(sha);
|
|
113
123
|
|
|
114
124
|
const deps: Map<string, string> = new Map();
|
|
115
125
|
|
|
@@ -128,8 +138,8 @@ const main = defineCommand({
|
|
|
128
138
|
deps.set(
|
|
129
139
|
pJson.name,
|
|
130
140
|
new URL(
|
|
131
|
-
`/${owner}/${repo}/${pJson.name}@${
|
|
132
|
-
|
|
141
|
+
`/${owner}/${repo}/${pJson.name}@${abbreviatedSha}`,
|
|
142
|
+
apiUrl,
|
|
133
143
|
).href,
|
|
134
144
|
);
|
|
135
145
|
}
|
|
@@ -177,6 +187,21 @@ const main = defineCommand({
|
|
|
177
187
|
await restore();
|
|
178
188
|
}
|
|
179
189
|
|
|
190
|
+
const noDefaultTemplate = args.template === false;
|
|
191
|
+
|
|
192
|
+
if (!templates.length && !noDefaultTemplate) {
|
|
193
|
+
const project = createDefaultTemplate(
|
|
194
|
+
Object.fromEntries(deps.entries()),
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
for (const filePath of Object.keys(project)) {
|
|
198
|
+
formData.append(
|
|
199
|
+
`template:default:${encodeURIComponent(filePath)}`,
|
|
200
|
+
project[filePath],
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
180
205
|
const restoreMap = new Map<
|
|
181
206
|
string,
|
|
182
207
|
Awaited<ReturnType<typeof writeDeps>>
|
|
@@ -219,6 +244,7 @@ const main = defineCommand({
|
|
|
219
244
|
const res = await fetch(publishUrl, {
|
|
220
245
|
method: "POST",
|
|
221
246
|
headers: {
|
|
247
|
+
"sb-comment": comment,
|
|
222
248
|
"sb-compact": `${isCompact}`,
|
|
223
249
|
"sb-key": key,
|
|
224
250
|
"sb-shasums": JSON.stringify(shasums),
|
|
@@ -259,30 +285,18 @@ runMain(main);
|
|
|
259
285
|
|
|
260
286
|
// TODO: we'll add support for yarn if users hit issues with npm
|
|
261
287
|
async function resolveTarball(pm: "npm" | "pnpm", p: string) {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
stdio: "overlapped",
|
|
275
|
-
cwd: p,
|
|
276
|
-
});
|
|
277
|
-
const filename = stdout.trim();
|
|
278
|
-
|
|
279
|
-
const shasum = createHash("sha1")
|
|
280
|
-
.update(await fs.readFile(path.resolve(p, filename)))
|
|
281
|
-
.digest("hex");
|
|
282
|
-
|
|
283
|
-
return { filename, shasum };
|
|
284
|
-
}
|
|
285
|
-
throw new Error("Could not resolve package manager");
|
|
288
|
+
const { stdout } = await ezSpawn.async(`${pm} pack`, {
|
|
289
|
+
stdio: "overlapped",
|
|
290
|
+
cwd: p,
|
|
291
|
+
});
|
|
292
|
+
const lines = stdout.split("\n").filter(Boolean);
|
|
293
|
+
const filename = lines[lines.length - 1].trim();
|
|
294
|
+
|
|
295
|
+
const shasum = createHash("sha1")
|
|
296
|
+
.update(await fs.readFile(path.resolve(p, filename)))
|
|
297
|
+
.digest("hex");
|
|
298
|
+
|
|
299
|
+
return { filename, shasum };
|
|
286
300
|
}
|
|
287
301
|
|
|
288
302
|
async function writeDeps(p: string, deps: Map<string, string>) {
|
|
@@ -314,23 +328,33 @@ function hijackDeps(
|
|
|
314
328
|
}
|
|
315
329
|
|
|
316
330
|
async function verifyCompactMode(packageName: string) {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
Make sure to have your package on npm first or configure the 'repository' field in your package.json properly.`,
|
|
320
|
-
);
|
|
331
|
+
let manifest: PackageManifest;
|
|
332
|
+
|
|
321
333
|
try {
|
|
322
|
-
|
|
334
|
+
manifest = await getPackageManifest(packageName);
|
|
335
|
+
} catch {
|
|
336
|
+
throw new Error(
|
|
337
|
+
`pkg-pr-new cannot resolve ${packageName} from npm. --compact flag depends on the package being available in npm.
|
|
338
|
+
Make sure to have your package on npm first.`,
|
|
339
|
+
);
|
|
340
|
+
}
|
|
323
341
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
throw error;
|
|
327
|
-
}
|
|
342
|
+
const instruction = `Make sure to configure the 'repository' / 'repository.url' field in its package.json properly.
|
|
343
|
+
See https://docs.npmjs.com/cli/v10/configuring-npm/package-json#repository for details.`;
|
|
328
344
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
345
|
+
const repository = extractRepository(manifest);
|
|
346
|
+
if (!repository) {
|
|
347
|
+
throw new Error(
|
|
348
|
+
`pkg-pr-new cannot extract the repository link from the ${packageName} manifest. --compact flag requires the link to be present.
|
|
349
|
+
${instruction}`,
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
const match = extractOwnerAndRepo(repository);
|
|
354
|
+
if (!match) {
|
|
355
|
+
throw new Error(
|
|
356
|
+
`pkg-pr-new cannot extract the owner and repo names from the ${packageName} repository link: ${repository}. --compact flag requires these names.
|
|
357
|
+
${instruction}`,
|
|
358
|
+
);
|
|
335
359
|
}
|
|
336
360
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pkg-pr-new",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"ignore": "^5.3.1",
|
|
23
23
|
"isbinaryfile": "^5.0.2",
|
|
24
24
|
"pkg-types": "^1.1.1",
|
|
25
|
-
"query-registry": "^3.0.
|
|
25
|
+
"query-registry": "^3.0.1"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@pkg-pr-new/utils": "workspace:^",
|
package/template.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export const createDefaultTemplate = (
|
|
2
|
+
dependencies: Record<string, string>,
|
|
3
|
+
) => ({
|
|
4
|
+
"index.js": "",
|
|
5
|
+
"README.md": `
|
|
6
|
+
# Default Template
|
|
7
|
+
|
|
8
|
+
This is a template that leverages the experimental templates feature in the \`pkg.pr.new\` tool.
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
Templates are particularly useful for creating live, interactive examples of your packages, which can be very beneficial for both development and documentation purposes.
|
|
13
|
+
|
|
14
|
+
As a user, you can check the package.json file and see the new generated packages! You can just copy those and put them in your package.json or install them with your favorite package manager.
|
|
15
|
+
|
|
16
|
+
${Object.values(dependencies)
|
|
17
|
+
.map(
|
|
18
|
+
(url) => `
|
|
19
|
+
\`\`\`sh
|
|
20
|
+
npm i ${url}
|
|
21
|
+
\`\`\`
|
|
22
|
+
`,
|
|
23
|
+
)
|
|
24
|
+
.join("")}
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
To use this feature as a maintainer, you can run the following command:
|
|
29
|
+
|
|
30
|
+
\`\`\`sh
|
|
31
|
+
npx pkg-pr-new publish ./packages/A --template ./examples/*
|
|
32
|
+
\`\`\`
|
|
33
|
+
|
|
34
|
+
## Benefits
|
|
35
|
+
|
|
36
|
+
- Interactive Demos: Automatically create live demos that users can interact with directly in their browser.
|
|
37
|
+
- Enhanced Testing: Quickly spin up environments to test your package in different scenarios.
|
|
38
|
+
- Improved Sharing: Easily share working examples of your package with collaborators or users without needing them to set up their environment.
|
|
39
|
+
`,
|
|
40
|
+
"package.json": JSON.stringify(
|
|
41
|
+
{
|
|
42
|
+
name: "default",
|
|
43
|
+
version: "1.0.0",
|
|
44
|
+
description: "generated by pkg.pr.new",
|
|
45
|
+
main: "index.js",
|
|
46
|
+
dependencies,
|
|
47
|
+
keywords: [],
|
|
48
|
+
author: "pkg.pr.new",
|
|
49
|
+
license: "ISC",
|
|
50
|
+
},
|
|
51
|
+
null,
|
|
52
|
+
2,
|
|
53
|
+
),
|
|
54
|
+
});
|