sitevision-cli 1.0.0 → 1.0.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.2
4
+
5
+ - Workspace settings can switch environment again. Press `v` in the settings
6
+ pane to cycle the workspace's environments; the pane now cycles the ones
7
+ defined in the workspace's root file, so an environment that only exists
8
+ in one app can no longer become a root override.
9
+ - Adding an environment in a workspace checks the name against the file
10
+ being written, not the current app, so a name that clashes with the
11
+ workspace's base environment is rejected there too.
12
+
13
+ ## 1.0.1
14
+
15
+ - The "what's new" panel shown after an update now lists the earlier releases
16
+ below the new ones, dimmed, instead of stopping at the version you had.
17
+
3
18
  ## 1.0.0
4
19
 
5
20
  First stable release. Everything from the betas is in, see the entries below.
@@ -5,8 +5,9 @@ import { Box, Text, useInput } from 'ink';
5
5
  import { t } from '../utils/i18n.js';
6
6
  import { ACCENT } from './Frame.js';
7
7
  /**
8
- * CHANGELOG.md without its title, or undefined when it isn't shipped. With
9
- * `since`, only the releases above that version's heading.
8
+ * CHANGELOG.md without its title, or undefined when it isn't shipped. `cutoff`
9
+ * is the line where `since` (the version the user had) begins: everything
10
+ * before it is new to them, everything from it on is shown dimmed for context.
10
11
  */
11
12
  export function readChangelog(since) {
12
13
  try {
@@ -15,14 +16,16 @@ export function readChangelog(since) {
15
16
  .trim()
16
17
  .split('\n');
17
18
  const end = since ? lines.indexOf(`## ${since}`) : -1;
18
- return end > 0 ? lines.slice(0, end) : lines;
19
+ return { lines, cutoff: end > 0 ? end : lines.length };
19
20
  }
20
21
  catch {
21
22
  return undefined;
22
23
  }
23
24
  }
24
25
  export function ChangelogPanel({ since, height, onClose, }) {
25
- const lines = useMemo(() => readChangelog(since), [since]);
26
+ const changelog = useMemo(() => readChangelog(since), [since]);
27
+ const lines = changelog?.lines;
28
+ const cutoff = changelog?.cutoff ?? 0;
26
29
  const [top, setTop] = useState(0);
27
30
  const visible = Math.max(1, height - 1);
28
31
  const max = Math.max(0, (lines?.length ?? 0) - visible);
@@ -40,5 +43,8 @@ export function ChangelogPanel({ since, height, onClose, }) {
40
43
  });
41
44
  return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsxs(Text, { children: [_jsx(Text, { bold: true, children: since
42
45
  ? t("What's new since {version}", { version: since })
43
- : t('Changelog') }), _jsxs(Text, { dimColor: true, children: [" \u00B7 ", t('↑↓ scroll · Esc close')] })] }), lines ? (lines.slice(top, top + visible).map((line, i) => line.startsWith('## ') ? (_jsx(Text, { bold: true, color: ACCENT, children: line.slice(3) }, top + i)) : (_jsx(Text, { wrap: "truncate", children: line || ' ' }, top + i)))) : (_jsx(Text, { dimColor: true, children: t('No changelog found.') }))] }));
46
+ : t('Changelog') }), _jsxs(Text, { dimColor: true, children: [" \u00B7 ", t('↑↓ scroll · Esc close')] })] }), lines ? (lines.slice(top, top + visible).map((line, i) => {
47
+ const old = top + i >= cutoff;
48
+ return line.startsWith('## ') ? (_jsx(Text, { bold: true, color: old ? undefined : ACCENT, dimColor: old, children: line.slice(3) }, top + i)) : (_jsx(Text, { wrap: "truncate", dimColor: old, children: line || ' ' }, top + i));
49
+ })) : (_jsx(Text, { dimColor: true, children: t('No changelog found.') }))] }));
44
50
  }
@@ -90,27 +90,33 @@ export function Shell({ apps: initialApps, workspaceRoot, version, minimal = fal
90
90
  // Active environment, remembered per workspace (or app) in .svcconfig.
91
91
  const configRoot = workspaceRoot ?? rawProject.root;
92
92
  const [envChoice, setEnvChoice] = useState(() => readSvcConfig(configRoot).environment ?? '');
93
- const envNames = environmentNames(rawProject.devProperties);
93
+ const rootDev = useMemo(() => workspaceRoot
94
+ ? readWorkspaceDevProperties(workspaceRoot)
95
+ : undefined,
96
+ // Re-read after any reload so saved values show up.
97
+ // eslint-disable-next-line react-hooks/exhaustive-deps
98
+ [workspaceRoot, apps]);
99
+ // The settings pane edits the shared root file, so it only cycles the
100
+ // root's environments: an app-only one must never become a root override.
101
+ const envDev = settings ? rootDev : rawProject.devProperties;
102
+ const envNames = environmentNames(envDev);
94
103
  const envList = envNames.join(',');
95
104
  const env = envNames.includes(envChoice)
96
105
  ? envChoice
97
- : baseEnvironment(rawProject.devProperties);
106
+ : baseEnvironment(envDev);
98
107
  const project = useMemo(() => environmentProject(rawProject, env), [rawProject, env]);
99
- const isProduction = isProductionEnvironment(env, rawProject.devProperties);
108
+ const isProduction = isProductionEnvironment(env, envDev);
100
109
  const versionsKey = `${project.root}|${env}`;
101
110
  const single = !workspaceRoot;
102
- const workspaceTarget = useMemo(() => workspaceRoot
111
+ const workspaceTarget = useMemo(() => workspaceRoot && rootDev
103
112
  ? {
104
113
  root: workspaceRoot,
105
- base: readWorkspaceDevProperties(workspaceRoot),
106
- devProperties: resolveEnvironment(readWorkspaceDevProperties(workspaceRoot), env),
114
+ base: rootDev,
115
+ devProperties: resolveEnvironment(rootDev, env),
107
116
  environment: env,
108
117
  workspace: true,
109
118
  }
110
- : undefined,
111
- // Re-read after any reload so saved values show up.
112
- // eslint-disable-next-line react-hooks/exhaustive-deps
113
- [workspaceRoot, apps, env]);
119
+ : undefined, [workspaceRoot, rootDev, env]);
114
120
  const narrow = minimal || columns < NARROW_BELOW;
115
121
  const sidebar = navWidth(columns);
116
122
  // The navigator shows the fuzzy matches; `selected` stays an index into
@@ -210,13 +216,13 @@ export function Shell({ apps: initialApps, workspaceRoot, version, minimal = fal
210
216
  ?.trim()
211
217
  .toLowerCase()
212
218
  .replaceAll(/[^\d\-a-z]/g, '');
213
- if (!clean || clean === baseEnvironment(rawProject.devProperties))
214
- return;
215
219
  const targetRoot = workspaceRoot ?? rawProject.root;
216
220
  const base = (workspaceRoot
217
221
  ? readWorkspaceDevProperties(workspaceRoot)
218
222
  : rawProject.devProperties);
219
- if (!base)
223
+ // The base of the file being written: an app's package.json may
224
+ // name a different one, and a duplicate of the base is never listed.
225
+ if (!clean || !base || clean === baseEnvironment(base))
220
226
  return;
221
227
  writeDevProperties(targetRoot, { ...base, environments: { ...base.environments, [clean]: {} } }, { complete: !workspaceRoot });
222
228
  reload();
@@ -591,9 +597,11 @@ export function Shell({ apps: initialApps, workspaceRoot, version, minimal = fal
591
597
  return;
592
598
  }
593
599
  if (settings && focus === 'content') {
594
- // Settings pane: the form owns everything but q, y and Tab/Esc above.
600
+ // Settings pane: the form owns everything but q, v, y and Tab/Esc above.
595
601
  if (input === 'q')
596
602
  quit();
603
+ else if (input === 'v')
604
+ context.cycleEnvironment();
597
605
  else if (input === 'y') {
598
606
  try {
599
607
  if (syncDevPropertiesToPackageJson(workspaceRoot)) {
@@ -679,6 +687,7 @@ export function Shell({ apps: initialApps, workspaceRoot, version, minimal = fal
679
687
  ? h([
680
688
  ['↑↓', 'field'],
681
689
  ['Enter', 'edit'],
690
+ ['v', 'env'],
682
691
  ['y', 'sync'],
683
692
  ['Esc', 'back'],
684
693
  ['q', 'quit'],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sitevision-cli",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Build, sign and deploy Sitevision apps from the terminal",
5
5
  "license": "MIT",
6
6
  "author": "Rasmus Söderström",
@@ -25,8 +25,8 @@
25
25
  "node": ">=22"
26
26
  },
27
27
  "scripts": {
28
- "build": "node -e \"fs.rmSync('dist',{recursive:true,force:true})\" && tsc && node -e \"fs.chmodSync('dist/cli.js',0o755)\"",
29
- "dev": "tsc --watch",
28
+ "build": "node -e \"fs.rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.build.json && node -e \"fs.chmodSync('dist/cli.js',0o755)\"",
29
+ "dev": "tsc -p tsconfig.build.json --watch",
30
30
  "test": "prettier --check . && xo && ava",
31
31
  "prepublishOnly": "npm test && npm run build",
32
32
  "release": "./scripts/publish.sh",
@@ -62,6 +62,7 @@
62
62
  "xo": "^3.0.2"
63
63
  },
64
64
  "ava": {
65
+ "workerThreads": false,
65
66
  "extensions": [
66
67
  "ts",
67
68
  "tsx"
package/readme.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Sitevision CLI
2
2
 
3
+ [![Test](https://github.com/xrasod/SitevisionCli/actions/workflows/test.yml/badge.svg)](https://github.com/xrasod/SitevisionCli/actions/workflows/test.yml)
4
+ [![npm](https://img.shields.io/npm/v/sitevision-cli)](https://www.npmjs.com/package/sitevision-cli)
5
+
3
6
  `svc` builds, signs and deploys Sitevision apps (WebApp, Widget, RESTApp,
4
7
  MCPServer) from a full-screen terminal shell or as plain commands.
5
8
 
@@ -147,7 +150,8 @@ To run your local build as `svc`, link it once with `npm link`, then keep
147
150
  any Sitevision app reflects your changes. `npm unlink -g sitevision-cli` and
148
151
  `npm install -g sitevision-cli` restore the published version.
149
152
 
150
- Releasing: see [RELEASING.md](RELEASING.md).
153
+ Contributing: see [CONTRIBUTING.md](CONTRIBUTING.md). Releasing: see
154
+ [RELEASING.md](RELEASING.md).
151
155
 
152
156
  ## License
153
157