@lingo.dev/cli 1.0.0 → 1.0.2
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/dist/bin.js +3 -3
- package/dist/index.js +2 -2
- package/dist/{renderer-DvB06WWF.js → renderer-D2iDOMA6.js} +1 -1
- package/dist/{server-BxEBM9NU.js → server-DGIsMSAq.js} +7 -7
- package/dist/{update-C-JdpZwG.js → update-RHUBOb93.js} +3 -3
- package/guides/api.md +3 -3
- package/guides/index.md +1 -1
- package/guides/migrate.md +1 -1
- package/guides/setup.md +2 -2
- package/package.json +3 -4
package/dist/bin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as extractCommandInfo, b as ApiClientLive, d as subcommands, f as TelemetryService, g as cancel, i as collectOptions, l as helpConfig, m as trackCommand, n as renderRootHelp, o as unwrapCommand, p as TelemetryServiceLive, s as cliConfig, t as renderCommandHelp, u as run, w as AuthServiceLive, x as AuthContext, y as ConfigServiceLive } from "./renderer-
|
|
2
|
-
import { n as UpdateService, r as UpdateServiceLive } from "./update-
|
|
1
|
+
import { a as extractCommandInfo, b as ApiClientLive, d as subcommands, f as TelemetryService, g as cancel, i as collectOptions, l as helpConfig, m as trackCommand, n as renderRootHelp, o as unwrapCommand, p as TelemetryServiceLive, s as cliConfig, t as renderCommandHelp, u as run, w as AuthServiceLive, x as AuthContext, y as ConfigServiceLive } from "./renderer-D2iDOMA6.js";
|
|
2
|
+
import { n as UpdateService, r as UpdateServiceLive } from "./update-RHUBOb93.js";
|
|
3
3
|
import { AutoCorrect, CliConfig, ValidationError } from "@effect/cli";
|
|
4
4
|
import { NodeContext, NodeRuntime } from "@effect/platform-node";
|
|
5
5
|
import { Cause, Effect, Layer, pipe } from "effect";
|
|
@@ -68,7 +68,7 @@ process.on("SIGINT", () => process.exit(0));
|
|
|
68
68
|
process.on("SIGTERM", () => process.exit(0));
|
|
69
69
|
const args = process.argv;
|
|
70
70
|
const userArgs = args.slice(2).filter((a) => a !== "--");
|
|
71
|
-
if (userArgs[0] === "mcp") import("./server-
|
|
71
|
+
if (userArgs[0] === "mcp") import("./server-DGIsMSAq.js").then((m) => m.startMcpServer()).catch((e) => {
|
|
72
72
|
process.stderr.write(`MCP server error: ${e}\n`);
|
|
73
73
|
process.exit(1);
|
|
74
74
|
});
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { C as AuthService, S as AuthError, _ as ConfigError, a as extractCommandInfo, c as command, d as subcommands, h as PromptCancelledError, i as collectOptions, l as helpConfig, n as renderRootHelp, r as collectArgs, s as cliConfig, t as renderCommandHelp, u as run, v as ConfigService, w as AuthServiceLive, x as AuthContext, y as ConfigServiceLive } from "./renderer-
|
|
2
|
-
import { n as UpdateService, r as UpdateServiceLive, s as VERSION, t as UpdateError } from "./update-
|
|
1
|
+
import { C as AuthService, S as AuthError, _ as ConfigError, a as extractCommandInfo, c as command, d as subcommands, h as PromptCancelledError, i as collectOptions, l as helpConfig, n as renderRootHelp, r as collectArgs, s as cliConfig, t as renderCommandHelp, u as run, v as ConfigService, w as AuthServiceLive, x as AuthContext, y as ConfigServiceLive } from "./renderer-D2iDOMA6.js";
|
|
2
|
+
import { n as UpdateService, r as UpdateServiceLive, s as VERSION, t as UpdateError } from "./update-RHUBOb93.js";
|
|
3
3
|
export { AuthContext, AuthError, AuthService, AuthServiceLive, ConfigError, ConfigService, ConfigServiceLive, PromptCancelledError, UpdateError, UpdateService, UpdateServiceLive, VERSION, cliConfig, collectArgs, collectOptions, command, extractCommandInfo, helpConfig, renderCommandHelp, renderRootHelp, run, subcommands };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as discoverLocales, S as writeLocaleFile, T as tryReadFile, _ as runExtractionPipeline, b as mergeEntries, c as formatCheckResult, d as computeSourceStatus, f as formatStatusTable, g as generateTypes, h as toApiPayload, l as runChecks, m as planLocalization, n as UpdateService, p as applyTranslations, s as VERSION, t as UpdateError, u as computeLocaleStatus, v as toLocaleEntries, w as findSourceFiles, x as readLocaleFile, y as getActiveEntries } from "./update-
|
|
1
|
+
import { C as discoverLocales, S as writeLocaleFile, T as tryReadFile, _ as runExtractionPipeline, b as mergeEntries, c as formatCheckResult, d as computeSourceStatus, f as formatStatusTable, g as generateTypes, h as toApiPayload, l as runChecks, m as planLocalization, n as UpdateService, p as applyTranslations, s as VERSION, t as UpdateError, u as computeLocaleStatus, v as toLocaleEntries, w as findSourceFiles, x as readLocaleFile, y as getActiveEntries } from "./update-RHUBOb93.js";
|
|
2
2
|
import { Args, CliConfig, Command, Options } from "@effect/cli";
|
|
3
3
|
import { Console, Context, Data, Effect, Layer, Option, pipe } from "effect";
|
|
4
4
|
import pc from "picocolors";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as discoverLocales, S as writeLocaleFile, T as tryReadFile, _ as runExtractionPipeline, a as detectInstallMethod, b as mergeEntries, d as computeSourceStatus, g as generateTypes, h as toApiPayload, i as compareVersions, l as runChecks, m as planLocalization, o as generateUpdateCommand, p as applyTranslations, s as VERSION, u as computeLocaleStatus, v as toLocaleEntries, w as findSourceFiles } from "./update-
|
|
1
|
+
import { C as discoverLocales, S as writeLocaleFile, T as tryReadFile, _ as runExtractionPipeline, a as detectInstallMethod, b as mergeEntries, d as computeSourceStatus, g as generateTypes, h as toApiPayload, i as compareVersions, l as runChecks, m as planLocalization, o as generateUpdateCommand, p as applyTranslations, s as VERSION, u as computeLocaleStatus, v as toLocaleEntries, w as findSourceFiles } from "./update-RHUBOb93.js";
|
|
2
2
|
import * as fs from "node:fs/promises";
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import { computeKey, getActiveEntries, readLocaleFile } from "@lingo.dev/spec";
|
|
@@ -205,13 +205,13 @@ l.text("Save", { context: "Form submit button" })
|
|
|
205
205
|
l.text("Save", { context: "Toolbar save action" }) // same text, different context = different translation
|
|
206
206
|
\`\`\`
|
|
207
207
|
|
|
208
|
-
**\`l.
|
|
208
|
+
**\`l.rich(source, { context, tags?, values? })\`** - Rich text with tags
|
|
209
209
|
\`\`\`tsx
|
|
210
|
-
l.
|
|
210
|
+
l.rich("Read our <link>terms of service</link>", {
|
|
211
211
|
context: "Footer legal link",
|
|
212
212
|
tags: { link: (children) => <a href="/terms">{children}</a> },
|
|
213
213
|
})
|
|
214
|
-
l.
|
|
214
|
+
l.rich("Welcome, <bold>{name}</bold>!", {
|
|
215
215
|
context: "Dashboard header",
|
|
216
216
|
tags: { bold: (children) => <strong>{children}</strong> },
|
|
217
217
|
values: { name: user.name },
|
|
@@ -242,7 +242,7 @@ l.list(["Alice", "Bob", "Charlie"]) // "Alice, Bob, and Charlie"
|
|
|
242
242
|
|
|
243
243
|
### Context Rules
|
|
244
244
|
|
|
245
|
-
1. Context is REQUIRED on every \`l.text()\`, \`l.
|
|
245
|
+
1. Context is REQUIRED on every \`l.text()\`, \`l.rich()\`, \`l.plural()\`, \`l.select()\` call
|
|
246
246
|
2. Context describes WHERE and HOW the text is used (not WHAT it says)
|
|
247
247
|
3. Good context: "Checkout form submit button", "Hero section heading", "Error toast message"
|
|
248
248
|
4. Bad context: "button", "heading", "text" (too generic)
|
|
@@ -273,7 +273,7 @@ export function LocaleSwitcher() {
|
|
|
273
273
|
## Step 7: Extract
|
|
274
274
|
|
|
275
275
|
Run the \`lingo_extract\` tool (or \`pnpm lingo extract\`). This:
|
|
276
|
-
- Scans source files for all \`l.text()\`, \`l.
|
|
276
|
+
- Scans source files for all \`l.text()\`, \`l.rich()\`, \`l.plural()\`, \`l.select()\` calls
|
|
277
277
|
- Generates \`locales/en.jsonc\` with source messages, @context metadata, @src file locations
|
|
278
278
|
- Generates \`lingo.d.ts\` with TypeScript types (exact context unions, value types)
|
|
279
279
|
|
|
@@ -394,7 +394,7 @@ No key management. No key naming conventions. The key is a deterministic hash co
|
|
|
394
394
|
|---------|-----------|------------|---------|------------------|
|
|
395
395
|
| Plain text | \`t("key")\` | \`formatMessage({ id: "key" })\` | \`t("key")\` | \`l.text("source", { context: "..." })\` |
|
|
396
396
|
| With values | \`t("key", { name })\` | \`formatMessage({ id }, { name })\` | \`t("key", { name })\` | \`l.text("Hello, {name}", { context: "...", values: { name } })\` |
|
|
397
|
-
| Rich text | \`t.rich("key", { link })\` | \`<FormattedMessage components />\` | \`<Trans components />\` | \`l.
|
|
397
|
+
| Rich text | \`t.rich("key", { link })\` | \`<FormattedMessage components />\` | \`<Trans components />\` | \`l.rich("Click <link>here</link>", { context: "...", tags: { link } })\` |
|
|
398
398
|
| Plurals | ICU in JSON | \`<FormattedPlural />\` | ICU in JSON | \`l.plural(count, { one: "...", other: "..." }, { context: "..." })\` |
|
|
399
399
|
| Provider | \`NextIntlClientProvider\` | \`IntlProvider\` | \`I18nextProvider\` | \`LingoProvider\` (via \`withLingoApp\`) |
|
|
400
400
|
| Hook | \`useTranslations()\` | \`useIntl()\` | \`useTranslation()\` | \`useLingo()\` |
|
|
@@ -127,7 +127,7 @@ function mergeEntries(existing, extracted) {
|
|
|
127
127
|
//#region src/services/extractor.ts
|
|
128
128
|
/**
|
|
129
129
|
* AST-based extraction of translatable strings from TypeScript/TSX source files.
|
|
130
|
-
* Uses Babel to parse and traverse, extracting l.text(), l.
|
|
130
|
+
* Uses Babel to parse and traverse, extracting l.text(), l.rich(), l.plural(),
|
|
131
131
|
* and l.select() calls with source text, context, and source location.
|
|
132
132
|
*
|
|
133
133
|
* Scope rules:
|
|
@@ -138,7 +138,7 @@ function mergeEntries(existing, extracted) {
|
|
|
138
138
|
*/
|
|
139
139
|
const traverse = typeof _traverse === "function" ? _traverse : _traverse.default;
|
|
140
140
|
/** Methods where the first arg is the source string */
|
|
141
|
-
const TEXT_METHODS = new Set(["text", "
|
|
141
|
+
const TEXT_METHODS = new Set(["text", "rich"]);
|
|
142
142
|
/** Methods where the second arg is a forms object that becomes the ICU source */
|
|
143
143
|
const FORMS_METHODS = new Set(["plural", "select"]);
|
|
144
144
|
const ALL_METHODS = new Set([...TEXT_METHODS, ...FORMS_METHODS]);
|
|
@@ -400,7 +400,7 @@ function escapeForTs(s) {
|
|
|
400
400
|
/**
|
|
401
401
|
* Generates a TypeScript declaration file from a source locale file.
|
|
402
402
|
* The output augments @lingo.dev/react's LingoMessages interface via
|
|
403
|
-
* `declare module` so that l.text() and l.
|
|
403
|
+
* `declare module` so that l.text() and l.rich() get:
|
|
404
404
|
*
|
|
405
405
|
* 1. Autocomplete on source strings
|
|
406
406
|
* 2. Compile errors for typos
|
package/guides/api.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
## Translation helpers (context required)
|
|
7
7
|
```tsx
|
|
8
8
|
l.text(source, { context, values? })
|
|
9
|
-
l.
|
|
9
|
+
l.rich(source, { context, tags?, values? })
|
|
10
10
|
l.plural(count, { one, other, zero?, two?, few?, many? }, { context })
|
|
11
11
|
l.select(value, { ...forms, other }, { context })
|
|
12
12
|
```
|
|
@@ -15,13 +15,13 @@ Examples:
|
|
|
15
15
|
```tsx
|
|
16
16
|
l.text("Save", { context: "Form submit button" })
|
|
17
17
|
l.text("Hello, {name}!", { context: "Dashboard welcome", values: { name } })
|
|
18
|
-
l.
|
|
18
|
+
l.rich("Read <link>docs</link>", { context: "Footer link", tags: { link: c => <a href="/docs">{c}</a> } })
|
|
19
19
|
l.plural(items, { one: "# item", other: "# items" }, { context: "Cart count" })
|
|
20
20
|
l.select(role, { admin: "Admin", user: "User", other: "Guest" }, { context: "Nav label" })
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
Context rules:
|
|
24
|
-
1) Always required on text/
|
|
24
|
+
1) Always required on text/rich/plural/select.
|
|
25
25
|
2) Describes where/how the string is used ("Checkout CTA", "Toast error").
|
|
26
26
|
3) Same source + different context = different translation key.
|
|
27
27
|
|
package/guides/index.md
CHANGED
|
@@ -4,7 +4,7 @@ Use `npx @lingo.dev/cli guide <name>` to view a guide.
|
|
|
4
4
|
|
|
5
5
|
Available guides:
|
|
6
6
|
- `setup` – first-time setup for @lingo.dev/react (Next.js Pages Router focus, works for React too)
|
|
7
|
-
- `api` – API reference for `l.text`, `l.
|
|
7
|
+
- `api` – API reference for `l.text`, `l.rich`, `l.plural`, `l.select`, formatting helpers
|
|
8
8
|
- `migrate` – migrate from next-intl, react-intl, i18next, lingui to @lingo.dev/react
|
|
9
9
|
|
|
10
10
|
Always finish workflows with `npx @lingo.dev/cli check` (or `pnpm lingo check`) and expect 0 issues.
|
package/guides/migrate.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|------------------|----------------------------|---------------------------------|---------------------------|------------------------------------------------------|
|
|
11
11
|
| Plain text | `t("key")` | `formatMessage({ id })` | `t("key")` | `l.text("source", { context: "..." })` |
|
|
12
12
|
| With values | `t("key", { name })` | `formatMessage({ id }, { name })`| `t("key", { name })` | `l.text("Hello, {name}", { context: "...", values: { name } })` |
|
|
13
|
-
| Rich text | `t.rich("key", { link })`| `<FormattedMessage components>` | `<Trans components>` | `l.
|
|
13
|
+
| Rich text | `t.rich("key", { link })`| `<FormattedMessage components>` | `<Trans components>` | `l.rich("Click <link>here</link>", { context: "...", tags: { link } })` |
|
|
14
14
|
| Plurals | ICU in JSON | `<FormattedPlural>` | ICU in JSON | `l.plural(count, { one: "# item", other: "# items" }, { context: "..." })` |
|
|
15
15
|
| Provider | `NextIntlProvider` | `IntlProvider` | `I18nextProvider` | `withLingoApp` (wraps LingoProvider) |
|
|
16
16
|
| Hook | `useTranslations()` | `useIntl()` | `useTranslation()` | `useLingo()` |
|
package/guides/setup.md
CHANGED
|
@@ -65,11 +65,11 @@ const l = useLingo();
|
|
|
65
65
|
<p>{l.text("The best tool for teams.", { context: "Hero subheading" })}</p>
|
|
66
66
|
<button>{l.text("Get started", { context: "Hero CTA" })}</button>
|
|
67
67
|
```
|
|
68
|
-
Context is REQUIRED on l.text/l.
|
|
68
|
+
Context is REQUIRED on l.text/l.rich/l.plural/l.select.
|
|
69
69
|
|
|
70
70
|
### API cheatsheet
|
|
71
71
|
- `l.text(source, { context, values? })`
|
|
72
|
-
- `l.
|
|
72
|
+
- `l.rich(source, { context, tags?, values? })`
|
|
73
73
|
- `l.plural(count, forms, { context })`
|
|
74
74
|
- `l.select(value, forms, { context })`
|
|
75
75
|
- Formatting: `l.num`, `l.currency`, `l.percent`, `l.date`, `l.time`, `l.relative`, `l.list`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lingo.dev/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"lingo": "./dist/bin.js"
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"posthog-node": "^5.28.2",
|
|
34
34
|
"semver": "^7.7.4",
|
|
35
35
|
"zod": "^4.0.0",
|
|
36
|
-
"@lingo.dev/spec": "1.0.
|
|
36
|
+
"@lingo.dev/spec": "1.0.2"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@babel/types": "^7.29.0",
|
|
@@ -49,7 +49,6 @@
|
|
|
49
49
|
"build": "tsdown",
|
|
50
50
|
"typecheck": "tsc --noEmit",
|
|
51
51
|
"test": "vitest run",
|
|
52
|
-
"cli": "node --import tsx/esm src/bin.ts"
|
|
53
|
-
"dev": "tsdown && node dist/bin.js"
|
|
52
|
+
"cli": "node --import tsx/esm src/bin.ts"
|
|
54
53
|
}
|
|
55
54
|
}
|