@emeryld/manager 1.0.0 → 1.0.1

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 (2) hide show
  1. package/dist/publish.js +80 -0
  2. package/package.json +1 -1
package/dist/publish.js CHANGED
@@ -1,4 +1,8 @@
1
1
  // src/publish.js
2
+ import { readFile } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { lt, valid } from 'semver';
2
6
  import { runHelperCli } from './helper-cli.js';
3
7
  import { buildPackageSelectionMenu, runStepLoop } from './menu.js';
4
8
  import { getOrderedPackages, loadPackages, resolvePackage } from './packages.js';
@@ -7,6 +11,67 @@ import { ensureWorkingTreeCommitted } from './preflight.js';
7
11
  import { publishCliState } from './prompts.js';
8
12
  import { createRrrPackage, runCreatePackageCli, } from './create-package/index.js';
9
13
  import { colors, logGlobal } from './utils/log.js';
14
+ import { run } from './utils/run.js';
15
+ const MANAGER_PACKAGE = '@emeryld/manager';
16
+ const UPDATE_CHECK_TIMEOUT_MS = 2500;
17
+ const managerRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
18
+ const managerPackageJsonPath = path.join(managerRoot, 'package.json');
19
+ async function readJsonFile(filePath) {
20
+ try {
21
+ const raw = await readFile(filePath, 'utf8');
22
+ return JSON.parse(raw);
23
+ }
24
+ catch {
25
+ return undefined;
26
+ }
27
+ }
28
+ async function getCurrentManagerVersion() {
29
+ const pkg = await readJsonFile(managerPackageJsonPath);
30
+ return pkg?.version;
31
+ }
32
+ async function fetchLatestVersion(pkgName) {
33
+ if (typeof fetch !== 'function')
34
+ return undefined;
35
+ const encoded = pkgName.replace('/', '%2F');
36
+ const controller = new AbortController();
37
+ const timeout = setTimeout(() => controller.abort(), UPDATE_CHECK_TIMEOUT_MS);
38
+ try {
39
+ const response = await fetch(`https://registry.npmjs.org/${encoded}`, {
40
+ headers: { Accept: 'application/vnd.npm.install-v1+json' },
41
+ signal: controller.signal,
42
+ });
43
+ if (!response.ok)
44
+ return undefined;
45
+ const data = (await response.json());
46
+ return data?.['dist-tags']?.latest;
47
+ }
48
+ catch {
49
+ return undefined;
50
+ }
51
+ finally {
52
+ clearTimeout(timeout);
53
+ }
54
+ }
55
+ function isManagerLocalInstall(rootDir) {
56
+ const relative = path.relative(rootDir, managerRoot);
57
+ return Boolean(relative && !relative.startsWith('..') && !path.isAbsolute(relative));
58
+ }
59
+ async function getManagerUpdateInfo(rootDir) {
60
+ const current = await getCurrentManagerVersion();
61
+ if (!current)
62
+ return undefined;
63
+ const latest = await fetchLatestVersion(MANAGER_PACKAGE);
64
+ if (!latest)
65
+ return undefined;
66
+ if (!valid(current) || !valid(latest) || !lt(current, latest)) {
67
+ return undefined;
68
+ }
69
+ const command = 'pnpm';
70
+ const args = isManagerLocalInstall(rootDir)
71
+ ? ['update', '--latest', MANAGER_PACKAGE]
72
+ : ['add', '-g', `${MANAGER_PACKAGE}@latest`];
73
+ return { current, latest, command, args };
74
+ }
10
75
  function resolveTargetsFromArg(packages, arg) {
11
76
  if (arg.toLowerCase() === 'all')
12
77
  return getOrderedPackages(packages);
@@ -92,12 +157,27 @@ function optsFromParsed(p) {
92
157
  async function runPackageSelectionLoop(packages, helperArgs) {
93
158
  let argv = [...helperArgs];
94
159
  let currentPackages = packages;
160
+ const updateInfo = await getManagerUpdateInfo(process.cwd());
95
161
  // eslint-disable-next-line no-constant-condition
96
162
  while (true) {
97
163
  let lastStep;
164
+ const updateEntry = updateInfo
165
+ ? {
166
+ name: 'Update @emeryld/manager to latest version',
167
+ emoji: '⬆️',
168
+ description: `Current v${updateInfo.current}, latest v${updateInfo.latest}`,
169
+ handler: async () => {
170
+ logGlobal(`Updating ${MANAGER_PACKAGE} to v${updateInfo.latest}...`, colors.cyan);
171
+ await run(updateInfo.command, updateInfo.args);
172
+ logGlobal(`${MANAGER_PACKAGE} updated. Re-run manager-cli to use v${updateInfo.latest}.`, colors.green);
173
+ lastStep = 'back';
174
+ },
175
+ }
176
+ : undefined;
98
177
  await runHelperCli({
99
178
  title: 'Pick one of the packages or all',
100
179
  scripts: [
180
+ ...(updateEntry ? [updateEntry] : []),
101
181
  ...buildPackageSelectionMenu(currentPackages, (step) => {
102
182
  lastStep = step;
103
183
  }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emeryld/manager",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Interactive manager for pnpm monorepos (update/test/build/publish).",
5
5
  "license": "MIT",
6
6
  "type": "module",