utils.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /**
  2. * @_ignore
  3. */
  4. import {
  5. getBytesCopy, assertArgument, toUtf8Bytes
  6. } from "../utils/index.js";
  7. export function looseArrayify(hexString: string): Uint8Array {
  8. if (typeof(hexString) === "string" && !hexString.startsWith("0x")) {
  9. hexString = "0x" + hexString;
  10. }
  11. return getBytesCopy(hexString);
  12. }
  13. export function zpad(value: String | number, length: number): String {
  14. value = String(value);
  15. while (value.length < length) { value = '0' + value; }
  16. return value;
  17. }
  18. export function getPassword(password: string | Uint8Array): Uint8Array {
  19. if (typeof(password) === 'string') {
  20. return toUtf8Bytes(password, "NFKC");
  21. }
  22. return getBytesCopy(password);
  23. }
  24. export function spelunk<T>(object: any, _path: string): T {
  25. const match = _path.match(/^([a-z0-9$_.-]*)(:([a-z]+))?(!)?$/i);
  26. assertArgument(match != null, "invalid path", "path", _path);
  27. const path = match[1];
  28. const type = match[3];
  29. const reqd = (match[4] === "!");
  30. let cur = object;
  31. for (const comp of path.toLowerCase().split('.')) {
  32. // Search for a child object with a case-insensitive matching key
  33. if (Array.isArray(cur)) {
  34. if (!comp.match(/^[0-9]+$/)) { break; }
  35. cur = cur[parseInt(comp)];
  36. } else if (typeof(cur) === "object") {
  37. let found: any = null;
  38. for (const key in cur) {
  39. if (key.toLowerCase() === comp) {
  40. found = cur[key];
  41. break;
  42. }
  43. }
  44. cur = found;
  45. } else {
  46. cur = null;
  47. }
  48. if (cur == null) { break; }
  49. }
  50. assertArgument(!reqd || cur != null, "missing required value", "path", path);
  51. if (type && cur != null) {
  52. if (type === "int") {
  53. if (typeof(cur) === "string" && cur.match(/^-?[0-9]+$/)) {
  54. return <T><unknown>parseInt(cur);
  55. } else if (Number.isSafeInteger(cur)) {
  56. return cur;
  57. }
  58. }
  59. if (type === "number") {
  60. if (typeof(cur) === "string" && cur.match(/^-?[0-9.]*$/)) {
  61. return <T><unknown>parseFloat(cur);
  62. }
  63. }
  64. if (type === "data") {
  65. if (typeof(cur) === "string") { return <T><unknown>looseArrayify(cur); }
  66. }
  67. if (type === "array" && Array.isArray(cur)) { return <T><unknown>cur; }
  68. if (type === typeof(cur)) { return cur; }
  69. assertArgument(false, `wrong type found for ${ type } `, "path", path);
  70. }
  71. return cur;
  72. }
  73. /*
  74. export function follow(object: any, path: string): null | string {
  75. let currentChild = object;
  76. for (const comp of path.toLowerCase().split('/')) {
  77. // Search for a child object with a case-insensitive matching key
  78. let matchingChild = null;
  79. for (const key in currentChild) {
  80. if (key.toLowerCase() === comp) {
  81. matchingChild = currentChild[key];
  82. break;
  83. }
  84. }
  85. if (matchingChild === null) { return null; }
  86. currentChild = matchingChild;
  87. }
  88. return currentChild;
  89. }
  90. // "path/to/something:type!"
  91. export function followRequired(data: any, path: string): string {
  92. const value = follow(data, path);
  93. if (value != null) { return value; }
  94. return logger.throwArgumentError("invalid value", `data:${ path }`,
  95. JSON.stringify(data));
  96. }
  97. */
  98. // See: https://www.ietf.org/rfc/rfc4122.txt (Section 4.4)
  99. /*
  100. export function uuidV4(randomBytes: BytesLike): string {
  101. const bytes = getBytes(randomBytes, "randomBytes");
  102. // Section: 4.1.3:
  103. // - time_hi_and_version[12:16] = 0b0100
  104. bytes[6] = (bytes[6] & 0x0f) | 0x40;
  105. // Section 4.4
  106. // - clock_seq_hi_and_reserved[6] = 0b0
  107. // - clock_seq_hi_and_reserved[7] = 0b1
  108. bytes[8] = (bytes[8] & 0x3f) | 0x80;
  109. const value = hexlify(bytes);
  110. return [
  111. value.substring(2, 10),
  112. value.substring(10, 14),
  113. value.substring(14, 18),
  114. value.substring(18, 22),
  115. value.substring(22, 34),
  116. ].join("-");
  117. }
  118. */