tsoft-cli 3.13.1 → 3.13.3
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 +10 -0
- package/locales/en.json +2 -1
- package/locales/tr.json +2 -1
- package/package.json +1 -1
- package/src/commands/theme-dev.js +6 -0
- package/src/commands/theme-push.js +5 -4
- package/src/commands/theme-section.js +2 -2
- package/src/storage.js +26 -0
- package/src/ui/help-renderer.js +4 -2
- package/src/ui/theme-choice.js +9 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,16 @@ All notable changes to T-Soft CLI will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [3.13.3] - 2026-09-10
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- `theme dev` no longer crashes after you sign out. With no active store it read the store name as text anyway and died with "Cannot read properties of null (reading 'replace')", which says nothing about what went wrong or how to recover. It now reports that there is no active store, points at `tsoft login`, and exits non-zero like `theme list` and `theme init` already did in the same situation.
|
|
12
|
+
|
|
13
|
+
## [3.13.2] - 2026-09-10
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- Commands no longer print a theme's folder id where its name belongs. `theme push`, `theme section list`, `theme section add` and the help screen showed whatever is recorded as the active theme, and for most themes that is the folder id — so a line meant to confirm what you are about to push read "Store: example.com - Theme: adf806ec-9ee6-4ce8-af40-cd1af10a4c04" and told you nothing. The commands that already talk to the store now show the theme's name; the help screen, which must not make a network call to draw its status line, leaves the theme out rather than printing an id.
|
|
17
|
+
|
|
8
18
|
## [3.13.1] - 2026-09-10
|
|
9
19
|
|
|
10
20
|
### Fixed
|
package/locales/en.json
CHANGED
|
@@ -395,5 +395,6 @@
|
|
|
395
395
|
"config.autoupgrade.off": "Version checking is off.",
|
|
396
396
|
"config.autoupgrade.status_on": "Version checking: on",
|
|
397
397
|
"config.autoupgrade.status_off": "Version checking: off",
|
|
398
|
-
"config.autoupgrade.usage": "Usage: tsoft config autoupgrade on | off | status"
|
|
398
|
+
"config.autoupgrade.usage": "Usage: tsoft config autoupgrade on | off | status",
|
|
399
|
+
"dev.no_active_store": "No active store.\n\nTo sign in: tsoft login"
|
|
399
400
|
}
|
package/locales/tr.json
CHANGED
|
@@ -395,5 +395,6 @@
|
|
|
395
395
|
"config.autoupgrade.off": "Sürüm kontrolü kapatıldı.",
|
|
396
396
|
"config.autoupgrade.status_on": "Sürüm kontrolü: açık",
|
|
397
397
|
"config.autoupgrade.status_off": "Sürüm kontrolü: kapalı",
|
|
398
|
-
"config.autoupgrade.usage": "Kullanım: tsoft config autoupgrade on | off | status"
|
|
398
|
+
"config.autoupgrade.usage": "Kullanım: tsoft config autoupgrade on | off | status",
|
|
399
|
+
"dev.no_active_store": "Aktif mağaza bulunamadı.\n\nGiriş yapmak için: tsoft login"
|
|
399
400
|
}
|
package/package.json
CHANGED
|
@@ -332,6 +332,12 @@ export async function themeDevCommand(themeName) {
|
|
|
332
332
|
console.log(chalk.cyan(t('dev.starting') + '\n'));
|
|
333
333
|
|
|
334
334
|
const store = await getActiveStore();
|
|
335
|
+
|
|
336
|
+
if (!store) {
|
|
337
|
+
showError(t('dev.no_active_store'));
|
|
338
|
+
process.exit(1);
|
|
339
|
+
}
|
|
340
|
+
|
|
335
341
|
const storeSlug = normalizeStoreDomain(store);
|
|
336
342
|
|
|
337
343
|
let themeSlug = themeName;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import ora from 'ora';
|
|
3
3
|
import { createApiClient } from '../api-client.js';
|
|
4
|
-
import {
|
|
4
|
+
import { describeActiveTheme, getActiveStore } from '../storage.js';
|
|
5
5
|
import { mapPushError } from '../errors/error-mapper.js';
|
|
6
6
|
import { isJsonMode, jsonOut } from '../output-mode.js';
|
|
7
7
|
import { t } from '../i18n.js';
|
|
@@ -91,11 +91,12 @@ export async function themePushCommand(themeName, options = {}) {
|
|
|
91
91
|
if (themeName) {
|
|
92
92
|
themeUuid = themeName;
|
|
93
93
|
} else {
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
const active = await describeActiveTheme();
|
|
95
|
+
themeUuid = active?.uuid ?? null;
|
|
96
|
+
if (active && !isJsonMode()) {
|
|
96
97
|
const store = await getActiveStore();
|
|
97
98
|
if (store) {
|
|
98
|
-
console.log(chalk.gray(t('context.line', { store, theme:
|
|
99
|
+
console.log(chalk.gray(t('context.line', { store, theme: active.label })));
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
102
|
if (!themeUuid) {
|
|
@@ -35,10 +35,10 @@ export async function themeSectionListCommand() {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
console.log(chalk.cyan(t('section.list.starting') + '\n'));
|
|
38
|
-
console.log(chalk.gray(t('section.list.active_theme', { theme: activeTheme }) + '\n'));
|
|
39
38
|
|
|
40
39
|
// Tema UUID'sini al
|
|
41
40
|
const themeInfo = await getThemeUuidBySlug(activeTheme);
|
|
41
|
+
console.log(chalk.gray(t('section.list.active_theme', { theme: themeInfo.name ?? activeTheme }) + '\n'));
|
|
42
42
|
|
|
43
43
|
// Section'ları çek
|
|
44
44
|
const apiClient = await createApiClient();
|
|
@@ -98,10 +98,10 @@ export async function themeSectionAddCommand() {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
console.log(chalk.cyan(t('section.add.starting') + '\n'));
|
|
101
|
-
console.log(chalk.gray(t('section.add.active_theme', { theme: activeTheme }) + '\n'));
|
|
102
101
|
|
|
103
102
|
// Tema UUID'sini al
|
|
104
103
|
const themeInfo = await getThemeUuidBySlug(activeTheme);
|
|
104
|
+
console.log(chalk.gray(t('section.add.active_theme', { theme: themeInfo.name ?? activeTheme }) + '\n'));
|
|
105
105
|
|
|
106
106
|
// Section'ları çek
|
|
107
107
|
const apiClient = await createApiClient();
|
package/src/storage.js
CHANGED
|
@@ -729,6 +729,32 @@ export async function resolveActiveThemeUuid() {
|
|
|
729
729
|
return uuid;
|
|
730
730
|
}
|
|
731
731
|
|
|
732
|
+
/**
|
|
733
|
+
* Aktif temayı hem kimliğiyle hem okunabilir adıyla döner.
|
|
734
|
+
*
|
|
735
|
+
* Kayıt UUID ise ad mağazadan çözülür; mağazaya ulaşılamazsa kayıtlı değer
|
|
736
|
+
* olduğu gibi etiket olur. Kullanıcıya UUID göstermemek için vardır.
|
|
737
|
+
*
|
|
738
|
+
* @returns {Promise<{uuid: string, label: string}|null>}
|
|
739
|
+
*/
|
|
740
|
+
export async function describeActiveTheme() {
|
|
741
|
+
const uuid = await resolveActiveThemeUuid();
|
|
742
|
+
|
|
743
|
+
if (!uuid) {
|
|
744
|
+
return null;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
try {
|
|
748
|
+
const { fetchAllThemes } = await import('./theme-list.js');
|
|
749
|
+
const { themes } = await fetchAllThemes();
|
|
750
|
+
const match = themes.find(theme => theme.theme_folder === uuid);
|
|
751
|
+
|
|
752
|
+
return { uuid, label: match?.name ?? uuid };
|
|
753
|
+
} catch {
|
|
754
|
+
return { uuid, label: uuid };
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
|
|
732
758
|
/**
|
|
733
759
|
* Tema slug'ından UUID/folder adını bulur
|
|
734
760
|
* @param {string} themeSlug - Tema slug (örn: 'my-theme')
|
package/src/ui/help-renderer.js
CHANGED
|
@@ -4,6 +4,7 @@ import { TSOFT_COLORS, createTSoftGradient } from './prompt-wrapper.js';
|
|
|
4
4
|
import { humanOut, isJsonMode, jsonOut } from '../output-mode.js';
|
|
5
5
|
import { t } from '../i18n.js';
|
|
6
6
|
import { loadTokens, getActiveStore, getActiveTheme } from '../storage.js';
|
|
7
|
+
import { themeStatusLabel } from './theme-choice.js';
|
|
7
8
|
|
|
8
9
|
const require = createRequire(import.meta.url);
|
|
9
10
|
|
|
@@ -150,8 +151,9 @@ function buildStatusLines(status) {
|
|
|
150
151
|
}
|
|
151
152
|
|
|
152
153
|
// Theme line
|
|
153
|
-
|
|
154
|
-
|
|
154
|
+
const themeLabel = themeStatusLabel(activeTheme);
|
|
155
|
+
if (themeLabel) {
|
|
156
|
+
const themeText = t('help.status.active_theme', { theme: themeLabel });
|
|
155
157
|
lines.push(' ' + orangeBullet + ' ' + themeText);
|
|
156
158
|
} else {
|
|
157
159
|
lines.push(' ' + chalk.dim('○ ' + t('help.status.no_theme')));
|
package/src/ui/theme-choice.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import { slugify } from '../storage.js';
|
|
2
|
+
import { slugify, isThemeUuid } from '../storage.js';
|
|
3
3
|
import { t } from '../i18n.js';
|
|
4
4
|
|
|
5
5
|
export function themeLabels(theme, selectedTheme) {
|
|
@@ -31,3 +31,11 @@ export function decorateThemeName(theme, selectedTheme) {
|
|
|
31
31
|
|
|
32
32
|
return [name, chalk.gray(`v${theme.version}`), ...marks].join(' ');
|
|
33
33
|
}
|
|
34
|
+
|
|
35
|
+
export function themeStatusLabel(activeTheme) {
|
|
36
|
+
if (!activeTheme || isThemeUuid(activeTheme)) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return activeTheme;
|
|
41
|
+
}
|