relayax-cli 0.2.17 → 0.2.19
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/changelog.d.ts +2 -0
- package/dist/commands/changelog.js +67 -0
- package/dist/commands/install.js +1 -1
- package/dist/commands/update.js +15 -0
- package/dist/index.js +2 -0
- package/dist/lib/api.d.ts +2 -2
- package/dist/lib/api.js +26 -5
- package/dist/lib/version-check.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.registerChangelog = registerChangelog;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
10
|
+
function registerChangelog(program) {
|
|
11
|
+
const changelog = program
|
|
12
|
+
.command('changelog')
|
|
13
|
+
.description('팀 패키지의 changelog를 관리합니다');
|
|
14
|
+
changelog
|
|
15
|
+
.command('add')
|
|
16
|
+
.description('relay.yaml에 changelog 엔트리를 추가합니다')
|
|
17
|
+
.argument('[message]', 'changelog 메시지 (없으면 에디터에서 입력)')
|
|
18
|
+
.action(async (message) => {
|
|
19
|
+
const yamlPath = path_1.default.resolve('relay.yaml');
|
|
20
|
+
if (!fs_1.default.existsSync(yamlPath)) {
|
|
21
|
+
console.error('relay.yaml을 찾을 수 없습니다. 팀 패키지 디렉토리에서 실행하세요.');
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
const content = fs_1.default.readFileSync(yamlPath, 'utf-8');
|
|
25
|
+
const doc = js_yaml_1.default.load(content) ?? {};
|
|
26
|
+
if (!message) {
|
|
27
|
+
// Read from stdin if piped, otherwise prompt
|
|
28
|
+
const readline = await import('readline');
|
|
29
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
30
|
+
message = await new Promise((resolve) => {
|
|
31
|
+
rl.question('Changelog 메시지: ', (answer) => {
|
|
32
|
+
rl.close();
|
|
33
|
+
resolve(answer);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
if (!message || message.trim() === '') {
|
|
38
|
+
console.error('changelog 메시지가 비어있습니다.');
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
const version = String(doc.version ?? '1.0.0');
|
|
42
|
+
const date = new Date().toISOString().split('T')[0];
|
|
43
|
+
const entry = `## v${version} (${date})\n\n- ${message.trim()}`;
|
|
44
|
+
const existing = doc.changelog ? String(doc.changelog) : '';
|
|
45
|
+
doc.changelog = existing ? `${entry}\n\n${existing}` : entry;
|
|
46
|
+
fs_1.default.writeFileSync(yamlPath, js_yaml_1.default.dump(doc, { lineWidth: -1, noRefs: true }), 'utf-8');
|
|
47
|
+
console.log(`\x1b[32m✓\x1b[0m changelog 추가됨 (v${version})`);
|
|
48
|
+
console.log(` ${message.trim()}`);
|
|
49
|
+
});
|
|
50
|
+
changelog
|
|
51
|
+
.command('show')
|
|
52
|
+
.description('현재 relay.yaml의 changelog를 표시합니다')
|
|
53
|
+
.action(() => {
|
|
54
|
+
const yamlPath = path_1.default.resolve('relay.yaml');
|
|
55
|
+
if (!fs_1.default.existsSync(yamlPath)) {
|
|
56
|
+
console.error('relay.yaml을 찾을 수 없습니다.');
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
const content = fs_1.default.readFileSync(yamlPath, 'utf-8');
|
|
60
|
+
const doc = js_yaml_1.default.load(content) ?? {};
|
|
61
|
+
if (!doc.changelog) {
|
|
62
|
+
console.log('changelog가 없습니다. `relay changelog add "메시지"`로 추가하세요.');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
console.log(String(doc.changelog));
|
|
66
|
+
});
|
|
67
|
+
}
|
package/dist/commands/install.js
CHANGED
|
@@ -75,7 +75,7 @@ function registerInstall(program) {
|
|
|
75
75
|
};
|
|
76
76
|
(0, config_js_1.saveInstalled)(installed);
|
|
77
77
|
// 7. Report install (non-blocking)
|
|
78
|
-
await (0, api_js_1.reportInstall)(slug);
|
|
78
|
+
await (0, api_js_1.reportInstall)(slug, team.version);
|
|
79
79
|
const result = {
|
|
80
80
|
status: 'ok',
|
|
81
81
|
team: team.name,
|
package/dist/commands/update.js
CHANGED
|
@@ -101,6 +101,21 @@ function registerUpdate(program) {
|
|
|
101
101
|
const authorDisplayName = team.author?.display_name ?? authorUsername ?? '';
|
|
102
102
|
const contactParts = (0, contact_format_js_1.formatContactParts)(team.author?.contact_links);
|
|
103
103
|
const hasCard = team.welcome || contactParts.length > 0 || authorUsername;
|
|
104
|
+
// Show changelog for this version
|
|
105
|
+
try {
|
|
106
|
+
const versions = await (0, api_js_1.fetchTeamVersions)(slug);
|
|
107
|
+
const thisVersion = versions.find((v) => v.version === latestVersion);
|
|
108
|
+
if (thisVersion?.changelog) {
|
|
109
|
+
console.log(`\n \x1b[90m── Changelog ──────────────────────────────\x1b[0m`);
|
|
110
|
+
for (const line of thisVersion.changelog.split('\n').slice(0, 5)) {
|
|
111
|
+
console.log(` ${line}`);
|
|
112
|
+
}
|
|
113
|
+
console.log(` \x1b[90m───────────────────────────────────────────\x1b[0m`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// Non-critical: skip changelog display
|
|
118
|
+
}
|
|
104
119
|
if (hasCard) {
|
|
105
120
|
console.log(`\n \x1b[90m┌─ ${authorDisplayName || '빌더'}의 명함 ${'─'.repeat(Math.max(0, 34 - (authorDisplayName || '빌더').length))}┐\x1b[0m`);
|
|
106
121
|
if (team.welcome) {
|
package/dist/index.js
CHANGED
|
@@ -15,6 +15,7 @@ const update_js_1 = require("./commands/update.js");
|
|
|
15
15
|
const outdated_js_1 = require("./commands/outdated.js");
|
|
16
16
|
const check_update_js_1 = require("./commands/check-update.js");
|
|
17
17
|
const follow_js_1 = require("./commands/follow.js");
|
|
18
|
+
const changelog_js_1 = require("./commands/changelog.js");
|
|
18
19
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
19
20
|
const pkg = require('../package.json');
|
|
20
21
|
const program = new commander_1.Command();
|
|
@@ -36,4 +37,5 @@ program
|
|
|
36
37
|
(0, outdated_js_1.registerOutdated)(program);
|
|
37
38
|
(0, check_update_js_1.registerCheckUpdate)(program);
|
|
38
39
|
(0, follow_js_1.registerFollow)(program);
|
|
40
|
+
(0, changelog_js_1.registerChangelog)(program);
|
|
39
41
|
program.parse();
|
package/dist/lib/api.d.ts
CHANGED
|
@@ -7,12 +7,12 @@ export interface TeamVersionInfo {
|
|
|
7
7
|
created_at: string;
|
|
8
8
|
}
|
|
9
9
|
export declare function fetchTeamVersions(slug: string): Promise<TeamVersionInfo[]>;
|
|
10
|
-
export declare function reportInstall(slug: string): Promise<void>;
|
|
10
|
+
export declare function reportInstall(slug: string, version?: string): Promise<void>;
|
|
11
11
|
export interface ResolvedSlug {
|
|
12
12
|
owner: string;
|
|
13
13
|
name: string;
|
|
14
14
|
full: string;
|
|
15
15
|
}
|
|
16
16
|
export declare function resolveSlugFromServer(name: string): Promise<ResolvedSlug[]>;
|
|
17
|
-
export declare function sendUsagePing(slug: string): Promise<void>;
|
|
17
|
+
export declare function sendUsagePing(slug: string, version?: string): Promise<void>;
|
|
18
18
|
export declare function followBuilder(username: string): Promise<void>;
|
package/dist/lib/api.js
CHANGED
|
@@ -41,10 +41,24 @@ async function fetchTeamVersions(slug) {
|
|
|
41
41
|
}
|
|
42
42
|
return res.json();
|
|
43
43
|
}
|
|
44
|
-
async function reportInstall(slug) {
|
|
44
|
+
async function reportInstall(slug, version) {
|
|
45
45
|
const registrySlug = slug.startsWith('@') ? slug.slice(1) : slug;
|
|
46
46
|
const url = `${config_js_1.API_URL}/api/registry/${registrySlug}/install`;
|
|
47
|
-
|
|
47
|
+
const headers = {};
|
|
48
|
+
const body = {};
|
|
49
|
+
if (version) {
|
|
50
|
+
headers['Content-Type'] = 'application/json';
|
|
51
|
+
body.version = version;
|
|
52
|
+
}
|
|
53
|
+
const token = await (0, config_js_1.getValidToken)();
|
|
54
|
+
if (token) {
|
|
55
|
+
headers['Authorization'] = `Bearer ${token}`;
|
|
56
|
+
}
|
|
57
|
+
await fetch(url, {
|
|
58
|
+
method: 'POST',
|
|
59
|
+
headers: Object.keys(headers).length > 0 ? headers : undefined,
|
|
60
|
+
body: Object.keys(body).length > 0 ? JSON.stringify(body) : undefined,
|
|
61
|
+
}).catch(() => {
|
|
48
62
|
// non-critical: ignore errors
|
|
49
63
|
});
|
|
50
64
|
}
|
|
@@ -57,7 +71,7 @@ async function resolveSlugFromServer(name) {
|
|
|
57
71
|
const data = (await res.json());
|
|
58
72
|
return data.results;
|
|
59
73
|
}
|
|
60
|
-
async function sendUsagePing(slug) {
|
|
74
|
+
async function sendUsagePing(slug, version) {
|
|
61
75
|
const registrySlug = slug.startsWith('@') ? slug.slice(1) : slug;
|
|
62
76
|
const { createHash } = await import('crypto');
|
|
63
77
|
const { hostname, userInfo } = await import('os');
|
|
@@ -65,10 +79,17 @@ async function sendUsagePing(slug) {
|
|
|
65
79
|
.update(`${hostname()}:${userInfo().username}`)
|
|
66
80
|
.digest('hex');
|
|
67
81
|
const url = `${config_js_1.API_URL}/api/registry/${registrySlug}/ping`;
|
|
82
|
+
const payload = { device_hash: deviceHash };
|
|
83
|
+
if (version)
|
|
84
|
+
payload.installed_version = version;
|
|
85
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
86
|
+
const token = await (0, config_js_1.getValidToken)();
|
|
87
|
+
if (token)
|
|
88
|
+
headers['Authorization'] = `Bearer ${token}`;
|
|
68
89
|
await fetch(url, {
|
|
69
90
|
method: 'POST',
|
|
70
|
-
headers
|
|
71
|
-
body: JSON.stringify(
|
|
91
|
+
headers,
|
|
92
|
+
body: JSON.stringify(payload),
|
|
72
93
|
}).catch(() => {
|
|
73
94
|
// fire-and-forget: ignore errors
|
|
74
95
|
});
|
|
@@ -43,7 +43,7 @@ async function checkTeamVersion(slug, force) {
|
|
|
43
43
|
const team = await (0, api_js_1.fetchTeamInfo)(slug);
|
|
44
44
|
(0, update_cache_js_1.updateCacheTimestamp)(slug);
|
|
45
45
|
// Fire-and-forget usage ping (only when cache expired = actual API call happened)
|
|
46
|
-
(0, api_js_1.sendUsagePing)(slug);
|
|
46
|
+
(0, api_js_1.sendUsagePing)(slug, entry.version);
|
|
47
47
|
if (team.version !== entry.version) {
|
|
48
48
|
return {
|
|
49
49
|
type: 'team',
|