@ducky7go/ducky-cli 0.0.4-dev.1 → 0.0.5-dev.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/README.md +47 -199
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/steam/index.d.ts +3 -0
- package/dist/commands/steam/index.d.ts.map +1 -0
- package/dist/commands/steam/index.js +21 -0
- package/dist/commands/steam/index.js.map +1 -0
- package/dist/commands/steam/push.d.ts +3 -0
- package/dist/commands/steam/push.d.ts.map +1 -0
- package/dist/commands/steam/push.js +29 -0
- package/dist/commands/steam/push.js.map +1 -0
- package/dist/commands/steam/validate.d.ts +3 -0
- package/dist/commands/steam/validate.d.ts.map +1 -0
- package/dist/commands/steam/validate.js +47 -0
- package/dist/commands/steam/validate.js.map +1 -0
- package/dist/formats/steam/config.d.ts +23 -0
- package/dist/formats/steam/config.d.ts.map +1 -0
- package/dist/formats/steam/config.js +32 -0
- package/dist/formats/steam/config.js.map +1 -0
- package/dist/formats/steam/metadata.d.ts +45 -0
- package/dist/formats/steam/metadata.d.ts.map +1 -0
- package/dist/formats/steam/metadata.js +293 -0
- package/dist/formats/steam/metadata.js.map +1 -0
- package/dist/formats/steam/parser.d.ts +20 -0
- package/dist/formats/steam/parser.d.ts.map +1 -0
- package/dist/formats/steam/parser.js +88 -0
- package/dist/formats/steam/parser.js.map +1 -0
- package/dist/formats/steam/progress-display.d.ts +38 -0
- package/dist/formats/steam/progress-display.d.ts.map +1 -0
- package/dist/formats/steam/progress-display.js +123 -0
- package/dist/formats/steam/progress-display.js.map +1 -0
- package/dist/formats/steam/progress.d.ts +79 -0
- package/dist/formats/steam/progress.d.ts.map +1 -0
- package/dist/formats/steam/progress.js +126 -0
- package/dist/formats/steam/progress.js.map +1 -0
- package/dist/formats/steam/push-handler.d.ts +22 -0
- package/dist/formats/steam/push-handler.d.ts.map +1 -0
- package/dist/formats/steam/push-handler.js +31 -0
- package/dist/formats/steam/push-handler.js.map +1 -0
- package/dist/formats/steam/upload-standalone.d.ts +20 -0
- package/dist/formats/steam/upload-standalone.d.ts.map +1 -0
- package/dist/formats/steam/upload-standalone.js +221 -0
- package/dist/formats/steam/upload-standalone.js.map +1 -0
- package/dist/formats/steam/validator.d.ts +58 -0
- package/dist/formats/steam/validator.d.ts.map +1 -0
- package/dist/formats/steam/validator.js +136 -0
- package/dist/formats/steam/validator.js.map +1 -0
- package/dist/formats/steam/workshop.d.ts +72 -0
- package/dist/formats/steam/workshop.d.ts.map +1 -0
- package/dist/formats/steam/workshop.js +221 -0
- package/dist/formats/steam/workshop.js.map +1 -0
- package/dist/utils/errors.d.ts +24 -0
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +51 -0
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/fs.d.ts +8 -0
- package/dist/utils/fs.d.ts.map +1 -1
- package/dist/utils/fs.js +22 -0
- package/dist/utils/fs.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { readTextFile, directoryExists } from '../../utils/fs.js';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Language code mapping from filename to Steam language code
|
|
5
|
+
* Based on Steam's supported languages:
|
|
6
|
+
* https://partner.steamgames.com/doc/store/localization
|
|
7
|
+
*/
|
|
8
|
+
const LANGUAGE_CODE_MAP = {
|
|
9
|
+
// Chinese variants
|
|
10
|
+
'zh': 'schinese',
|
|
11
|
+
'zh-cn': 'schinese',
|
|
12
|
+
'zh_cn': 'schinese',
|
|
13
|
+
'zh-hans': 'schinese',
|
|
14
|
+
'zh_hans': 'schinese',
|
|
15
|
+
'schinese': 'schinese',
|
|
16
|
+
'zh-hant': 'tchinese',
|
|
17
|
+
'zh_hant': 'tchinese',
|
|
18
|
+
'zh-tw': 'tchinese',
|
|
19
|
+
'zh_tw': 'tchinese',
|
|
20
|
+
'tchinese': 'tchinese',
|
|
21
|
+
// English
|
|
22
|
+
'en': 'english',
|
|
23
|
+
'english': 'english',
|
|
24
|
+
// Japanese
|
|
25
|
+
'ja': 'japanese',
|
|
26
|
+
'japanese': 'japanese',
|
|
27
|
+
// Korean
|
|
28
|
+
'ko': 'koreana',
|
|
29
|
+
'koreana': 'koreana',
|
|
30
|
+
// Spanish - use latam for Spanish (Latin America)
|
|
31
|
+
'es': 'latam',
|
|
32
|
+
'spanish': 'latam',
|
|
33
|
+
'latam': 'latam',
|
|
34
|
+
// Portuguese - use brazilian for Portuguese
|
|
35
|
+
'pt': 'brazilian',
|
|
36
|
+
'pt-br': 'brazilian',
|
|
37
|
+
'pt_br': 'brazilian',
|
|
38
|
+
'brazilian': 'brazilian',
|
|
39
|
+
// German
|
|
40
|
+
'de': 'german',
|
|
41
|
+
'german': 'german',
|
|
42
|
+
// French
|
|
43
|
+
'fr': 'french',
|
|
44
|
+
'french': 'french',
|
|
45
|
+
// Italian
|
|
46
|
+
'it': 'italian',
|
|
47
|
+
'italian': 'italian',
|
|
48
|
+
// Russian
|
|
49
|
+
'ru': 'russian',
|
|
50
|
+
'russian': 'russian',
|
|
51
|
+
// Polish
|
|
52
|
+
'pl': 'polish',
|
|
53
|
+
'polish': 'polish',
|
|
54
|
+
// Thai
|
|
55
|
+
'th': 'thai',
|
|
56
|
+
'thai': 'thai',
|
|
57
|
+
// Turkish
|
|
58
|
+
'tr': 'turkish',
|
|
59
|
+
'turkish': 'turkish',
|
|
60
|
+
// Czech
|
|
61
|
+
'cs': 'czech',
|
|
62
|
+
'czech': 'czech',
|
|
63
|
+
// Hungarian
|
|
64
|
+
'hu': 'hungarian',
|
|
65
|
+
'hungarian': 'hungarian',
|
|
66
|
+
// Dutch
|
|
67
|
+
'nl': 'dutch',
|
|
68
|
+
'dutch': 'dutch',
|
|
69
|
+
// Swedish
|
|
70
|
+
'sv': 'swedish',
|
|
71
|
+
'swedish': 'swedish',
|
|
72
|
+
// Norwegian
|
|
73
|
+
'no': 'norwegian',
|
|
74
|
+
'norwegian': 'norwegian',
|
|
75
|
+
// Danish
|
|
76
|
+
'da': 'danish',
|
|
77
|
+
'danish': 'danish',
|
|
78
|
+
// Finnish
|
|
79
|
+
'fi': 'finnish',
|
|
80
|
+
'finnish': 'finnish',
|
|
81
|
+
// Greek
|
|
82
|
+
'el': 'greek',
|
|
83
|
+
'greek': 'greek',
|
|
84
|
+
// Bulgarian
|
|
85
|
+
'bg': 'bulgarian',
|
|
86
|
+
'bulgarian': 'bulgarian',
|
|
87
|
+
// Romanian
|
|
88
|
+
'ro': 'romanian',
|
|
89
|
+
'romanian': 'romanian',
|
|
90
|
+
// Ukrainian
|
|
91
|
+
'uk': 'ukrainian',
|
|
92
|
+
'ukrainian': 'ukrainian',
|
|
93
|
+
// Vietnamese
|
|
94
|
+
'vi': 'vietnamese',
|
|
95
|
+
'vietnamese': 'vietnamese',
|
|
96
|
+
// Arabic
|
|
97
|
+
'ar': 'arabic',
|
|
98
|
+
'arabic': 'arabic',
|
|
99
|
+
// Indonesian
|
|
100
|
+
'id': 'indonesian',
|
|
101
|
+
'indonesian': 'indonesian',
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Map filename to Steam language code
|
|
105
|
+
* @param filename - The filename without extension (e.g., "zh", "en", "japanese")
|
|
106
|
+
* @returns Steam language code or null if not found
|
|
107
|
+
*/
|
|
108
|
+
export function mapFilenameToLanguage(filename) {
|
|
109
|
+
const normalized = filename.toLowerCase().trim();
|
|
110
|
+
return LANGUAGE_CODE_MAP[normalized] || null;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Extract title from markdown content
|
|
114
|
+
* The title is the first H1 heading found in the markdown
|
|
115
|
+
* @param markdown - The markdown content
|
|
116
|
+
* @returns The extracted title or empty string if not found
|
|
117
|
+
*/
|
|
118
|
+
function extractTitleFromMarkdown(markdown) {
|
|
119
|
+
// Match first H1 heading (# Title)
|
|
120
|
+
const h1Match = markdown.match(/^#\s+(.+)$/m);
|
|
121
|
+
if (h1Match) {
|
|
122
|
+
return h1Match[1].trim();
|
|
123
|
+
}
|
|
124
|
+
return '';
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Convert Markdown to Steam Workshop BBCode format
|
|
128
|
+
* @param markdown - The markdown content
|
|
129
|
+
* @returns BBCode content
|
|
130
|
+
*/
|
|
131
|
+
function markdownToBBCode(markdown) {
|
|
132
|
+
let result = markdown;
|
|
133
|
+
// Escape HTML tags first (prevent HTML injection)
|
|
134
|
+
result = result.replace(/</g, '<').replace(/>/g, '>');
|
|
135
|
+
// Code blocks - must be processed before other transformations
|
|
136
|
+
result = result.replace(/```(\w*)\n([\s\S]*?)```/g, '[code]$2[/code]');
|
|
137
|
+
// Inline code - convert to bold for single-line code
|
|
138
|
+
result = result.replace(/`([^`]+)`/g, '[b]$1[/b]');
|
|
139
|
+
// Headers (h1-h6)
|
|
140
|
+
result = result.replace(/^######\s+(.+)$/gm, '[h6]$1[/h6]');
|
|
141
|
+
result = result.replace(/^#####\s+(.+)$/gm, '[h5]$1[/h5]');
|
|
142
|
+
result = result.replace(/^####\s+(.+)$/gm, '[h4]$1[/h4]');
|
|
143
|
+
result = result.replace(/^###\s+(.+)$/gm, '[h3]$1[/h3]');
|
|
144
|
+
result = result.replace(/^##\s+(.+)$/gm, '[h2]$1[/h2]');
|
|
145
|
+
result = result.replace(/^#\s+(.+)$/gm, '[h1]$1[/h1]');
|
|
146
|
+
// Bold and Italic combinations (must be processed before individual ones)
|
|
147
|
+
result = result.replace(/\*\*\*(.+?)\*\*\*/g, '[b][i]$1[/i][/b]');
|
|
148
|
+
result = result.replace(/___(.+?)___/g, '[b][i]$1[/i][/b]');
|
|
149
|
+
// Bold
|
|
150
|
+
result = result.replace(/\*\*(.+?)\*\*/g, '[b]$1[/b]');
|
|
151
|
+
result = result.replace(/__(.+?)__/g, '[b]$1[/b]');
|
|
152
|
+
// Italic
|
|
153
|
+
result = result.replace(/\*(.+?)\*/g, '[i]$1[/i]');
|
|
154
|
+
result = result.replace(/_(.+?)_/g, '[i]$1[/i]');
|
|
155
|
+
// Strikethrough
|
|
156
|
+
result = result.replace(/~~(.+?)~~/g, '[s]$1[/s]');
|
|
157
|
+
// Horizontal rule
|
|
158
|
+
result = result.replace(/^-{3,}$/gm, '[hr]');
|
|
159
|
+
result = result.replace(/^\*{3,}$/gm, '[hr]');
|
|
160
|
+
// Images 
|
|
161
|
+
result = result.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '[img]$2[/img]');
|
|
162
|
+
// Links [text](url)
|
|
163
|
+
result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '[url=$2]$1[/url]');
|
|
164
|
+
// Unordered lists
|
|
165
|
+
result = result.replace(/^[\*\-]\s+(.+)$/gm, '[*]$1');
|
|
166
|
+
// Ordered lists
|
|
167
|
+
result = result.replace(/^\d+\.\s+(.+)$/gm, '[*]$1');
|
|
168
|
+
// Wrap lists in [list] tags
|
|
169
|
+
// Find consecutive [*] lines and wrap them
|
|
170
|
+
result = result.replace(/(\[\*].+\n?)+/g, (match) => {
|
|
171
|
+
// Remove trailing newline from the match
|
|
172
|
+
const content = match.trimEnd();
|
|
173
|
+
return `[list]\n${content}\n[/list]\n`;
|
|
174
|
+
});
|
|
175
|
+
// Blockquotes
|
|
176
|
+
result = result.replace(/^>\s+(.+)$/gm, '[quote]$1[/quote]');
|
|
177
|
+
// Multiple consecutive quotes should be grouped
|
|
178
|
+
result = result.replace(/(\[quote\].+\n?)+/g, (match) => {
|
|
179
|
+
const content = match.trimEnd();
|
|
180
|
+
return content + '\n';
|
|
181
|
+
});
|
|
182
|
+
// Paragraphs - double newline becomes paragraph break
|
|
183
|
+
result = result.replace(/\n\n+/g, '\n\n');
|
|
184
|
+
return result;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Load descriptions from description/*.md files
|
|
188
|
+
* @param directory - Path to the mod directory
|
|
189
|
+
* @returns Array of localized descriptions
|
|
190
|
+
*/
|
|
191
|
+
export async function loadDescriptions(directory) {
|
|
192
|
+
const descriptions = [];
|
|
193
|
+
const descDir = join(directory, 'description');
|
|
194
|
+
// Check if description directory exists
|
|
195
|
+
if (!(await directoryExists(descDir))) {
|
|
196
|
+
return descriptions;
|
|
197
|
+
}
|
|
198
|
+
// Import fs for reading directory
|
|
199
|
+
const fs = await import('fs/promises');
|
|
200
|
+
const { readdir } = fs;
|
|
201
|
+
try {
|
|
202
|
+
const files = await readdir(descDir);
|
|
203
|
+
for (const file of files) {
|
|
204
|
+
if (!file.endsWith('.md')) {
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
const languageCode = file.slice(0, -3); // Remove .md extension
|
|
208
|
+
const steamLanguage = mapFilenameToLanguage(languageCode);
|
|
209
|
+
if (steamLanguage) {
|
|
210
|
+
const filePath = join(descDir, file);
|
|
211
|
+
const markdown = await readTextFile(filePath);
|
|
212
|
+
const bbcode = markdownToBBCode(markdown);
|
|
213
|
+
descriptions.push({
|
|
214
|
+
language: steamLanguage,
|
|
215
|
+
content: bbcode,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
// If directory read fails, return empty array
|
|
222
|
+
console.warn(`Failed to read description directory: ${error}`);
|
|
223
|
+
}
|
|
224
|
+
return descriptions;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Load titles from description/*.md files
|
|
228
|
+
* @param directory - Path to the mod directory
|
|
229
|
+
* @param defaultTitle - The default title to use if no title is found in a file
|
|
230
|
+
* @returns Array of localized titles
|
|
231
|
+
*/
|
|
232
|
+
export async function loadTitles(directory, defaultTitle) {
|
|
233
|
+
const titles = [];
|
|
234
|
+
const descDir = join(directory, 'description');
|
|
235
|
+
// Check if description directory exists
|
|
236
|
+
if (!(await directoryExists(descDir))) {
|
|
237
|
+
return titles;
|
|
238
|
+
}
|
|
239
|
+
// Import fs for reading directory
|
|
240
|
+
const fs = await import('fs/promises');
|
|
241
|
+
const { readdir } = fs;
|
|
242
|
+
try {
|
|
243
|
+
const files = await readdir(descDir);
|
|
244
|
+
for (const file of files) {
|
|
245
|
+
if (!file.endsWith('.md')) {
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
const languageCode = file.slice(0, -3); // Remove .md extension
|
|
249
|
+
const steamLanguage = mapFilenameToLanguage(languageCode);
|
|
250
|
+
if (steamLanguage) {
|
|
251
|
+
const filePath = join(descDir, file);
|
|
252
|
+
const markdown = await readTextFile(filePath);
|
|
253
|
+
const title = extractTitleFromMarkdown(markdown) || defaultTitle;
|
|
254
|
+
titles.push({
|
|
255
|
+
language: steamLanguage,
|
|
256
|
+
title,
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
// If directory read fails, return empty array
|
|
263
|
+
console.warn(`Failed to read description directory: ${error}`);
|
|
264
|
+
}
|
|
265
|
+
return titles;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Get the primary language description and title
|
|
269
|
+
* Priority: english -> schinese -> first available
|
|
270
|
+
* @param descriptions - Array of localized descriptions
|
|
271
|
+
* @param titles - Array of localized titles
|
|
272
|
+
* @returns Primary description and title
|
|
273
|
+
*/
|
|
274
|
+
export function getPrimaryLanguageContent(descriptions, titles) {
|
|
275
|
+
// Try English first
|
|
276
|
+
const englishDesc = descriptions.find((d) => d.language === 'english');
|
|
277
|
+
const englishTitle = titles.find((t) => t.language === 'english');
|
|
278
|
+
if (englishDesc || englishTitle) {
|
|
279
|
+
return { description: englishDesc, title: englishTitle };
|
|
280
|
+
}
|
|
281
|
+
// Try Simplified Chinese second
|
|
282
|
+
const schineseDesc = descriptions.find((d) => d.language === 'schinese');
|
|
283
|
+
const schineseTitle = titles.find((t) => t.language === 'schinese');
|
|
284
|
+
if (schineseDesc || schineseTitle) {
|
|
285
|
+
return { description: schineseDesc, title: schineseTitle };
|
|
286
|
+
}
|
|
287
|
+
// Return first available
|
|
288
|
+
return {
|
|
289
|
+
description: descriptions[0],
|
|
290
|
+
title: titles[0],
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
//# sourceMappingURL=metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../../src/formats/steam/metadata.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ModMetadata } from '../nuget/parser.js';
|
|
2
|
+
/**
|
|
3
|
+
* Save publishedFileId to info.ini as a top-level property
|
|
4
|
+
* @param directory - Path to the mod directory
|
|
5
|
+
* @param publishedFileId - The publishedFileId to save
|
|
6
|
+
*/
|
|
7
|
+
export declare function savePublishedFileId(directory: string, publishedFileId: number): Promise<void>;
|
|
8
|
+
/**
|
|
9
|
+
* Get publishedFileId from mod metadata
|
|
10
|
+
* @param metadata - Parsed mod metadata
|
|
11
|
+
* @returns The publishedFileId or undefined if not set
|
|
12
|
+
*/
|
|
13
|
+
export declare function getPublishedFileId(metadata: ModMetadata): number | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Check if the mod has a publishedFileId (already published)
|
|
16
|
+
* @param metadata - Parsed mod metadata
|
|
17
|
+
* @returns True if the mod has a publishedFileId
|
|
18
|
+
*/
|
|
19
|
+
export declare function hasPublishedFileId(metadata: ModMetadata): boolean;
|
|
20
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/formats/steam/parser.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAgEf;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAQ5E;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAEjE"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { readTextFile, writeTextFile } from '../../utils/fs.js';
|
|
2
|
+
import { FileSystemError } from '../../utils/errors.js';
|
|
3
|
+
/**
|
|
4
|
+
* Save publishedFileId to info.ini as a top-level property
|
|
5
|
+
* @param directory - Path to the mod directory
|
|
6
|
+
* @param publishedFileId - The publishedFileId to save
|
|
7
|
+
*/
|
|
8
|
+
export async function savePublishedFileId(directory, publishedFileId) {
|
|
9
|
+
const infoIniPath = `${directory}/info.ini`;
|
|
10
|
+
try {
|
|
11
|
+
// Read existing content
|
|
12
|
+
const content = await readTextFile(infoIniPath);
|
|
13
|
+
// Check if publishedFileId already exists
|
|
14
|
+
const lines = content.split('\n');
|
|
15
|
+
let found = false;
|
|
16
|
+
// Update or add publishedFileId
|
|
17
|
+
const updatedLines = lines.map((line) => {
|
|
18
|
+
const trimmed = line.trim();
|
|
19
|
+
// Check if this is the publishedFileId line (outside of any section)
|
|
20
|
+
if (trimmed.startsWith('publishedFileId') && !trimmed.startsWith('[')) {
|
|
21
|
+
found = true;
|
|
22
|
+
return `publishedFileId = ${publishedFileId}`;
|
|
23
|
+
}
|
|
24
|
+
return line;
|
|
25
|
+
});
|
|
26
|
+
// If not found, add it after the version line (or at the end)
|
|
27
|
+
if (!found) {
|
|
28
|
+
let insertIndex = -1;
|
|
29
|
+
for (let i = 0; i < updatedLines.length; i++) {
|
|
30
|
+
const trimmed = updatedLines[i].trim();
|
|
31
|
+
if (trimmed.startsWith('version') && !trimmed.startsWith('[')) {
|
|
32
|
+
insertIndex = i + 1;
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (insertIndex >= 0) {
|
|
37
|
+
updatedLines.splice(insertIndex, 0, `publishedFileId = ${publishedFileId}`);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
// Insert before the first section or at the end
|
|
41
|
+
let firstSectionIndex = -1;
|
|
42
|
+
for (let i = 0; i < updatedLines.length; i++) {
|
|
43
|
+
if (updatedLines[i].trim().startsWith('[')) {
|
|
44
|
+
firstSectionIndex = i;
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (firstSectionIndex >= 0) {
|
|
49
|
+
updatedLines.splice(firstSectionIndex, 0, `publishedFileId = ${publishedFileId}`);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
updatedLines.push(`publishedFileId = ${publishedFileId}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Write back
|
|
57
|
+
await writeTextFile(infoIniPath, updatedLines.join('\n'));
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (error instanceof FileSystemError) {
|
|
61
|
+
throw new FileSystemError(`Failed to update info.ini: ${error.message}`, ['Ensure info.ini exists and is writable']);
|
|
62
|
+
}
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get publishedFileId from mod metadata
|
|
68
|
+
* @param metadata - Parsed mod metadata
|
|
69
|
+
* @returns The publishedFileId or undefined if not set
|
|
70
|
+
*/
|
|
71
|
+
export function getPublishedFileId(metadata) {
|
|
72
|
+
if (metadata.publishedFileId) {
|
|
73
|
+
const id = parseInt(metadata.publishedFileId, 10);
|
|
74
|
+
if (!isNaN(id)) {
|
|
75
|
+
return id;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Check if the mod has a publishedFileId (already published)
|
|
82
|
+
* @param metadata - Parsed mod metadata
|
|
83
|
+
* @returns True if the mod has a publishedFileId
|
|
84
|
+
*/
|
|
85
|
+
export function hasPublishedFileId(metadata) {
|
|
86
|
+
return getPublishedFileId(metadata) !== undefined;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../src/formats/steam/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress display component for Workshop uploads
|
|
3
|
+
* Provides visual progress bar using ora
|
|
4
|
+
*/
|
|
5
|
+
import { WorkshopUploadProgress, WorkshopUploadStatus } from './progress.js';
|
|
6
|
+
/**
|
|
7
|
+
* Progress display class
|
|
8
|
+
*/
|
|
9
|
+
export declare class ProgressDisplay {
|
|
10
|
+
private spinner;
|
|
11
|
+
private currentStatus;
|
|
12
|
+
private startTime;
|
|
13
|
+
/**
|
|
14
|
+
* Start the progress display
|
|
15
|
+
*/
|
|
16
|
+
start(): void;
|
|
17
|
+
/**
|
|
18
|
+
* Update the progress display
|
|
19
|
+
*/
|
|
20
|
+
update(progress: WorkshopUploadProgress): void;
|
|
21
|
+
/**
|
|
22
|
+
* Update upload progress with percentage and speed
|
|
23
|
+
*/
|
|
24
|
+
private updateUploadProgress;
|
|
25
|
+
/**
|
|
26
|
+
* Format seconds to human-readable time
|
|
27
|
+
*/
|
|
28
|
+
private formatTime;
|
|
29
|
+
/**
|
|
30
|
+
* Stop the progress display
|
|
31
|
+
*/
|
|
32
|
+
stop(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Get the current status
|
|
35
|
+
*/
|
|
36
|
+
getCurrentStatus(): WorkshopUploadStatus;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=progress-display.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress-display.d.ts","sourceRoot":"","sources":["../../../src/formats/steam/progress-display.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAG7E;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,aAAa,CAAsD;IAC3E,OAAO,CAAC,SAAS,CAAa;IAE9B;;OAEG;IACH,KAAK,IAAI,IAAI;IAQb;;OAEG;IACH,MAAM,CAAC,QAAQ,EAAE,sBAAsB,GAAG,IAAI;IA6C9C;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA6B5B;;OAEG;IACH,OAAO,CAAC,UAAU;IAclB;;OAEG;IACH,IAAI,IAAI,IAAI;IAOZ;;OAEG;IACH,gBAAgB,IAAI,oBAAoB;CAGzC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress display component for Workshop uploads
|
|
3
|
+
* Provides visual progress bar using ora
|
|
4
|
+
*/
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
import { WorkshopUploadStatus } from './progress.js';
|
|
7
|
+
import { formatBytes } from '../../utils/fs.js';
|
|
8
|
+
/**
|
|
9
|
+
* Progress display class
|
|
10
|
+
*/
|
|
11
|
+
export class ProgressDisplay {
|
|
12
|
+
spinner = null;
|
|
13
|
+
currentStatus = WorkshopUploadStatus.Pending;
|
|
14
|
+
startTime = 0;
|
|
15
|
+
/**
|
|
16
|
+
* Start the progress display
|
|
17
|
+
*/
|
|
18
|
+
start() {
|
|
19
|
+
this.spinner = ora({
|
|
20
|
+
text: 'Initializing...',
|
|
21
|
+
spinner: 'dots',
|
|
22
|
+
}).start();
|
|
23
|
+
this.startTime = Date.now();
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Update the progress display
|
|
27
|
+
*/
|
|
28
|
+
update(progress) {
|
|
29
|
+
if (!this.spinner) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
this.currentStatus = progress.status;
|
|
33
|
+
switch (progress.status) {
|
|
34
|
+
case WorkshopUploadStatus.Preparing:
|
|
35
|
+
this.spinner.text = `${progress.message}`;
|
|
36
|
+
break;
|
|
37
|
+
case WorkshopUploadStatus.RequestingId:
|
|
38
|
+
this.spinner.text = `Creating Workshop item...`;
|
|
39
|
+
break;
|
|
40
|
+
case WorkshopUploadStatus.WritingIni:
|
|
41
|
+
this.spinner.text = `Saving configuration...`;
|
|
42
|
+
break;
|
|
43
|
+
case WorkshopUploadStatus.StartingSteamUpload:
|
|
44
|
+
this.spinner.text = `Starting upload...`;
|
|
45
|
+
break;
|
|
46
|
+
case WorkshopUploadStatus.UploadingContent:
|
|
47
|
+
this.updateUploadProgress(progress);
|
|
48
|
+
break;
|
|
49
|
+
case WorkshopUploadStatus.UploadingTranslations:
|
|
50
|
+
this.spinner.text = progress.message;
|
|
51
|
+
break;
|
|
52
|
+
case WorkshopUploadStatus.Completed:
|
|
53
|
+
this.spinner.succeed(progress.message || 'Upload completed successfully!');
|
|
54
|
+
break;
|
|
55
|
+
case WorkshopUploadStatus.Failed:
|
|
56
|
+
this.spinner.fail(progress.message || 'Upload failed');
|
|
57
|
+
break;
|
|
58
|
+
default:
|
|
59
|
+
this.spinner.text = progress.message || 'Processing...';
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Update upload progress with percentage and speed
|
|
64
|
+
*/
|
|
65
|
+
updateUploadProgress(progress) {
|
|
66
|
+
if (!this.spinner) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const { bytesProcessed, bytesTotal, message } = progress;
|
|
70
|
+
if (bytesTotal > 0) {
|
|
71
|
+
const percentage = (bytesProcessed / bytesTotal) * 100;
|
|
72
|
+
const elapsed = (Date.now() - this.startTime) / 1000; // seconds
|
|
73
|
+
const speed = bytesProcessed / elapsed; // bytes per second
|
|
74
|
+
// Format the progress bar
|
|
75
|
+
const barWidth = 20;
|
|
76
|
+
const filled = Math.floor((bytesProcessed / bytesTotal) * barWidth);
|
|
77
|
+
const empty = barWidth - filled;
|
|
78
|
+
const bar = '█'.repeat(filled) + '░'.repeat(empty);
|
|
79
|
+
// Calculate remaining time
|
|
80
|
+
const remainingBytes = bytesTotal - bytesProcessed;
|
|
81
|
+
const remainingSeconds = speed > 0 ? remainingBytes / speed : 0;
|
|
82
|
+
const remainingTime = this.formatTime(remainingSeconds);
|
|
83
|
+
this.spinner.text = `Uploading content [${bar}] ${percentage.toFixed(1)}% | ${formatBytes(bytesProcessed)}/${formatBytes(bytesTotal)} | ${formatBytes(speed)}/s | ETA: ${remainingTime}`;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
this.spinner.text = message || 'Uploading content...';
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Format seconds to human-readable time
|
|
91
|
+
*/
|
|
92
|
+
formatTime(seconds) {
|
|
93
|
+
if (seconds < 60) {
|
|
94
|
+
return `${Math.round(seconds)}s`;
|
|
95
|
+
}
|
|
96
|
+
else if (seconds < 3600) {
|
|
97
|
+
const mins = Math.floor(seconds / 60);
|
|
98
|
+
const secs = Math.round(seconds % 60);
|
|
99
|
+
return `${mins}m ${secs}s`;
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
const hours = Math.floor(seconds / 3600);
|
|
103
|
+
const mins = Math.round((seconds % 3600) / 60);
|
|
104
|
+
return `${hours}h ${mins}m`;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Stop the progress display
|
|
109
|
+
*/
|
|
110
|
+
stop() {
|
|
111
|
+
if (this.spinner && this.spinner.isSpinning) {
|
|
112
|
+
this.spinner.stop();
|
|
113
|
+
}
|
|
114
|
+
this.spinner = null;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Get the current status
|
|
118
|
+
*/
|
|
119
|
+
getCurrentStatus() {
|
|
120
|
+
return this.currentStatus;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=progress-display.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress-display.js","sourceRoot":"","sources":["../../../src/formats/steam/progress-display.ts"],"names":[],"mappings":"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"}
|