@ai-translate/apple 0.1.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/LICENSE +21 -0
- package/README.md +129 -0
- package/dist/index.d.mts +38 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +1262 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +61 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Thiago Peres
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# @ai-translate/apple
|
|
2
|
+
|
|
3
|
+
Native Apple localization resources for ai-translate. Works with SwiftUI, UIKit,
|
|
4
|
+
AppKit, Swift packages, and any application that loads Apple string resources.
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
npm install --save-dev @ai-translate/apple @ai-translate/cli @ai-translate/fs-json @ai-translate/provider-openai
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
Requires Node 20.19+. Resource translation runs on any supported operating
|
|
11
|
+
system; Xcode resource extraction and app compilation require Apple's tools.
|
|
12
|
+
|
|
13
|
+
## Xcode string catalogs
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { createAppleStringCatalog } from "@ai-translate/apple";
|
|
17
|
+
|
|
18
|
+
const native = createAppleStringCatalog({
|
|
19
|
+
id: "native",
|
|
20
|
+
rootDir: "Shared/Resources",
|
|
21
|
+
sourceLocale: "en",
|
|
22
|
+
// Optional globs relative to rootDir:
|
|
23
|
+
include: ["**/*.xcstrings"],
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Add this adapter to your configuration's `catalogs` array. Every `.xcstrings`
|
|
28
|
+
file is one document unit, named by its relative path without the extension;
|
|
29
|
+
every locale writes to the same physical file. The source language must match
|
|
30
|
+
`sourceLocale`. Discovery excludes common build/dependency directories.
|
|
31
|
+
|
|
32
|
+
Only string-unit values are translated. Source text falls back to the key when
|
|
33
|
+
there is no explicit source localization. Comments and variant context reach
|
|
34
|
+
the provider. Metadata, source content, unrelated locales, and nontranslatable
|
|
35
|
+
entries are preserved. Empty keys, `shouldTranslate: false`, and stale extracted
|
|
36
|
+
entries are skipped. String Catalog versions 1.0–1.3 are supported and preserved,
|
|
37
|
+
including the version emitted by Xcode 27. Unknown versions and unsupported
|
|
38
|
+
localization structures fail explicitly.
|
|
39
|
+
|
|
40
|
+
Plural/device variants and substitutions are supported. Target plural categories
|
|
41
|
+
are expanded from the source fallback; existing authored categories remain.
|
|
42
|
+
Apple printf tokens are protected automatically. Xcode `new` and `needs_review`
|
|
43
|
+
values remain pending; accepted generated values are marked `translated`.
|
|
44
|
+
Scaffolded values are marked `new` and still require a sync.
|
|
45
|
+
|
|
46
|
+
Existing locale-specific device and plural variants may vary a plain source
|
|
47
|
+
message. Named substitutions require matching definitions in the source
|
|
48
|
+
localization: a target-only `%#@count@` fragment cannot be safely inferred from
|
|
49
|
+
a flat source such as `Found %lld birds`. The adapter reports the affected key
|
|
50
|
+
and substitution before translation. Define the corresponding source
|
|
51
|
+
substitution in Xcode, including its plural fragments, then sync again.
|
|
52
|
+
Named substitutions may reorder in translations: their source `argNum` bindings
|
|
53
|
+
keep each reference attached to the same runtime argument. Ordinary printf
|
|
54
|
+
arguments still require compatible types and explicit positions when reordered.
|
|
55
|
+
|
|
56
|
+
For literal percentages that resemble format directives, such as `100% done`,
|
|
57
|
+
set `plainTextKeys: ["progress"]` on either Apple adapter, using the exact
|
|
58
|
+
resource lookup key. Those keys use the core plain message format; every other
|
|
59
|
+
key keeps printf protection. The setting applies to all variants of a catalog
|
|
60
|
+
key and to matching keys in every table selected by that adapter. Use it only
|
|
61
|
+
for messages without runtime printf arguments or named substitutions: literal
|
|
62
|
+
text and directives cannot be distinguished reliably from their spelling.
|
|
63
|
+
|
|
64
|
+
Paths for `--include-path` are locale-independent JSON pointers, for example
|
|
65
|
+
`/welcome/stringUnit/value` or
|
|
66
|
+
`/items/variations/plural/few/stringUnit/value`. Escape key slashes as `~1` and
|
|
67
|
+
tildes as `~0`. A path-scoped run requires an existing target document; first
|
|
68
|
+
scaffold it or perform an initial full sync. Seeding a new structured message may
|
|
69
|
+
create required fallback arms marked `new`; those are not accepted translations.
|
|
70
|
+
|
|
71
|
+
## Legacy strings tables
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import { createAppleStringsCatalog } from "@ai-translate/apple";
|
|
75
|
+
|
|
76
|
+
const tables = createAppleStringsCatalog({
|
|
77
|
+
id: "legacy",
|
|
78
|
+
rootDir: "App/Resources", // contains en.lproj, de.lproj, ...
|
|
79
|
+
sourceLocale: "en",
|
|
80
|
+
// sourceLocaleDirectory: "Base.lproj",
|
|
81
|
+
// include: ["Localizable.strings", "InfoPlist.strings"],
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Units are table paths relative to the source `.lproj` directory, including the
|
|
86
|
+
`.strings` suffix. Entry paths are `/<key>`. The adapter handles UTF-8 with or
|
|
87
|
+
without BOM and UTF-16 in either byte order. It preserves existing formatting,
|
|
88
|
+
comments, encoding, and unrelated target keys; it rejects ambiguous duplicate
|
|
89
|
+
keys and malformed syntax. Key-only entries (`"Hello";`) and optional dictionary
|
|
90
|
+
braces are supported. Apple printf validation is automatic here too.
|
|
91
|
+
|
|
92
|
+
## Discovery and composition
|
|
93
|
+
|
|
94
|
+
`ai-translate init --integration apple --preview` inspects native resources,
|
|
95
|
+
Xcode projects, and Apple Swift packages without executing project code. Projects
|
|
96
|
+
without catalogs receive explicit extraction/setup warnings. `init` writes only
|
|
97
|
+
the configuration; it does not edit Xcode projects or extract hardcoded text.
|
|
98
|
+
|
|
99
|
+
Generated configs list the authored files found during detection. Mixed
|
|
100
|
+
`Base.lproj` and source-locale tables are partitioned without translating the
|
|
101
|
+
same table twice. Nested projects with another declared source language are
|
|
102
|
+
reported for separate configuration. Expo native trees follow their ancestor
|
|
103
|
+
ignore rules; compiled app/framework bundles and build folders are excluded.
|
|
104
|
+
|
|
105
|
+
When no usable resources exist, the starter has `include: []`. After adding or
|
|
106
|
+
repairing resources, run `init --preview` and update the include lists from its
|
|
107
|
+
output. Legacy directory names such as `French.lproj` or `pt_BR.lproj` need
|
|
108
|
+
manual setup or migration to language tags such as `fr` and `pt-BR`.
|
|
109
|
+
|
|
110
|
+
`appleIntegration` implements the platform-neutral `Integration` interface from
|
|
111
|
+
`@ai-translate/integrations`. Both adapters implement `CatalogAdapter`, so they
|
|
112
|
+
compose with existing JSON, HTML, or Markdoc adapters and every provider.
|
|
113
|
+
|
|
114
|
+
Use the [native app guide](../../docs/native-apps.md) for a full configuration and
|
|
115
|
+
specific Swift package, shared iOS/macOS, Expo, and Tauri setup recipes. For Expo
|
|
116
|
+
prebuild, translate committed locale JSON using `applePrintfMessageFormat` from
|
|
117
|
+
`@ai-translate/message-formats`; preserve generated iOS resources through Expo's
|
|
118
|
+
own build workflow.
|
|
119
|
+
|
|
120
|
+
The CLI stages resource and state writes together. It checks for changes to live
|
|
121
|
+
files before committing and aborts if they were edited during translation; rerun
|
|
122
|
+
to use those edits. Use `sync --dry-run` to plan,
|
|
123
|
+
`adopt` to migrate existing translations, and `check` as a read-only CI gate.
|
|
124
|
+
Direct programmatic adapter writes are atomic per file, not across an entire
|
|
125
|
+
configuration; use the CLI when you need the transaction guarantee.
|
|
126
|
+
|
|
127
|
+
Legacy `.stringsdict`, XLIFF, source rewriting, and runtime lookup installation
|
|
128
|
+
are outside this package. Xcode can migrate legacy plural files into string
|
|
129
|
+
catalogs. Runtime layout and bundle membership still need app-level validation.
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Integration } from "@ai-translate/integrations";
|
|
2
|
+
import { CatalogAdapter } from "@ai-translate/core/types";
|
|
3
|
+
//#region src/xcstrings.d.ts
|
|
4
|
+
interface AppleStringCatalogOptions {
|
|
5
|
+
id?: string;
|
|
6
|
+
/** Glob patterns relative to rootDir. Defaults to all authored .xcstrings. */
|
|
7
|
+
include?: readonly string[];
|
|
8
|
+
/** Exact catalog keys whose percent signs are literal text, not runtime printf arguments. */
|
|
9
|
+
plainTextKeys?: readonly string[];
|
|
10
|
+
rootDir: string;
|
|
11
|
+
/** Must match each catalog's sourceLanguage exactly. */
|
|
12
|
+
sourceLocale: string;
|
|
13
|
+
}
|
|
14
|
+
/** Native Xcode catalogs: one physical file, independently reconciled locales. */
|
|
15
|
+
export declare function createAppleStringCatalog(options: AppleStringCatalogOptions): CatalogAdapter;
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/strings.d.ts
|
|
18
|
+
interface AppleStringsCatalogOptions {
|
|
19
|
+
id?: string;
|
|
20
|
+
/** Glob(s) relative to the source locale directory; all nested tables by default. */
|
|
21
|
+
include?: string | readonly string[];
|
|
22
|
+
/** Exact keys whose percent signs are literal text, not runtime printf arguments. */
|
|
23
|
+
plainTextKeys?: readonly string[];
|
|
24
|
+
rootDir: string;
|
|
25
|
+
sourceLocale: string;
|
|
26
|
+
/** For projects whose source files are in Base.lproj. Defaults to <locale>.lproj. */
|
|
27
|
+
sourceLocaleDirectory?: string;
|
|
28
|
+
}
|
|
29
|
+
/** Translate .lproj tables without replacing comments or unrelated translations. */
|
|
30
|
+
export declare function createAppleStringsCatalog(options: AppleStringsCatalogOptions): CatalogAdapter;
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/integration.d.ts
|
|
33
|
+
/** Native resources are shared by Swift, Objective-C, React Native and Expo
|
|
34
|
+
* prebuild projects, so discovery follows authored resources rather than a UI framework. */
|
|
35
|
+
export declare const appleIntegration: Integration;
|
|
36
|
+
//#endregion
|
|
37
|
+
export type { AppleStringCatalogOptions, AppleStringsCatalogOptions };
|
|
38
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/xcstrings.ts","../src/strings.ts","../src/integration.ts"],"mappings":";;;UAciB;EACf;;EAEA;;EAEA;EACA;;EAEA;;;wBA6Bc,yBAAyB,SAAS,4BAA4B;;;UCtC7D;EACf;;EAEA;;EAEA;EACA;EACA;;EAEA;;;wBAsEc,0BAA0B,SAAS,6BAA6B;;;;;qBCiInE,kBAAkB"}
|