lingo.dev 0.99.8 → 0.100.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/cli.cjs CHANGED
@@ -4134,6 +4134,127 @@ function createIgnoredKeysLoader(ignoredKeys) {
4134
4134
  });
4135
4135
  }
4136
4136
 
4137
+ // src/cli/loaders/ejs.ts
4138
+ function parseEjsForTranslation(input2) {
4139
+ const translatable = {};
4140
+ let counter = 0;
4141
+ const ejsTagRegex = /<%[\s\S]*?%>/g;
4142
+ const parts = [];
4143
+ let lastIndex = 0;
4144
+ let match2;
4145
+ while ((match2 = ejsTagRegex.exec(input2)) !== null) {
4146
+ if (match2.index > lastIndex) {
4147
+ parts.push({
4148
+ type: "text",
4149
+ content: input2.slice(lastIndex, match2.index)
4150
+ });
4151
+ }
4152
+ parts.push({
4153
+ type: "ejs",
4154
+ content: match2[0]
4155
+ });
4156
+ lastIndex = match2.index + match2[0].length;
4157
+ }
4158
+ if (lastIndex < input2.length) {
4159
+ parts.push({
4160
+ type: "text",
4161
+ content: input2.slice(lastIndex)
4162
+ });
4163
+ }
4164
+ let template = "";
4165
+ for (const part of parts) {
4166
+ if (part.type === "ejs") {
4167
+ template += part.content;
4168
+ } else {
4169
+ const textContent = part.content;
4170
+ const htmlTagRegex = /<[^>]+>/g;
4171
+ const textParts = [];
4172
+ let lastTextIndex = 0;
4173
+ let htmlMatch;
4174
+ while ((htmlMatch = htmlTagRegex.exec(textContent)) !== null) {
4175
+ if (htmlMatch.index > lastTextIndex) {
4176
+ const textBefore = textContent.slice(lastTextIndex, htmlMatch.index);
4177
+ if (textBefore.trim()) {
4178
+ textParts.push({ type: "text", content: textBefore });
4179
+ } else {
4180
+ textParts.push({ type: "html", content: textBefore });
4181
+ }
4182
+ }
4183
+ textParts.push({ type: "html", content: htmlMatch[0] });
4184
+ lastTextIndex = htmlMatch.index + htmlMatch[0].length;
4185
+ }
4186
+ if (lastTextIndex < textContent.length) {
4187
+ const remainingText = textContent.slice(lastTextIndex);
4188
+ if (remainingText.trim()) {
4189
+ textParts.push({ type: "text", content: remainingText });
4190
+ } else {
4191
+ textParts.push({ type: "html", content: remainingText });
4192
+ }
4193
+ }
4194
+ if (textParts.length === 0) {
4195
+ const trimmedContent = textContent.trim();
4196
+ if (trimmedContent) {
4197
+ textParts.push({ type: "text", content: textContent });
4198
+ } else {
4199
+ textParts.push({ type: "html", content: textContent });
4200
+ }
4201
+ }
4202
+ for (const textPart of textParts) {
4203
+ if (textPart.type === "text") {
4204
+ const trimmedContent = textPart.content.trim();
4205
+ if (trimmedContent) {
4206
+ const key = `text_${counter++}`;
4207
+ translatable[key] = trimmedContent;
4208
+ template += textPart.content.replace(trimmedContent, `__LINGO_PLACEHOLDER_${key}__`);
4209
+ } else {
4210
+ template += textPart.content;
4211
+ }
4212
+ } else {
4213
+ template += textPart.content;
4214
+ }
4215
+ }
4216
+ }
4217
+ }
4218
+ return { content: template, translatable };
4219
+ }
4220
+ function reconstructEjsWithTranslation(template, translatable) {
4221
+ let result = template;
4222
+ for (const [key, value] of Object.entries(translatable)) {
4223
+ const placeholder = `__LINGO_PLACEHOLDER_${key}__`;
4224
+ result = result.replace(new RegExp(placeholder, "g"), value);
4225
+ }
4226
+ return result;
4227
+ }
4228
+ function createEjsLoader() {
4229
+ return createLoader({
4230
+ async pull(locale, input2) {
4231
+ if (!input2 || input2.trim() === "") {
4232
+ return {};
4233
+ }
4234
+ try {
4235
+ const parseResult = parseEjsForTranslation(input2);
4236
+ return parseResult.translatable;
4237
+ } catch (error) {
4238
+ console.warn("Warning: Could not parse EJS template, treating as plain text");
4239
+ return { content: input2.trim() };
4240
+ }
4241
+ },
4242
+ async push(locale, data, originalInput) {
4243
+ if (!originalInput) {
4244
+ return Object.values(data).join("\n");
4245
+ }
4246
+ try {
4247
+ const parseResult = parseEjsForTranslation(originalInput);
4248
+ const mergedTranslatable = { ...parseResult.translatable, ...data };
4249
+ return reconstructEjsWithTranslation(parseResult.content, mergedTranslatable);
4250
+ } catch (error) {
4251
+ console.warn("Warning: Could not reconstruct EJS template, returning translated data");
4252
+ return Object.values(data).join("\n");
4253
+ }
4254
+ }
4255
+ });
4256
+ }
4257
+
4137
4258
  // src/cli/loaders/index.ts
4138
4259
  function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys, lockedPatterns, ignoredKeys) {
4139
4260
  switch (bucketType) {
@@ -4172,6 +4293,16 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
4172
4293
  options.returnUnlocalizedKeys
4173
4294
  )
4174
4295
  );
4296
+ case "ejs":
4297
+ return composeLoaders(
4298
+ createTextFileLoader(bucketPathPattern),
4299
+ createEjsLoader(),
4300
+ createSyncLoader(),
4301
+ createUnlocalizableLoader(
4302
+ options.isCacheRestore,
4303
+ options.returnUnlocalizedKeys
4304
+ )
4305
+ );
4175
4306
  case "json":
4176
4307
  return composeLoaders(
4177
4308
  createTextFileLoader(bucketPathPattern),
@@ -9127,7 +9258,7 @@ async function renderHero2() {
9127
9258
  // package.json
9128
9259
  var package_default = {
9129
9260
  name: "lingo.dev",
9130
- version: "0.99.8",
9261
+ version: "0.100.0",
9131
9262
  description: "Lingo.dev CLI",
9132
9263
  private: false,
9133
9264
  publishConfig: {
@@ -9257,6 +9388,7 @@ var package_default = {
9257
9388
  "@modelcontextprotocol/sdk": "^1.5.0",
9258
9389
  "@openrouter/ai-sdk-provider": "^0.7.1",
9259
9390
  "@paralleldrive/cuid2": "^2.2.2",
9391
+ "@types/ejs": "^3.1.5",
9260
9392
  ai: "^4.3.15",
9261
9393
  bitbucket: "^2.12.0",
9262
9394
  chalk: "^5.4.1",
@@ -9269,6 +9401,7 @@ var package_default = {
9269
9401
  dedent: "^1.5.3",
9270
9402
  diff: "^7.0.0",
9271
9403
  dotenv: "^16.4.7",
9404
+ ejs: "^3.1.10",
9272
9405
  express: "^5.1.0",
9273
9406
  "external-editor": "^3.1.0",
9274
9407
  figlet: "^1.8.0",