@pipelab/core-node 1.0.0-beta.0 → 1.0.0-beta.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/CHANGELOG.md +6 -0
- package/dist/index.d.mts +32 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +59 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/utils/github.ts +115 -0
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import semver from "semver";
|
|
2
|
+
|
|
3
|
+
export interface GitHubRelease {
|
|
4
|
+
tag_name: string;
|
|
5
|
+
prerelease: boolean;
|
|
6
|
+
published_at: string;
|
|
7
|
+
html_url: string;
|
|
8
|
+
assets: Array<{
|
|
9
|
+
name: string;
|
|
10
|
+
browser_download_url: string;
|
|
11
|
+
}>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface FetchReleaseOptions {
|
|
15
|
+
repo?: string;
|
|
16
|
+
allowPrerelease?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Fetches all releases for a specific package from GitHub.
|
|
21
|
+
* Tags are expected to follow the pattern "{packageName}@{version}"
|
|
22
|
+
*/
|
|
23
|
+
export async function fetchPackageReleases(
|
|
24
|
+
packageName: string,
|
|
25
|
+
options: FetchReleaseOptions = {}
|
|
26
|
+
): Promise<GitHubRelease[]> {
|
|
27
|
+
const { repo = "CynToolkit/pipelab", allowPrerelease = false } = options;
|
|
28
|
+
const url = `https://api.github.com/repos/${repo}/releases`;
|
|
29
|
+
|
|
30
|
+
console.log(`[GitHub] Fetching releases for ${packageName} from ${url}...`);
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
const response = await fetch(url, {
|
|
34
|
+
headers: {
|
|
35
|
+
"User-Agent": "Pipelab-Desktop-Updater",
|
|
36
|
+
Accept: "application/vnd.github.v3+json",
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
if (!response.ok) {
|
|
41
|
+
throw new Error(`GitHub API error: ${response.status} ${response.statusText}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const releases: GitHubRelease[] = await response.json();
|
|
45
|
+
|
|
46
|
+
// Filter for releases that follow the {packageName}@X.Y.Z tag pattern
|
|
47
|
+
const packageReleases = releases
|
|
48
|
+
.filter((r) => r.tag_name.startsWith(`${packageName}@`))
|
|
49
|
+
.filter((r) => allowPrerelease || !r.prerelease);
|
|
50
|
+
|
|
51
|
+
return packageReleases;
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error(`[GitHub] Failed to fetch releases for ${packageName}:`, error);
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Fetches the latest release for a specific package.
|
|
60
|
+
* Supports PIPELAB_OVERRIDE_RELEASE environment variable.
|
|
61
|
+
*/
|
|
62
|
+
export async function fetchLatestPackageRelease(
|
|
63
|
+
packageName: string,
|
|
64
|
+
options: FetchReleaseOptions = {}
|
|
65
|
+
): Promise<GitHubRelease | null> {
|
|
66
|
+
const releases = await fetchPackageReleases(packageName, options);
|
|
67
|
+
|
|
68
|
+
if (releases.length === 0) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Handle environment variable override
|
|
73
|
+
const override = process.env.PIPELAB_OVERRIDE_RELEASE;
|
|
74
|
+
if (override) {
|
|
75
|
+
const targetTag = override.includes("@") ? override : `${packageName}@${override}`;
|
|
76
|
+
const release = releases.find((r) => r.tag_name === targetTag);
|
|
77
|
+
if (release) {
|
|
78
|
+
console.log(`[GitHub] Using release override from PIPELAB_OVERRIDE_RELEASE: ${release.tag_name}`);
|
|
79
|
+
return release;
|
|
80
|
+
}
|
|
81
|
+
console.warn(`[GitHub] Override release ${override} not found for package ${packageName}`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Sort by semver
|
|
85
|
+
const getVersion = (tagName: string) => tagName.split("@").pop() || "0.0.0";
|
|
86
|
+
|
|
87
|
+
releases.sort((a, b) => {
|
|
88
|
+
const vA = getVersion(a.tag_name);
|
|
89
|
+
const vB = getVersion(b.tag_name);
|
|
90
|
+
if (semver.valid(vA) && semver.valid(vB)) {
|
|
91
|
+
return semver.rcompare(vA, vB);
|
|
92
|
+
}
|
|
93
|
+
return new Date(b.published_at).getTime() - new Date(a.published_at).getTime();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
return releases[0];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Fetches all releases from GitHub and finds the latest one that matches the Pipelab Desktop app tag.
|
|
101
|
+
* This ensures we don't accidentally pick a package release (e.g. @pipelab/shared) as the "latest".
|
|
102
|
+
*/
|
|
103
|
+
export async function fetchLatestDesktopRelease(
|
|
104
|
+
options: FetchReleaseOptions = {}
|
|
105
|
+
): Promise<GitHubRelease | null> {
|
|
106
|
+
const latest = await fetchLatestPackageRelease("@pipelab/app", options);
|
|
107
|
+
|
|
108
|
+
if (latest) {
|
|
109
|
+
console.log(`[GitHub] Found latest desktop release: ${latest.tag_name} (${latest.prerelease ? "pre-release" : "stable"})`);
|
|
110
|
+
} else {
|
|
111
|
+
console.warn(`[GitHub] No desktop releases found`);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return latest;
|
|
115
|
+
}
|