storelingo 0.5.0 → 0.5.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/CHANGELOG.md +4 -0
- package/README.md +3 -2
- package/README.ru.md +3 -2
- package/dist/cli/main.js +12 -3
- package/dist/commands/init.js +13 -10
- package/dist/config/schema.js +2 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.1 — 2026-11-15
|
|
4
|
+
|
|
5
|
+
- `stores.appstore.appId` is needed only for `pull` and `push`. `translate` and `check` work with `"appstore": {}` before the app exists in App Store Connect, and `init` accepts an empty Apple ID. `pull` / `push` without it stop with a clear `E_CONFIG` before any network call (found while localizing a real app).
|
|
6
|
+
|
|
3
7
|
## 0.5.0 — 2026-11-15
|
|
4
8
|
|
|
5
9
|
- First release on npm: `npx storelingo` works without building from source.
|
package/README.md
CHANGED
|
@@ -96,7 +96,8 @@ For Google Play, the newest changelog (highest version code) of the source local
|
|
|
96
96
|
| `sourceLocale` | yes | storelingo locale code of your source texts, e.g. `en-US`. |
|
|
97
97
|
| `targetLocales` | yes | Non-empty list of storelingo locale codes to translate into, without duplicates. |
|
|
98
98
|
| `stores.play.packageName` | one store required | Enables Google Play. |
|
|
99
|
-
| `stores.appstore
|
|
99
|
+
| `stores.appstore` | one store required | Enables the App Store. `{}` is enough for `translate` and `check`, even before the app exists in App Store Connect. |
|
|
100
|
+
| `stores.appstore.appId` | for `pull` / `push` | The numeric Apple ID of the app (App Store Connect → App Information). |
|
|
100
101
|
| `stores.appstore.platform` | no (default `IOS`) | `IOS`, `MAC_OS`, `TV_OS` or `VISION_OS`: the platform whose version storelingo works with. |
|
|
101
102
|
| `translator.provider` | yes | `anthropic` or `openai-compatible`. |
|
|
102
103
|
| `translator.model` | `anthropic`: no (default `claude-opus-5-5`); `openai-compatible`: yes | Model name. |
|
|
@@ -242,7 +243,7 @@ How it behaves:
|
|
|
242
243
|
|
|
243
244
|
## GitHub Action
|
|
244
245
|
|
|
245
|
-
Run storelingo in CI with `uses: Alisher23/storelingo@v0.
|
|
246
|
+
Run storelingo in CI with `uses: Alisher23/storelingo@v0.5.1` (pin a release tag or a commit SHA). It can translate on push and commit the result, or only run the offline `check` on pull requests with no secrets. See the [GitHub Action guide](https://github.com/Alisher23/storelingo/blob/main/docs/github-action.md) for workflows, inputs and security notes.
|
|
246
247
|
|
|
247
248
|
## How translation works
|
|
248
249
|
|
package/README.ru.md
CHANGED
|
@@ -96,7 +96,8 @@ fastlane/metadata/ # App Store (fastlane deliver)
|
|
|
96
96
|
| `sourceLocale` | да | Код локали storelingo для исходных текстов, например `en-US`. |
|
|
97
97
|
| `targetLocales` | да | Непустой список кодов локалей storelingo, на которые переводить, без повторов. |
|
|
98
98
|
| `stores.play.packageName` | нужен хотя бы один магазин | Включает Google Play. |
|
|
99
|
-
| `stores.appstore
|
|
99
|
+
| `stores.appstore` | нужен хотя бы один магазин | Включает App Store. Для `translate` и `check` достаточно `{}`, даже если приложения ещё нет в App Store Connect. |
|
|
100
|
+
| `stores.appstore.appId` | для `pull` / `push` | Числовой Apple ID приложения (App Store Connect → App Information). |
|
|
100
101
|
| `stores.appstore.platform` | нет (по умолчанию `IOS`) | `IOS`, `MAC_OS`, `TV_OS` или `VISION_OS`: платформа, с версией которой работает storelingo. |
|
|
101
102
|
| `translator.provider` | да | `anthropic` или `openai-compatible`. |
|
|
102
103
|
| `translator.model` | `anthropic`: нет (по умолчанию `claude-opus-5-5`); `openai-compatible`: да | Название модели. |
|
|
@@ -242,7 +243,7 @@ npx storelingo push --store appstore
|
|
|
242
243
|
|
|
243
244
|
## GitHub Action
|
|
244
245
|
|
|
245
|
-
Запускайте storelingo в CI через `uses: Alisher23/storelingo@v0.
|
|
246
|
+
Запускайте storelingo в CI через `uses: Alisher23/storelingo@v0.5.1` (закрепляйте релизный тег или SHA коммита). Он может переводить при push и коммитить результат либо только запускать офлайн-проверку `check` в pull request'ах без секретов. Workflow, параметры и заметки по безопасности смотрите в [руководстве по GitHub Action](https://github.com/Alisher23/storelingo/blob/main/docs/github-action.ru.md).
|
|
246
247
|
|
|
247
248
|
## Как работает перевод
|
|
248
249
|
|
package/dist/cli/main.js
CHANGED
|
@@ -28,12 +28,14 @@ const defaultTranslator = (config, env) => createTranslator(createLlmClient(conf
|
|
|
28
28
|
const pkg = createRequire(import.meta.url)("../../package.json");
|
|
29
29
|
const defaultMakeStore = async (store, config, env) => {
|
|
30
30
|
if (store === "appstore") {
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
const appId = config.stores.appstore?.appId;
|
|
32
|
+
if (!config.stores.appstore || appId === undefined) {
|
|
33
|
+
throw new StorelingoError("E_CONFIG", "stores.appstore.appId is required for pull and push");
|
|
34
|
+
}
|
|
33
35
|
const key = await loadAscKey(env);
|
|
34
36
|
const tokens = createAscTokenProvider({ key });
|
|
35
37
|
const api = createAscApi({ getToken: () => tokens.getToken() });
|
|
36
|
-
return createAppStoreStore(api, { appId
|
|
38
|
+
return createAppStoreStore(api, { appId, platform: config.stores.appstore.platform });
|
|
37
39
|
}
|
|
38
40
|
if (!config.stores.play)
|
|
39
41
|
throw new StorelingoError("E_CONFIG", "stores.play is not configured");
|
|
@@ -44,6 +46,13 @@ const defaultMakeStore = async (store, config, env) => {
|
|
|
44
46
|
};
|
|
45
47
|
/** Validated before any network call; without --store every configured store runs (play, then appstore). */
|
|
46
48
|
function selectStores(option, config) {
|
|
49
|
+
const stores = selectConfiguredStores(option, config);
|
|
50
|
+
if (stores.includes("appstore") && config.stores.appstore?.appId === undefined) {
|
|
51
|
+
throw new StorelingoError("E_CONFIG", "stores.appstore.appId is required for pull and push", "Add the numeric Apple ID from App Store Connect (App Information) as stores.appstore.appId in storelingo.config.json, or use --store play.");
|
|
52
|
+
}
|
|
53
|
+
return stores;
|
|
54
|
+
}
|
|
55
|
+
function selectConfiguredStores(option, config) {
|
|
47
56
|
if (option === undefined)
|
|
48
57
|
return configuredStores(config);
|
|
49
58
|
if (option !== "play" && option !== "appstore") {
|
package/dist/commands/init.js
CHANGED
|
@@ -10,8 +10,8 @@ export function buildConfigJson(a) {
|
|
|
10
10
|
const stores = {};
|
|
11
11
|
if (a.playPackageName)
|
|
12
12
|
stores.play = { packageName: a.playPackageName };
|
|
13
|
-
if (a.
|
|
14
|
-
stores.appstore = { appId: a.
|
|
13
|
+
if (a.appstore)
|
|
14
|
+
stores.appstore = a.appstore.appId ? { appId: a.appstore.appId } : {};
|
|
15
15
|
const translator = a.provider === "anthropic"
|
|
16
16
|
? { provider: "anthropic", ...(a.model ? { model: a.model } : {}) }
|
|
17
17
|
: { provider: "openai-compatible", baseUrl: a.baseUrl, model: a.model };
|
|
@@ -87,13 +87,16 @@ export async function promptInitAnswers() {
|
|
|
87
87
|
const playPackageName = stores.includes("play")
|
|
88
88
|
? await input({ message: "Google Play package name (e.g. com.example.app)", required: true })
|
|
89
89
|
: undefined;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
validate: (v) =>
|
|
95
|
-
|
|
96
|
-
|
|
90
|
+
let appstore;
|
|
91
|
+
if (stores.includes("appstore")) {
|
|
92
|
+
const appId = (await input({
|
|
93
|
+
message: "App Store app ID (numbers from App Store Connect; leave empty if the app is not there yet)",
|
|
94
|
+
validate: (v) => v.trim() === "" ||
|
|
95
|
+
/^[0-9]+$/.test(v.trim()) ||
|
|
96
|
+
"Enter the numeric Apple ID from App Store Connect (App Information), or leave it empty",
|
|
97
|
+
})).trim();
|
|
98
|
+
appstore = appId ? { appId } : {};
|
|
99
|
+
}
|
|
97
100
|
const provider = await select({
|
|
98
101
|
message: "Translator",
|
|
99
102
|
choices: [
|
|
@@ -106,5 +109,5 @@ export async function promptInitAnswers() {
|
|
|
106
109
|
: undefined;
|
|
107
110
|
const model = provider === "openai-compatible" ? await input({ message: "Model name", required: true }) : undefined;
|
|
108
111
|
const context = await input({ message: "One sentence about your app (helps the translator)", default: "" });
|
|
109
|
-
return { sourceLocale, targetLocales, playPackageName,
|
|
112
|
+
return { sourceLocale, targetLocales, playPackageName, appstore, provider, baseUrl, model, context };
|
|
110
113
|
}
|
package/dist/config/schema.js
CHANGED
|
@@ -31,7 +31,8 @@ export const ConfigSchema = z.strictObject({
|
|
|
31
31
|
play: z.strictObject({ packageName: z.string().min(1) }).optional(),
|
|
32
32
|
appstore: z
|
|
33
33
|
.strictObject({
|
|
34
|
-
|
|
34
|
+
// Needed only for pull and push: translate and check work before the app exists in App Store Connect.
|
|
35
|
+
appId: z.string().regex(/^\d+$/, "must be the numeric Apple ID of the app").optional(),
|
|
35
36
|
platform: z.enum(["IOS", "MAC_OS", "TV_OS", "VISION_OS"]).default("IOS"),
|
|
36
37
|
})
|
|
37
38
|
.optional(),
|
package/package.json
CHANGED