epicshop 6.71.4 ā 6.72.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.
- package/dist/commands/start.js +32 -13
- package/dist/commands/workshops.js +24 -5
- package/package.json +4 -4
package/dist/commands/start.js
CHANGED
|
@@ -124,16 +124,36 @@ export async function start(options = {}) {
|
|
|
124
124
|
try {
|
|
125
125
|
const { checkForUpdatesCached } = await import('@epic-web/workshop-utils/git.server');
|
|
126
126
|
const { getMutedNotifications } = await import('@epic-web/workshop-utils/db.server');
|
|
127
|
-
const updates = await checkForUpdatesCached();
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
127
|
+
const updates = (await checkForUpdatesCached());
|
|
128
|
+
const updateNotificationId = updates.updateNotificationId ?? null;
|
|
129
|
+
const repoUpdatesAvailable = updates.repoUpdatesAvailable ?? updates.updatesAvailable;
|
|
130
|
+
const dependenciesNeedInstall = updates.dependenciesNeedInstall ?? false;
|
|
131
|
+
if (!updates.updatesAvailable || !updateNotificationId) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
// Check if update notification is muted
|
|
135
|
+
const mutedNotifications = await getMutedNotifications();
|
|
136
|
+
if (mutedNotifications.includes(updateNotificationId)) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const updateLink = repoUpdatesAvailable && updates.diffLink
|
|
140
|
+
? chalk.blue.bgWhite(` ${updates.diffLink} `)
|
|
141
|
+
: null;
|
|
142
|
+
const headline = repoUpdatesAvailable
|
|
143
|
+
? `š There are ${chalk.yellow('updates available')} for this workshop repository. š`
|
|
144
|
+
: `š¦ ${chalk.yellow('Dependencies are out of date')} for this workshop repository. š¦`;
|
|
145
|
+
const lines = [headline];
|
|
146
|
+
if (dependenciesNeedInstall) {
|
|
147
|
+
lines.push(`Your installed packages don't match ${chalk.cyan('package.json')}.`);
|
|
148
|
+
}
|
|
149
|
+
lines.push(repoUpdatesAvailable
|
|
150
|
+
? `To get the updates${dependenciesNeedInstall ? ' and reinstall dependencies' : ''}, ${chalk.green.bold.bgWhite(`press the "u" key`)}`
|
|
151
|
+
: `To reinstall dependencies, ${chalk.green.bold.bgWhite(`press the "u" key`)}`);
|
|
152
|
+
if (updateLink) {
|
|
153
|
+
lines.push(`To view a diff, check:\n ${updateLink}`);
|
|
136
154
|
}
|
|
155
|
+
lines.push(`To dismiss this notification, ${chalk.red.bold.bgWhite(`press the "d" key`)}`);
|
|
156
|
+
console.log('\n', `${lines.join('\n\n')}\n`);
|
|
137
157
|
}
|
|
138
158
|
catch {
|
|
139
159
|
// Silently ignore update check errors
|
|
@@ -381,10 +401,9 @@ export async function start(options = {}) {
|
|
|
381
401
|
try {
|
|
382
402
|
const { checkForUpdatesCached } = await import('@epic-web/workshop-utils/git.server');
|
|
383
403
|
const { muteNotification } = await import('@epic-web/workshop-utils/db.server');
|
|
384
|
-
const updates = await checkForUpdatesCached();
|
|
385
|
-
if (updates.updatesAvailable && updates.
|
|
386
|
-
|
|
387
|
-
await muteNotification(updateNotificationId);
|
|
404
|
+
const updates = (await checkForUpdatesCached());
|
|
405
|
+
if (updates.updatesAvailable && updates.updateNotificationId) {
|
|
406
|
+
await muteNotification(updates.updateNotificationId);
|
|
388
407
|
console.log(chalk.green('\nā
Update notification dismissed permanently.\n'));
|
|
389
408
|
}
|
|
390
409
|
else {
|
|
@@ -9,6 +9,7 @@ import { userHasAccessToWorkshop } from '@epic-web/workshop-utils/epic-api.serve
|
|
|
9
9
|
import chalk from 'chalk';
|
|
10
10
|
import { matchSorter, rankings } from 'match-sorter';
|
|
11
11
|
import ora from 'ora';
|
|
12
|
+
import { z } from 'zod';
|
|
12
13
|
import { assertCanPrompt, isCiEnvironment } from "../utils/cli-runtime.js";
|
|
13
14
|
import { runCommand, runCommandInteractive } from "../utils/command-runner.js";
|
|
14
15
|
import { setup } from "./setup.js";
|
|
@@ -70,6 +71,20 @@ export async function findWorkshopRoot() {
|
|
|
70
71
|
export async function isInWorkshopDirectory() {
|
|
71
72
|
return (await findWorkshopRoot()) !== null;
|
|
72
73
|
}
|
|
74
|
+
const GitHubRepoSchema = z.object({
|
|
75
|
+
name: z.string(),
|
|
76
|
+
description: z.string().nullable(),
|
|
77
|
+
html_url: z.string(),
|
|
78
|
+
stargazers_count: z.number(),
|
|
79
|
+
topics: z.array(z.string()).default([]),
|
|
80
|
+
archived: z.boolean(),
|
|
81
|
+
});
|
|
82
|
+
const GitHubSearchResponseSchema = z.object({
|
|
83
|
+
total_count: z.number(),
|
|
84
|
+
incomplete_results: z.boolean(),
|
|
85
|
+
items: z.array(GitHubRepoSchema),
|
|
86
|
+
});
|
|
87
|
+
const PackageJsonSchema = z.record(z.unknown());
|
|
73
88
|
const PRODUCT_ICONS = {
|
|
74
89
|
'www.epicweb.dev': 'š',
|
|
75
90
|
'www.epicai.pro': 'ā”',
|
|
@@ -103,6 +118,7 @@ async function fetchAvailableWorkshops() {
|
|
|
103
118
|
cache: githubCache,
|
|
104
119
|
ttl: 1000 * 60 * 15, // 15 minutes
|
|
105
120
|
swr: 1000 * 60 * 60 * 6, // 6 hours stale-while-revalidate
|
|
121
|
+
checkValue: GitHubRepoSchema.array(),
|
|
106
122
|
async getFreshValue() {
|
|
107
123
|
// Note: `archived:false` is supported by GitHub search.
|
|
108
124
|
const baseUrl = `https://api.github.com/search/repositories?q=topic:workshop+org:${GITHUB_ORG}+archived:false&sort=stars&order=desc`;
|
|
@@ -125,11 +141,12 @@ async function fetchAvailableWorkshops() {
|
|
|
125
141
|
}
|
|
126
142
|
throw new Error(`Failed to fetch workshops from GitHub: ${response.status}`);
|
|
127
143
|
}
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
totalCount = data.total_count;
|
|
144
|
+
const parseResult = GitHubSearchResponseSchema.safeParse(await response.json());
|
|
145
|
+
if (!parseResult.success) {
|
|
146
|
+
throw new Error(`Failed to parse GitHub API response: ${parseResult.error.message}`);
|
|
132
147
|
}
|
|
148
|
+
const { items, total_count } = parseResult.data;
|
|
149
|
+
totalCount = total_count;
|
|
133
150
|
allItems.push(...items);
|
|
134
151
|
// Stop when there are no more results for the next page.
|
|
135
152
|
if (items.length < perPage)
|
|
@@ -151,6 +168,7 @@ async function fetchWorkshopPackageJson(repoName) {
|
|
|
151
168
|
cache: githubCache,
|
|
152
169
|
ttl: 1000 * 60 * 60 * 6, // 6 hours
|
|
153
170
|
swr: 1000 * 60 * 60 * 24 * 30, // 30 days stale-while-revalidate
|
|
171
|
+
checkValue: PackageJsonSchema.nullable(),
|
|
154
172
|
async getFreshValue() {
|
|
155
173
|
const url = `https://raw.githubusercontent.com/${GITHUB_ORG}/${repoName}/main/package.json`;
|
|
156
174
|
const response = await fetch(url, {
|
|
@@ -163,7 +181,8 @@ async function fetchWorkshopPackageJson(repoName) {
|
|
|
163
181
|
return null;
|
|
164
182
|
}
|
|
165
183
|
try {
|
|
166
|
-
|
|
184
|
+
const parsed = PackageJsonSchema.safeParse(await response.json());
|
|
185
|
+
return parsed.success ? parsed.data : null;
|
|
167
186
|
}
|
|
168
187
|
catch {
|
|
169
188
|
return null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "epicshop",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.72.1",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -99,9 +99,9 @@
|
|
|
99
99
|
"build:watch": "nx watch --projects=epicshop -- nx run \\$NX_PROJECT_NAME:build"
|
|
100
100
|
},
|
|
101
101
|
"dependencies": {
|
|
102
|
-
"@epic-web/workshop-utils": "6.
|
|
102
|
+
"@epic-web/workshop-utils": "6.72.1",
|
|
103
103
|
"@inquirer/prompts": "^8.2.0",
|
|
104
|
-
"@sentry/node": "^10.
|
|
104
|
+
"@sentry/node": "^10.36.0",
|
|
105
105
|
"chalk": "^5.6.2",
|
|
106
106
|
"close-with-grace": "^2.4.0",
|
|
107
107
|
"execa": "^9.6.1",
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
"match-sorter": "^8.2.0",
|
|
110
110
|
"open": "^11.0.0",
|
|
111
111
|
"openid-client": "^6.8.1",
|
|
112
|
-
"ora": "^9.
|
|
112
|
+
"ora": "^9.1.0",
|
|
113
113
|
"yargs": "^18.0.0"
|
|
114
114
|
},
|
|
115
115
|
"devDependencies": {
|