pkg-pr-new 0.0.19 → 0.0.21

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.
Files changed (3) hide show
  1. package/dist/index.js +64 -21
  2. package/index.ts +81 -20
  3. package/package.json +4 -4
package/index.ts CHANGED
@@ -6,7 +6,7 @@ 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 { detect } from "detect-package-manager";
9
+ import { detect } from "package-manager-detector";
10
10
  import { getPackageManifest, type PackageManifest } from "query-registry";
11
11
  import type { Comment } from "@pkg-pr-new/utils";
12
12
  import {
@@ -14,7 +14,7 @@ import {
14
14
  extractOwnerAndRepo,
15
15
  extractRepository,
16
16
  } from "@pkg-pr-new/utils";
17
- import fg from "fast-glob";
17
+ import { glob, globSync } from "tinyglobby";
18
18
  import ignore from "ignore";
19
19
  import "./environments";
20
20
  import pkg from "./package.json" with { type: "json" };
@@ -26,6 +26,18 @@ declare global {
26
26
  var API_URL: string;
27
27
  }
28
28
 
29
+ type OutputMetadata = {
30
+ packages: {
31
+ name: string;
32
+ url: string;
33
+ shasum: string;
34
+ }[];
35
+ templates: {
36
+ name: string;
37
+ url: string;
38
+ }[];
39
+ };
40
+
29
41
  const apiUrl = process.env.API_URL ?? API_URL;
30
42
  const publishUrl = new URL("/publish", apiUrl);
31
43
 
@@ -64,10 +76,19 @@ const main = defineCommand({
64
76
  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)`,
65
77
  default: "update",
66
78
  },
79
+ "only-templates": {
80
+ type: "boolean",
81
+ description: `generate only stackblitz templates`,
82
+ default: false,
83
+ },
84
+ json: {
85
+ type: "mixed",
86
+ description: `Save metadata to a JSON file. If true, log the output for piping. If a string, save the output to the specified file path.`,
87
+ },
67
88
  },
68
89
  run: async ({ args }) => {
69
90
  const paths = (args._.length ? args._ : ["."])
70
- .flatMap((p) => fg.sync(p, { onlyDirectories: true }))
91
+ .flatMap((p) => globSync([p], { expandDirectories: false, onlyDirectories: true }))
71
92
  .map((p) => path.resolve(p.trim()));
72
93
 
73
94
  const templates = (
@@ -75,7 +96,7 @@ const main = defineCommand({
75
96
  ? [args.template]
76
97
  : ([...(args.template || [])] as string[])
77
98
  )
78
- .flatMap((p) => fg.sync(p, { onlyDirectories: true }))
99
+ .flatMap((p) => globSync([p], { expandDirectories: false, onlyDirectories: true }))
79
100
  .map((p) => path.resolve(p.trim()));
80
101
 
81
102
  const formData = new FormData();
@@ -83,6 +104,7 @@ const main = defineCommand({
83
104
  const isCompact = !!args.compact;
84
105
  const isPnpm = !!args.pnpm;
85
106
  const isPeerDepsEnabled = !!args.peerDeps
107
+ const isOnlyTemplates = !!args['only-templates']
86
108
 
87
109
  const comment: Comment = args.comment as Comment;
88
110
 
@@ -122,7 +144,7 @@ const main = defineCommand({
122
144
  });
123
145
 
124
146
  if (!checkResponse.ok) {
125
- console.log(await checkResponse.text());
147
+ console.error(await checkResponse.text());
126
148
  process.exit(1);
127
149
  }
128
150
 
@@ -132,6 +154,14 @@ const main = defineCommand({
132
154
  const deps: Map<string, string> = new Map(); // pkg.pr.new versions of the package
133
155
  const realDeps: Map<string, string> | null = isPeerDepsEnabled ? new Map() : null // real versions of the package, useful for peerDependencies
134
156
 
157
+ const printJson = typeof args.json === 'boolean';
158
+ const saveJson = typeof args.json === 'string';
159
+ const jsonFilePath = saveJson ? args.json : '';
160
+ const outputMetadata: OutputMetadata = {
161
+ packages: [],
162
+ templates: [],
163
+ };
164
+
135
165
  for (const p of paths) {
136
166
  if (!(await hasPackageJson(p))) {
137
167
  continue;
@@ -151,9 +181,9 @@ const main = defineCommand({
151
181
  }
152
182
 
153
183
  const depUrl = new URL(
154
- `/${owner}/${repo}/${pJson.name}@${abbreviatedSha}`,
155
- apiUrl,
156
- ).href
184
+ `/${owner}/${repo}/${pJson.name}@${abbreviatedSha}`,
185
+ apiUrl,
186
+ ).href
157
187
  deps.set(
158
188
  pJson.name,
159
189
  depUrl,
@@ -164,11 +194,18 @@ const main = defineCommand({
164
194
  if (resource.ok) {
165
195
  console.warn(`${pJson.name}@${abbreviatedSha} was already published on ${depUrl}`)
166
196
  }
197
+
198
+ // Collect package metadata
199
+ outputMetadata.packages.push({
200
+ name: pJson.name,
201
+ url: depUrl,
202
+ shasum: "", // will be filled later
203
+ });
167
204
  }
168
205
 
169
206
  for (const templateDir of templates) {
170
207
  if (!(await hasPackageJson(templateDir))) {
171
- console.log(
208
+ console.warn(
172
209
  `skipping ${templateDir} because there's no package.json file`,
173
210
  );
174
211
  continue;
@@ -180,7 +217,7 @@ const main = defineCommand({
180
217
  throw new Error(`"name" field in ${pJsonPath} should be defined`);
181
218
  }
182
219
 
183
- console.log("preparing template:", pJson.name);
220
+ console.warn("preparing template:", pJson.name);
184
221
 
185
222
  const restore = await writeDeps(templateDir, deps, realDeps);
186
223
 
@@ -194,11 +231,11 @@ const main = defineCommand({
194
231
  ig.add(gitignoreContent);
195
232
  }
196
233
 
197
- const files = await fg(["**/*"], {
234
+ const files = await glob(["**/*"], {
198
235
  cwd: templateDir,
199
236
  dot: true,
200
237
  onlyFiles: true,
201
- ignore: ['node_modules', '.git'], // always ignore node_modules and .git
238
+ ignore: ['**/node_modules', '.git'], // always ignore node_modules and .git
202
239
  });
203
240
 
204
241
  const filteredFiles = files.filter((file) => !ig.ignores(file));
@@ -215,6 +252,16 @@ const main = defineCommand({
215
252
  );
216
253
  }
217
254
  await restore();
255
+
256
+ // Collect template metadata
257
+ const templateUrl = new URL(
258
+ `/${owner}/${repo}/template/${pJson.name}`,
259
+ apiUrl,
260
+ ).href;
261
+ outputMetadata.templates.push({
262
+ name: pJson.name,
263
+ url: templateUrl,
264
+ });
218
265
  }
219
266
 
220
267
  const noDefaultTemplate = args.template === false;
@@ -253,7 +300,7 @@ const main = defineCommand({
253
300
  const shasums: Record<string, string> = {};
254
301
  for (const p of paths) {
255
302
  if (!(await hasPackageJson(p))) {
256
- console.log(`skipping ${p} because there's no package.json file`);
303
+ console.warn(`skipping ${p} because there's no package.json file`);
257
304
  continue;
258
305
  }
259
306
  const pJsonPath = path.resolve(p, "package.json");
@@ -266,7 +313,7 @@ const main = defineCommand({
266
313
  );
267
314
  }
268
315
  if (pJson.private) {
269
- console.log(`skipping ${p} because the package is private`);
316
+ console.warn(`skipping ${p} because the package is private`);
270
317
  continue;
271
318
  }
272
319
 
@@ -276,7 +323,10 @@ const main = defineCommand({
276
323
  );
277
324
 
278
325
  shasums[pJson.name] = shasum;
279
- console.log(`shasum for ${pJson.name}(${filename}): ${shasum}`);
326
+ console.warn(`shasum for ${pJson.name}(${filename}): ${shasum}`);
327
+
328
+ const outputPkg = outputMetadata.packages.find(p => p.name === pJson.name)!;
329
+ outputPkg.shasum = shasum;
280
330
 
281
331
  const file = await fs.readFile(path.resolve(p, filename));
282
332
 
@@ -298,7 +348,8 @@ const main = defineCommand({
298
348
  "sb-key": key,
299
349
  "sb-shasums": JSON.stringify(shasums),
300
350
  "sb-run-id": GITHUB_RUN_ID,
301
- "sb-package-manager": packageManager,
351
+ "sb-package-manager": packageManager.agent ?? "npm",
352
+ "sb-only-templates": `${isOnlyTemplates}`
302
353
  },
303
354
  body: formData,
304
355
  });
@@ -309,8 +360,8 @@ const main = defineCommand({
309
360
  `publishing failed: ${await res.text()}`,
310
361
  );
311
362
 
312
- console.log("\n");
313
- console.log(
363
+ console.warn("\n");
364
+ console.warn(
314
365
  `⚡️ Your npm packages are published.\n${[...formData.keys()]
315
366
  .filter((k) => k.startsWith("package:"))
316
367
  .map(
@@ -319,19 +370,28 @@ const main = defineCommand({
319
370
  )
320
371
  .join("\n")}`,
321
372
  );
373
+
374
+ const output = JSON.stringify(outputMetadata, null, 2);
375
+ if (printJson) {
376
+ console.log(output); // Log output for piping
377
+ }
378
+ if (saveJson) {
379
+ await fs.writeFile(jsonFilePath, output);
380
+ console.warn(`metadata written to ${jsonFilePath}`);
381
+ }
322
382
  },
323
383
  };
324
384
  },
325
385
  link: () => {
326
386
  return {
327
387
  meta: {},
328
- run: () => {},
388
+ run: () => { },
329
389
  };
330
390
  },
331
391
  },
332
392
  });
333
393
 
334
- runMain(main);
394
+ runMain(main).then(() => process.exit(0)).catch(() => process.exit(1));
335
395
 
336
396
  // TODO: we'll add support for yarn if users hit issues with npm
337
397
  async function resolveTarball(pm: "npm" | "pnpm", p: string) {
@@ -357,6 +417,7 @@ async function writeDeps(p: string, deps: Map<string, string>, realDeps: Map<str
357
417
 
358
418
  hijackDeps(deps, pJson.dependencies);
359
419
  hijackDeps(deps, pJson.devDependencies);
420
+ hijackDeps(deps, pJson.optionalDependencies);
360
421
 
361
422
  if (realDeps) {
362
423
  hijackDeps(realDeps, pJson.peerDependencies);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pkg-pr-new",
3
- "version": "0.0.19",
3
+ "version": "0.0.21",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -23,12 +23,12 @@
23
23
  "dependencies": {
24
24
  "@jsdevtools/ez-spawn": "^3.0.4",
25
25
  "@octokit/action": "^6.1.0",
26
- "detect-package-manager": "^3.0.2",
27
- "fast-glob": "^3.3.2",
28
26
  "ignore": "^5.3.1",
29
27
  "isbinaryfile": "^5.0.2",
28
+ "package-manager-detector": "^0.1.2",
30
29
  "pkg-types": "^1.1.1",
31
- "query-registry": "^3.0.1"
30
+ "query-registry": "^3.0.1",
31
+ "tinyglobby": "^0.2.2"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@pkg-pr-new/utils": "workspace:^",