uvako-cli 0.2.1 → 0.4.0
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 +175 -125
- package/package.json +1 -1
- package/src/api.js +6 -5
- package/src/check.js +155 -63
- package/src/config.js +6 -5
- package/src/i18n.js +67 -0
- package/src/init.js +74 -17
- package/src/locales/en.js +226 -0
- package/src/main.js +15 -10
- package/src/package.js +3 -2
- package/src/remote.js +51 -50
- package/src/zip.js +5 -4
package/src/init.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { getLocale, t } from "./i18n.js";
|
|
3
4
|
|
|
4
5
|
// Yeni tema iskeleti. Tema kod içermez: bir katalog temasını ("base") temel alır ve onun üstüne
|
|
5
6
|
// ayar, ana sayfa bölüm sırası, SCSS ve görsel getirir.
|
|
@@ -19,10 +20,10 @@ function logo(name) {
|
|
|
19
20
|
* sayfa şablonu). Verilmezse iskelet şablonsuz kurulur; tema temel temanın bölüm sırasını kullanır.
|
|
20
21
|
*/
|
|
21
22
|
export function initTheme(key, { name, author, cwd, base = "linea", starter = null }) {
|
|
22
|
-
if (!keyPattern.test(key) || key.length > 40) throw new Error(
|
|
23
|
-
if (!keyPattern.test(base)) throw new Error(
|
|
23
|
+
if (!keyPattern.test(key) || key.length > 40) throw new Error(t("Tema anahtarı küçük harf, rakam ve tireden oluşmalı (ör. \"atolye\"): {0}", key));
|
|
24
|
+
if (!keyPattern.test(base)) throw new Error(t("Temel tema adı geçersiz: {0}", base));
|
|
24
25
|
const dir = path.join(cwd, key);
|
|
25
|
-
if (existsSync(dir)) throw new Error(
|
|
26
|
+
if (existsSync(dir)) throw new Error(t("Klasör zaten var: {0}", dir));
|
|
26
27
|
const title = String(name || key.replace(/(^|-)([a-z])/g, (_, dash, letter) => (dash ? " " : "") + letter.toUpperCase()));
|
|
27
28
|
const write = (rel, content) => {
|
|
28
29
|
const file = path.join(dir, rel);
|
|
@@ -30,7 +31,8 @@ export function initTheme(key, { name, author, cwd, base = "linea", starter = nu
|
|
|
30
31
|
writeFileSync(file, content, "utf8");
|
|
31
32
|
};
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
const description = t("{0} teması.", title);
|
|
35
|
+
write("theme.json", json({ key, name: title, version: "0.1.0", base, author: String(author || ""), description, screenshot: "", industries: [], features: [], price: 0 }));
|
|
34
36
|
|
|
35
37
|
// Yalnızca temel temadan farklı olan değerler yazılır; gerisi temel temadan gelir.
|
|
36
38
|
write("config/settings_data.json", json({ logo: "uploads/logo.svg" }));
|
|
@@ -43,7 +45,24 @@ export function initTheme(key, { name, author, cwd, base = "linea", starter = nu
|
|
|
43
45
|
write("reference/sections.json", json(starter.sections ?? {}));
|
|
44
46
|
}
|
|
45
47
|
|
|
46
|
-
|
|
48
|
+
const en = getLocale() === "en";
|
|
49
|
+
|
|
50
|
+
// Temanın kendi metinlerinin çevirisi: anahtar temadaki metin, değer o dildeki karşılığıdır.
|
|
51
|
+
// İskelet tek bir örnekle gelir; settings_data.json'a yazdığınız başlık ve buton metinlerini ekleyin.
|
|
52
|
+
if (en) write("locales/tr.json", json({ [description]: `${title} teması.` }));
|
|
53
|
+
else write("locales/en.json", json({ [description]: `${title} theme.` }));
|
|
54
|
+
|
|
55
|
+
write("styles/_tokens.scss", en ? `// Overrides the base theme's variables: the values you set here spread across the whole theme.
|
|
56
|
+
// This file may contain only variable assignments and font @imports.
|
|
57
|
+
//
|
|
58
|
+
// @import url('https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700&display=swap');
|
|
59
|
+
// $font-family: 'Manrope', sans-serif;
|
|
60
|
+
// $color-text: #111111;
|
|
61
|
+
// $color-sub-text: #6b6b6b;
|
|
62
|
+
// $color-border: #e5e5e5;
|
|
63
|
+
// $color-background: #ffffff;
|
|
64
|
+
// $border-radius: 0;
|
|
65
|
+
` : `// Temel temanın değişkenlerinin üstüne yazılır: burada verdiğiniz değerler temanın tamamına yayılır.
|
|
47
66
|
// Bu dosyada yalnızca değişken ataması ve yazı tipi @import'u bulunabilir.
|
|
48
67
|
//
|
|
49
68
|
// @import url('https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700&display=swap');
|
|
@@ -55,7 +74,14 @@ export function initTheme(key, { name, author, cwd, base = "linea", starter = nu
|
|
|
55
74
|
// $border-radius: 0;
|
|
56
75
|
`);
|
|
57
76
|
|
|
58
|
-
write("styles/theme.scss", `//
|
|
77
|
+
write("styles/theme.scss", en ? `// Theme-specific rules. Compiled after the base theme's stylesheet; the base theme's variables
|
|
78
|
+
// ($color-text, $font-family…) and mixins (@include) can be used.
|
|
79
|
+
// Images: url("#{$theme-assets}/uploads/file.webp")
|
|
80
|
+
// Panel settings: $s-<setting_name> (e.g. $s-color_primary)
|
|
81
|
+
|
|
82
|
+
.theme-${base} {
|
|
83
|
+
}
|
|
84
|
+
` : `// Temaya özgü kurallar. Temel temanın stilinden sonra derlenir; temel temanın değişkenleri
|
|
59
85
|
// ($color-text, $font-family…) ve mixin'leri (@include) kullanılabilir.
|
|
60
86
|
// Görseller: url("#{$theme-assets}/uploads/dosya.webp")
|
|
61
87
|
// Panel ayarları: $s-<ayar_adı> (ör. $s-color_primary)
|
|
@@ -66,7 +92,41 @@ export function initTheme(key, { name, author, cwd, base = "linea", starter = nu
|
|
|
66
92
|
|
|
67
93
|
write("assets/uploads/logo.svg", logo(title));
|
|
68
94
|
|
|
69
|
-
|
|
95
|
+
const commands = `\`\`\`bash
|
|
96
|
+
uvako login --store ${en ? "mystore" : "magazam"}
|
|
97
|
+
\`\`\`
|
|
98
|
+
|
|
99
|
+
\`\`\`bash
|
|
100
|
+
uvako theme dev
|
|
101
|
+
\`\`\`
|
|
102
|
+
|
|
103
|
+
\`\`\`bash
|
|
104
|
+
uvako theme push
|
|
105
|
+
\`\`\`
|
|
106
|
+
`;
|
|
107
|
+
|
|
108
|
+
write("README.md", en ? `# ${title}
|
|
109
|
+
|
|
110
|
+
An Uvako theme. Built on the \`${base}\` theme; contains no code.
|
|
111
|
+
|
|
112
|
+
- \`theme.json\` — identity: key, name, version, base theme, theme store details.
|
|
113
|
+
- \`config/settings_data.json\` — the setting values that differ from the base theme.
|
|
114
|
+
- \`config/settings_schema.json\` — (optional) the settings shown in the panel; the base theme's are used if absent.
|
|
115
|
+
- \`templates/index.json\` — (optional) the order of the sections on the home page.
|
|
116
|
+
- \`locales/tr.json\`, \`en.json\`, \`de.json\` — (optional) translations of the theme's own texts: \`{"text in the theme": "translation"}\`.
|
|
117
|
+
- \`styles/_tokens.scss\` — variables such as colour, font and radius.
|
|
118
|
+
- \`styles/theme.scss\` — theme-specific SCSS.
|
|
119
|
+
- \`assets/\` — logo, slide and banner images, fonts.
|
|
120
|
+
- \`reference/\` — the base theme's setting schema, defaults and section types. Not included in the package.
|
|
121
|
+
|
|
122
|
+
## Languages
|
|
123
|
+
|
|
124
|
+
Stores can publish their storefront in Turkish, English and German. Write the texts in
|
|
125
|
+
\`config/settings_data.json\` and \`theme.json\` in one language and put their equivalents in
|
|
126
|
+
\`locales/<language>.json\`. A text without a translation is shown as written. \`uvako theme check\`
|
|
127
|
+
lists the texts that are missing from each file.
|
|
128
|
+
|
|
129
|
+
${commands}` : `# ${title}
|
|
70
130
|
|
|
71
131
|
Uvako teması. \`${base}\` temasını temel alır; kod içermez.
|
|
72
132
|
|
|
@@ -74,22 +134,19 @@ Uvako teması. \`${base}\` temasını temel alır; kod içermez.
|
|
|
74
134
|
- \`config/settings_data.json\` — temel temadan farklı olan ayar değerleri.
|
|
75
135
|
- \`config/settings_schema.json\` — (isteğe bağlı) panelde görünen ayarlar; yoksa temel temanınki kullanılır.
|
|
76
136
|
- \`templates/index.json\` — (isteğe bağlı) ana sayfadaki bölümlerin sırası.
|
|
137
|
+
- \`locales/en.json\`, \`de.json\`, \`tr.json\` — (isteğe bağlı) temanın kendi metinlerinin çevirisi: \`{"temadaki metin": "çevirisi"}\`.
|
|
77
138
|
- \`styles/_tokens.scss\` — renk, yazı tipi, köşe gibi değişkenler.
|
|
78
139
|
- \`styles/theme.scss\` — temaya özgü SCSS.
|
|
79
140
|
- \`assets/\` — logo, slayt ve banner görselleri, yazı tipleri.
|
|
80
141
|
- \`reference/\` — temel temanın ayar şeması, varsayılanları ve bölüm türleri. Pakete girmez.
|
|
81
142
|
|
|
82
|
-
|
|
83
|
-
uvako login --store magazam
|
|
84
|
-
\`\`\`
|
|
143
|
+
## Diller
|
|
85
144
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
145
|
+
Mağazalar vitrinini Türkçe, İngilizce ve Almanca yayınlayabilir. \`config/settings_data.json\` ve
|
|
146
|
+
\`theme.json\` içindeki metinleri tek dilde yazın, karşılıklarını \`locales/<dil>.json\` dosyasına koyun.
|
|
147
|
+
Çevirisi olmayan metin yazıldığı gibi gösterilir. \`uvako theme check\` her dosyada eksik kalan
|
|
148
|
+
metinleri listeler.
|
|
89
149
|
|
|
90
|
-
|
|
91
|
-
uvako theme push
|
|
92
|
-
\`\`\`
|
|
93
|
-
`);
|
|
150
|
+
${commands}`);
|
|
94
151
|
return dir;
|
|
95
152
|
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
// İngilizce sözlük. Anahtar, koddaki Türkçe metnin kendisidir; karşılığı olmayan metin Türkçe yazılır.
|
|
2
|
+
// Sunucunun (mağazanın tema uç noktası) Türkçe döndürdüğü denetim mesajları da buradadır.
|
|
3
|
+
// Yeni metin eklerken t("…") ile sarın ve karşılığını buraya yazın. {0}, {1}… yer tutucuları korunur.
|
|
4
|
+
export const en = {
|
|
5
|
+
"Mağazaya bağlanılamadı ({0}): {1}": "Could not connect to the store ({0}): {1}",
|
|
6
|
+
"Bu adreste Uvako tema uç noktası yok. Mağaza adresini kontrol edin.": "There is no Uvako theme endpoint at this address. Check the store address.",
|
|
7
|
+
"Sunucu {0} yanıtı verdi.": "The server responded with {0}.",
|
|
8
|
+
"uvako.com'a bağlanılamadı: {0}": "Could not connect to uvako.com: {0}",
|
|
9
|
+
"\"{0}\" adında bir temel tema yok. Temalar: https://themes.uvako.com": "There is no base theme named \"{0}\". Themes: https://themes.uvako.com",
|
|
10
|
+
"Temel tema okunamadı ({0}).": "The base theme could not be read ({0}).",
|
|
11
|
+
"olay özniteliği (onclick, onload…)": "an event attribute (onclick, onload…)",
|
|
12
|
+
"gömülü içerik etiketi": "an embedded content tag",
|
|
13
|
+
"{0} geçerli JSON değil: {1}": "{0} is not valid JSON: {1}",
|
|
14
|
+
"{0}: düz bir metin sözlüğü olmalı ({\"temadaki metin\": \"çevirisi\"}).": "{0}: must be a flat text dictionary ({\"text in the theme\": \"translation\"}).",
|
|
15
|
+
"{0}: en çok {1} metin içerebilir.": "{0}: may contain at most {1} texts.",
|
|
16
|
+
"{0}: metin en çok 500, çevirisi en çok 2000 karakter olabilir; boş metin olamaz.": "{0}: a text can be 500 characters at most and its translation 2000; a text cannot be empty.",
|
|
17
|
+
"locales/{0}.json: {1} metnin çevirisi yok (ör. \"{2}\"). Çevirisi olmayan metin yazıldığı gibi gösterilir.": "locales/{0}.json: {1} texts have no translation (e.g. \"{2}\"). A text without a translation is shown as written.",
|
|
18
|
+
"Ayar şeması: \"{0}\" ayarının türü yok ({1}).": "Setting schema: the setting \"{0}\" has no type ({1}).",
|
|
19
|
+
"{0}: {1} içeriyor. Tema içinde betik çalıştırılamaz.": "{0}: contains {1}. Scripts cannot run inside a theme.",
|
|
20
|
+
"{0}: gizli anahtar ya da parola gibi görünen bir değer içeriyor.": "{0}: contains a value that looks like a secret key or password.",
|
|
21
|
+
"{0}: tarayıcıda kod çalıştıran CSS (expression, behavior, -moz-binding) içeriyor.": "{0}: contains CSS that runs code in the browser (expression, behavior, -moz-binding).",
|
|
22
|
+
"{0}: javascript: adresi içeriyor.": "{0}: contains a javascript: address.",
|
|
23
|
+
"{0}: @{1} kullanılamaz. Tema stilleri döngü, fonksiyon ve mixin tanımı içeremez; temel temanın mixin'leri @include ile kullanılabilir.": "{0}: @{1} cannot be used. Theme styles cannot define loops, functions or mixins; the base theme's mixins can be used with @include.",
|
|
24
|
+
"{0}: tırnak dışında ters eğik çizgi kullanılamaz.": "{0}: a backslash cannot be used outside quotes.",
|
|
25
|
+
"{0}: yalnızca görsel ve yazı tipi data: adresleri kullanılabilir.": "{0}: only image and font data: addresses can be used.",
|
|
26
|
+
"{0}: izin verilmeyen dış adres ({1}). Görsel ve yazı tiplerini assets/ altına koyun; yalnızca şu adresler çağrılabilir: {2}.": "{0}: external address not allowed ({1}). Put images and fonts under assets/; only these addresses may be called: {2}.",
|
|
27
|
+
"{0}: izin verilmeyen dış adres ({1}).": "{0}: external address not allowed ({1}).",
|
|
28
|
+
"{0}: @import \"{1}\" pakette yok. Yalnızca paketin kendi styles/ dosyaları içe aktarılabilir.": "{0}: @import \"{1}\" is not in the package. Only the package's own styles/ files can be imported.",
|
|
29
|
+
"{0}: yalnızca değişken ataması ($ad: değer;) ve yazı tipi @import'u içerebilir.": "{0}: may contain only variable assignments ($name: value;) and font @imports.",
|
|
30
|
+
"theme.json: \"key\" küçük harf, rakam ve tireden oluşmalı (ör. \"linea\").": "theme.json: \"key\" must consist of lowercase letters, numbers and hyphens (e.g. \"linea\").",
|
|
31
|
+
"theme.json: \"key\" ({0}) klasör adıyla ({1}) aynı olmalı.": "theme.json: \"key\" ({0}) must be the same as the folder name ({1}).",
|
|
32
|
+
"theme.json: \"version\" 1.0.0 biçiminde olmalı.": "theme.json: \"version\" must be in the form 1.0.0.",
|
|
33
|
+
"theme.json: \"description\" boş; tema listesinde açıklama görünmez.": "theme.json: \"description\" is empty; no description is shown in the theme list.",
|
|
34
|
+
"templates/index.json: \"order\" boş; ana sayfada bölüm görünmez.": "templates/index.json: \"order\" is empty; no sections are shown on the home page.",
|
|
35
|
+
"templates/index.json: \"order\" içindeki \"{0}\" bölümü \"sections\" altında tanımlı değil.": "templates/index.json: the section \"{0}\" in \"order\" is not defined under \"sections\".",
|
|
36
|
+
"templates/index.json: \"{0}\" bölümünün türü ({1}) {2} yok.": "templates/index.json: the type ({1}) of the section \"{0}\" does not exist {2}.",
|
|
37
|
+
"{0} 1 (hepsi açık) ya da {\"display_product_comments\": 1, …} nesnesi olmalı.": "{0} must be 1 (all on) or an object like {\"display_product_comments\": 1, …}.",
|
|
38
|
+
"{0}: \"{1}\" bilinen bir sekme değil ({2}).": "{0}: \"{1}\" is not a known tab ({2}).",
|
|
39
|
+
"{0}: \"{1}\" değeri 1 ya da 0 olmalı.": "{0}: the value of \"{1}\" must be 1 or 0.",
|
|
40
|
+
"config/settings_data.json: \"{0}\" sekme başlığı metin olmalı.": "config/settings_data.json: the tab title \"{0}\" must be text.",
|
|
41
|
+
"config/settings_data.json: \"{0}\" ayarındaki görsel bulunamadı (assets/{1}).": "config/settings_data.json: the image in the setting \"{0}\" was not found (assets/{1}).",
|
|
42
|
+
"theme.json: \"base\" gerekli: paketin temel aldığı katalog teması (ör. \"linea\"). Temalar: https://themes.uvako.com": "theme.json: \"base\" is required: the catalog theme the package builds on (e.g. \"linea\"). Themes: https://themes.uvako.com",
|
|
43
|
+
"theme.json: \"price\" 0 ile 100.000 arasında olmalı.": "theme.json: \"price\" must be between 0 and 100,000.",
|
|
44
|
+
"theme.json: \"demo_url\" https:// ile başlayan bir adres olmalı.": "theme.json: \"demo_url\" must be an address starting with https://.",
|
|
45
|
+
"{0}: sembolik bağ pakete alınamaz.": "{0}: a symbolic link cannot be included in the package.",
|
|
46
|
+
"{0}: dosya adında yalnızca harf, rakam, nokta, tire ve alt çizgi olabilir; gizli dosya olamaz.": "{0}: a file name may contain only letters, numbers, dots, hyphens and underscores; hidden files are not allowed.",
|
|
47
|
+
"{0}: 1 MB sınırını aşıyor.": "{0}: exceeds the 1 MB limit.",
|
|
48
|
+
"{0}: desteklenmeyen dil. Kullanılabilir dosyalar: {1}.": "{0}: unsupported language. Available files: {1}.",
|
|
49
|
+
"{0}: {1} KB sınırını aşıyor.": "{0}: exceeds the {1} KB limit.",
|
|
50
|
+
"{0}: bu dosya türü ({1}) temada bulunamaz.": "{0}: this file type ({1}) cannot be in a theme.",
|
|
51
|
+
"{0}: {1} MB; tek dosya sınırı {2} MB.": "{0}: {1} MB; the limit per file is {2} MB.",
|
|
52
|
+
"{0}: {1} MB. WebP ya da sıkıştırılmış JPEG sayfayı hızlandırır.": "{0}: {1} MB. WebP or a compressed JPEG makes the page faster.",
|
|
53
|
+
"{0}: bu dosya pakette bulunamaz. İzin verilenler: theme.json, config/settings_schema.json, config/settings_data.json, templates/index.json, locales/tr.json, locales/en.json, locales/de.json, styles/*.scss, assets/**.": "{0}: this file cannot be in the package. Allowed: theme.json, config/settings_schema.json, config/settings_data.json, templates/index.json, locales/tr.json, locales/en.json, locales/de.json, styles/*.scss, assets/**.",
|
|
54
|
+
"Stil dosyaları toplam {0} KB sınırını aşıyor.": "The style files exceed the total limit of {0} KB.",
|
|
55
|
+
"styles/theme.scss yok: stil dosyaları oradan içe aktarılır.": "styles/theme.scss is missing: style files are imported from there.",
|
|
56
|
+
"config/settings_schema.json: \"group\" sekmeli olmalı ({\"type\":\"tab\",\"values\":[…]}).": "config/settings_schema.json: \"group\" must be tabbed ({\"type\":\"tab\",\"values\":[…]}).",
|
|
57
|
+
"config/settings_data.json: anahtar-değer nesnesi olmalı.": "config/settings_data.json: must be a key-value object.",
|
|
58
|
+
"{0} temasında": "in the {0} theme",
|
|
59
|
+
"theme.json: ekran görüntüsü pakette yok (assets/{0}).": "theme.json: the screenshot is not in the package (assets/{0}).",
|
|
60
|
+
"Tema {0} MB; sınır {1} MB.": "The theme is {0} MB; the limit is {1} MB.",
|
|
61
|
+
"Tema {0} dosya içeriyor; sınır {1}.": "The theme contains {0} files; the limit is {1}.",
|
|
62
|
+
"{0}: gizli dosya ya da üst klasöre çıkan yol.": "{0}: a hidden file or a path that leaves the folder.",
|
|
63
|
+
"config/sections.json: \"sections\" altında en az bir bölüm türü olmalı.": "config/sections.json: there must be at least one section type under \"sections\".",
|
|
64
|
+
"config/sections.json: \"{0}\" bölüm türü tema anahtarıyla (\"{1}-\") başlamıyor.": "config/sections.json: the section type \"{0}\" does not start with the theme key (\"{1}-\").",
|
|
65
|
+
"config/sections.json: \"{0}\" bölümünün adı yok.": "config/sections.json: the section \"{0}\" has no name.",
|
|
66
|
+
"config/sections.json: \"{0}\" bölümünün \"keys\" alanı liste olmalı.": "config/sections.json: the \"keys\" field of the section \"{0}\" must be a list.",
|
|
67
|
+
"templates/index.json (ana sayfa şablonu)": "templates/index.json (home page template)",
|
|
68
|
+
"config/sections.json içinde": "in config/sections.json",
|
|
69
|
+
"Stil dosyası yok: {0}": "Style file missing: {0}",
|
|
70
|
+
"theme.json: ekran görüntüsü bulunamadı (assets/{0}).": "theme.json: the screenshot was not found (assets/{0}).",
|
|
71
|
+
"{0} bir tema klasörü değil: theme.json bulunamadı.": "{0} is not a theme folder: theme.json was not found.",
|
|
72
|
+
"platform deposu": "platform repository",
|
|
73
|
+
"paket": "package",
|
|
74
|
+
" · {0} dosya, {1} MB": " · {0} files, {1} MB",
|
|
75
|
+
"{0}: {1} hata, {2} uyarı{3}": "{0}: {1} errors, {2} warnings{3}",
|
|
76
|
+
"{0}: denetim geçti{1}{2}": "{0}: check passed{1}{2}",
|
|
77
|
+
", {0} uyarı": ", {0} warnings",
|
|
78
|
+
"Mağaza adresi gerekli (ör. magazam ya da magazam.uvoo.store).": "The store address is required (e.g. mystore or mystore.uvoo.store).",
|
|
79
|
+
"Mağaza adresi okunamadı: {0}": "The store address could not be read: {0}",
|
|
80
|
+
"Mağazaya yalnızca https ile bağlanılır.": "Stores are reached over https only.",
|
|
81
|
+
"Mağaza adresinde kullanıcı adı ya da parola olamaz.": "The store address cannot contain a username or password.",
|
|
82
|
+
"Bu mağaza için giriş yapılmamış: {0}\nÖnce: uvako login --store {1}": "Not signed in for this store: {0}\nFirst: uvako login --store {1}",
|
|
83
|
+
"Tema anahtarı küçük harf, rakam ve tireden oluşmalı (ör. \"atolye\"): {0}": "The theme key must consist of lowercase letters, numbers and hyphens (e.g. \"atelier\"): {0}",
|
|
84
|
+
"Temel tema adı geçersiz: {0}": "The base theme name is invalid: {0}",
|
|
85
|
+
"Klasör zaten var: {0}": "The folder already exists: {0}",
|
|
86
|
+
"{0} teması.": "{0} theme.",
|
|
87
|
+
"! Temel temanın ayarları okunamadı ({0}). İskelet başvuru dosyaları olmadan kuruluyor.": "! The base theme's settings could not be read ({0}). The scaffold is created without the reference files.",
|
|
88
|
+
"Bilinmeyen komut: {0}\n\n{1}": "Unknown command: {0}\n\n{1}",
|
|
89
|
+
"Tema anahtarı gerekli: uvako theme init <anahtar>": "A theme key is required: uvako theme init <key>",
|
|
90
|
+
"Tema oluşturuldu: {0} (temel: {1})": "Theme created: {0} (base: {1})",
|
|
91
|
+
"Sıradaki adım: uvako login --store <mağaza>, sonra: uvako theme dev {0}": "Next step: uvako login --store <store>, then: uvako theme dev {0}",
|
|
92
|
+
"Paket oluşturulmadı: önce hataları düzeltin.": "The package was not created: fix the errors first.",
|
|
93
|
+
"Paket: {0} ({1} dosya, {2} KB)": "Package: {0} ({1} files, {2} KB)",
|
|
94
|
+
"Bilinmeyen tema komutu: {0}\n\n{1}": "Unknown theme command: {0}\n\n{1}",
|
|
95
|
+
"Bu klasör platform deposundaki bir tema; paketleme ve yükleme yalnızca bağımsız tema klasörlerinde yapılır.": "This folder is a theme in the platform repository; packaging and uploading work only in standalone theme folders.",
|
|
96
|
+
"Paket {0} MB; yükleme sınırı {1} MB.": "The package is {0} MB; the upload limit is {1} MB.",
|
|
97
|
+
"İptal edildi.": "Cancelled.",
|
|
98
|
+
" Yeni anahtar: mağaza paneli → Ayarlar → Temalar → Geliştirici erişimi, sonra `uvako login`.": " New key: store panel → Settings → Themes → Developer access, then `uvako login`.",
|
|
99
|
+
"Mağaza adresi gerekli: uvako login --store <mağaza>": "The store address is required: uvako login --store <store>",
|
|
100
|
+
"Erişim anahtarı komut satırına yazılmaz. Komutu --token olmadan çalıştırın; anahtar sorulacak (ya da UVAKO_TOKEN ortam değişkenini kullanın).": "The access key is not typed on the command line. Run the command without --token; you will be asked for the key (or use the UVAKO_TOKEN environment variable).",
|
|
101
|
+
"{0} için tema erişim anahtarı (panel → Ayarlar → Temalar → Geliştirici erişimi): ": "Theme access key for {0} (panel → Settings → Themes → Developer access): ",
|
|
102
|
+
"Bu bir tema erişim anahtarı değil (uvt_ ile başlar).": "This is not a theme access key (it starts with uvt_).",
|
|
103
|
+
"Giriş yapıldı: {0} ({1})": "Signed in: {0} ({1})",
|
|
104
|
+
"! Bu mağaza için tema yükleme kapatılmış. Uvako desteğine yazın.": "! Theme uploads have been turned off for this store. Write to Uvako support.",
|
|
105
|
+
"Çıkış yapıldı: {0}": "Signed out: {0}",
|
|
106
|
+
"Kayıtlı giriş yok.": "No saved sign-in.",
|
|
107
|
+
"Anahtarı tamamen geçersiz kılmak için mağaza panelinden iptal edin.": "To invalidate the key completely, revoke it from the store panel.",
|
|
108
|
+
" diğer giriş: {0} — {1}": " other sign-in: {0} — {1}",
|
|
109
|
+
"yalnızca bu mağazada": "in this store only",
|
|
110
|
+
"tema mağazasında": "in the theme store",
|
|
111
|
+
"Mağazadaki temalar ({0}):": "Themes in the store ({0}):",
|
|
112
|
+
"● yayında ": "● live ",
|
|
113
|
+
"○ kütüphane": "○ library",
|
|
114
|
+
"\nYüklediğiniz paketler:": "\nThe packages you uploaded:",
|
|
115
|
+
"\nYüklediğiniz paket yok.": "\nYou have not uploaded any packages.",
|
|
116
|
+
" · mağazadaki sürüm {0}": " · version in the store {0}",
|
|
117
|
+
"Yüklenmedi: önce hataları düzeltin.": "Not uploaded: fix the errors first.",
|
|
118
|
+
"{0}: {1} {2} (sürüm no {3}) → {4}": "{0}: {1} {2} (revision {3}) → {4}",
|
|
119
|
+
"Yüklendi": "Uploaded",
|
|
120
|
+
"Güncellendi": "Updated",
|
|
121
|
+
"Önizleme: {0}": "Preview: {0}",
|
|
122
|
+
"Düzenleme: {0}": "Edit: {0}",
|
|
123
|
+
"Önizleme için tarayıcıda mağaza paneline giriş yapmış olmalısınız. Tema, panelden yayınlanana kadar vitrini değiştirmez.": "To preview, you must be signed in to the store panel in the browser. The theme does not change the storefront until it is published from the panel.",
|
|
124
|
+
"Tema mağazasındaki sürüm ({0}) değişmedi. Yeni sürümü incelemeye göndermek için: uvako theme submit {1}": "The version in the theme store ({0}) has not changed. To submit the new version for review: uvako theme submit {1}",
|
|
125
|
+
"Başlatılamadı: önce hataları düzeltin.": "Could not start: fix the errors first.",
|
|
126
|
+
"\nCanlı geliştirme: {0} → {1}": "\nLive development: {0} → {1}",
|
|
127
|
+
"Önizleme için tarayıcıda mağaza paneline giriş yapın. Dosyaları kaydettikçe sayfa yenilenir. Durdurmak için Ctrl+C.\n": "Sign in to the store panel in the browser to preview. The page refreshes as you save files. Press Ctrl+C to stop.\n",
|
|
128
|
+
"Durdurduğunuzda tema son hâliyle kütüphanede kalır (--keep).": "When you stop, the theme stays in the library in its latest state (--keep).",
|
|
129
|
+
"Durdurduğunuzda mağazadaki paket geliştirme öncesindeki sürümüne döner. Kalıcı yüklemek için: uvako theme push": "When you stop, the package in the store returns to the version it had before development. To upload permanently: uvako theme push",
|
|
130
|
+
"Durdurduğunuzda geliştirme kopyası mağazadan silinir. Kalıcı yüklemek için: uvako theme push": "When you stop, the development copy is deleted from the store. To upload permanently: uvako theme push",
|
|
131
|
+
"[{0}] yüklendi (sürüm no {1})": "[{0}] uploaded (revision {1})",
|
|
132
|
+
"[{0}] yüklenmedi: hataları düzeltip kaydedin.": "[{0}] not uploaded: fix the errors and save.",
|
|
133
|
+
"\nCanlı geliştirme durdu. Tema son hâliyle mağaza kütüphanesinde duruyor.": "\nLive development stopped. The theme stays in the store library in its latest state.",
|
|
134
|
+
"\nCanlı geliştirme durdu. Mağazadaki paket geliştirme öncesindeki sürümüne döndü.": "\nLive development stopped. The package in the store has returned to the version it had before development.",
|
|
135
|
+
"\nCanlı geliştirme durdu. Geliştirme kopyası mağazadan silindi; vitrin ve kütüphane eski hâlinde.": "\nLive development stopped. The development copy was deleted from the store; the storefront and library are as they were.",
|
|
136
|
+
"\nCanlı geliştirme durdu ama mağaza eski hâline döndürülemedi: {0}": "\nLive development stopped, but the store could not be restored: {0}",
|
|
137
|
+
"Elle kaldırmak için: uvako theme delete {0} --yes": "To remove it manually: uvako theme delete {0} --yes",
|
|
138
|
+
"Tema anahtarı gerekli: uvako theme pull <anahtar>": "A theme key is required: uvako theme pull <key>",
|
|
139
|
+
"Klasör zaten var: {0}\nÜstüne yazmak için --force ekleyin.": "The folder already exists: {0}\nAdd --force to overwrite.",
|
|
140
|
+
"Paketteki yol güvenli değil: {0}": "A path in the package is not safe: {0}",
|
|
141
|
+
"İndirildi: {0} ({1} dosya)": "Downloaded: {0} ({1} files)",
|
|
142
|
+
"Tema anahtarı gerekli: uvako theme submit <anahtar>": "A theme key is required: uvako theme submit <key>",
|
|
143
|
+
"İncelemeye gönderildi: {0} {1}. Uvako ekibi onayladığında themes.uvako.com'da yayınlanır.": "Submitted for review: {0} {1}. It is published on themes.uvako.com once the Uvako team approves it.",
|
|
144
|
+
"İnceleme sürerken yeni sürüm yüklerseniz onay o sürüm için yeniden istenir.": "If you upload a new version while the review is in progress, approval is requested again for that version.",
|
|
145
|
+
"Tema anahtarı gerekli: uvako theme delete <anahtar>": "A theme key is required: uvako theme delete <key>",
|
|
146
|
+
"\"{0}\" paketi ve mağazadaki kopyaları silinir; geri alınamaz. Onaylamak için --yes ekleyin.": "The package \"{0}\" and its copies in the store will be deleted; this cannot be undone. Add --yes to confirm.",
|
|
147
|
+
"Geçerli bir zip dosyası değil.": "Not a valid zip file.",
|
|
148
|
+
"Zip dizini okunamadı.": "The zip directory could not be read.",
|
|
149
|
+
"{0}: dosya çok büyük.": "{0}: the file is too large.",
|
|
150
|
+
"{0}: desteklenmeyen sıkıştırma yöntemi.": "{0}: unsupported compression method.",
|
|
151
|
+
"Paket {0} MB sınırını aşıyor.": "The package exceeds the {0} MB limit.",
|
|
152
|
+
"Paket geçerli bir zip dosyası değil.": "The package is not a valid zip file.",
|
|
153
|
+
"Paket çok fazla dosya içeriyor (sınır {0}).": "The package contains too many files (limit {0}).",
|
|
154
|
+
"{0}: geçersiz dosya yolu.": "{0}: invalid file path.",
|
|
155
|
+
"{0}: sembolik bağ ya da özel dosya pakete alınamaz.": "{0}: a symbolic link or special file cannot be included in the package.",
|
|
156
|
+
"{0}: {1} MB; sınır {2} MB.": "{0}: {1} MB; the limit is {2} MB.",
|
|
157
|
+
"{0}: okunamadı.": "{0}: could not be read.",
|
|
158
|
+
"{0}: okunamadı ya da boyut sınırını aşıyor.": "{0}: could not be read or exceeds the size limit.",
|
|
159
|
+
"Paket {0} dosya sınırını aşıyor.": "The package exceeds the limit of {0} files.",
|
|
160
|
+
"Paket açıldığında {0} MB sınırını aşıyor.": "When extracted, the package exceeds the {0} MB limit.",
|
|
161
|
+
"{0}: geçerli JSON değil.": "{0}: not valid JSON.",
|
|
162
|
+
"{0}: anahtar-değer nesnesi olmalı.": "{0}: must be a key-value object.",
|
|
163
|
+
"{0}: bu dosya pakette bulunamaz. İzin verilenler: theme.json, config/settings_schema.json, config/settings_data.json, templates/index.json, styles/*.scss, assets/**.": "{0}: this file cannot be in the package. Allowed: theme.json, config/settings_schema.json, config/settings_data.json, templates/index.json, styles/*.scss, assets/**.",
|
|
164
|
+
"theme.json: geçerli JSON değil.": "theme.json: not valid JSON.",
|
|
165
|
+
"theme.json: açıklama en çok 400, yazar en çok 80 karakter olabilir.": "theme.json: the description can be 400 characters at most and the author 80.",
|
|
166
|
+
"theme.json: en çok 12 sektör, 20 özellik ve 8 ekran görüntüsü yazılabilir.": "theme.json: at most 12 industries, 20 features and 8 screenshots can be listed.",
|
|
167
|
+
"templates/index.json: geçerli bir şablon değil.": "templates/index.json: not a valid template.",
|
|
168
|
+
"dosya boş.": "the file is empty.",
|
|
169
|
+
"içeriyor.": "is included.",
|
|
170
|
+
"geçerli bir SVG değil.": "is not a valid SVG.",
|
|
171
|
+
"uzantısı görsel ama içeriği görsel değil.": "has an image extension but its content is not an image.",
|
|
172
|
+
"{0}: izin verilmeyen dış adres ({1}). Görselleri assets/ altına koyun; yalnızca yazı tipi servisleri çağrılabilir.": "{0}: external address not allowed ({1}). Put images under assets/; only font services may be called.",
|
|
173
|
+
"Bir mağaza en çok {0} tema paketi yükleyebilir.": "A store can upload at most {0} theme packages.",
|
|
174
|
+
"Bu sürüm zaten onaylı.": "This version is already approved.",
|
|
175
|
+
"Çok fazla hatalı deneme. Biraz sonra tekrar deneyin.": "Too many failed attempts. Try again shortly.",
|
|
176
|
+
"Erişim anahtarı gerekli. `uvako login` ile giriş yapın.": "An access key is required. Sign in with `uvako login`.",
|
|
177
|
+
"Erişim anahtarı geçersiz ya da iptal edilmiş.": "The access key is invalid or has been revoked.",
|
|
178
|
+
"Bu erişim anahtarı bu mağazaya ait değil.": "This access key does not belong to this store.",
|
|
179
|
+
"Tema paketi denetimden geçmedi.": "The theme package did not pass validation.",
|
|
180
|
+
"Bu mağaza için tema yükleme kapatılmış. Uvako desteğine yazın.": "Theme uploads have been turned off for this store. Write to Uvako support.",
|
|
181
|
+
"Bu tema anahtarı kullanımda. theme.json içindeki \"key\" değerini değiştirin.": "This theme key is in use. Change the \"key\" value in theme.json.",
|
|
182
|
+
"Tema bulunamadı.": "Theme not found.",
|
|
183
|
+
"Onaylanmış tema silinemez: başka mağazalar kullanıyor olabilir.": "An approved theme cannot be deleted: other stores may be using it.",
|
|
184
|
+
"Tema mağazanızda yayında. Önce başka bir temayı yayınlayın.": "The theme is live in your store. Publish another theme first.",
|
|
185
|
+
"İşlem tamamlanamadı.": "The action could not be completed.",
|
|
186
|
+
"Paket boyut sınırını aşıyor.": "The package exceeds the size limit.",
|
|
187
|
+
"kopyası": "copy",
|
|
188
|
+
"{0}: \"group\" sekmeli olmalı ({\"type\":\"tab\",\"values\":[…]}).": "{0}: \"group\" must be tabbed ({\"type\":\"tab\",\"values\":[…]}).",
|
|
189
|
+
"theme.json yok.": "theme.json is missing.",
|
|
190
|
+
"theme.json: \"key\" küçük harf, rakam ve tireden oluşmalı (en çok 40 karakter).": "theme.json: \"key\" must consist of lowercase letters, numbers and hyphens (40 characters at most).",
|
|
191
|
+
"theme.json: \"name\" gerekli (en çok 60 karakter).": "theme.json: \"name\" is required (60 characters at most).",
|
|
192
|
+
"theme.json: \"base\" katalogdaki bir tema olmalı ({0}).": "theme.json: \"base\" must be a theme in the catalog ({0}).",
|
|
193
|
+
"tema paketi gecersiz: {0}": "the theme package is invalid: {0}",
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
export const help = (version) => `uvako-cli ${version} — Uvako theme development tool
|
|
197
|
+
https://uvako.com
|
|
198
|
+
|
|
199
|
+
Sign-in:
|
|
200
|
+
uvako login --store <store> Connects to the store with a theme access key (you are asked for the key)
|
|
201
|
+
uvako logout [--store <store>] Deletes the saved sign-in
|
|
202
|
+
uvako whoami Shows the connected store
|
|
203
|
+
|
|
204
|
+
Theme:
|
|
205
|
+
uvako theme init <key> [--base linea] [--name "Name"] [--author "Author"]
|
|
206
|
+
A new theme scaffold built on a catalog theme
|
|
207
|
+
uvako theme check [folder] Checks the theme (structure, settings, translations, security)
|
|
208
|
+
uvako theme dev [folder] Live development: uploads to the store as you save, the preview refreshes
|
|
209
|
+
The store returns to its previous state when you stop (--keep: leave in library)
|
|
210
|
+
uvako theme push [folder] Uploads the theme to the store's theme library
|
|
211
|
+
uvako theme pull <key> [--dir folder] Downloads a theme you uploaded
|
|
212
|
+
uvako theme list Lists the themes in the store and the packages you uploaded
|
|
213
|
+
uvako theme submit <key> Submits the theme for review for themes.uvako.com
|
|
214
|
+
uvako theme delete <key> --yes Deletes a package you uploaded
|
|
215
|
+
uvako theme package [folder] [--out x.zip] Checks the theme and builds a zip package
|
|
216
|
+
uvako version Prints the version
|
|
217
|
+
|
|
218
|
+
A theme is a package that runs no code: settings, section order, SCSS and images.
|
|
219
|
+
Packages containing JavaScript, templates or server code are rejected. An uploaded theme is
|
|
220
|
+
visible only in your own store; publishing it in the theme store depends on Uvako's review.
|
|
221
|
+
|
|
222
|
+
For CI: the UVAKO_STORE and UVAKO_TOKEN environment variables take the place of signing in.
|
|
223
|
+
Language: --lang tr or UVAKO_LANG=tr prints the output in Turkish.
|
|
224
|
+
|
|
225
|
+
Uvako — https://uvako.com
|
|
226
|
+
Rox Software · Rox Group`;
|
package/src/main.js
CHANGED
|
@@ -7,10 +7,12 @@ import { session, siteOrigin } from "./config.js";
|
|
|
7
7
|
import { initTheme } from "./init.js";
|
|
8
8
|
import { packageTheme } from "./package.js";
|
|
9
9
|
import { dev, list, login, logout, pull, push, remove, submit, whoami } from "./remote.js";
|
|
10
|
+
import { getLocale, t } from "./i18n.js";
|
|
11
|
+
import { help as helpEn } from "./locales/en.js";
|
|
10
12
|
|
|
11
13
|
const version = JSON.parse(readFileSync(path.join(path.dirname(fileURLToPath(import.meta.url)), "..", "package.json"), "utf8")).version;
|
|
12
14
|
|
|
13
|
-
const
|
|
15
|
+
const helpTr = `uvako-cli ${version} — Uvako tema geliştirme aracı
|
|
14
16
|
https://uvako.com
|
|
15
17
|
|
|
16
18
|
Giriş:
|
|
@@ -37,10 +39,13 @@ JavaScript, şablon ya da sunucu kodu içeren paketler reddedilir. Yüklenen tem
|
|
|
37
39
|
mağazanızda görünür; tema mağazasında yayınlanması Uvako incelemesine bağlıdır.
|
|
38
40
|
|
|
39
41
|
CI için: UVAKO_STORE ve UVAKO_TOKEN ortam değişkenleri girişin yerini tutar.
|
|
42
|
+
Dil: --lang en ya da UVAKO_LANG=en çıktıyı İngilizce verir.
|
|
40
43
|
|
|
41
44
|
Uvako — https://uvako.com
|
|
42
45
|
Rox Software · Rox Group`;
|
|
43
46
|
|
|
47
|
+
const help = getLocale() === "en" ? helpEn(version) : helpTr;
|
|
48
|
+
|
|
44
49
|
// "--ad değer" ve "--ad=değer" biçimli seçenekleri ayırır; kalanlar konumsal argümandır.
|
|
45
50
|
export function parseArgs(args) {
|
|
46
51
|
const options = {};
|
|
@@ -71,8 +76,8 @@ async function fetchStarter(base, options) {
|
|
|
71
76
|
}
|
|
72
77
|
return current ? await call(current, "GET", `/bases/${encodeURIComponent(base)}`) : await starter(siteOrigin(), base);
|
|
73
78
|
} catch (error) {
|
|
74
|
-
if (error instanceof ApiError && error.status === 404) throw new Error(
|
|
75
|
-
console.warn(
|
|
79
|
+
if (error instanceof ApiError && error.status === 404) throw new Error(t("\"{0}\" adında bir temel tema yok. Temalar: https://themes.uvako.com", base));
|
|
80
|
+
console.warn(t("! Temel temanın ayarları okunamadı ({0}). İskelet başvuru dosyaları olmadan kuruluyor.", error.message));
|
|
76
81
|
return null;
|
|
77
82
|
}
|
|
78
83
|
}
|
|
@@ -92,16 +97,16 @@ export async function main(argv) {
|
|
|
92
97
|
if (group === "logout") return logout(options);
|
|
93
98
|
if (group === "whoami") return whoami(options);
|
|
94
99
|
if (group !== "theme") {
|
|
95
|
-
console.error(
|
|
100
|
+
console.error(t("Bilinmeyen komut: {0}\n\n{1}", group, help));
|
|
96
101
|
return 1;
|
|
97
102
|
}
|
|
98
103
|
if (command === "init") {
|
|
99
|
-
if (!target) throw new Error("Tema anahtarı gerekli: uvako theme init <anahtar>");
|
|
104
|
+
if (!target) throw new Error(t("Tema anahtarı gerekli: uvako theme init <anahtar>"));
|
|
100
105
|
const base = typeof options.base === "string" ? options.base : "linea";
|
|
101
106
|
const dir = initTheme(target, { name: options.name, author: options.author, cwd: process.cwd(), base, starter: await fetchStarter(base, options) });
|
|
102
107
|
const rel = path.relative(process.cwd(), dir) || ".";
|
|
103
|
-
console.log(
|
|
104
|
-
console.log(
|
|
108
|
+
console.log(t("Tema oluşturuldu: {0} (temel: {1})", rel, base));
|
|
109
|
+
console.log(t("Sıradaki adım: uvako login --store <mağaza>, sonra: uvako theme dev {0}", rel));
|
|
105
110
|
return 0;
|
|
106
111
|
}
|
|
107
112
|
if (command === "check") {
|
|
@@ -113,10 +118,10 @@ export async function main(argv) {
|
|
|
113
118
|
const result = packageTheme(path.resolve(target ?? "."), { out: typeof options.out === "string" ? options.out : undefined });
|
|
114
119
|
printReport(result.report);
|
|
115
120
|
if (!result.ok) {
|
|
116
|
-
console.error("Paket oluşturulmadı: önce hataları düzeltin.");
|
|
121
|
+
console.error(t("Paket oluşturulmadı: önce hataları düzeltin."));
|
|
117
122
|
return 1;
|
|
118
123
|
}
|
|
119
|
-
console.log(
|
|
124
|
+
console.log(t("Paket: {0} ({1} dosya, {2} KB)", result.file, result.files, (result.bytes / 1024).toFixed(0)));
|
|
120
125
|
console.log(`SHA-256: ${result.sha256}`);
|
|
121
126
|
return 0;
|
|
122
127
|
}
|
|
@@ -126,6 +131,6 @@ export async function main(argv) {
|
|
|
126
131
|
if (command === "list") return list(options);
|
|
127
132
|
if (command === "submit") return submit(target, options);
|
|
128
133
|
if (command === "delete") return remove(target, options);
|
|
129
|
-
console.error(
|
|
134
|
+
console.error(t("Bilinmeyen tema komutu: {0}\n\n{1}", command ?? "(yok)", help));
|
|
130
135
|
return 1;
|
|
131
136
|
}
|
package/src/package.js
CHANGED
|
@@ -4,13 +4,14 @@ import path from "node:path";
|
|
|
4
4
|
import { checkTheme, limits, localOnly } from "./check.js";
|
|
5
5
|
import { walk } from "./files.js";
|
|
6
6
|
import { zip } from "./zip.js";
|
|
7
|
+
import { t } from "./i18n.js";
|
|
7
8
|
|
|
8
9
|
/** Denetimden geçen temanın zip paketini bellekte üretir. Yardımcı dosyalar (README, reference/) pakete girmez. */
|
|
9
10
|
export function buildArchive(dir) {
|
|
10
11
|
const report = checkTheme(dir);
|
|
11
12
|
if (report.errors.length) return { ok: false, report };
|
|
12
13
|
if (report.layout !== "package") {
|
|
13
|
-
report.errors.push("Bu klasör platform deposundaki bir tema; paketleme ve yükleme yalnızca bağımsız tema klasörlerinde yapılır.");
|
|
14
|
+
report.errors.push(t("Bu klasör platform deposundaki bir tema; paketleme ve yükleme yalnızca bağımsız tema klasörlerinde yapılır."));
|
|
14
15
|
return { ok: false, report };
|
|
15
16
|
}
|
|
16
17
|
const meta = JSON.parse(readFileSync(path.join(dir, "theme.json"), "utf8"));
|
|
@@ -19,7 +20,7 @@ export function buildArchive(dir) {
|
|
|
19
20
|
.map((file) => ({ name: `${meta.key}/${file.rel}`, data: readFileSync(file.full) }));
|
|
20
21
|
const buffer = zip(entries);
|
|
21
22
|
if (buffer.length > limits.archiveBytes) {
|
|
22
|
-
report.errors.push(
|
|
23
|
+
report.errors.push(t("Paket {0} MB; yükleme sınırı {1} MB.", (buffer.length / 1024 / 1024).toFixed(0), limits.archiveBytes / 1024 / 1024));
|
|
23
24
|
return { ok: false, report };
|
|
24
25
|
}
|
|
25
26
|
return { ok: true, report, meta, buffer, files: entries.length, sha256: createHash("sha256").update(buffer).digest("hex") };
|