Skip to content

Commit e20377f

Browse files
Merge branch 'lingodotdev:main' into fix/1733-batch-size
2 parents 53ce3dc + e490347 commit e20377f

File tree

15 files changed

+151
-85
lines changed

15 files changed

+151
-85
lines changed

packages/cli/CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# lingo.dev
22

3+
## 0.133.8
4+
5+
### Patch Changes
6+
7+
- [#2062](https://github.com/lingodotdev/lingo.dev/pull/2062) [`10e6364`](https://github.com/lingodotdev/lingo.dev/commit/10e636479046da5d53d059e539497195191a99fc) Thanks [@AndreyHirsa](https://github.com/AndreyHirsa)! - Migrate PostHog tracking identity from email to database user ID
8+
9+
- Updated dependencies [[`10e6364`](https://github.com/lingodotdev/lingo.dev/commit/10e636479046da5d53d059e539497195191a99fc)]:
10+
- @lingo.dev/_sdk@0.16.2
11+
- @lingo.dev/_compiler@0.12.2
12+
313
## 0.133.7
414

515
### Patch Changes

packages/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "lingo.dev",
3-
"version": "0.133.7",
3+
"version": "0.133.8",
44
"description": "Lingo.dev CLI",
55
"private": false,
66
"repository": {

packages/cli/src/cli/cmd/i18n.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import externalEditor from "external-editor";
3434
import updateGitignore from "../utils/update-gitignore";
3535
import createProcessor from "../processor";
3636
import { withExponentialBackoff } from "../utils/exp-backoff";
37-
import trackEvent from "../utils/observability";
37+
import trackEvent, { UserIdentity } from "../utils/observability";
3838
import { createDeltaProcessor } from "../utils/delta";
3939

4040
export default new Command()
@@ -140,7 +140,7 @@ export default new Command()
140140
}
141141

142142
let hasErrors = false;
143-
let email: string | null = null;
143+
let userIdentity: UserIdentity = null;
144144
const errorDetails: ErrorDetail[] = [];
145145
try {
146146
ora.start("Loading configuration...");
@@ -156,15 +156,15 @@ export default new Command()
156156
const isByokMode = !!i18nConfig?.provider;
157157

158158
if (isByokMode) {
159-
email = null;
159+
userIdentity = null;
160160
ora.succeed("Using external provider (BYOK mode)");
161161
} else {
162162
const auth = await validateAuth(settings);
163-
email = auth.email;
163+
userIdentity = { email: auth.email, id: auth.id };
164164
ora.succeed(`Authenticated as ${auth.email}`);
165165
}
166166

167-
await trackEvent(email, "cmd.i18n.start", {
167+
await trackEvent(userIdentity, "cmd.i18n.start", {
168168
i18nConfig,
169169
flags,
170170
});
@@ -591,7 +591,7 @@ export default new Command()
591591
console.log();
592592
if (!hasErrors) {
593593
ora.succeed("Localization completed.");
594-
await trackEvent(email, "cmd.i18n.success", {
594+
await trackEvent(userIdentity, "cmd.i18n.success", {
595595
i18nConfig: {
596596
sourceLocale: i18nConfig!.locale.source,
597597
targetLocales: i18nConfig!.locale.targets,
@@ -606,7 +606,7 @@ export default new Command()
606606
} else {
607607
ora.warn("Localization completed with errors.");
608608
process.exitCode = 1;
609-
await trackEvent(email, "cmd.i18n.error", {
609+
await trackEvent(userIdentity, "cmd.i18n.error", {
610610
flags,
611611
...aggregateErrorAnalytics(
612612
errorDetails,
@@ -638,7 +638,7 @@ export default new Command()
638638
};
639639
}
640640

641-
await trackEvent(email, "cmd.i18n.error", {
641+
await trackEvent(userIdentity, "cmd.i18n.error", {
642642
flags,
643643
errorType,
644644
errorName: error.name || "Error",

packages/cli/src/cli/cmd/run/_utils.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
11
import { CmdRunContext } from "./_types";
2+
import { UserIdentity } from "../../utils/observability";
23

34
/**
4-
* Determines the user's email for tracking purposes.
5+
* Determines the user's identity for tracking purposes.
56
* Returns null if using BYOK mode or if authentication fails.
67
*/
7-
export async function determineEmail(
8+
export async function determineUserIdentity(
89
ctx: CmdRunContext,
9-
): Promise<string | null> {
10+
): Promise<UserIdentity> {
1011
const isByokMode = !!ctx.config?.provider;
1112

1213
if (isByokMode) {
1314
return null;
1415
} else {
1516
try {
1617
const authStatus = await ctx.localizer?.checkAuth();
17-
return authStatus?.username || null;
18+
if (!authStatus?.username || !authStatus?.userId) return null;
19+
return {
20+
email: authStatus.username,
21+
id: authStatus.userId,
22+
};
1823
} catch {
1924
return null;
2025
}

packages/cli/src/cli/cmd/run/index.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ import {
1818
pauseIfDebug,
1919
renderSummary,
2020
} from "../../utils/ui";
21-
import trackEvent from "../../utils/observability";
22-
import { determineEmail } from "./_utils";
21+
import trackEvent, { UserIdentity } from "../../utils/observability";
22+
import { determineUserIdentity } from "./_utils";
2323

2424
const __dirname = path.dirname(fileURLToPath(import.meta.url));
2525

@@ -129,7 +129,7 @@ export default new Command()
129129
(val: string) => parseInt(val),
130130
)
131131
.action(async (args) => {
132-
let email: string | null = null;
132+
let userIdentity: UserIdentity = null;
133133
try {
134134
const ctx: CmdRunContext = {
135135
flags: flagsSchema.parse(args),
@@ -148,9 +148,9 @@ export default new Command()
148148

149149
await setup(ctx);
150150

151-
email = await determineEmail(ctx);
151+
userIdentity = await determineUserIdentity(ctx);
152152

153-
await trackEvent(email, "cmd.run.start", {
153+
await trackEvent(userIdentity, "cmd.run.start", {
154154
config: ctx.config,
155155
flags: ctx.flags,
156156
});
@@ -181,16 +181,16 @@ export default new Command()
181181
await watch(ctx);
182182
}
183183

184-
await trackEvent(email, "cmd.run.success", {
184+
await trackEvent(userIdentity, "cmd.run.success", {
185185
config: ctx.config,
186186
flags: ctx.flags,
187187
});
188188
await new Promise((resolve) => setTimeout(resolve, 50));
189189
} catch (error: any) {
190-
await trackEvent(email, "cmd.run.error", {
190+
await trackEvent(userIdentity, "cmd.run.error", {
191191
flags: args,
192192
error: error.message,
193-
authenticated: !!email,
193+
authenticated: !!userIdentity,
194194
});
195195
await new Promise((resolve) => setTimeout(resolve, 50));
196196
// Play sad sound if sound flag is enabled

packages/cli/src/cli/cmd/status.ts

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { getBuckets } from "../utils/buckets";
1818
import chalk from "chalk";
1919
import Table from "cli-table3";
2020
import { createDeltaProcessor } from "../utils/delta";
21-
import trackEvent from "../utils/observability";
21+
import trackEvent, { UserIdentity } from "../utils/observability";
2222
import { minimatch } from "minimatch";
2323
import { exitGracefully } from "../utils/exit-gracefully";
2424

@@ -63,7 +63,7 @@ export default new Command()
6363
.action(async function (options) {
6464
const ora = Ora();
6565
const flags = parseFlags(options);
66-
let email: string | null = null;
66+
let userIdentity: UserIdentity = null;
6767

6868
try {
6969
ora.start("Loading configuration...");
@@ -76,7 +76,7 @@ export default new Command()
7676
ora.start("Checking authentication status...");
7777
const auth = await tryAuthenticate(settings);
7878
if (auth) {
79-
email = auth.email;
79+
userIdentity = { email: auth.email, id: auth.id };
8080
ora.succeed(`Authenticated as ${auth.email}`);
8181
} else {
8282
ora.info(
@@ -92,7 +92,7 @@ export default new Command()
9292
ora.succeed("Localization configuration is valid");
9393

9494
// Track event with or without authentication
95-
trackEvent(email, "cmd.status.start", {
95+
trackEvent(userIdentity, "cmd.status.start", {
9696
i18nConfig,
9797
flags,
9898
});
@@ -356,10 +356,11 @@ export default new Command()
356356
)} (${completeKeys.length}/${totalKeysInFile} keys)`,
357357
);
358358
} else {
359-
const message = `[${sourceLocale} -> ${targetLocale}] ${parseFloat(completionPercent) > 50
359+
const message = `[${sourceLocale} -> ${targetLocale}] ${
360+
parseFloat(completionPercent) > 50
360361
? chalk.yellow(`${completionPercent}% complete`)
361362
: chalk.red(`${completionPercent}% complete`)
362-
} (${completeKeys.length}/${totalKeysInFile} keys)`;
363+
} (${completeKeys.length}/${totalKeysInFile} keys)`;
363364

364365
bucketOra.succeed(message);
365366

@@ -369,7 +370,8 @@ export default new Command()
369370
` ${chalk.red(`Missing:`)} ${missingKeys.length} keys, ~${wordsToTranslate} words`,
370371
);
371372
console.log(
372-
` ${chalk.red(`Missing:`)} ${missingKeys.length
373+
` ${chalk.red(`Missing:`)} ${
374+
missingKeys.length
373375
} keys, ~${wordsToTranslate} words`,
374376
);
375377
console.log(
@@ -382,7 +384,8 @@ export default new Command()
382384
}
383385
if (updatedKeys.length > 0) {
384386
console.log(
385-
` ${chalk.yellow(`Updated:`)} ${updatedKeys.length
387+
` ${chalk.yellow(`Updated:`)} ${
388+
updatedKeys.length
386389
} keys that changed in source`,
387390
);
388391
}
@@ -536,7 +539,8 @@ export default new Command()
536539

537540
console.log(chalk.bold(`\n• ${path}:`));
538541
console.log(
539-
` ${stats.sourceKeys
542+
` ${
543+
stats.sourceKeys
540544
} source keys, ~${stats.wordCount.toLocaleString()} source words`,
541545
);
542546

@@ -603,14 +607,16 @@ export default new Command()
603607

604608
if (missingLanguages.length > 0) {
605609
console.log(
606-
`• ${chalk.yellow(missingLanguages.join(", "))} ${missingLanguages.length === 1 ? "has" : "have"
610+
`• ${chalk.yellow(missingLanguages.join(", "))} ${
611+
missingLanguages.length === 1 ? "has" : "have"
607612
} no translations yet`,
608613
);
609614
}
610615

611616
if (completeLanguages.length > 0) {
612617
console.log(
613-
`• ${chalk.green(completeLanguages.join(", "))} ${completeLanguages.length === 1 ? "is" : "are"
618+
`• ${chalk.green(completeLanguages.join(", "))} ${
619+
completeLanguages.length === 1 ? "is" : "are"
614620
} completely translated`,
615621
);
616622
}
@@ -624,22 +630,22 @@ export default new Command()
624630
}
625631

626632
// Track successful completion
627-
trackEvent(email, "cmd.status.success", {
633+
trackEvent(userIdentity, "cmd.status.success", {
628634
i18nConfig,
629635
flags,
630636
totalSourceKeyCount,
631637
languageStats,
632638
totalWordsToTranslate,
633-
authenticated: !!email,
639+
authenticated: !!userIdentity,
634640
});
635641
await new Promise((resolve) => setTimeout(resolve, 50));
636642
exitGracefully();
637643
} catch (error: any) {
638644
ora.fail(error.message);
639-
trackEvent(email, "cmd.status.error", {
645+
trackEvent(userIdentity, "cmd.status.error", {
640646
flags,
641647
error: error.message,
642-
authenticated: !!email,
648+
authenticated: !!userIdentity,
643649
});
644650
await new Promise((resolve) => setTimeout(resolve, 50));
645651
process.exit(1);

packages/cli/src/cli/localizer/_types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export interface ILocalizer {
2121
checkAuth: () => Promise<{
2222
authenticated: boolean;
2323
username?: string;
24+
userId?: string;
2425
error?: string;
2526
}>;
2627
validateSettings?: () => Promise<{ valid: boolean; error?: string }>;

packages/cli/src/cli/localizer/lingodotdev.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,11 @@ export default function createLingoDotDevLocalizer(
4646
"Invalid API key. Run `lingo.dev login` or check your LINGO_API_KEY.",
4747
};
4848
}
49-
return { authenticated: true, username: response.email };
49+
return {
50+
authenticated: true,
51+
username: response.email,
52+
userId: response.id,
53+
};
5054
} catch (error) {
5155
const errorMessage =
5256
error instanceof Error ? error.message : String(error);

0 commit comments

Comments
 (0)