Skip to content

Commit 6ef6f89

Browse files
authored
chore(cli): add notifications (#1682)
1 parent 4ecfc11 commit 6ef6f89

File tree

5 files changed

+56
-6
lines changed

5 files changed

+56
-6
lines changed

packages/schema/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
"semver": "^7.5.2",
109109
"sleep-promise": "^9.1.0",
110110
"strip-color": "^0.1.0",
111+
"terminal-link": "^2.0.0",
111112
"tiny-invariant": "^1.3.1",
112113
"ts-morph": "^16.0.0",
113114
"ts-pattern": "^4.3.0",

packages/schema/src/cli/actions/generate.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
getZenStackPackages,
1111
loadDocument,
1212
requiredPrismaVersion,
13+
showNotification,
1314
} from '../cli-util';
1415
import { PluginRunner, PluginRunnerOptions } from '../plugin-runner';
1516

@@ -22,6 +23,7 @@ type Options = {
2223
withPlugins?: string[];
2324
withoutPlugins?: string[];
2425
defaultPlugins: boolean;
26+
offline?: boolean;
2527
};
2628

2729
/**
@@ -48,11 +50,19 @@ export async function generate(projectPath: string, options: Options) {
4850

4951
await runPlugins(options);
5052

51-
if (options.versionCheck) {
52-
// note that we can't run plugins and do version check concurrently because
53-
// plugins are CPU-bound and can cause version check to false timeout
54-
await checkNewVersion();
53+
// note that we can't run online jobs concurrently with plugins because
54+
// plugins are CPU-bound and can cause false timeout
55+
const postJobs: Promise<void>[] = [];
56+
57+
if (options.versionCheck && !options.offline) {
58+
postJobs.push(checkNewVersion());
59+
}
60+
61+
if (!options.offline) {
62+
postJobs.push(showNotification());
5563
}
64+
65+
await Promise.all(postJobs);
5666
}
5767

5868
async function runPlugins(options: Options) {

packages/schema/src/cli/cli-util.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import { getDocument, LangiumDocument, LangiumDocuments, linkContentToContainer
66
import { NodeFileSystem } from 'langium/node';
77
import path from 'path';
88
import semver from 'semver';
9+
import terminalLink from 'terminal-link';
910
import { TextDocument } from 'vscode-languageserver-textdocument';
1011
import { URI } from 'vscode-uri';
12+
import { z } from 'zod';
1113
import { PLUGIN_MODULE_NAME, STD_LIB_MODULE_NAME } from '../language-server/constants';
1214
import { ZModelFormatter } from '../language-server/zmodel-formatter';
1315
import { createZModelServices, ZModelServices } from '../language-server/zmodel-module';
@@ -20,6 +22,8 @@ import { CliError } from './cli-error';
2022
export const requiredPrismaVersion = '4.8.0';
2123

2224
const CHECK_VERSION_TIMEOUT = 1000;
25+
const FETCH_CLI_CONFIG_TIMEOUT = 500;
26+
const CLI_CONFIG_ENDPOINT = 'https://zenstack.dev/config/cli.json';
2327

2428
/**
2529
* Loads a zmodel document from a file.
@@ -364,3 +368,33 @@ async function relinkAll(model: Model, services: ZModelServices) {
364368

365369
return newDoc.parseResult.value as Model;
366370
}
371+
372+
export async function showNotification() {
373+
try {
374+
const fetchResult = await fetch(CLI_CONFIG_ENDPOINT, {
375+
headers: { accept: 'application/json' },
376+
signal: AbortSignal.timeout(FETCH_CLI_CONFIG_TIMEOUT),
377+
});
378+
379+
if (!fetchResult.ok) {
380+
return;
381+
}
382+
383+
const data = await fetchResult.json();
384+
const schema = z.object({
385+
notifications: z.array(z.object({ title: z.string(), url: z.string().url(), active: z.boolean() })),
386+
});
387+
const parseResult = schema.safeParse(data);
388+
389+
if (parseResult.success) {
390+
const activeItems = parseResult.data.notifications.filter((item) => item.active);
391+
// return a random active item
392+
if (activeItems.length > 0) {
393+
const item = activeItems[Math.floor(Math.random() * activeItems.length)];
394+
console.log(terminalLink(item.title, item.url));
395+
}
396+
}
397+
} catch {
398+
// noop
399+
}
400+
}

packages/schema/src/cli/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ export function createProgram() {
9797
'pnpm',
9898
]);
9999
const noVersionCheckOption = new Option('--no-version-check', 'do not check for new version');
100-
const noDependencyCheck = new Option('--no-dependency-check', 'do not check if dependencies are installed');
100+
const noDependencyCheckOption = new Option('--no-dependency-check', 'do not check if dependencies are installed');
101+
const offlineOption = new Option('--offline', 'run in offline mode');
101102

102103
program
103104
.command('info')
@@ -125,7 +126,8 @@ export function createProgram() {
125126
.addOption(new Option('--no-default-plugins', 'do not run default plugins'))
126127
.addOption(new Option('--no-compile', 'do not compile the output of core plugins'))
127128
.addOption(noVersionCheckOption)
128-
.addOption(noDependencyCheck)
129+
.addOption(noDependencyCheckOption)
130+
.addOption(offlineOption)
129131
.action(generateAction);
130132

131133
program

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)