@lingo.dev/compiler 0.1.3 → 0.1.5
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/build/plugin/unplugin.cjs +78 -0
- package/build/plugin/unplugin.d.cts.map +1 -1
- package/build/plugin/unplugin.d.mts.map +1 -1
- package/build/plugin/unplugin.mjs +78 -0
- package/build/plugin/unplugin.mjs.map +1 -1
- package/build/react/server/ServerLingoProvider.d.cts +2 -2
- package/build/react/server/ServerLingoProvider.d.mts +2 -2
- package/build/react/shared/LingoProvider.d.cts +2 -2
- package/build/react/shared/LingoProvider.d.mts +2 -2
- package/build/react/shared/LocaleSwitcher.d.cts +2 -2
- package/build/react/shared/LocaleSwitcher.d.mts +2 -2
- package/build/utils/observability.cjs +84 -0
- package/build/utils/observability.mjs +83 -0
- package/build/utils/observability.mjs.map +1 -0
- package/build/utils/rc.cjs +21 -0
- package/build/utils/rc.mjs +17 -0
- package/build/utils/rc.mjs.map +1 -0
- package/build/utils/repository-id.cjs +64 -0
- package/build/utils/repository-id.mjs +64 -0
- package/build/utils/repository-id.mjs.map +1 -0
- package/build/utils/tracking-events.cjs +28 -0
- package/build/utils/tracking-events.mjs +25 -0
- package/build/utils/tracking-events.mjs.map +1 -0
- package/package.json +41 -37
|
@@ -9,6 +9,8 @@ const require_cleanup = require('./cleanup.cjs');
|
|
|
9
9
|
const require_use_i18n = require('./transform/use-i18n.cjs');
|
|
10
10
|
const require_index = require('./transform/index.cjs');
|
|
11
11
|
const require_code_generator = require('../virtual/code-generator.cjs');
|
|
12
|
+
const require_tracking_events = require('../utils/tracking-events.cjs');
|
|
13
|
+
const require_observability = require('../utils/observability.cjs');
|
|
12
14
|
let path = require("path");
|
|
13
15
|
path = require_rolldown_runtime.__toESM(path);
|
|
14
16
|
let fs = require("fs");
|
|
@@ -18,6 +20,12 @@ let unplugin = require("unplugin");
|
|
|
18
20
|
//#region src/plugin/unplugin.ts
|
|
19
21
|
let translationServer;
|
|
20
22
|
const PLUGIN_NAME = "lingo-compiler";
|
|
23
|
+
let alreadySentBuildStartEvent = false;
|
|
24
|
+
let buildStartTime = null;
|
|
25
|
+
let filesTransformedCount = 0;
|
|
26
|
+
let totalEntriesCount = 0;
|
|
27
|
+
let hasTransformErrors = false;
|
|
28
|
+
let currentFramework = null;
|
|
21
29
|
function tryLocalOrReturnVirtual(config, fileName, virtualName) {
|
|
22
30
|
const customPath = path.default.join(config.sourceRoot, config.lingoDir, fileName);
|
|
23
31
|
if (fs.default.existsSync(customPath)) return customPath;
|
|
@@ -49,6 +57,18 @@ const virtualModules = {
|
|
|
49
57
|
const virtualModulesResolvers = Object.fromEntries(Object.entries(virtualModules).map(([importPath, module$1]) => [importPath, (config) => module$1.customFileCheck ? tryLocalOrReturnVirtual(config, module$1.customFileCheck, module$1.virtualId) : module$1.virtualId]));
|
|
50
58
|
const virtualModulesLoaders = Object.fromEntries(Object.values(virtualModules).map((value) => [value.virtualId, value.loader]));
|
|
51
59
|
/**
|
|
60
|
+
* Send build start tracking event
|
|
61
|
+
*/
|
|
62
|
+
function sendBuildStartEvent(framework, config) {
|
|
63
|
+
if (alreadySentBuildStartEvent) return;
|
|
64
|
+
alreadySentBuildStartEvent = true;
|
|
65
|
+
require_observability.default(require_tracking_events.TRACKING_EVENTS.BUILD_START, {
|
|
66
|
+
framework,
|
|
67
|
+
configuration: require_tracking_events.sanitizeConfigForTracking(config),
|
|
68
|
+
environment: config.environment
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
52
72
|
* Universal plugin for Lingo.dev compiler
|
|
53
73
|
* Supports Vite, Webpack
|
|
54
74
|
*/
|
|
@@ -89,6 +109,12 @@ const lingoUnplugin = (0, unplugin.createUnplugin)((options) => {
|
|
|
89
109
|
},
|
|
90
110
|
async buildStart() {
|
|
91
111
|
const metadataFilePath = getMetadataPath$1();
|
|
112
|
+
currentFramework = "vite";
|
|
113
|
+
sendBuildStartEvent("vite", config);
|
|
114
|
+
buildStartTime = Date.now();
|
|
115
|
+
filesTransformedCount = 0;
|
|
116
|
+
totalEntriesCount = 0;
|
|
117
|
+
hasTransformErrors = false;
|
|
92
118
|
require_manager.cleanupExistingMetadata(metadataFilePath);
|
|
93
119
|
require_cleanup.registerCleanupOnCurrentProcess({ cleanup: () => require_manager.cleanupExistingMetadata(metadataFilePath) });
|
|
94
120
|
if (isDev && !translationServer) translationServer = await startServer();
|
|
@@ -101,9 +127,27 @@ const lingoUnplugin = (0, unplugin.createUnplugin)((options) => {
|
|
|
101
127
|
publicOutputPath: "public/translations",
|
|
102
128
|
metadataFilePath
|
|
103
129
|
});
|
|
130
|
+
if (buildStartTime && !hasTransformErrors) require_observability.default(require_tracking_events.TRACKING_EVENTS.BUILD_SUCCESS, {
|
|
131
|
+
framework: "vite",
|
|
132
|
+
stats: {
|
|
133
|
+
totalEntries: totalEntriesCount,
|
|
134
|
+
filesTransformed: filesTransformedCount,
|
|
135
|
+
buildDuration: Date.now() - buildStartTime
|
|
136
|
+
},
|
|
137
|
+
environment: config.environment
|
|
138
|
+
});
|
|
104
139
|
} catch (error) {
|
|
105
140
|
require_logger.logger.error("Build-time translation processing failed:", error);
|
|
106
141
|
}
|
|
142
|
+
else if (buildStartTime && !hasTransformErrors) require_observability.default(require_tracking_events.TRACKING_EVENTS.BUILD_SUCCESS, {
|
|
143
|
+
framework: "vite",
|
|
144
|
+
stats: {
|
|
145
|
+
totalEntries: totalEntriesCount,
|
|
146
|
+
filesTransformed: filesTransformedCount,
|
|
147
|
+
buildDuration: Date.now() - buildStartTime
|
|
148
|
+
},
|
|
149
|
+
environment: config.environment
|
|
150
|
+
});
|
|
107
151
|
}
|
|
108
152
|
},
|
|
109
153
|
webpack(compiler) {
|
|
@@ -111,6 +155,12 @@ const lingoUnplugin = (0, unplugin.createUnplugin)((options) => {
|
|
|
111
155
|
const metadataFilePath = getMetadataPath$1();
|
|
112
156
|
config.environment = webpackMode;
|
|
113
157
|
compiler.hooks.initialize.tap(PLUGIN_NAME, () => {
|
|
158
|
+
currentFramework = "webpack";
|
|
159
|
+
sendBuildStartEvent("webpack", config);
|
|
160
|
+
buildStartTime = Date.now();
|
|
161
|
+
filesTransformedCount = 0;
|
|
162
|
+
totalEntriesCount = 0;
|
|
163
|
+
hasTransformErrors = false;
|
|
114
164
|
require_manager.cleanupExistingMetadata(metadataFilePath);
|
|
115
165
|
require_cleanup.registerCleanupOnCurrentProcess({ cleanup: () => require_manager.cleanupExistingMetadata(metadataFilePath) });
|
|
116
166
|
});
|
|
@@ -124,10 +174,28 @@ const lingoUnplugin = (0, unplugin.createUnplugin)((options) => {
|
|
|
124
174
|
publicOutputPath: "public/translations",
|
|
125
175
|
metadataFilePath
|
|
126
176
|
});
|
|
177
|
+
if (buildStartTime && !hasTransformErrors) require_observability.default(require_tracking_events.TRACKING_EVENTS.BUILD_SUCCESS, {
|
|
178
|
+
framework: "webpack",
|
|
179
|
+
stats: {
|
|
180
|
+
totalEntries: totalEntriesCount,
|
|
181
|
+
filesTransformed: filesTransformedCount,
|
|
182
|
+
buildDuration: Date.now() - buildStartTime
|
|
183
|
+
},
|
|
184
|
+
environment: config.environment
|
|
185
|
+
});
|
|
127
186
|
} catch (error) {
|
|
128
187
|
require_logger.logger.error("Build-time translation processing failed:", error);
|
|
129
188
|
throw error;
|
|
130
189
|
}
|
|
190
|
+
else if (buildStartTime && !hasTransformErrors) require_observability.default(require_tracking_events.TRACKING_EVENTS.BUILD_SUCCESS, {
|
|
191
|
+
framework: "webpack",
|
|
192
|
+
stats: {
|
|
193
|
+
totalEntries: totalEntriesCount,
|
|
194
|
+
filesTransformed: filesTransformedCount,
|
|
195
|
+
buildDuration: Date.now() - buildStartTime
|
|
196
|
+
},
|
|
197
|
+
environment: config.environment
|
|
198
|
+
});
|
|
131
199
|
});
|
|
132
200
|
compiler.hooks.shutdown.tapPromise(PLUGIN_NAME, async () => {
|
|
133
201
|
require_manager.cleanupExistingMetadata(metadataFilePath);
|
|
@@ -169,6 +237,8 @@ const lingoUnplugin = (0, unplugin.createUnplugin)((options) => {
|
|
|
169
237
|
const metadataManager = new require_manager.MetadataManager(getMetadataPath$1());
|
|
170
238
|
if (result.newEntries && result.newEntries.length > 0) {
|
|
171
239
|
await metadataManager.saveMetadataWithEntries(result.newEntries);
|
|
240
|
+
totalEntriesCount += result.newEntries.length;
|
|
241
|
+
filesTransformedCount++;
|
|
172
242
|
require_logger.logger.debug(`Found ${result.newEntries.length} translatable text(s) in ${id}`);
|
|
173
243
|
}
|
|
174
244
|
require_logger.logger.debug(`Returning transformed code for ${id}`);
|
|
@@ -177,6 +247,14 @@ const lingoUnplugin = (0, unplugin.createUnplugin)((options) => {
|
|
|
177
247
|
map: result.map
|
|
178
248
|
};
|
|
179
249
|
} catch (error) {
|
|
250
|
+
hasTransformErrors = true;
|
|
251
|
+
if (currentFramework) require_observability.default(require_tracking_events.TRACKING_EVENTS.BUILD_ERROR, {
|
|
252
|
+
framework: currentFramework,
|
|
253
|
+
errorType: "transform",
|
|
254
|
+
errorMessage: error instanceof Error ? error.message : "Unknown transform error",
|
|
255
|
+
filePath: id,
|
|
256
|
+
environment: config.environment
|
|
257
|
+
});
|
|
180
258
|
require_logger.logger.error(`Transform error in ${id}:`, error);
|
|
181
259
|
return null;
|
|
182
260
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unplugin.d.cts","names":[],"sources":["../../src/plugin/unplugin.ts"],"sourcesContent":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"unplugin.d.cts","names":[],"sources":["../../src/plugin/unplugin.ts"],"sourcesContent":[],"mappings":";;;;KAmCY,kBAAA,GAAqB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unplugin.d.mts","names":[],"sources":["../../src/plugin/unplugin.ts"],"sourcesContent":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"unplugin.d.mts","names":[],"sources":["../../src/plugin/unplugin.ts"],"sourcesContent":[],"mappings":";;;;KAmCY,kBAAA,GAAqB"}
|
|
@@ -8,6 +8,8 @@ import { registerCleanupOnCurrentProcess } from "./cleanup.mjs";
|
|
|
8
8
|
import { useI18nRegex } from "./transform/use-i18n.mjs";
|
|
9
9
|
import { transformComponent } from "./transform/index.mjs";
|
|
10
10
|
import { generateClientLocaleModule, generateConfigModule, generateServerLocaleModule } from "../virtual/code-generator.mjs";
|
|
11
|
+
import { TRACKING_EVENTS, sanitizeConfigForTracking } from "../utils/tracking-events.mjs";
|
|
12
|
+
import trackEvent from "../utils/observability.mjs";
|
|
11
13
|
import path from "path";
|
|
12
14
|
import fs from "fs";
|
|
13
15
|
import { createUnplugin } from "unplugin";
|
|
@@ -15,6 +17,12 @@ import { createUnplugin } from "unplugin";
|
|
|
15
17
|
//#region src/plugin/unplugin.ts
|
|
16
18
|
let translationServer;
|
|
17
19
|
const PLUGIN_NAME = "lingo-compiler";
|
|
20
|
+
let alreadySentBuildStartEvent = false;
|
|
21
|
+
let buildStartTime = null;
|
|
22
|
+
let filesTransformedCount = 0;
|
|
23
|
+
let totalEntriesCount = 0;
|
|
24
|
+
let hasTransformErrors = false;
|
|
25
|
+
let currentFramework = null;
|
|
18
26
|
function tryLocalOrReturnVirtual(config, fileName, virtualName) {
|
|
19
27
|
const customPath = path.join(config.sourceRoot, config.lingoDir, fileName);
|
|
20
28
|
if (fs.existsSync(customPath)) return customPath;
|
|
@@ -46,6 +54,18 @@ const virtualModules = {
|
|
|
46
54
|
const virtualModulesResolvers = Object.fromEntries(Object.entries(virtualModules).map(([importPath, module]) => [importPath, (config) => module.customFileCheck ? tryLocalOrReturnVirtual(config, module.customFileCheck, module.virtualId) : module.virtualId]));
|
|
47
55
|
const virtualModulesLoaders = Object.fromEntries(Object.values(virtualModules).map((value) => [value.virtualId, value.loader]));
|
|
48
56
|
/**
|
|
57
|
+
* Send build start tracking event
|
|
58
|
+
*/
|
|
59
|
+
function sendBuildStartEvent(framework, config) {
|
|
60
|
+
if (alreadySentBuildStartEvent) return;
|
|
61
|
+
alreadySentBuildStartEvent = true;
|
|
62
|
+
trackEvent(TRACKING_EVENTS.BUILD_START, {
|
|
63
|
+
framework,
|
|
64
|
+
configuration: sanitizeConfigForTracking(config),
|
|
65
|
+
environment: config.environment
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
49
69
|
* Universal plugin for Lingo.dev compiler
|
|
50
70
|
* Supports Vite, Webpack
|
|
51
71
|
*/
|
|
@@ -86,6 +106,12 @@ const lingoUnplugin = createUnplugin((options) => {
|
|
|
86
106
|
},
|
|
87
107
|
async buildStart() {
|
|
88
108
|
const metadataFilePath = getMetadataPath$1();
|
|
109
|
+
currentFramework = "vite";
|
|
110
|
+
sendBuildStartEvent("vite", config);
|
|
111
|
+
buildStartTime = Date.now();
|
|
112
|
+
filesTransformedCount = 0;
|
|
113
|
+
totalEntriesCount = 0;
|
|
114
|
+
hasTransformErrors = false;
|
|
89
115
|
cleanupExistingMetadata(metadataFilePath);
|
|
90
116
|
registerCleanupOnCurrentProcess({ cleanup: () => cleanupExistingMetadata(metadataFilePath) });
|
|
91
117
|
if (isDev && !translationServer) translationServer = await startServer();
|
|
@@ -98,9 +124,27 @@ const lingoUnplugin = createUnplugin((options) => {
|
|
|
98
124
|
publicOutputPath: "public/translations",
|
|
99
125
|
metadataFilePath
|
|
100
126
|
});
|
|
127
|
+
if (buildStartTime && !hasTransformErrors) trackEvent(TRACKING_EVENTS.BUILD_SUCCESS, {
|
|
128
|
+
framework: "vite",
|
|
129
|
+
stats: {
|
|
130
|
+
totalEntries: totalEntriesCount,
|
|
131
|
+
filesTransformed: filesTransformedCount,
|
|
132
|
+
buildDuration: Date.now() - buildStartTime
|
|
133
|
+
},
|
|
134
|
+
environment: config.environment
|
|
135
|
+
});
|
|
101
136
|
} catch (error) {
|
|
102
137
|
logger.error("Build-time translation processing failed:", error);
|
|
103
138
|
}
|
|
139
|
+
else if (buildStartTime && !hasTransformErrors) trackEvent(TRACKING_EVENTS.BUILD_SUCCESS, {
|
|
140
|
+
framework: "vite",
|
|
141
|
+
stats: {
|
|
142
|
+
totalEntries: totalEntriesCount,
|
|
143
|
+
filesTransformed: filesTransformedCount,
|
|
144
|
+
buildDuration: Date.now() - buildStartTime
|
|
145
|
+
},
|
|
146
|
+
environment: config.environment
|
|
147
|
+
});
|
|
104
148
|
}
|
|
105
149
|
},
|
|
106
150
|
webpack(compiler) {
|
|
@@ -108,6 +152,12 @@ const lingoUnplugin = createUnplugin((options) => {
|
|
|
108
152
|
const metadataFilePath = getMetadataPath$1();
|
|
109
153
|
config.environment = webpackMode;
|
|
110
154
|
compiler.hooks.initialize.tap(PLUGIN_NAME, () => {
|
|
155
|
+
currentFramework = "webpack";
|
|
156
|
+
sendBuildStartEvent("webpack", config);
|
|
157
|
+
buildStartTime = Date.now();
|
|
158
|
+
filesTransformedCount = 0;
|
|
159
|
+
totalEntriesCount = 0;
|
|
160
|
+
hasTransformErrors = false;
|
|
111
161
|
cleanupExistingMetadata(metadataFilePath);
|
|
112
162
|
registerCleanupOnCurrentProcess({ cleanup: () => cleanupExistingMetadata(metadataFilePath) });
|
|
113
163
|
});
|
|
@@ -121,10 +171,28 @@ const lingoUnplugin = createUnplugin((options) => {
|
|
|
121
171
|
publicOutputPath: "public/translations",
|
|
122
172
|
metadataFilePath
|
|
123
173
|
});
|
|
174
|
+
if (buildStartTime && !hasTransformErrors) trackEvent(TRACKING_EVENTS.BUILD_SUCCESS, {
|
|
175
|
+
framework: "webpack",
|
|
176
|
+
stats: {
|
|
177
|
+
totalEntries: totalEntriesCount,
|
|
178
|
+
filesTransformed: filesTransformedCount,
|
|
179
|
+
buildDuration: Date.now() - buildStartTime
|
|
180
|
+
},
|
|
181
|
+
environment: config.environment
|
|
182
|
+
});
|
|
124
183
|
} catch (error) {
|
|
125
184
|
logger.error("Build-time translation processing failed:", error);
|
|
126
185
|
throw error;
|
|
127
186
|
}
|
|
187
|
+
else if (buildStartTime && !hasTransformErrors) trackEvent(TRACKING_EVENTS.BUILD_SUCCESS, {
|
|
188
|
+
framework: "webpack",
|
|
189
|
+
stats: {
|
|
190
|
+
totalEntries: totalEntriesCount,
|
|
191
|
+
filesTransformed: filesTransformedCount,
|
|
192
|
+
buildDuration: Date.now() - buildStartTime
|
|
193
|
+
},
|
|
194
|
+
environment: config.environment
|
|
195
|
+
});
|
|
128
196
|
});
|
|
129
197
|
compiler.hooks.shutdown.tapPromise(PLUGIN_NAME, async () => {
|
|
130
198
|
cleanupExistingMetadata(metadataFilePath);
|
|
@@ -166,6 +234,8 @@ const lingoUnplugin = createUnplugin((options) => {
|
|
|
166
234
|
const metadataManager = new MetadataManager(getMetadataPath$1());
|
|
167
235
|
if (result.newEntries && result.newEntries.length > 0) {
|
|
168
236
|
await metadataManager.saveMetadataWithEntries(result.newEntries);
|
|
237
|
+
totalEntriesCount += result.newEntries.length;
|
|
238
|
+
filesTransformedCount++;
|
|
169
239
|
logger.debug(`Found ${result.newEntries.length} translatable text(s) in ${id}`);
|
|
170
240
|
}
|
|
171
241
|
logger.debug(`Returning transformed code for ${id}`);
|
|
@@ -174,6 +244,14 @@ const lingoUnplugin = createUnplugin((options) => {
|
|
|
174
244
|
map: result.map
|
|
175
245
|
};
|
|
176
246
|
} catch (error) {
|
|
247
|
+
hasTransformErrors = true;
|
|
248
|
+
if (currentFramework) trackEvent(TRACKING_EVENTS.BUILD_ERROR, {
|
|
249
|
+
framework: currentFramework,
|
|
250
|
+
errorType: "transform",
|
|
251
|
+
errorMessage: error instanceof Error ? error.message : "Unknown transform error",
|
|
252
|
+
filePath: id,
|
|
253
|
+
environment: config.environment
|
|
254
|
+
});
|
|
177
255
|
logger.error(`Transform error in ${id}:`, error);
|
|
178
256
|
return null;
|
|
179
257
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unplugin.mjs","names":["translationServer: TranslationServer","webpackMode: \"development\" | \"production\" | undefined","getMetadataPath","rawGetMetadataPath"],"sources":["../../src/plugin/unplugin.ts"],"sourcesContent":["import { createUnplugin } from \"unplugin\";\nimport { transformComponent } from \"./transform\";\nimport type {\n LingoConfig,\n LingoInternalFields,\n PartialLingoConfig,\n} from \"../types\";\nimport {\n startTranslationServer,\n type TranslationServer,\n} from \"../translation-server\";\nimport {\n cleanupExistingMetadata,\n getMetadataPath as rawGetMetadataPath,\n MetadataManager,\n} from \"../metadata/manager\";\nimport { createLingoConfig } from \"../utils/config-factory\";\nimport { logger } from \"../utils/logger\";\nimport { useI18nRegex } from \"./transform/use-i18n\";\nimport {\n generateClientLocaleModule,\n generateConfigModule,\n generateServerLocaleModule,\n} from \"../virtual/code-generator\";\nimport { processBuildTranslations } from \"./build-translator\";\nimport { registerCleanupOnCurrentProcess } from \"./cleanup\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport { TranslationService } from \"../translators\";\n\nexport type LingoPluginOptions = PartialLingoConfig;\n\nlet translationServer: TranslationServer;\n\nconst PLUGIN_NAME = \"lingo-compiler\";\n\nfunction tryLocalOrReturnVirtual(\n config: LingoConfig,\n fileName: string,\n virtualName: string,\n) {\n const customPath = path.join(config.sourceRoot, config.lingoDir, fileName);\n if (fs.existsSync(customPath)) {\n return customPath;\n }\n return virtualName;\n}\n\n/**\n * Single source of truth for virtual modules\n * Each entry defines both resolver (import path → virtual ID) and loader (virtual ID → code)\n *\n * If customFileCheck is defined, the specified file will be first searched for, and if not found virtual module will be used.\n */\nconst virtualModules = {\n \"@lingo.dev/compiler/virtual/config\": {\n virtualId: \"\\0virtual:lingo-config\",\n loader: (config: LingoConfig) => generateConfigModule(config),\n customFileCheck: undefined,\n },\n \"@lingo.dev/compiler/virtual/locale/server\": {\n virtualId: \"\\0virtual:locale-resolver.server\" as const,\n loader: (config: LingoConfig) => generateServerLocaleModule(config),\n customFileCheck: \"locale-resolver.server.ts\" as const,\n },\n \"@lingo.dev/compiler/virtual/locale/client\": {\n virtualId: \"\\0virtual:locale-resolver.client\" as const,\n loader: (config: LingoConfig) => generateClientLocaleModule(config),\n customFileCheck: \"locale-resolver.client.ts\" as const,\n },\n} as const;\n\n// Derive resolver and loader maps from the single source\nconst virtualModulesResolvers = Object.fromEntries(\n Object.entries(virtualModules).map(([importPath, module]) => [\n importPath,\n (config: LingoConfig) =>\n module.customFileCheck\n ? tryLocalOrReturnVirtual(\n config,\n module.customFileCheck,\n module.virtualId,\n )\n : module.virtualId,\n ]),\n);\n\nconst virtualModulesLoaders = Object.fromEntries(\n Object.values(virtualModules).map((value) => [value.virtualId, value.loader]),\n);\n\n/**\n * Universal plugin for Lingo.dev compiler\n * Supports Vite, Webpack\n */\nexport const lingoUnplugin = createUnplugin<\n LingoPluginOptions & Partial<Pick<LingoConfig, LingoInternalFields>>\n>((options) => {\n const config = createLingoConfig(options);\n\n // Won't work for webpack most likely. Use mode there to set correct environment in configs.\n const isDev = config.environment === \"development\";\n const startPort = config.dev.translationServerStartPort;\n\n // For webpack: store the actual mode and use it to compute the correct metadata path\n let webpackMode: \"development\" | \"production\" | undefined;\n // Should be dynamic, because webpack only tells us the mode inside the plugin, not inside the config.\n const getMetadataPath = () => {\n return rawGetMetadataPath(\n webpackMode ? { ...config, environment: webpackMode } : config,\n );\n };\n\n async function startServer() {\n const server = await startTranslationServer({\n translationService: new TranslationService(config, logger),\n onError: (err) => {\n logger.error(\"Translation server error:\", err);\n },\n onReady: (port) => {\n logger.info(`Translation server started successfully on port: ${port}`);\n },\n config,\n });\n // I don't like this quite a lot. But starting server inside the loader seems lame.\n config.dev.translationServerUrl = server.getUrl();\n registerCleanupOnCurrentProcess({\n asyncCleanup: async () => {\n await translationServer.stop();\n },\n });\n return server;\n }\n\n return {\n name: PLUGIN_NAME,\n enforce: \"pre\", // Run before other plugins (especially before React plugin)\n\n vite: {\n // Vite handles deep merge\n config() {\n // Required for custom virtual like modules to be resolved; otherwise they are bundled with raw source code.\n return {\n optimizeDeps: {\n exclude: [\"@lingo.dev/compiler\"],\n },\n };\n },\n async buildStart() {\n const metadataFilePath = getMetadataPath();\n\n cleanupExistingMetadata(metadataFilePath);\n registerCleanupOnCurrentProcess({\n cleanup: () => cleanupExistingMetadata(metadataFilePath),\n });\n\n if (isDev && !translationServer) {\n translationServer = await startServer();\n }\n },\n\n async buildEnd() {\n const metadataFilePath = getMetadataPath();\n if (!isDev) {\n try {\n await processBuildTranslations({\n config,\n publicOutputPath: \"public/translations\",\n metadataFilePath,\n });\n } catch (error) {\n logger.error(\"Build-time translation processing failed:\", error);\n }\n }\n },\n },\n\n webpack(compiler) {\n webpackMode =\n compiler.options.mode === \"development\" ? \"development\" : \"production\";\n const metadataFilePath = getMetadataPath();\n // Yes, this is dirty play, but webpack runs only for this plugin, and this way we save people from using wrong config\n config.environment = webpackMode;\n\n compiler.hooks.initialize.tap(PLUGIN_NAME, () => {\n cleanupExistingMetadata(metadataFilePath);\n registerCleanupOnCurrentProcess({\n cleanup: () => cleanupExistingMetadata(metadataFilePath),\n });\n });\n\n compiler.hooks.watchRun.tapPromise(PLUGIN_NAME, async () => {\n if (webpackMode === \"development\" && !translationServer) {\n translationServer = await startServer();\n }\n });\n\n compiler.hooks.additionalPass.tapPromise(PLUGIN_NAME, async () => {\n if (webpackMode === \"production\") {\n try {\n await processBuildTranslations({\n config,\n publicOutputPath: \"public/translations\",\n metadataFilePath,\n });\n } catch (error) {\n logger.error(\"Build-time translation processing failed:\", error);\n throw error;\n }\n }\n });\n\n // Duplicates the cleanup process handlers does, but won't hurt since cleanup is idempotent.\n compiler.hooks.shutdown.tapPromise(PLUGIN_NAME, async () => {\n cleanupExistingMetadata(metadataFilePath);\n await translationServer?.stop();\n });\n },\n\n resolveId(id) {\n const handler = virtualModulesResolvers[id];\n if (handler) {\n return handler(config);\n }\n return null;\n },\n\n load: {\n filter: {\n // Without the filter webpack goes mad\n id: /virtual:/,\n },\n handler(id: string) {\n const handler = virtualModulesLoaders[id];\n if (handler) {\n return handler(config);\n }\n return null;\n },\n },\n\n transform: {\n filter: {\n id: {\n include: [/\\.[tj]sx$/],\n exclude: /node_modules/,\n },\n // If useDirective is enabled, only process files with \"use i18n\"\n // This is more efficient than checking in the handler\n code: config.useDirective ? useI18nRegex : undefined,\n },\n async handler(code, id) {\n try {\n // Transform the component\n const result = transformComponent({\n code,\n filePath: id,\n config,\n });\n\n // If no transformation occurred, return original code\n if (!result.transformed) {\n logger.debug(`No transformation needed for ${id}`);\n return null;\n }\n const metadataManager = new MetadataManager(getMetadataPath());\n\n // Update metadata with new entries (thread-safe)\n if (result.newEntries && result.newEntries.length > 0) {\n await metadataManager.saveMetadataWithEntries(result.newEntries);\n\n logger.debug(\n `Found ${result.newEntries.length} translatable text(s) in ${id}`,\n );\n }\n\n logger.debug(`Returning transformed code for ${id}`);\n return {\n code: result.code,\n map: result.map,\n };\n } catch (error) {\n logger.error(`Transform error in ${id}:`, error);\n return null;\n }\n },\n },\n };\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"unplugin.mjs","names":["translationServer: TranslationServer","buildStartTime: number | null","currentFramework: \"vite\" | \"webpack\" | \"next\" | null","webpackMode: \"development\" | \"production\" | undefined","getMetadataPath","rawGetMetadataPath"],"sources":["../../src/plugin/unplugin.ts"],"sourcesContent":["import { createUnplugin } from \"unplugin\";\nimport { transformComponent } from \"./transform\";\nimport type {\n LingoConfig,\n LingoInternalFields,\n PartialLingoConfig,\n} from \"../types\";\nimport {\n startTranslationServer,\n type TranslationServer,\n} from \"../translation-server\";\nimport {\n cleanupExistingMetadata,\n getMetadataPath as rawGetMetadataPath,\n MetadataManager,\n} from \"../metadata/manager\";\nimport { createLingoConfig } from \"../utils/config-factory\";\nimport { logger } from \"../utils/logger\";\nimport { useI18nRegex } from \"./transform/use-i18n\";\nimport {\n generateClientLocaleModule,\n generateConfigModule,\n generateServerLocaleModule,\n} from \"../virtual/code-generator\";\nimport { processBuildTranslations } from \"./build-translator\";\nimport { registerCleanupOnCurrentProcess } from \"./cleanup\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport { TranslationService } from \"../translators\";\nimport trackEvent from \"../utils/observability\";\nimport {\n TRACKING_EVENTS,\n sanitizeConfigForTracking,\n} from \"../utils/tracking-events\";\n\nexport type LingoPluginOptions = PartialLingoConfig;\n\nlet translationServer: TranslationServer;\n\nconst PLUGIN_NAME = \"lingo-compiler\";\n\n// Tracking state\nlet alreadySentBuildStartEvent = false;\nlet buildStartTime: number | null = null;\nlet filesTransformedCount = 0;\nlet totalEntriesCount = 0;\nlet hasTransformErrors = false;\nlet currentFramework: \"vite\" | \"webpack\" | \"next\" | null = null;\n\nfunction tryLocalOrReturnVirtual(\n config: LingoConfig,\n fileName: string,\n virtualName: string,\n) {\n const customPath = path.join(config.sourceRoot, config.lingoDir, fileName);\n if (fs.existsSync(customPath)) {\n return customPath;\n }\n return virtualName;\n}\n\n/**\n * Single source of truth for virtual modules\n * Each entry defines both resolver (import path → virtual ID) and loader (virtual ID → code)\n *\n * If customFileCheck is defined, the specified file will be first searched for, and if not found virtual module will be used.\n */\nconst virtualModules = {\n \"@lingo.dev/compiler/virtual/config\": {\n virtualId: \"\\0virtual:lingo-config\",\n loader: (config: LingoConfig) => generateConfigModule(config),\n customFileCheck: undefined,\n },\n \"@lingo.dev/compiler/virtual/locale/server\": {\n virtualId: \"\\0virtual:locale-resolver.server\" as const,\n loader: (config: LingoConfig) => generateServerLocaleModule(config),\n customFileCheck: \"locale-resolver.server.ts\" as const,\n },\n \"@lingo.dev/compiler/virtual/locale/client\": {\n virtualId: \"\\0virtual:locale-resolver.client\" as const,\n loader: (config: LingoConfig) => generateClientLocaleModule(config),\n customFileCheck: \"locale-resolver.client.ts\" as const,\n },\n} as const;\n\n// Derive resolver and loader maps from the single source\nconst virtualModulesResolvers = Object.fromEntries(\n Object.entries(virtualModules).map(([importPath, module]) => [\n importPath,\n (config: LingoConfig) =>\n module.customFileCheck\n ? tryLocalOrReturnVirtual(\n config,\n module.customFileCheck,\n module.virtualId,\n )\n : module.virtualId,\n ]),\n);\n\nconst virtualModulesLoaders = Object.fromEntries(\n Object.values(virtualModules).map((value) => [value.virtualId, value.loader]),\n);\n\n/**\n * Send build start tracking event\n */\nfunction sendBuildStartEvent(\n framework: \"vite\" | \"webpack\" | \"next\",\n config: LingoConfig,\n) {\n if (alreadySentBuildStartEvent) return;\n alreadySentBuildStartEvent = true;\n\n trackEvent(TRACKING_EVENTS.BUILD_START, {\n framework,\n configuration: sanitizeConfigForTracking(config),\n environment: config.environment,\n });\n}\n\n/**\n * Universal plugin for Lingo.dev compiler\n * Supports Vite, Webpack\n */\nexport const lingoUnplugin = createUnplugin<\n LingoPluginOptions & Partial<Pick<LingoConfig, LingoInternalFields>>\n>((options) => {\n const config = createLingoConfig(options);\n\n // Won't work for webpack most likely. Use mode there to set correct environment in configs.\n const isDev = config.environment === \"development\";\n const startPort = config.dev.translationServerStartPort;\n\n // For webpack: store the actual mode and use it to compute the correct metadata path\n let webpackMode: \"development\" | \"production\" | undefined;\n // Should be dynamic, because webpack only tells us the mode inside the plugin, not inside the config.\n const getMetadataPath = () => {\n return rawGetMetadataPath(\n webpackMode ? { ...config, environment: webpackMode } : config,\n );\n };\n\n async function startServer() {\n const server = await startTranslationServer({\n translationService: new TranslationService(config, logger),\n onError: (err) => {\n logger.error(\"Translation server error:\", err);\n },\n onReady: (port) => {\n logger.info(`Translation server started successfully on port: ${port}`);\n },\n config,\n });\n // I don't like this quite a lot. But starting server inside the loader seems lame.\n config.dev.translationServerUrl = server.getUrl();\n registerCleanupOnCurrentProcess({\n asyncCleanup: async () => {\n await translationServer.stop();\n },\n });\n return server;\n }\n\n return {\n name: PLUGIN_NAME,\n enforce: \"pre\", // Run before other plugins (especially before React plugin)\n\n vite: {\n // Vite handles deep merge\n config() {\n // Required for custom virtual like modules to be resolved; otherwise they are bundled with raw source code.\n return {\n optimizeDeps: {\n exclude: [\"@lingo.dev/compiler\"],\n },\n };\n },\n async buildStart() {\n const metadataFilePath = getMetadataPath();\n\n // Track build start\n currentFramework = \"vite\";\n sendBuildStartEvent(\"vite\", config);\n buildStartTime = Date.now();\n filesTransformedCount = 0;\n totalEntriesCount = 0;\n hasTransformErrors = false;\n\n cleanupExistingMetadata(metadataFilePath);\n registerCleanupOnCurrentProcess({\n cleanup: () => cleanupExistingMetadata(metadataFilePath),\n });\n\n if (isDev && !translationServer) {\n translationServer = await startServer();\n }\n },\n\n async buildEnd() {\n const metadataFilePath = getMetadataPath();\n if (!isDev) {\n try {\n await processBuildTranslations({\n config,\n publicOutputPath: \"public/translations\",\n metadataFilePath,\n });\n\n if (buildStartTime && !hasTransformErrors) {\n trackEvent(TRACKING_EVENTS.BUILD_SUCCESS, {\n framework: \"vite\",\n stats: {\n totalEntries: totalEntriesCount,\n filesTransformed: filesTransformedCount,\n buildDuration: Date.now() - buildStartTime,\n },\n environment: config.environment,\n });\n }\n } catch (error) {\n logger.error(\"Build-time translation processing failed:\", error);\n }\n } else if (buildStartTime && !hasTransformErrors) {\n trackEvent(TRACKING_EVENTS.BUILD_SUCCESS, {\n framework: \"vite\",\n stats: {\n totalEntries: totalEntriesCount,\n filesTransformed: filesTransformedCount,\n buildDuration: Date.now() - buildStartTime,\n },\n environment: config.environment,\n });\n }\n },\n },\n\n webpack(compiler) {\n webpackMode =\n compiler.options.mode === \"development\" ? \"development\" : \"production\";\n const metadataFilePath = getMetadataPath();\n // Yes, this is dirty play, but webpack runs only for this plugin, and this way we save people from using wrong config\n config.environment = webpackMode;\n\n compiler.hooks.initialize.tap(PLUGIN_NAME, () => {\n // Track build start\n currentFramework = \"webpack\";\n sendBuildStartEvent(\"webpack\", config);\n buildStartTime = Date.now();\n filesTransformedCount = 0;\n totalEntriesCount = 0;\n hasTransformErrors = false;\n\n cleanupExistingMetadata(metadataFilePath);\n registerCleanupOnCurrentProcess({\n cleanup: () => cleanupExistingMetadata(metadataFilePath),\n });\n });\n\n compiler.hooks.watchRun.tapPromise(PLUGIN_NAME, async () => {\n if (webpackMode === \"development\" && !translationServer) {\n translationServer = await startServer();\n }\n });\n\n compiler.hooks.additionalPass.tapPromise(PLUGIN_NAME, async () => {\n if (webpackMode === \"production\") {\n try {\n await processBuildTranslations({\n config,\n publicOutputPath: \"public/translations\",\n metadataFilePath,\n });\n\n if (buildStartTime && !hasTransformErrors) {\n trackEvent(TRACKING_EVENTS.BUILD_SUCCESS, {\n framework: \"webpack\",\n stats: {\n totalEntries: totalEntriesCount,\n filesTransformed: filesTransformedCount,\n buildDuration: Date.now() - buildStartTime,\n },\n environment: config.environment,\n });\n }\n } catch (error) {\n logger.error(\"Build-time translation processing failed:\", error);\n throw error;\n }\n } else if (buildStartTime && !hasTransformErrors) {\n trackEvent(TRACKING_EVENTS.BUILD_SUCCESS, {\n framework: \"webpack\",\n stats: {\n totalEntries: totalEntriesCount,\n filesTransformed: filesTransformedCount,\n buildDuration: Date.now() - buildStartTime,\n },\n environment: config.environment,\n });\n }\n });\n\n // Duplicates the cleanup process handlers does, but won't hurt since cleanup is idempotent.\n compiler.hooks.shutdown.tapPromise(PLUGIN_NAME, async () => {\n cleanupExistingMetadata(metadataFilePath);\n await translationServer?.stop();\n });\n },\n\n resolveId(id) {\n const handler = virtualModulesResolvers[id];\n if (handler) {\n return handler(config);\n }\n return null;\n },\n\n load: {\n filter: {\n // Without the filter webpack goes mad\n id: /virtual:/,\n },\n handler(id: string) {\n const handler = virtualModulesLoaders[id];\n if (handler) {\n return handler(config);\n }\n return null;\n },\n },\n\n transform: {\n filter: {\n id: {\n include: [/\\.[tj]sx$/],\n exclude: /node_modules/,\n },\n // If useDirective is enabled, only process files with \"use i18n\"\n // This is more efficient than checking in the handler\n code: config.useDirective ? useI18nRegex : undefined,\n },\n async handler(code, id) {\n try {\n // Transform the component\n const result = transformComponent({\n code,\n filePath: id,\n config,\n });\n\n // If no transformation occurred, return original code\n if (!result.transformed) {\n logger.debug(`No transformation needed for ${id}`);\n return null;\n }\n const metadataManager = new MetadataManager(getMetadataPath());\n\n // Update metadata with new entries (thread-safe)\n if (result.newEntries && result.newEntries.length > 0) {\n await metadataManager.saveMetadataWithEntries(result.newEntries);\n\n // Track stats for observability\n totalEntriesCount += result.newEntries.length;\n filesTransformedCount++;\n\n logger.debug(\n `Found ${result.newEntries.length} translatable text(s) in ${id}`,\n );\n }\n\n logger.debug(`Returning transformed code for ${id}`);\n return {\n code: result.code,\n map: result.map,\n };\n } catch (error) {\n hasTransformErrors = true;\n\n // Track error event\n if (currentFramework) {\n trackEvent(TRACKING_EVENTS.BUILD_ERROR, {\n framework: currentFramework,\n errorType: \"transform\",\n errorMessage: error instanceof Error ? error.message : \"Unknown transform error\",\n filePath: id,\n environment: config.environment,\n });\n }\n\n logger.error(`Transform error in ${id}:`, error);\n return null;\n }\n },\n },\n };\n});\n"],"mappings":"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"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { LingoProviderProps } from "../shared/LingoProvider.cjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime1 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/react/server/ServerLingoProvider.d.ts
|
|
5
5
|
declare function LingoProvider({
|
|
6
6
|
initialLocale,
|
|
7
7
|
initialTranslations,
|
|
8
8
|
...rest
|
|
9
|
-
}: LingoProviderProps): Promise<
|
|
9
|
+
}: LingoProviderProps): Promise<react_jsx_runtime1.JSX.Element>;
|
|
10
10
|
//#endregion
|
|
11
11
|
export { LingoProvider };
|
|
12
12
|
//# sourceMappingURL=ServerLingoProvider.d.cts.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { LingoProviderProps } from "../shared/LingoProvider.mjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime1 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/react/server/ServerLingoProvider.d.ts
|
|
5
5
|
declare function LingoProvider({
|
|
6
6
|
initialLocale,
|
|
7
7
|
initialTranslations,
|
|
8
8
|
...rest
|
|
9
|
-
}: LingoProviderProps): Promise<
|
|
9
|
+
}: LingoProviderProps): Promise<react_jsx_runtime1.JSX.Element>;
|
|
10
10
|
//#endregion
|
|
11
11
|
export { LingoProvider };
|
|
12
12
|
//# sourceMappingURL=ServerLingoProvider.d.mts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LocaleCode } from "lingo.dev/spec";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime3 from "react/jsx-runtime";
|
|
3
3
|
import { PropsWithChildren } from "react";
|
|
4
4
|
|
|
5
5
|
//#region src/react/shared/LingoProvider.d.ts
|
|
@@ -70,7 +70,7 @@ declare function LingoProvider__Dev({
|
|
|
70
70
|
router,
|
|
71
71
|
devWidget,
|
|
72
72
|
children
|
|
73
|
-
}: LingoProviderProps):
|
|
73
|
+
}: LingoProviderProps): react_jsx_runtime3.JSX.Element;
|
|
74
74
|
//#endregion
|
|
75
75
|
export { LingoProvider, LingoProviderProps };
|
|
76
76
|
//# sourceMappingURL=LingoProvider.d.cts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PropsWithChildren } from "react";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime3 from "react/jsx-runtime";
|
|
3
3
|
import { LocaleCode } from "lingo.dev/spec";
|
|
4
4
|
|
|
5
5
|
//#region src/react/shared/LingoProvider.d.ts
|
|
@@ -70,7 +70,7 @@ declare function LingoProvider__Dev({
|
|
|
70
70
|
router,
|
|
71
71
|
devWidget,
|
|
72
72
|
children
|
|
73
|
-
}: LingoProviderProps):
|
|
73
|
+
}: LingoProviderProps): react_jsx_runtime3.JSX.Element;
|
|
74
74
|
//#endregion
|
|
75
75
|
export { LingoProvider, LingoProviderProps };
|
|
76
76
|
//# sourceMappingURL=LingoProvider.d.mts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LocaleCode } from "lingo.dev/spec";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime2 from "react/jsx-runtime";
|
|
3
3
|
import { CSSProperties } from "react";
|
|
4
4
|
|
|
5
5
|
//#region src/react/shared/LocaleSwitcher.d.ts
|
|
@@ -65,7 +65,7 @@ declare function LocaleSwitcher({
|
|
|
65
65
|
style,
|
|
66
66
|
className,
|
|
67
67
|
showLoadingState
|
|
68
|
-
}: LocaleSwitcherProps):
|
|
68
|
+
}: LocaleSwitcherProps): react_jsx_runtime2.JSX.Element;
|
|
69
69
|
//#endregion
|
|
70
70
|
export { LocaleSwitcher };
|
|
71
71
|
//# sourceMappingURL=LocaleSwitcher.d.cts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CSSProperties } from "react";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime2 from "react/jsx-runtime";
|
|
3
3
|
import { LocaleCode } from "lingo.dev/spec";
|
|
4
4
|
|
|
5
5
|
//#region src/react/shared/LocaleSwitcher.d.ts
|
|
@@ -65,7 +65,7 @@ declare function LocaleSwitcher({
|
|
|
65
65
|
style,
|
|
66
66
|
className,
|
|
67
67
|
showLoadingState
|
|
68
|
-
}: LocaleSwitcherProps):
|
|
68
|
+
}: LocaleSwitcherProps): react_jsx_runtime2.JSX.Element;
|
|
69
69
|
//#endregion
|
|
70
70
|
export { LocaleSwitcher };
|
|
71
71
|
//# sourceMappingURL=LocaleSwitcher.d.mts.map
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_rc = require('./rc.cjs');
|
|
3
|
+
const require_repository_id = require('./repository-id.cjs');
|
|
4
|
+
const require_tracking_events = require('./tracking-events.cjs');
|
|
5
|
+
let node_machine_id = require("node-machine-id");
|
|
6
|
+
node_machine_id = require_rolldown_runtime.__toESM(node_machine_id);
|
|
7
|
+
|
|
8
|
+
//#region src/utils/observability.ts
|
|
9
|
+
async function trackEvent(event, properties) {
|
|
10
|
+
if (process.env.DO_NOT_TRACK === "1") return;
|
|
11
|
+
try {
|
|
12
|
+
const identityInfo = await getDistinctId();
|
|
13
|
+
if (process.env.DEBUG === "true") console.log(`[Tracking] Event: ${event}, ID: ${identityInfo.distinct_id}, Source: ${identityInfo.distinct_id_source}`);
|
|
14
|
+
const { PostHog } = await import("posthog-node");
|
|
15
|
+
const posthog = new PostHog("phc_eR0iSoQufBxNY36k0f0T15UvHJdTfHlh8rJcxsfhfXk", {
|
|
16
|
+
host: "https://eu.i.posthog.com",
|
|
17
|
+
flushAt: 1,
|
|
18
|
+
flushInterval: 0
|
|
19
|
+
});
|
|
20
|
+
await posthog.capture({
|
|
21
|
+
distinctId: identityInfo.distinct_id,
|
|
22
|
+
event,
|
|
23
|
+
properties: {
|
|
24
|
+
...properties,
|
|
25
|
+
isByokMode: properties?.models !== "lingo.dev",
|
|
26
|
+
tracking_version: require_tracking_events.TRACKING_VERSION,
|
|
27
|
+
compiler_package: require_tracking_events.COMPILER_PACKAGE,
|
|
28
|
+
distinct_id_source: identityInfo.distinct_id_source,
|
|
29
|
+
project_id: identityInfo.project_id,
|
|
30
|
+
meta: {
|
|
31
|
+
version: process.env.npm_package_version,
|
|
32
|
+
isCi: process.env.CI === "true"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
await posthog.shutdown();
|
|
37
|
+
} catch (error) {
|
|
38
|
+
if (process.env.DEBUG === "true") console.error("[Tracking] Error:", error);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async function getDistinctId() {
|
|
42
|
+
const email = await tryGetEmail();
|
|
43
|
+
if (email) return {
|
|
44
|
+
distinct_id: email,
|
|
45
|
+
distinct_id_source: "email",
|
|
46
|
+
project_id: require_repository_id.getRepositoryId()
|
|
47
|
+
};
|
|
48
|
+
const repoId = require_repository_id.getRepositoryId();
|
|
49
|
+
if (repoId) return {
|
|
50
|
+
distinct_id: repoId,
|
|
51
|
+
distinct_id_source: "git_repo",
|
|
52
|
+
project_id: repoId
|
|
53
|
+
};
|
|
54
|
+
const deviceId = `device-${await node_machine_id.machineId()}`;
|
|
55
|
+
if (process.env.DEBUG === "true") console.warn("[Tracking] Using device ID fallback. Consider using git repository for consistent tracking.");
|
|
56
|
+
return {
|
|
57
|
+
distinct_id: deviceId,
|
|
58
|
+
distinct_id_source: "device",
|
|
59
|
+
project_id: null
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
async function tryGetEmail() {
|
|
63
|
+
const rc = require_rc.getRc();
|
|
64
|
+
const apiKey = process.env.LINGODOTDEV_API_KEY || rc?.auth?.apiKey;
|
|
65
|
+
const apiUrl = process.env.LINGODOTDEV_API_URL || rc?.auth?.apiUrl || "https://engine.lingo.dev";
|
|
66
|
+
if (!apiKey) return null;
|
|
67
|
+
try {
|
|
68
|
+
const res = await fetch(`${apiUrl}/whoami`, {
|
|
69
|
+
method: "POST",
|
|
70
|
+
headers: {
|
|
71
|
+
Authorization: `Bearer ${apiKey}`,
|
|
72
|
+
ContentType: "application/json"
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
if (res.ok) {
|
|
76
|
+
const payload = await res.json();
|
|
77
|
+
if (payload?.email) return payload.email;
|
|
78
|
+
}
|
|
79
|
+
} catch (err) {}
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
//#endregion
|
|
84
|
+
exports.default = trackEvent;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { getRc } from "./rc.mjs";
|
|
2
|
+
import { getRepositoryId } from "./repository-id.mjs";
|
|
3
|
+
import { COMPILER_PACKAGE, TRACKING_VERSION } from "./tracking-events.mjs";
|
|
4
|
+
import * as machineIdLib from "node-machine-id";
|
|
5
|
+
|
|
6
|
+
//#region src/utils/observability.ts
|
|
7
|
+
async function trackEvent(event, properties) {
|
|
8
|
+
if (process.env.DO_NOT_TRACK === "1") return;
|
|
9
|
+
try {
|
|
10
|
+
const identityInfo = await getDistinctId();
|
|
11
|
+
if (process.env.DEBUG === "true") console.log(`[Tracking] Event: ${event}, ID: ${identityInfo.distinct_id}, Source: ${identityInfo.distinct_id_source}`);
|
|
12
|
+
const { PostHog } = await import("posthog-node");
|
|
13
|
+
const posthog = new PostHog("phc_eR0iSoQufBxNY36k0f0T15UvHJdTfHlh8rJcxsfhfXk", {
|
|
14
|
+
host: "https://eu.i.posthog.com",
|
|
15
|
+
flushAt: 1,
|
|
16
|
+
flushInterval: 0
|
|
17
|
+
});
|
|
18
|
+
await posthog.capture({
|
|
19
|
+
distinctId: identityInfo.distinct_id,
|
|
20
|
+
event,
|
|
21
|
+
properties: {
|
|
22
|
+
...properties,
|
|
23
|
+
isByokMode: properties?.models !== "lingo.dev",
|
|
24
|
+
tracking_version: TRACKING_VERSION,
|
|
25
|
+
compiler_package: COMPILER_PACKAGE,
|
|
26
|
+
distinct_id_source: identityInfo.distinct_id_source,
|
|
27
|
+
project_id: identityInfo.project_id,
|
|
28
|
+
meta: {
|
|
29
|
+
version: process.env.npm_package_version,
|
|
30
|
+
isCi: process.env.CI === "true"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
await posthog.shutdown();
|
|
35
|
+
} catch (error) {
|
|
36
|
+
if (process.env.DEBUG === "true") console.error("[Tracking] Error:", error);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function getDistinctId() {
|
|
40
|
+
const email = await tryGetEmail();
|
|
41
|
+
if (email) return {
|
|
42
|
+
distinct_id: email,
|
|
43
|
+
distinct_id_source: "email",
|
|
44
|
+
project_id: getRepositoryId()
|
|
45
|
+
};
|
|
46
|
+
const repoId = getRepositoryId();
|
|
47
|
+
if (repoId) return {
|
|
48
|
+
distinct_id: repoId,
|
|
49
|
+
distinct_id_source: "git_repo",
|
|
50
|
+
project_id: repoId
|
|
51
|
+
};
|
|
52
|
+
const deviceId = `device-${await machineIdLib.machineId()}`;
|
|
53
|
+
if (process.env.DEBUG === "true") console.warn("[Tracking] Using device ID fallback. Consider using git repository for consistent tracking.");
|
|
54
|
+
return {
|
|
55
|
+
distinct_id: deviceId,
|
|
56
|
+
distinct_id_source: "device",
|
|
57
|
+
project_id: null
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
async function tryGetEmail() {
|
|
61
|
+
const rc = getRc();
|
|
62
|
+
const apiKey = process.env.LINGODOTDEV_API_KEY || rc?.auth?.apiKey;
|
|
63
|
+
const apiUrl = process.env.LINGODOTDEV_API_URL || rc?.auth?.apiUrl || "https://engine.lingo.dev";
|
|
64
|
+
if (!apiKey) return null;
|
|
65
|
+
try {
|
|
66
|
+
const res = await fetch(`${apiUrl}/whoami`, {
|
|
67
|
+
method: "POST",
|
|
68
|
+
headers: {
|
|
69
|
+
Authorization: `Bearer ${apiKey}`,
|
|
70
|
+
ContentType: "application/json"
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
if (res.ok) {
|
|
74
|
+
const payload = await res.json();
|
|
75
|
+
if (payload?.email) return payload.email;
|
|
76
|
+
}
|
|
77
|
+
} catch (err) {}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
//#endregion
|
|
82
|
+
export { trackEvent as default };
|
|
83
|
+
//# sourceMappingURL=observability.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observability.mjs","names":[],"sources":["../../src/utils/observability.ts"],"sourcesContent":["import * as machineIdLib from \"node-machine-id\";\nimport { getRc } from \"./rc\";\nimport { getRepositoryId } from \"./repository-id\";\nimport { TRACKING_VERSION, COMPILER_PACKAGE } from \"./tracking-events\";\n\nexport default async function trackEvent(\n event: string,\n properties?: Record<string, any>,\n) {\n if (process.env.DO_NOT_TRACK === \"1\") {\n return;\n }\n\n try {\n const identityInfo = await getDistinctId();\n\n if (process.env.DEBUG === \"true\") {\n console.log(\n `[Tracking] Event: ${event}, ID: ${identityInfo.distinct_id}, Source: ${identityInfo.distinct_id_source}`,\n );\n }\n\n const { PostHog } = await import(\"posthog-node\");\n const posthog = new PostHog(\n \"phc_eR0iSoQufBxNY36k0f0T15UvHJdTfHlh8rJcxsfhfXk\",\n {\n host: \"https://eu.i.posthog.com\",\n flushAt: 1,\n flushInterval: 0,\n },\n );\n\n await posthog.capture({\n distinctId: identityInfo.distinct_id,\n event,\n properties: {\n ...properties,\n isByokMode: properties?.models !== \"lingo.dev\",\n tracking_version: TRACKING_VERSION,\n compiler_package: COMPILER_PACKAGE,\n distinct_id_source: identityInfo.distinct_id_source,\n project_id: identityInfo.project_id,\n meta: {\n version: process.env.npm_package_version,\n isCi: process.env.CI === \"true\",\n },\n },\n });\n\n await posthog.shutdown();\n } catch (error) {\n if (process.env.DEBUG === \"true\") {\n console.error(\"[Tracking] Error:\", error);\n }\n }\n}\n\nasync function getDistinctId(): Promise<{\n distinct_id: string;\n distinct_id_source: string;\n project_id: string | null;\n}> {\n const email = await tryGetEmail();\n if (email) {\n const projectId = getRepositoryId();\n return {\n distinct_id: email,\n distinct_id_source: \"email\",\n project_id: projectId,\n };\n }\n\n const repoId = getRepositoryId();\n if (repoId) {\n return {\n distinct_id: repoId,\n distinct_id_source: \"git_repo\",\n project_id: repoId,\n };\n }\n\n const deviceId = `device-${await machineIdLib.machineId()}`;\n if (process.env.DEBUG === \"true\") {\n console.warn(\n \"[Tracking] Using device ID fallback. Consider using git repository for consistent tracking.\",\n );\n }\n return {\n distinct_id: deviceId,\n distinct_id_source: \"device\",\n project_id: null,\n };\n}\n\nasync function tryGetEmail(): Promise<string | null> {\n const rc = getRc();\n const apiKey = process.env.LINGODOTDEV_API_KEY || rc?.auth?.apiKey;\n const apiUrl =\n process.env.LINGODOTDEV_API_URL ||\n rc?.auth?.apiUrl ||\n \"https://engine.lingo.dev\";\n\n if (!apiKey) {\n return null;\n }\n\n try {\n const res = await fetch(`${apiUrl}/whoami`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n ContentType: \"application/json\",\n },\n });\n if (res.ok) {\n const payload = await res.json();\n if (payload?.email) {\n return payload.email;\n }\n }\n } catch (err) {\n // ignore\n }\n\n return null;\n}\n"],"mappings":";;;;;;AAKA,eAA8B,WAC5B,OACA,YACA;AACA,KAAI,QAAQ,IAAI,iBAAiB,IAC/B;AAGF,KAAI;EACF,MAAM,eAAe,MAAM,eAAe;AAE1C,MAAI,QAAQ,IAAI,UAAU,OACxB,SAAQ,IACN,qBAAqB,MAAM,QAAQ,aAAa,YAAY,YAAY,aAAa,qBACtF;EAGH,MAAM,EAAE,YAAY,MAAM,OAAO;EACjC,MAAM,UAAU,IAAI,QAClB,mDACA;GACE,MAAM;GACN,SAAS;GACT,eAAe;GAChB,CACF;AAED,QAAM,QAAQ,QAAQ;GACpB,YAAY,aAAa;GACzB;GACA,YAAY;IACV,GAAG;IACH,YAAY,YAAY,WAAW;IACnC,kBAAkB;IAClB,kBAAkB;IAClB,oBAAoB,aAAa;IACjC,YAAY,aAAa;IACzB,MAAM;KACJ,SAAS,QAAQ,IAAI;KACrB,MAAM,QAAQ,IAAI,OAAO;KAC1B;IACF;GACF,CAAC;AAEF,QAAM,QAAQ,UAAU;UACjB,OAAO;AACd,MAAI,QAAQ,IAAI,UAAU,OACxB,SAAQ,MAAM,qBAAqB,MAAM;;;AAK/C,eAAe,gBAIZ;CACD,MAAM,QAAQ,MAAM,aAAa;AACjC,KAAI,MAEF,QAAO;EACL,aAAa;EACb,oBAAoB;EACpB,YAJgB,iBAAiB;EAKlC;CAGH,MAAM,SAAS,iBAAiB;AAChC,KAAI,OACF,QAAO;EACL,aAAa;EACb,oBAAoB;EACpB,YAAY;EACb;CAGH,MAAM,WAAW,UAAU,MAAM,aAAa,WAAW;AACzD,KAAI,QAAQ,IAAI,UAAU,OACxB,SAAQ,KACN,8FACD;AAEH,QAAO;EACL,aAAa;EACb,oBAAoB;EACpB,YAAY;EACb;;AAGH,eAAe,cAAsC;CACnD,MAAM,KAAK,OAAO;CAClB,MAAM,SAAS,QAAQ,IAAI,uBAAuB,IAAI,MAAM;CAC5D,MAAM,SACJ,QAAQ,IAAI,uBACZ,IAAI,MAAM,UACV;AAEF,KAAI,CAAC,OACH,QAAO;AAGT,KAAI;EACF,MAAM,MAAM,MAAM,MAAM,GAAG,OAAO,UAAU;GAC1C,QAAQ;GACR,SAAS;IACP,eAAe,UAAU;IACzB,aAAa;IACd;GACF,CAAC;AACF,MAAI,IAAI,IAAI;GACV,MAAM,UAAU,MAAM,IAAI,MAAM;AAChC,OAAI,SAAS,MACX,QAAO,QAAQ;;UAGZ,KAAK;AAId,QAAO"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
let path = require("path");
|
|
3
|
+
path = require_rolldown_runtime.__toESM(path);
|
|
4
|
+
let fs = require("fs");
|
|
5
|
+
fs = require_rolldown_runtime.__toESM(fs);
|
|
6
|
+
let os = require("os");
|
|
7
|
+
os = require_rolldown_runtime.__toESM(os);
|
|
8
|
+
let ini = require("ini");
|
|
9
|
+
ini = require_rolldown_runtime.__toESM(ini);
|
|
10
|
+
|
|
11
|
+
//#region src/utils/rc.ts
|
|
12
|
+
function getRc() {
|
|
13
|
+
const settingsFile = ".lingodotdevrc";
|
|
14
|
+
const homedir = os.default.homedir();
|
|
15
|
+
const settingsFilePath = path.default.join(homedir, settingsFile);
|
|
16
|
+
const content = fs.default.existsSync(settingsFilePath) ? fs.default.readFileSync(settingsFilePath, "utf-8") : "";
|
|
17
|
+
return ini.default.parse(content);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
//#endregion
|
|
21
|
+
exports.getRc = getRc;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import os from "os";
|
|
4
|
+
import Ini from "ini";
|
|
5
|
+
|
|
6
|
+
//#region src/utils/rc.ts
|
|
7
|
+
function getRc() {
|
|
8
|
+
const settingsFile = ".lingodotdevrc";
|
|
9
|
+
const homedir = os.homedir();
|
|
10
|
+
const settingsFilePath = path.join(homedir, settingsFile);
|
|
11
|
+
const content = fs.existsSync(settingsFilePath) ? fs.readFileSync(settingsFilePath, "utf-8") : "";
|
|
12
|
+
return Ini.parse(content);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
export { getRc };
|
|
17
|
+
//# sourceMappingURL=rc.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rc.mjs","names":[],"sources":["../../src/utils/rc.ts"],"sourcesContent":["import os from \"os\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport Ini from \"ini\";\n\nexport function getRc() {\n const settingsFile = \".lingodotdevrc\";\n const homedir = os.homedir();\n const settingsFilePath = path.join(homedir, settingsFile);\n const content = fs.existsSync(settingsFilePath)\n ? fs.readFileSync(settingsFilePath, \"utf-8\")\n : \"\";\n const data = Ini.parse(content);\n return data;\n}\n"],"mappings":";;;;;;AAKA,SAAgB,QAAQ;CACtB,MAAM,eAAe;CACrB,MAAM,UAAU,GAAG,SAAS;CAC5B,MAAM,mBAAmB,KAAK,KAAK,SAAS,aAAa;CACzD,MAAM,UAAU,GAAG,WAAW,iBAAiB,GAC3C,GAAG,aAAa,kBAAkB,QAAQ,GAC1C;AAEJ,QADa,IAAI,MAAM,QAAQ"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
let crypto = require("crypto");
|
|
3
|
+
let child_process = require("child_process");
|
|
4
|
+
|
|
5
|
+
//#region src/utils/repository-id.ts
|
|
6
|
+
let cachedGitRepoId = void 0;
|
|
7
|
+
function hashProjectName(fullPath) {
|
|
8
|
+
const parts = fullPath.split("/");
|
|
9
|
+
if (parts.length !== 2) return (0, crypto.createHash)("sha256").update(fullPath).digest("hex").slice(0, 8);
|
|
10
|
+
const [org, project] = parts;
|
|
11
|
+
return `${org}/${(0, crypto.createHash)("sha256").update(project).digest("hex").slice(0, 8)}`;
|
|
12
|
+
}
|
|
13
|
+
function getRepositoryId() {
|
|
14
|
+
const ciRepoId = getCIRepositoryId();
|
|
15
|
+
if (ciRepoId) return ciRepoId;
|
|
16
|
+
const gitRepoId = getGitRepositoryId();
|
|
17
|
+
if (gitRepoId) return gitRepoId;
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
function getCIRepositoryId() {
|
|
21
|
+
if (process.env.GITHUB_REPOSITORY) return `github:${hashProjectName(process.env.GITHUB_REPOSITORY)}`;
|
|
22
|
+
if (process.env.CI_PROJECT_PATH) return `gitlab:${hashProjectName(process.env.CI_PROJECT_PATH)}`;
|
|
23
|
+
if (process.env.BITBUCKET_REPO_FULL_NAME) return `bitbucket:${hashProjectName(process.env.BITBUCKET_REPO_FULL_NAME)}`;
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
function getGitRepositoryId() {
|
|
27
|
+
if (cachedGitRepoId !== void 0) return cachedGitRepoId;
|
|
28
|
+
try {
|
|
29
|
+
const remoteUrl = (0, child_process.execSync)("git config --get remote.origin.url", {
|
|
30
|
+
encoding: "utf8",
|
|
31
|
+
stdio: [
|
|
32
|
+
"pipe",
|
|
33
|
+
"pipe",
|
|
34
|
+
"ignore"
|
|
35
|
+
]
|
|
36
|
+
}).trim();
|
|
37
|
+
if (!remoteUrl) {
|
|
38
|
+
cachedGitRepoId = null;
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
cachedGitRepoId = parseGitUrl(remoteUrl);
|
|
42
|
+
return cachedGitRepoId;
|
|
43
|
+
} catch {
|
|
44
|
+
cachedGitRepoId = null;
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function parseGitUrl(url) {
|
|
49
|
+
const cleanUrl = url.replace(/\.git$/, "");
|
|
50
|
+
let platform = null;
|
|
51
|
+
if (cleanUrl.includes("github.com")) platform = "github";
|
|
52
|
+
else if (cleanUrl.includes("gitlab.com")) platform = "gitlab";
|
|
53
|
+
else if (cleanUrl.includes("bitbucket.org")) platform = "bitbucket";
|
|
54
|
+
const sshMatch = cleanUrl.match(/[@:]([^:/@]+\/[^:/@]+)$/);
|
|
55
|
+
const httpsMatch = cleanUrl.match(/\/([^/]+\/[^/]+)$/);
|
|
56
|
+
const repoPath = sshMatch?.[1] || httpsMatch?.[1];
|
|
57
|
+
if (!repoPath) return null;
|
|
58
|
+
const hashedPath = hashProjectName(repoPath);
|
|
59
|
+
if (platform) return `${platform}:${hashedPath}`;
|
|
60
|
+
return `git:${hashedPath}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
//#endregion
|
|
64
|
+
exports.getRepositoryId = getRepositoryId;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { createHash } from "crypto";
|
|
2
|
+
import { execSync } from "child_process";
|
|
3
|
+
|
|
4
|
+
//#region src/utils/repository-id.ts
|
|
5
|
+
let cachedGitRepoId = void 0;
|
|
6
|
+
function hashProjectName(fullPath) {
|
|
7
|
+
const parts = fullPath.split("/");
|
|
8
|
+
if (parts.length !== 2) return createHash("sha256").update(fullPath).digest("hex").slice(0, 8);
|
|
9
|
+
const [org, project] = parts;
|
|
10
|
+
return `${org}/${createHash("sha256").update(project).digest("hex").slice(0, 8)}`;
|
|
11
|
+
}
|
|
12
|
+
function getRepositoryId() {
|
|
13
|
+
const ciRepoId = getCIRepositoryId();
|
|
14
|
+
if (ciRepoId) return ciRepoId;
|
|
15
|
+
const gitRepoId = getGitRepositoryId();
|
|
16
|
+
if (gitRepoId) return gitRepoId;
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
function getCIRepositoryId() {
|
|
20
|
+
if (process.env.GITHUB_REPOSITORY) return `github:${hashProjectName(process.env.GITHUB_REPOSITORY)}`;
|
|
21
|
+
if (process.env.CI_PROJECT_PATH) return `gitlab:${hashProjectName(process.env.CI_PROJECT_PATH)}`;
|
|
22
|
+
if (process.env.BITBUCKET_REPO_FULL_NAME) return `bitbucket:${hashProjectName(process.env.BITBUCKET_REPO_FULL_NAME)}`;
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
function getGitRepositoryId() {
|
|
26
|
+
if (cachedGitRepoId !== void 0) return cachedGitRepoId;
|
|
27
|
+
try {
|
|
28
|
+
const remoteUrl = execSync("git config --get remote.origin.url", {
|
|
29
|
+
encoding: "utf8",
|
|
30
|
+
stdio: [
|
|
31
|
+
"pipe",
|
|
32
|
+
"pipe",
|
|
33
|
+
"ignore"
|
|
34
|
+
]
|
|
35
|
+
}).trim();
|
|
36
|
+
if (!remoteUrl) {
|
|
37
|
+
cachedGitRepoId = null;
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
cachedGitRepoId = parseGitUrl(remoteUrl);
|
|
41
|
+
return cachedGitRepoId;
|
|
42
|
+
} catch {
|
|
43
|
+
cachedGitRepoId = null;
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function parseGitUrl(url) {
|
|
48
|
+
const cleanUrl = url.replace(/\.git$/, "");
|
|
49
|
+
let platform = null;
|
|
50
|
+
if (cleanUrl.includes("github.com")) platform = "github";
|
|
51
|
+
else if (cleanUrl.includes("gitlab.com")) platform = "gitlab";
|
|
52
|
+
else if (cleanUrl.includes("bitbucket.org")) platform = "bitbucket";
|
|
53
|
+
const sshMatch = cleanUrl.match(/[@:]([^:/@]+\/[^:/@]+)$/);
|
|
54
|
+
const httpsMatch = cleanUrl.match(/\/([^/]+\/[^/]+)$/);
|
|
55
|
+
const repoPath = sshMatch?.[1] || httpsMatch?.[1];
|
|
56
|
+
if (!repoPath) return null;
|
|
57
|
+
const hashedPath = hashProjectName(repoPath);
|
|
58
|
+
if (platform) return `${platform}:${hashedPath}`;
|
|
59
|
+
return `git:${hashedPath}`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
//#endregion
|
|
63
|
+
export { getRepositoryId };
|
|
64
|
+
//# sourceMappingURL=repository-id.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository-id.mjs","names":["cachedGitRepoId: string | null | undefined","platform: string | null"],"sources":["../../src/utils/repository-id.ts"],"sourcesContent":["import { execSync } from \"child_process\";\nimport { createHash } from \"crypto\";\n\nlet cachedGitRepoId: string | null | undefined = undefined;\n\nfunction hashProjectName(fullPath: string): string {\n const parts = fullPath.split(\"/\");\n if (parts.length !== 2) {\n return createHash(\"sha256\").update(fullPath).digest(\"hex\").slice(0, 8);\n }\n\n const [org, project] = parts;\n const hashedProject = createHash(\"sha256\")\n .update(project)\n .digest(\"hex\")\n .slice(0, 8);\n\n return `${org}/${hashedProject}`;\n}\n\nexport function getRepositoryId(): string | null {\n const ciRepoId = getCIRepositoryId();\n if (ciRepoId) return ciRepoId;\n\n const gitRepoId = getGitRepositoryId();\n if (gitRepoId) return gitRepoId;\n\n return null;\n}\n\nfunction getCIRepositoryId(): string | null {\n if (process.env.GITHUB_REPOSITORY) {\n const hashed = hashProjectName(process.env.GITHUB_REPOSITORY);\n return `github:${hashed}`;\n }\n\n if (process.env.CI_PROJECT_PATH) {\n const hashed = hashProjectName(process.env.CI_PROJECT_PATH);\n return `gitlab:${hashed}`;\n }\n\n if (process.env.BITBUCKET_REPO_FULL_NAME) {\n const hashed = hashProjectName(process.env.BITBUCKET_REPO_FULL_NAME);\n return `bitbucket:${hashed}`;\n }\n\n return null;\n}\n\nfunction getGitRepositoryId(): string | null {\n if (cachedGitRepoId !== undefined) {\n return cachedGitRepoId;\n }\n\n try {\n const remoteUrl = execSync(\"git config --get remote.origin.url\", {\n encoding: \"utf8\",\n stdio: [\"pipe\", \"pipe\", \"ignore\"],\n }).trim();\n\n if (!remoteUrl) {\n cachedGitRepoId = null;\n return null;\n }\n\n cachedGitRepoId = parseGitUrl(remoteUrl);\n return cachedGitRepoId;\n } catch {\n cachedGitRepoId = null;\n return null;\n }\n}\n\nfunction parseGitUrl(url: string): string | null {\n const cleanUrl = url.replace(/\\.git$/, \"\");\n\n let platform: string | null = null;\n if (cleanUrl.includes(\"github.com\")) {\n platform = \"github\";\n } else if (cleanUrl.includes(\"gitlab.com\")) {\n platform = \"gitlab\";\n } else if (cleanUrl.includes(\"bitbucket.org\")) {\n platform = \"bitbucket\";\n }\n\n const sshMatch = cleanUrl.match(/[@:]([^:/@]+\\/[^:/@]+)$/);\n const httpsMatch = cleanUrl.match(/\\/([^/]+\\/[^/]+)$/);\n\n const repoPath = sshMatch?.[1] || httpsMatch?.[1];\n\n if (!repoPath) return null;\n\n const hashedPath = hashProjectName(repoPath);\n\n if (platform) {\n return `${platform}:${hashedPath}`;\n }\n\n return `git:${hashedPath}`;\n}\n"],"mappings":";;;;AAGA,IAAIA,kBAA6C;AAEjD,SAAS,gBAAgB,UAA0B;CACjD,MAAM,QAAQ,SAAS,MAAM,IAAI;AACjC,KAAI,MAAM,WAAW,EACnB,QAAO,WAAW,SAAS,CAAC,OAAO,SAAS,CAAC,OAAO,MAAM,CAAC,MAAM,GAAG,EAAE;CAGxE,MAAM,CAAC,KAAK,WAAW;AAMvB,QAAO,GAAG,IAAI,GALQ,WAAW,SAAS,CACvC,OAAO,QAAQ,CACf,OAAO,MAAM,CACb,MAAM,GAAG,EAAE;;AAKhB,SAAgB,kBAAiC;CAC/C,MAAM,WAAW,mBAAmB;AACpC,KAAI,SAAU,QAAO;CAErB,MAAM,YAAY,oBAAoB;AACtC,KAAI,UAAW,QAAO;AAEtB,QAAO;;AAGT,SAAS,oBAAmC;AAC1C,KAAI,QAAQ,IAAI,kBAEd,QAAO,UADQ,gBAAgB,QAAQ,IAAI,kBAAkB;AAI/D,KAAI,QAAQ,IAAI,gBAEd,QAAO,UADQ,gBAAgB,QAAQ,IAAI,gBAAgB;AAI7D,KAAI,QAAQ,IAAI,yBAEd,QAAO,aADQ,gBAAgB,QAAQ,IAAI,yBAAyB;AAItE,QAAO;;AAGT,SAAS,qBAAoC;AAC3C,KAAI,oBAAoB,OACtB,QAAO;AAGT,KAAI;EACF,MAAM,YAAY,SAAS,sCAAsC;GAC/D,UAAU;GACV,OAAO;IAAC;IAAQ;IAAQ;IAAS;GAClC,CAAC,CAAC,MAAM;AAET,MAAI,CAAC,WAAW;AACd,qBAAkB;AAClB,UAAO;;AAGT,oBAAkB,YAAY,UAAU;AACxC,SAAO;SACD;AACN,oBAAkB;AAClB,SAAO;;;AAIX,SAAS,YAAY,KAA4B;CAC/C,MAAM,WAAW,IAAI,QAAQ,UAAU,GAAG;CAE1C,IAAIC,WAA0B;AAC9B,KAAI,SAAS,SAAS,aAAa,CACjC,YAAW;UACF,SAAS,SAAS,aAAa,CACxC,YAAW;UACF,SAAS,SAAS,gBAAgB,CAC3C,YAAW;CAGb,MAAM,WAAW,SAAS,MAAM,0BAA0B;CAC1D,MAAM,aAAa,SAAS,MAAM,oBAAoB;CAEtD,MAAM,WAAW,WAAW,MAAM,aAAa;AAE/C,KAAI,CAAC,SAAU,QAAO;CAEtB,MAAM,aAAa,gBAAgB,SAAS;AAE5C,KAAI,SACF,QAAO,GAAG,SAAS,GAAG;AAGxB,QAAO,OAAO"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/utils/tracking-events.ts
|
|
3
|
+
const TRACKING_EVENTS = {
|
|
4
|
+
BUILD_START: "compiler.build.start",
|
|
5
|
+
BUILD_SUCCESS: "compiler.build.success",
|
|
6
|
+
BUILD_ERROR: "compiler.build.error"
|
|
7
|
+
};
|
|
8
|
+
const TRACKING_VERSION = "3.0";
|
|
9
|
+
const COMPILER_PACKAGE = "@lingo.dev/compiler";
|
|
10
|
+
function sanitizeConfigForTracking(config) {
|
|
11
|
+
return {
|
|
12
|
+
sourceLocale: config.sourceLocale,
|
|
13
|
+
targetLocalesCount: config.targetLocales.length,
|
|
14
|
+
hasCustomModels: config.models !== "lingo.dev",
|
|
15
|
+
isByokMode: config.models !== "lingo.dev",
|
|
16
|
+
useDirective: config.useDirective,
|
|
17
|
+
buildMode: config.buildMode,
|
|
18
|
+
hasPluralisation: config.pluralization.enabled,
|
|
19
|
+
hasCustomPrompt: !!config.prompt,
|
|
20
|
+
hasCustomLocaleResolver: false
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
//#endregion
|
|
25
|
+
exports.COMPILER_PACKAGE = COMPILER_PACKAGE;
|
|
26
|
+
exports.TRACKING_EVENTS = TRACKING_EVENTS;
|
|
27
|
+
exports.TRACKING_VERSION = TRACKING_VERSION;
|
|
28
|
+
exports.sanitizeConfigForTracking = sanitizeConfigForTracking;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region src/utils/tracking-events.ts
|
|
2
|
+
const TRACKING_EVENTS = {
|
|
3
|
+
BUILD_START: "compiler.build.start",
|
|
4
|
+
BUILD_SUCCESS: "compiler.build.success",
|
|
5
|
+
BUILD_ERROR: "compiler.build.error"
|
|
6
|
+
};
|
|
7
|
+
const TRACKING_VERSION = "3.0";
|
|
8
|
+
const COMPILER_PACKAGE = "@lingo.dev/compiler";
|
|
9
|
+
function sanitizeConfigForTracking(config) {
|
|
10
|
+
return {
|
|
11
|
+
sourceLocale: config.sourceLocale,
|
|
12
|
+
targetLocalesCount: config.targetLocales.length,
|
|
13
|
+
hasCustomModels: config.models !== "lingo.dev",
|
|
14
|
+
isByokMode: config.models !== "lingo.dev",
|
|
15
|
+
useDirective: config.useDirective,
|
|
16
|
+
buildMode: config.buildMode,
|
|
17
|
+
hasPluralisation: config.pluralization.enabled,
|
|
18
|
+
hasCustomPrompt: !!config.prompt,
|
|
19
|
+
hasCustomLocaleResolver: false
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
export { COMPILER_PACKAGE, TRACKING_EVENTS, TRACKING_VERSION, sanitizeConfigForTracking };
|
|
25
|
+
//# sourceMappingURL=tracking-events.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracking-events.mjs","names":[],"sources":["../../src/utils/tracking-events.ts"],"sourcesContent":["import type { LingoConfig } from \"../types\";\n\nexport const TRACKING_EVENTS = {\n BUILD_START: \"compiler.build.start\",\n BUILD_SUCCESS: \"compiler.build.success\",\n BUILD_ERROR: \"compiler.build.error\",\n} as const;\n\nexport const TRACKING_VERSION = \"3.0\";\n\nexport const COMPILER_PACKAGE = \"@lingo.dev/compiler\";\n\nexport function sanitizeConfigForTracking(config: LingoConfig) {\n return {\n sourceLocale: config.sourceLocale,\n targetLocalesCount: config.targetLocales.length,\n hasCustomModels: config.models !== \"lingo.dev\",\n isByokMode: config.models !== \"lingo.dev\",\n useDirective: config.useDirective,\n buildMode: config.buildMode,\n hasPluralisation: config.pluralization.enabled,\n hasCustomPrompt: !!config.prompt,\n hasCustomLocaleResolver: false,\n };\n}\n"],"mappings":";AAEA,MAAa,kBAAkB;CAC7B,aAAa;CACb,eAAe;CACf,aAAa;CACd;AAED,MAAa,mBAAmB;AAEhC,MAAa,mBAAmB;AAEhC,SAAgB,0BAA0B,QAAqB;AAC7D,QAAO;EACL,cAAc,OAAO;EACrB,oBAAoB,OAAO,cAAc;EACzC,iBAAiB,OAAO,WAAW;EACnC,YAAY,OAAO,WAAW;EAC9B,cAAc,OAAO;EACrB,WAAW,OAAO;EAClB,kBAAkB,OAAO,cAAc;EACvC,iBAAiB,CAAC,CAAC,OAAO;EAC1B,yBAAyB;EAC1B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lingo.dev/compiler",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Lingo.dev Compiler",
|
|
5
5
|
"private": false,
|
|
6
6
|
"repository": {
|
|
@@ -120,44 +120,48 @@
|
|
|
120
120
|
"author": "",
|
|
121
121
|
"license": "ISC",
|
|
122
122
|
"devDependencies": {
|
|
123
|
-
"@playwright/test": "
|
|
124
|
-
"@types/babel__core": "
|
|
125
|
-
"@types/babel__generator": "
|
|
126
|
-
"@types/babel__traverse": "
|
|
127
|
-
"@types/
|
|
128
|
-
"@types/
|
|
129
|
-
"@types/
|
|
130
|
-
"@types/react
|
|
131
|
-
"@types/
|
|
132
|
-
"
|
|
133
|
-
"
|
|
134
|
-
"
|
|
135
|
-
"
|
|
136
|
-
"
|
|
137
|
-
"
|
|
123
|
+
"@playwright/test": "1.56.1",
|
|
124
|
+
"@types/babel__core": "7.20.5",
|
|
125
|
+
"@types/babel__generator": "7.27.0",
|
|
126
|
+
"@types/babel__traverse": "7.28.0",
|
|
127
|
+
"@types/ini": "4.1.1",
|
|
128
|
+
"@types/node": "25.0.3",
|
|
129
|
+
"@types/proper-lockfile": "4.1.4",
|
|
130
|
+
"@types/react": "19.2.7",
|
|
131
|
+
"@types/react-dom": "19.2.3",
|
|
132
|
+
"@types/ws": "8.18.1",
|
|
133
|
+
"next": "16.1.0",
|
|
134
|
+
"tsdown": "0.18.2",
|
|
135
|
+
"tsx": "4.21.0",
|
|
136
|
+
"typescript": "5.9.3",
|
|
137
|
+
"unplugin": "2.3.11",
|
|
138
|
+
"vitest": "4.0.16"
|
|
138
139
|
},
|
|
139
140
|
"dependencies": {
|
|
140
|
-
"@ai-sdk/google": "
|
|
141
|
-
"@ai-sdk/groq": "
|
|
142
|
-
"@ai-sdk/mistral": "
|
|
143
|
-
"@babel/core": "
|
|
144
|
-
"@babel/generator": "
|
|
145
|
-
"@babel/parser": "
|
|
146
|
-
"@babel/preset-react": "
|
|
147
|
-
"@babel/preset-typescript": "
|
|
148
|
-
"@babel/traverse": "
|
|
149
|
-
"@babel/types": "
|
|
150
|
-
"@formatjs/icu-messageformat-parser": "
|
|
151
|
-
"@openrouter/ai-sdk-provider": "
|
|
152
|
-
"ai": "
|
|
153
|
-
"ai-sdk-ollama": "
|
|
154
|
-
"dotenv": "
|
|
155
|
-
"fast-xml-parser": "
|
|
156
|
-
"
|
|
157
|
-
"
|
|
158
|
-
"lodash": "
|
|
159
|
-
"
|
|
160
|
-
"
|
|
141
|
+
"@ai-sdk/google": "3.0.1",
|
|
142
|
+
"@ai-sdk/groq": "3.0.1",
|
|
143
|
+
"@ai-sdk/mistral": "3.0.1",
|
|
144
|
+
"@babel/core": "7.26.0",
|
|
145
|
+
"@babel/generator": "7.28.5",
|
|
146
|
+
"@babel/parser": "7.28.5",
|
|
147
|
+
"@babel/preset-react": "7.26.3",
|
|
148
|
+
"@babel/preset-typescript": "7.26.0",
|
|
149
|
+
"@babel/traverse": "7.28.5",
|
|
150
|
+
"@babel/types": "7.28.5",
|
|
151
|
+
"@formatjs/icu-messageformat-parser": "3.1.1",
|
|
152
|
+
"@openrouter/ai-sdk-provider": "1.5.4",
|
|
153
|
+
"ai": "6.0.3",
|
|
154
|
+
"ai-sdk-ollama": "3.0.0",
|
|
155
|
+
"dotenv": "17.2.3",
|
|
156
|
+
"fast-xml-parser": "5.3.3",
|
|
157
|
+
"ini": "5.0.0",
|
|
158
|
+
"intl-messageformat": "11.0.6",
|
|
159
|
+
"lodash": "4.17.21",
|
|
160
|
+
"node-machine-id": "1.1.12",
|
|
161
|
+
"posthog-node": "5.14.0",
|
|
162
|
+
"proper-lockfile": "4.1.2",
|
|
163
|
+
"ws": "8.18.3",
|
|
164
|
+
"lingo.dev": "^0.118.0"
|
|
161
165
|
},
|
|
162
166
|
"peerDependencies": {
|
|
163
167
|
"next": "^15.0.0 || ^16.0.4",
|