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/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 { Octokit } from "@octokit/action";
10
- import { getPackageManifest } from "query-registry";
11
- import { extractOwnerAndRepo, extractRepository } from "@pkg-pr-new/utils";
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 publishUrl = new URL("/publish", API_URL);
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 ?? [])] as string[])
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
- job: GITHUB_JOB,
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", API_URL), {
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}@${sha}`,
132
- API_URL,
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
- if (pm === "npm") {
263
- const { stdout } = await ezSpawn.async("npm pack --json", {
264
- stdio: "overlapped",
265
- cwd: p,
266
- });
267
-
268
- const { filename, shasum }: { filename: string; shasum: string } =
269
- JSON.parse(stdout)[0];
270
-
271
- return { filename, shasum };
272
- } else if (pm === "pnpm") {
273
- const { stdout } = await ezSpawn.async("pnpm pack", {
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
- const error = new Error(
318
- `pkg-pr-new cannot resolve ${packageName} from npm. --compact flag depends on the package being available in npm.
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
- const manifest = await getPackageManifest(packageName);
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
- const repository = extractRepository(manifest);
325
- if (!repository) {
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
- const match = extractOwnerAndRepo(repository);
330
- if (!match) {
331
- throw error;
332
- }
333
- } catch {
334
- throw error;
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.7",
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.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
+ });