@synopackageland/cli 0.7.2 → 0.7.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
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.3 (2026-10-11)
|
|
4
|
+
|
|
5
|
+
Rebuild every package built with 0.7.2 that has `i18n.info` translations. In
|
|
6
|
+
0.7.2 its DSM main-menu entry, desktop shortcut and window title showed the raw
|
|
7
|
+
key `synopkgland:app_title` in every language.
|
|
8
|
+
|
|
9
|
+
### Translated DSM title fix
|
|
10
|
+
|
|
11
|
+
- `ui/config` entries that use the `synopkgland:app_title` and `app_desc`
|
|
12
|
+
strings now declare `"texts": "texts"`: the main-menu `app` entry, its window
|
|
13
|
+
`lib` entry and the `.url` entry of a `synology-app.yaml` app. DSM loads
|
|
14
|
+
`ui/texts/<DSM language>/strings` only for entries that declare `texts`, so
|
|
15
|
+
0.7.2 titles never resolved (seen on DSM 7.4 and 7.1.1). Without `i18n.info`
|
|
16
|
+
`ui/config` is unchanged.
|
|
17
|
+
|
|
18
|
+
### Correction to 0.7.2
|
|
19
|
+
|
|
20
|
+
- 0.7.2 said `synology-app.yaml` `i18n.info` localizes the DSM window title.
|
|
21
|
+
It localizes the DSM main-menu and desktop label only. `launch: dsm-window`
|
|
22
|
+
adds a main-menu and desktop entry that DSM always opens in a new browser
|
|
23
|
+
tab, as it does for every URL entry; the app has no DSM window and no window
|
|
24
|
+
title. This is not caused by DSM's CSRF protection setting. The container app
|
|
25
|
+
guide and the `synology-app.yaml` reference now say so.
|
|
26
|
+
|
|
27
|
+
### 繁體中文摘要
|
|
28
|
+
|
|
29
|
+
- 修正 0.7.2 的在地化標題:有 `i18n.info` 翻譯時,`ui/config` 中使用 `synopkgland:` 字串的
|
|
30
|
+
`app`、`lib` 與 `.url` 項目都加上 `"texts": "texts"`。0.7.2 少了這個欄位,DSM 不會載入
|
|
31
|
+
`ui/texts/<語言>/strings`,主選單、桌面捷徑與視窗標題在各語言都顯示 `synopkgland:app_title`。
|
|
32
|
+
- 用 0.7.2 建置且含 `i18n.info` 的套件,請以 0.7.3 重新建置並遞增 build 後重新發佈;沒有
|
|
33
|
+
`i18n.info` 的套件不受影響。
|
|
34
|
+
- 更正 0.7.2:`synology-app.yaml` 的 `i18n.info` 只翻譯 DSM 主選單與桌面標籤,沒有視窗標題。
|
|
35
|
+
`launch: dsm-window` 的項目一律由 DSM 在新的瀏覽器分頁開啟(DSM 對所有網址項目都如此),
|
|
36
|
+
與 CSRF 防護設定無關;容器 App 指南與 `synology-app.yaml` 參考已更正。
|
|
37
|
+
|
|
3
38
|
## 0.7.2 (2026-10-11)
|
|
4
39
|
|
|
5
40
|
Rebuild packages to pick up the new default icon. Packages without `icon` now
|
|
@@ -9,10 +9,13 @@ export interface AppTitle {
|
|
|
9
9
|
* `ui/config` title fields. With translations they are `section:key`
|
|
10
10
|
* references DSM resolves from `ui/texts/<lang>/strings` for the main menu
|
|
11
11
|
* and the window title; without, the literal English text as before.
|
|
12
|
+
* DSM loads those strings only for entries that declare `texts`. Spread the
|
|
13
|
+
* result into an entry; absent fields stay out of the JSON.
|
|
12
14
|
*/
|
|
13
15
|
export declare function uiTitleFields(app: AppTitle): {
|
|
14
16
|
title: string;
|
|
15
17
|
desc: string;
|
|
18
|
+
texts?: string;
|
|
16
19
|
preloadTexts?: string[];
|
|
17
20
|
};
|
|
18
21
|
/** `ui/texts/<dsm lang>/strings` for English and every translated language; none without translations. */
|
|
@@ -4,6 +4,8 @@ import { DSM_LANGS, LOCALES } from "../standalone/i18n.js";
|
|
|
4
4
|
const SECTION = "synopkgland";
|
|
5
5
|
const TITLE = `${SECTION}:app_title`;
|
|
6
6
|
const DESC = `${SECTION}:app_desc`;
|
|
7
|
+
/** `ui/` subdirectory with the strings; a `ui/config` entry's `texts` names it relative to `ui/`. */
|
|
8
|
+
const TEXTS_DIR = "texts";
|
|
7
9
|
function translated(app) {
|
|
8
10
|
return Object.values(app.info ?? {}).some((text) => text?.displayname || text?.description);
|
|
9
11
|
}
|
|
@@ -11,10 +13,12 @@ function translated(app) {
|
|
|
11
13
|
* `ui/config` title fields. With translations they are `section:key`
|
|
12
14
|
* references DSM resolves from `ui/texts/<lang>/strings` for the main menu
|
|
13
15
|
* and the window title; without, the literal English text as before.
|
|
16
|
+
* DSM loads those strings only for entries that declare `texts`. Spread the
|
|
17
|
+
* result into an entry; absent fields stay out of the JSON.
|
|
14
18
|
*/
|
|
15
19
|
export function uiTitleFields(app) {
|
|
16
20
|
return translated(app)
|
|
17
|
-
? { title: TITLE, desc: DESC, preloadTexts: [TITLE, DESC] }
|
|
21
|
+
? { title: TITLE, desc: DESC, texts: TEXTS_DIR, preloadTexts: [TITLE, DESC] }
|
|
18
22
|
: { title: app.displayname, desc: app.description };
|
|
19
23
|
}
|
|
20
24
|
/** `ui/texts/<dsm lang>/strings` for English and every translated language; none without translations. */
|
|
@@ -34,8 +38,8 @@ export function renderUiTexts(app) {
|
|
|
34
38
|
}
|
|
35
39
|
export function writeUiTexts(uiRoot, app) {
|
|
36
40
|
for (const [lang, strings] of renderUiTexts(app)) {
|
|
37
|
-
mkdirSync(join(uiRoot,
|
|
38
|
-
const path = join(uiRoot,
|
|
41
|
+
mkdirSync(join(uiRoot, TEXTS_DIR, lang), { recursive: true });
|
|
42
|
+
const path = join(uiRoot, TEXTS_DIR, lang, "strings");
|
|
39
43
|
writeFileSync(path, strings, "utf8");
|
|
40
44
|
chmodSync(path, 0o644);
|
|
41
45
|
}
|
|
@@ -141,15 +141,12 @@ export function renderWebStationResource(contract) {
|
|
|
141
141
|
}
|
|
142
142
|
export function renderDsmWindowConfig(contract) {
|
|
143
143
|
const packageId = String(contract.package);
|
|
144
|
-
const { title, desc, preloadTexts } = uiTitleFields(contractAppTitle(contract));
|
|
145
144
|
return `${JSON.stringify({
|
|
146
145
|
".url": {
|
|
147
146
|
[packageId]: {
|
|
148
147
|
type: "url",
|
|
149
148
|
allUsers: true,
|
|
150
|
-
|
|
151
|
-
desc,
|
|
152
|
-
...(preloadTexts ? { preloadTexts } : {}),
|
|
149
|
+
...uiTitleFields(contractAppTitle(contract)),
|
|
153
150
|
icon: "images/app_{0}.png",
|
|
154
151
|
url: trustedAppEntryPath(contract),
|
|
155
152
|
},
|
|
@@ -69,14 +69,12 @@ export function appTitle(manifest) {
|
|
|
69
69
|
/** `ui/config`: registers the DSM main-menu app and its window class. */
|
|
70
70
|
export function renderUiConfig(manifest) {
|
|
71
71
|
const ns = `SYNO.SDS.${manifest.package}`;
|
|
72
|
-
const
|
|
72
|
+
const titleFields = uiTitleFields(appTitle(manifest));
|
|
73
73
|
return `${JSON.stringify({
|
|
74
74
|
[windowScriptName(manifest)]: {
|
|
75
75
|
[`${ns}.Instance`]: {
|
|
76
76
|
type: "app",
|
|
77
|
-
|
|
78
|
-
desc,
|
|
79
|
-
...(preloadTexts ? { preloadTexts } : {}),
|
|
77
|
+
...titleFields,
|
|
80
78
|
icon: "images/app_{0}.png",
|
|
81
79
|
appWindow: `${ns}.MainWindow`,
|
|
82
80
|
allowMultiInstance: false,
|
|
@@ -85,7 +83,8 @@ export function renderUiConfig(manifest) {
|
|
|
85
83
|
},
|
|
86
84
|
[`${ns}.MainWindow`]: {
|
|
87
85
|
type: "lib",
|
|
88
|
-
title,
|
|
86
|
+
title: titleFields.title,
|
|
87
|
+
texts: titleFields.texts,
|
|
89
88
|
icon: "images/app_{0}.png",
|
|
90
89
|
depend: [],
|
|
91
90
|
},
|