@ducky7go/ducky-cli 0.0.4 → 0.0.5-dev.2

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.
Files changed (61) hide show
  1. package/README.md +47 -199
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +2 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/steam/index.d.ts +3 -0
  6. package/dist/commands/steam/index.d.ts.map +1 -0
  7. package/dist/commands/steam/index.js +21 -0
  8. package/dist/commands/steam/index.js.map +1 -0
  9. package/dist/commands/steam/push.d.ts +3 -0
  10. package/dist/commands/steam/push.d.ts.map +1 -0
  11. package/dist/commands/steam/push.js +29 -0
  12. package/dist/commands/steam/push.js.map +1 -0
  13. package/dist/commands/steam/validate.d.ts +3 -0
  14. package/dist/commands/steam/validate.d.ts.map +1 -0
  15. package/dist/commands/steam/validate.js +47 -0
  16. package/dist/commands/steam/validate.js.map +1 -0
  17. package/dist/formats/steam/config.d.ts +23 -0
  18. package/dist/formats/steam/config.d.ts.map +1 -0
  19. package/dist/formats/steam/config.js +32 -0
  20. package/dist/formats/steam/config.js.map +1 -0
  21. package/dist/formats/steam/metadata.d.ts +45 -0
  22. package/dist/formats/steam/metadata.d.ts.map +1 -0
  23. package/dist/formats/steam/metadata.js +293 -0
  24. package/dist/formats/steam/metadata.js.map +1 -0
  25. package/dist/formats/steam/parser.d.ts +20 -0
  26. package/dist/formats/steam/parser.d.ts.map +1 -0
  27. package/dist/formats/steam/parser.js +88 -0
  28. package/dist/formats/steam/parser.js.map +1 -0
  29. package/dist/formats/steam/progress-display.d.ts +38 -0
  30. package/dist/formats/steam/progress-display.d.ts.map +1 -0
  31. package/dist/formats/steam/progress-display.js +123 -0
  32. package/dist/formats/steam/progress-display.js.map +1 -0
  33. package/dist/formats/steam/progress.d.ts +79 -0
  34. package/dist/formats/steam/progress.d.ts.map +1 -0
  35. package/dist/formats/steam/progress.js +126 -0
  36. package/dist/formats/steam/progress.js.map +1 -0
  37. package/dist/formats/steam/push-handler.d.ts +22 -0
  38. package/dist/formats/steam/push-handler.d.ts.map +1 -0
  39. package/dist/formats/steam/push-handler.js +31 -0
  40. package/dist/formats/steam/push-handler.js.map +1 -0
  41. package/dist/formats/steam/upload-standalone.d.ts +20 -0
  42. package/dist/formats/steam/upload-standalone.d.ts.map +1 -0
  43. package/dist/formats/steam/upload-standalone.js +221 -0
  44. package/dist/formats/steam/upload-standalone.js.map +1 -0
  45. package/dist/formats/steam/validator.d.ts +58 -0
  46. package/dist/formats/steam/validator.d.ts.map +1 -0
  47. package/dist/formats/steam/validator.js +136 -0
  48. package/dist/formats/steam/validator.js.map +1 -0
  49. package/dist/formats/steam/workshop.d.ts +72 -0
  50. package/dist/formats/steam/workshop.d.ts.map +1 -0
  51. package/dist/formats/steam/workshop.js +221 -0
  52. package/dist/formats/steam/workshop.js.map +1 -0
  53. package/dist/utils/errors.d.ts +24 -0
  54. package/dist/utils/errors.d.ts.map +1 -1
  55. package/dist/utils/errors.js +51 -0
  56. package/dist/utils/errors.js.map +1 -1
  57. package/dist/utils/fs.d.ts +8 -0
  58. package/dist/utils/fs.d.ts.map +1 -1
  59. package/dist/utils/fs.js +22 -0
  60. package/dist/utils/fs.js.map +1 -1
  61. 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, '&lt;').replace(/>/g, '&gt;');
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 ![alt](url)
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":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAmB,MAAM,uBAAuB,CAAC;AAGzE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,SAAiB,EACjB,eAAuB;IAEvB,MAAM,WAAW,GAAG,GAAG,SAAS,WAAW,CAAC;IAE5C,IAAI,CAAC;QACH,wBAAwB;QACxB,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;QAEhD,0CAA0C;QAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,KAAK,GAAG,KAAK,CAAC;QAElB,gCAAgC;QAChC,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACtC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,qEAAqE;YACrE,IAAI,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtE,KAAK,GAAG,IAAI,CAAC;gBACb,OAAO,qBAAqB,eAAe,EAAE,CAAC;YAChD,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,8DAA8D;QAC9D,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,WAAW,GAAG,CAAC,CAAC,CAAC;YACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7C,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBACvC,IAAI,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC9D,WAAW,GAAG,CAAC,GAAG,CAAC,CAAC;oBACpB,MAAM;gBACR,CAAC;YACH,CAAC;YAED,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;gBACrB,YAAY,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,EAAE,qBAAqB,eAAe,EAAE,CAAC,CAAC;YAC9E,CAAC;iBAAM,CAAC;gBACN,gDAAgD;gBAChD,IAAI,iBAAiB,GAAG,CAAC,CAAC,CAAC;gBAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC7C,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC3C,iBAAiB,GAAG,CAAC,CAAC;wBACtB,MAAM;oBACR,CAAC;gBACH,CAAC;gBAED,IAAI,iBAAiB,IAAI,CAAC,EAAE,CAAC;oBAC3B,YAAY,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,EAAE,qBAAqB,eAAe,EAAE,CAAC,CAAC;gBACpF,CAAC;qBAAM,CAAC;oBACN,YAAY,CAAC,IAAI,CAAC,qBAAqB,eAAe,EAAE,CAAC,CAAC;gBAC5D,CAAC;YACH,CAAC;QACH,CAAC;QAED,aAAa;QACb,MAAM,aAAa,CAAC,WAAW,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,eAAe,EAAE,CAAC;YACrC,MAAM,IAAI,eAAe,CACvB,8BAA8B,KAAK,CAAC,OAAO,EAAE,EAC7C,CAAC,wCAAwC,CAAC,CAC3C,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAqB;IACtD,IAAI,QAAQ,CAAC,eAAe,EAAE,CAAC;QAC7B,MAAM,EAAE,GAAG,QAAQ,CAAC,QAAQ,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QAClD,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YACf,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAqB;IACtD,OAAO,kBAAkB,CAAC,QAAQ,CAAC,KAAK,SAAS,CAAC;AACpD,CAAC"}
@@ -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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"}