livelocale 0.12.0 → 0.12.1

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.
@@ -1,4 +1,4 @@
1
- export { W as WrapOptions, d as decodeKey, e as encodeKey, h as hasWatermark, r as removeWatermarks, s as sanitizeZeroWidth, a as stripWatermark, u as unwrap, w as wrapNextIntl, b as wrapTranslationEngine } from '../wrap-2qVxLN9Q.cjs';
1
+ export { W as WrapOptions, d as decodeKey, e as encodeKey, h as hasWatermark, r as removeWatermarks, s as sanitizeZeroWidth, a as stripWatermark, u as unwrap, w as wrapNextIntl, b as wrapTranslationEngine } from '../wrap-COvz8N3U.cjs';
2
2
 
3
3
  type ClientMessageType = 'ELEMENT_SELECTED' | 'READY' | 'ERROR' | 'VISIBLE_KEYS_CHANGED' | 'VISIBLE_TEXTS_CHANGED' | 'LOCATION_CHANGED' | 'LEAVING';
4
4
  type StudioMessageType = 'APPLY_PREVIEW' | 'COMMIT_PREVIEW' | 'CLEAR_SELECTION' | 'NAVIGATE';
@@ -120,4 +120,5 @@ declare class DOMInterceptor {
120
120
  private handlePaste;
121
121
  }
122
122
 
123
- export { type ClientMessageType, DOMInterceptor, IframeBridge, type StudioMessageType, type TranslationPayload, type VisibleText };
123
+ export { DOMInterceptor, IframeBridge };
124
+ export type { ClientMessageType, StudioMessageType, TranslationPayload, VisibleText };
@@ -1,4 +1,4 @@
1
- export { W as WrapOptions, d as decodeKey, e as encodeKey, h as hasWatermark, r as removeWatermarks, s as sanitizeZeroWidth, a as stripWatermark, u as unwrap, w as wrapNextIntl, b as wrapTranslationEngine } from '../wrap-2qVxLN9Q.js';
1
+ export { W as WrapOptions, d as decodeKey, e as encodeKey, h as hasWatermark, r as removeWatermarks, s as sanitizeZeroWidth, a as stripWatermark, u as unwrap, w as wrapNextIntl, b as wrapTranslationEngine } from '../wrap-COvz8N3U.js';
2
2
 
3
3
  type ClientMessageType = 'ELEMENT_SELECTED' | 'READY' | 'ERROR' | 'VISIBLE_KEYS_CHANGED' | 'VISIBLE_TEXTS_CHANGED' | 'LOCATION_CHANGED' | 'LEAVING';
4
4
  type StudioMessageType = 'APPLY_PREVIEW' | 'COMMIT_PREVIEW' | 'CLEAR_SELECTION' | 'NAVIGATE';
@@ -120,4 +120,5 @@ declare class DOMInterceptor {
120
120
  private handlePaste;
121
121
  }
122
122
 
123
- export { type ClientMessageType, DOMInterceptor, IframeBridge, type StudioMessageType, type TranslationPayload, type VisibleText };
123
+ export { DOMInterceptor, IframeBridge };
124
+ export type { ClientMessageType, StudioMessageType, TranslationPayload, VisibleText };
@@ -6,8 +6,13 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getProtoOf = Object.getPrototypeOf;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __esm = (fn, res) => function __init() {
10
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
9
+ var __esm = (fn, res, err) => function __init() {
10
+ if (err) throw err[0];
11
+ try {
12
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
13
+ } catch (e) {
14
+ throw err = [e], e;
15
+ }
11
16
  };
12
17
  var __export = (target, all) => {
13
18
  for (var name in all)
@@ -405,7 +410,8 @@ function createStudioServer(options) {
405
410
  res.end("Bad Request");
406
411
  return;
407
412
  }
408
- if (filePath !== studioDir && !filePath.startsWith(studioDir + path2.sep)) {
413
+ const relativePath = path2.relative(studioDir, filePath);
414
+ if (relativePath.startsWith("..") || path2.isAbsolute(relativePath)) {
409
415
  res.statusCode = 403;
410
416
  res.end("Forbidden");
411
417
  return;
@@ -1577,7 +1583,7 @@ function parseIcu(message) {
1577
1583
  parseMessage(0);
1578
1584
  return { args, error };
1579
1585
  }
1580
- var I18NEXT_RE = /\{\{\s*([^{}]*?)\s*\}\}/g;
1586
+ var I18NEXT_RE = /\{\{([^{}]*)\}\}/g;
1581
1587
  var NESTING_RE = /\$t\([^)]*\)/g;
1582
1588
  var PRINTF_RE = /%(?:\d+\$)?[-+ 0#]*\d*(?:\.\d+)?[sdifgxXoc]/g;
1583
1589
  var TAG_RE = /<\/?([A-Za-z][\w-]*|\d+)\b[^<>]*>/g;
@@ -3041,7 +3047,12 @@ function escapeAttribute(value) {
3041
3047
  }
3042
3048
  function injectFlagScript(html, src) {
3043
3049
  const tag = `<script src="${escapeAttribute(src)}"></script>`;
3044
- const cleaned = html.replace(EXISTING_FLAG_TAG, "");
3050
+ let cleaned = html;
3051
+ let previous;
3052
+ do {
3053
+ previous = cleaned;
3054
+ cleaned = cleaned.replace(EXISTING_FLAG_TAG, "");
3055
+ } while (cleaned !== previous);
3045
3056
  for (const pattern of [HEAD_OPEN2, HTML_OPEN2, DOCTYPE2]) {
3046
3057
  const match = pattern.exec(cleaned);
3047
3058
  if (match) {
@@ -3057,8 +3068,8 @@ var NO_REPO_WARNING = "exposeRepo is on but no GitHub repository was found; the
3057
3068
  function isPlainObject2(value) {
3058
3069
  return typeof value === "object" && value !== null && !Array.isArray(value);
3059
3070
  }
3060
- function toPosix(relative10) {
3061
- return relative10.split(path11.sep).join("/") || ".";
3071
+ function toPosix(relative11) {
3072
+ return relative11.split(path11.sep).join("/") || ".";
3062
3073
  }
3063
3074
  function isInside(parent, child) {
3064
3075
  const rel = path11.relative(parent, child);
@@ -3555,11 +3566,14 @@ function setNestedProperty(obj, keyPath, value) {
3555
3566
  let current = obj;
3556
3567
  for (let i = 0; i < keys.length; i++) {
3557
3568
  const key = keys[i];
3569
+ if (key === "__proto__" || key === "constructor" || key === "prototype") {
3570
+ throw new Error(`[livelocale] Forbidden key segment in path: "${keyPath}".`);
3571
+ }
3558
3572
  if (i === keys.length - 1) {
3559
3573
  current[key] = value;
3560
3574
  return;
3561
3575
  }
3562
- if (!(key in current) || current[key] === null || typeof current[key] !== "object" || Array.isArray(current[key])) {
3576
+ if (!Object.prototype.hasOwnProperty.call(current, key) || current[key] === null || typeof current[key] !== "object" || Array.isArray(current[key])) {
3563
3577
  current[key] = {};
3564
3578
  }
3565
3579
  current = current[key];
@@ -3832,6 +3846,13 @@ var nodeInflate = async (bytes, maxOutputLength) => {
3832
3846
  return result.buffer;
3833
3847
  };
3834
3848
 
3849
+ // src/core/strings.ts
3850
+ function trimTrailingSlashes(value) {
3851
+ let end = value.length;
3852
+ while (end > 0 && value.charCodeAt(end - 1) === 47) end -= 1;
3853
+ return value.slice(0, end);
3854
+ }
3855
+
3835
3856
  // src/server/github-rest.ts
3836
3857
  var GitHubApiError = class extends Error {
3837
3858
  constructor(message, status) {
@@ -3864,7 +3885,7 @@ function encodeRefPath(ref) {
3864
3885
  }
3865
3886
  function createGitHubRest(config) {
3866
3887
  const repo = config.repo;
3867
- const apiBase = (config.apiBase ?? "https://api.github.com").replace(/\/+$/, "");
3888
+ const apiBase = trimTrailingSlashes(config.apiBase ?? "https://api.github.com");
3868
3889
  const fetchImpl = config.fetchImpl ?? globalThis.fetch;
3869
3890
  const owner = repo.split("/")[0] ?? "";
3870
3891
  if (!/^[\w.-]+\/[\w.-]+$/.test(repo)) {
@@ -4293,6 +4314,7 @@ var BIDI_CONTROL_RE = /[\u202a-\u202e\u2066-\u2069]/g;
4293
4314
  var NEWLINE_RE = /\r\n|\r|\n/g;
4294
4315
  var SPAN_CONTROL_RE = /[\u0000-\u0008\u000b-\u001f\u007f-\u009f]/g;
4295
4316
  var CONTROL_RE = /[\u0000-\u001f\u007f-\u009f]/g;
4317
+ var BACKSLASH_BEFORE_PIPE_RE = /\\(?=\|)/g;
4296
4318
  function cut(text, max) {
4297
4319
  if (text.length <= max) return text;
4298
4320
  let out = text.slice(0, max);
@@ -4322,7 +4344,7 @@ function codePointLabel(ch) {
4322
4344
  }
4323
4345
  function codeSpan(text, maxLength = DEFAULT_SPAN_LENGTH) {
4324
4346
  const truncated = text.length > maxLength ? `${cut(text, maxLength)}\u2026` : text;
4325
- const content = truncated.replace(NEWLINE_RE, "\u23CE").replace(BIDI_CONTROL_RE, codePointLabel).replace(SPAN_CONTROL_RE, codePointLabel).replace(/\|/g, "\\|");
4347
+ const content = truncated.replace(NEWLINE_RE, "\u23CE").replace(BIDI_CONTROL_RE, codePointLabel).replace(SPAN_CONTROL_RE, codePointLabel).replace(BACKSLASH_BEFORE_PIPE_RE, codePointLabel).replace(/\|/g, "\\|");
4326
4348
  if (content === "") return "` `";
4327
4349
  const fence = "`".repeat(longestBacktickRun(content) + 1);
4328
4350
  const pad = /^[` ]|[` ]$/.test(content) ? " " : "";
@@ -5962,8 +5984,8 @@ function planGitignore(projectDir) {
5962
5984
  if (parseGitignore(current).ignores("public/livelocale", true)) {
5963
5985
  return { path: ".gitignore", action: "unchanged" };
5964
5986
  }
5965
- const sep10 = current === "" || current.endsWith("\n") ? "" : "\n";
5966
- return { path: ".gitignore", action: "update", content: `${current}${sep10}${SHARE_GITIGNORE}
5987
+ const sep9 = current === "" || current.endsWith("\n") ? "" : "\n";
5988
+ return { path: ".gitignore", action: "update", content: `${current}${sep9}${SHARE_GITIGNORE}
5967
5989
  ` };
5968
5990
  }
5969
5991
  function planBuild(c) {