message-resolver.cjs.prod.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /*!
  2. * @intlify/message-resolver v9.1.9
  3. * (c) 2021 kazuya kawaguchi
  4. * Released under the MIT License.
  5. */
  6. 'use strict';
  7. Object.defineProperty(exports, '__esModule', { value: true });
  8. /**
  9. * Original Utilities
  10. * written by kazuya kawaguchi
  11. */
  12. const hasOwnProperty = Object.prototype.hasOwnProperty;
  13. function hasOwn(obj, key) {
  14. return hasOwnProperty.call(obj, key);
  15. }
  16. const isObject = (val) => // eslint-disable-line
  17. val !== null && typeof val === 'object';
  18. const pathStateMachine = [];
  19. pathStateMachine[0 /* BEFORE_PATH */] = {
  20. ["w" /* WORKSPACE */]: [0 /* BEFORE_PATH */],
  21. ["i" /* IDENT */]: [3 /* IN_IDENT */, 0 /* APPEND */],
  22. ["[" /* LEFT_BRACKET */]: [4 /* IN_SUB_PATH */],
  23. ["o" /* END_OF_FAIL */]: [7 /* AFTER_PATH */]
  24. };
  25. pathStateMachine[1 /* IN_PATH */] = {
  26. ["w" /* WORKSPACE */]: [1 /* IN_PATH */],
  27. ["." /* DOT */]: [2 /* BEFORE_IDENT */],
  28. ["[" /* LEFT_BRACKET */]: [4 /* IN_SUB_PATH */],
  29. ["o" /* END_OF_FAIL */]: [7 /* AFTER_PATH */]
  30. };
  31. pathStateMachine[2 /* BEFORE_IDENT */] = {
  32. ["w" /* WORKSPACE */]: [2 /* BEFORE_IDENT */],
  33. ["i" /* IDENT */]: [3 /* IN_IDENT */, 0 /* APPEND */],
  34. ["0" /* ZERO */]: [3 /* IN_IDENT */, 0 /* APPEND */]
  35. };
  36. pathStateMachine[3 /* IN_IDENT */] = {
  37. ["i" /* IDENT */]: [3 /* IN_IDENT */, 0 /* APPEND */],
  38. ["0" /* ZERO */]: [3 /* IN_IDENT */, 0 /* APPEND */],
  39. ["w" /* WORKSPACE */]: [1 /* IN_PATH */, 1 /* PUSH */],
  40. ["." /* DOT */]: [2 /* BEFORE_IDENT */, 1 /* PUSH */],
  41. ["[" /* LEFT_BRACKET */]: [4 /* IN_SUB_PATH */, 1 /* PUSH */],
  42. ["o" /* END_OF_FAIL */]: [7 /* AFTER_PATH */, 1 /* PUSH */]
  43. };
  44. pathStateMachine[4 /* IN_SUB_PATH */] = {
  45. ["'" /* SINGLE_QUOTE */]: [5 /* IN_SINGLE_QUOTE */, 0 /* APPEND */],
  46. ["\"" /* DOUBLE_QUOTE */]: [6 /* IN_DOUBLE_QUOTE */, 0 /* APPEND */],
  47. ["[" /* LEFT_BRACKET */]: [
  48. 4 /* IN_SUB_PATH */,
  49. 2 /* INC_SUB_PATH_DEPTH */
  50. ],
  51. ["]" /* RIGHT_BRACKET */]: [1 /* IN_PATH */, 3 /* PUSH_SUB_PATH */],
  52. ["o" /* END_OF_FAIL */]: 8 /* ERROR */,
  53. ["l" /* ELSE */]: [4 /* IN_SUB_PATH */, 0 /* APPEND */]
  54. };
  55. pathStateMachine[5 /* IN_SINGLE_QUOTE */] = {
  56. ["'" /* SINGLE_QUOTE */]: [4 /* IN_SUB_PATH */, 0 /* APPEND */],
  57. ["o" /* END_OF_FAIL */]: 8 /* ERROR */,
  58. ["l" /* ELSE */]: [5 /* IN_SINGLE_QUOTE */, 0 /* APPEND */]
  59. };
  60. pathStateMachine[6 /* IN_DOUBLE_QUOTE */] = {
  61. ["\"" /* DOUBLE_QUOTE */]: [4 /* IN_SUB_PATH */, 0 /* APPEND */],
  62. ["o" /* END_OF_FAIL */]: 8 /* ERROR */,
  63. ["l" /* ELSE */]: [6 /* IN_DOUBLE_QUOTE */, 0 /* APPEND */]
  64. };
  65. /**
  66. * Check if an expression is a literal value.
  67. */
  68. const literalValueRE = /^\s?(?:true|false|-?[\d.]+|'[^']*'|"[^"]*")\s?$/;
  69. function isLiteral(exp) {
  70. return literalValueRE.test(exp);
  71. }
  72. /**
  73. * Strip quotes from a string
  74. */
  75. function stripQuotes(str) {
  76. const a = str.charCodeAt(0);
  77. const b = str.charCodeAt(str.length - 1);
  78. return a === b && (a === 0x22 || a === 0x27) ? str.slice(1, -1) : str;
  79. }
  80. /**
  81. * Determine the type of a character in a keypath.
  82. */
  83. function getPathCharType(ch) {
  84. if (ch === undefined || ch === null) {
  85. return "o" /* END_OF_FAIL */;
  86. }
  87. const code = ch.charCodeAt(0);
  88. switch (code) {
  89. case 0x5b: // [
  90. case 0x5d: // ]
  91. case 0x2e: // .
  92. case 0x22: // "
  93. case 0x27: // '
  94. return ch;
  95. case 0x5f: // _
  96. case 0x24: // $
  97. case 0x2d: // -
  98. return "i" /* IDENT */;
  99. case 0x09: // Tab (HT)
  100. case 0x0a: // Newline (LF)
  101. case 0x0d: // Return (CR)
  102. case 0xa0: // No-break space (NBSP)
  103. case 0xfeff: // Byte Order Mark (BOM)
  104. case 0x2028: // Line Separator (LS)
  105. case 0x2029: // Paragraph Separator (PS)
  106. return "w" /* WORKSPACE */;
  107. }
  108. return "i" /* IDENT */;
  109. }
  110. /**
  111. * Format a subPath, return its plain form if it is
  112. * a literal string or number. Otherwise prepend the
  113. * dynamic indicator (*).
  114. */
  115. function formatSubPath(path) {
  116. const trimmed = path.trim();
  117. // invalid leading 0
  118. if (path.charAt(0) === '0' && isNaN(parseInt(path))) {
  119. return false;
  120. }
  121. return isLiteral(trimmed)
  122. ? stripQuotes(trimmed)
  123. : "*" /* ASTARISK */ + trimmed;
  124. }
  125. /**
  126. * Parse a string path into an array of segments
  127. */
  128. function parse(path) {
  129. const keys = [];
  130. let index = -1;
  131. let mode = 0 /* BEFORE_PATH */;
  132. let subPathDepth = 0;
  133. let c;
  134. let key; // eslint-disable-line
  135. let newChar;
  136. let type;
  137. let transition;
  138. let action;
  139. let typeMap;
  140. const actions = [];
  141. actions[0 /* APPEND */] = () => {
  142. if (key === undefined) {
  143. key = newChar;
  144. }
  145. else {
  146. key += newChar;
  147. }
  148. };
  149. actions[1 /* PUSH */] = () => {
  150. if (key !== undefined) {
  151. keys.push(key);
  152. key = undefined;
  153. }
  154. };
  155. actions[2 /* INC_SUB_PATH_DEPTH */] = () => {
  156. actions[0 /* APPEND */]();
  157. subPathDepth++;
  158. };
  159. actions[3 /* PUSH_SUB_PATH */] = () => {
  160. if (subPathDepth > 0) {
  161. subPathDepth--;
  162. mode = 4 /* IN_SUB_PATH */;
  163. actions[0 /* APPEND */]();
  164. }
  165. else {
  166. subPathDepth = 0;
  167. if (key === undefined) {
  168. return false;
  169. }
  170. key = formatSubPath(key);
  171. if (key === false) {
  172. return false;
  173. }
  174. else {
  175. actions[1 /* PUSH */]();
  176. }
  177. }
  178. };
  179. function maybeUnescapeQuote() {
  180. const nextChar = path[index + 1];
  181. if ((mode === 5 /* IN_SINGLE_QUOTE */ &&
  182. nextChar === "'" /* SINGLE_QUOTE */) ||
  183. (mode === 6 /* IN_DOUBLE_QUOTE */ &&
  184. nextChar === "\"" /* DOUBLE_QUOTE */)) {
  185. index++;
  186. newChar = '\\' + nextChar;
  187. actions[0 /* APPEND */]();
  188. return true;
  189. }
  190. }
  191. while (mode !== null) {
  192. index++;
  193. c = path[index];
  194. if (c === '\\' && maybeUnescapeQuote()) {
  195. continue;
  196. }
  197. type = getPathCharType(c);
  198. typeMap = pathStateMachine[mode];
  199. transition = typeMap[type] || typeMap["l" /* ELSE */] || 8 /* ERROR */;
  200. // check parse error
  201. if (transition === 8 /* ERROR */) {
  202. return;
  203. }
  204. mode = transition[0];
  205. if (transition[1] !== undefined) {
  206. action = actions[transition[1]];
  207. if (action) {
  208. newChar = c;
  209. if (action() === false) {
  210. return;
  211. }
  212. }
  213. }
  214. // check parse finish
  215. if (mode === 7 /* AFTER_PATH */) {
  216. return keys;
  217. }
  218. }
  219. }
  220. // path token cache
  221. const cache = new Map();
  222. function resolveValue(obj, path) {
  223. // check object
  224. if (!isObject(obj)) {
  225. return null;
  226. }
  227. // parse path
  228. let hit = cache.get(path);
  229. if (!hit) {
  230. hit = parse(path);
  231. if (hit) {
  232. cache.set(path, hit);
  233. }
  234. }
  235. // check hit
  236. if (!hit) {
  237. return null;
  238. }
  239. // resolve path value
  240. const len = hit.length;
  241. let last = obj;
  242. let i = 0;
  243. while (i < len) {
  244. const val = last[hit[i]];
  245. if (val === undefined) {
  246. return null;
  247. }
  248. last = val;
  249. i++;
  250. }
  251. return last;
  252. }
  253. /**
  254. * Transform flat json in obj to normal json in obj
  255. */
  256. function handleFlatJson(obj) {
  257. // check obj
  258. if (!isObject(obj)) {
  259. return obj;
  260. }
  261. for (const key in obj) {
  262. // check key
  263. if (!hasOwn(obj, key)) {
  264. continue;
  265. }
  266. // handle for normal json
  267. if (!key.includes("." /* DOT */)) {
  268. // recursive process value if value is also a object
  269. if (isObject(obj[key])) {
  270. handleFlatJson(obj[key]);
  271. }
  272. }
  273. // handle for flat json, transform to normal json
  274. else {
  275. // go to the last object
  276. const subKeys = key.split("." /* DOT */);
  277. const lastIndex = subKeys.length - 1;
  278. let currentObj = obj;
  279. for (let i = 0; i < lastIndex; i++) {
  280. if (!(subKeys[i] in currentObj)) {
  281. currentObj[subKeys[i]] = {};
  282. }
  283. currentObj = currentObj[subKeys[i]];
  284. }
  285. // update last object value, delete old property
  286. currentObj[subKeys[lastIndex]] = obj[key];
  287. delete obj[key];
  288. // recursive process value if value is also a object
  289. if (isObject(currentObj[subKeys[lastIndex]])) {
  290. handleFlatJson(currentObj[subKeys[lastIndex]]);
  291. }
  292. }
  293. }
  294. return obj;
  295. }
  296. exports.handleFlatJson = handleFlatJson;
  297. exports.parse = parse;
  298. exports.resolveValue = resolveValue;