@n8n/utils 1.39.0 → 1.41.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.
Files changed (110) hide show
  1. package/dist/assert.cjs +2 -2
  2. package/dist/assert.cjs.map +1 -1
  3. package/dist/assert.mjs +1 -1
  4. package/dist/assert.mjs.map +1 -1
  5. package/dist/client-assertion.cjs +3 -3
  6. package/dist/client-assertion.cjs.map +1 -1
  7. package/dist/client-assertion.mjs +2 -3
  8. package/dist/client-assertion.mjs.map +1 -1
  9. package/dist/create-event-queue.cjs +2 -2
  10. package/dist/create-event-queue.cjs.map +1 -1
  11. package/dist/create-event-queue.mjs +1 -1
  12. package/dist/create-event-queue.mjs.map +1 -1
  13. package/dist/errors/ensure-error.cjs +9 -2
  14. package/dist/errors/ensure-error.cjs.map +1 -0
  15. package/dist/errors/ensure-error.mjs +8 -2
  16. package/dist/errors/ensure-error.mjs.map +1 -0
  17. package/dist/event-bus.cjs +2 -2
  18. package/dist/event-bus.cjs.map +1 -1
  19. package/dist/event-bus.d.cts +1 -1
  20. package/dist/event-bus.d.mts +1 -1
  21. package/dist/event-bus.mjs +1 -1
  22. package/dist/event-bus.mjs.map +1 -1
  23. package/dist/files/is-windows-file-path.cjs +2 -2
  24. package/dist/files/is-windows-file-path.cjs.map +1 -1
  25. package/dist/files/is-windows-file-path.mjs +1 -1
  26. package/dist/files/is-windows-file-path.mjs.map +1 -1
  27. package/dist/files/sanitize-filename.cjs +3 -3
  28. package/dist/files/sanitize-filename.cjs.map +1 -1
  29. package/dist/files/sanitize-filename.mjs +2 -2
  30. package/dist/files/sanitize-filename.mjs.map +1 -1
  31. package/dist/format-pem-block.cjs +41 -2
  32. package/dist/format-pem-block.cjs.map +1 -0
  33. package/dist/format-pem-block.mjs +40 -2
  34. package/dist/format-pem-block.mjs.map +1 -0
  35. package/dist/generate-nano-id.cjs +4 -5
  36. package/dist/generate-nano-id.cjs.map +1 -1
  37. package/dist/generate-nano-id.mjs +1 -2
  38. package/dist/generate-nano-id.mjs.map +1 -1
  39. package/dist/get-jwt-expiry.cjs +2 -2
  40. package/dist/get-jwt-expiry.cjs.map +1 -1
  41. package/dist/get-jwt-expiry.mjs +1 -1
  42. package/dist/get-jwt-expiry.mjs.map +1 -1
  43. package/dist/is-record.cjs +2 -2
  44. package/dist/is-record.cjs.map +1 -1
  45. package/dist/is-record.mjs +1 -1
  46. package/dist/is-record.mjs.map +1 -1
  47. package/dist/json/to-json-value.cjs +40 -0
  48. package/dist/json/to-json-value.cjs.map +1 -0
  49. package/dist/json/to-json-value.d.cts +10 -0
  50. package/dist/json/to-json-value.d.mts +10 -0
  51. package/dist/json/to-json-value.mjs +39 -0
  52. package/dist/json/to-json-value.mjs.map +1 -0
  53. package/dist/lazy-import.cjs +23 -0
  54. package/dist/lazy-import.cjs.map +1 -0
  55. package/dist/lazy-import.d.cts +5 -0
  56. package/dist/lazy-import.d.mts +5 -0
  57. package/dist/lazy-import.mjs +22 -0
  58. package/dist/lazy-import.mjs.map +1 -0
  59. package/dist/number/smart-decimal.cjs +2 -2
  60. package/dist/number/smart-decimal.cjs.map +1 -1
  61. package/dist/number/smart-decimal.mjs +1 -1
  62. package/dist/number/smart-decimal.mjs.map +1 -1
  63. package/dist/placeholder.cjs +2 -2
  64. package/dist/placeholder.cjs.map +1 -1
  65. package/dist/placeholder.mjs +1 -1
  66. package/dist/placeholder.mjs.map +1 -1
  67. package/dist/promise/deferred-promise.cjs +2 -2
  68. package/dist/promise/deferred-promise.cjs.map +1 -1
  69. package/dist/promise/deferred-promise.mjs +1 -1
  70. package/dist/promise/deferred-promise.mjs.map +1 -1
  71. package/dist/result.cjs +5 -4
  72. package/dist/result.cjs.map +1 -1
  73. package/dist/result.mjs +4 -4
  74. package/dist/result.mjs.map +1 -1
  75. package/dist/retry.cjs +2 -2
  76. package/dist/retry.cjs.map +1 -1
  77. package/dist/retry.mjs +1 -1
  78. package/dist/retry.mjs.map +1 -1
  79. package/dist/scrub-secrets.cjs +2 -2
  80. package/dist/scrub-secrets.cjs.map +1 -1
  81. package/dist/scrub-secrets.mjs +1 -1
  82. package/dist/scrub-secrets.mjs.map +1 -1
  83. package/dist/search/re-rank-search-results.cjs +2 -2
  84. package/dist/search/re-rank-search-results.cjs.map +1 -1
  85. package/dist/search/re-rank-search-results.mjs +1 -1
  86. package/dist/search/re-rank-search-results.mjs.map +1 -1
  87. package/dist/search/sublime-search.cjs +2 -2
  88. package/dist/search/sublime-search.cjs.map +1 -1
  89. package/dist/search/sublime-search.mjs +1 -1
  90. package/dist/search/sublime-search.mjs.map +1 -1
  91. package/dist/sort/sort-by-property.cjs +2 -2
  92. package/dist/sort/sort-by-property.cjs.map +1 -1
  93. package/dist/sort/sort-by-property.d.cts +1 -1
  94. package/dist/sort/sort-by-property.d.mts +1 -1
  95. package/dist/sort/sort-by-property.mjs +1 -1
  96. package/dist/sort/sort-by-property.mjs.map +1 -1
  97. package/dist/string/truncate.cjs +2 -2
  98. package/dist/string/truncate.cjs.map +1 -1
  99. package/dist/string/truncate.mjs +1 -1
  100. package/dist/string/truncate.mjs.map +1 -1
  101. package/dist/types.mjs +1 -1
  102. package/package.json +8 -8
  103. package/dist/ensure-error.cjs +0 -15
  104. package/dist/ensure-error.cjs.map +0 -1
  105. package/dist/ensure-error.mjs +0 -9
  106. package/dist/ensure-error.mjs.map +0 -1
  107. package/dist/format-pem-block2.cjs +0 -47
  108. package/dist/format-pem-block2.cjs.map +0 -1
  109. package/dist/format-pem-block2.mjs +0 -41
  110. package/dist/format-pem-block2.mjs.map +0 -1
package/dist/assert.cjs CHANGED
@@ -1,4 +1,4 @@
1
-
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#region src/assert.ts
3
3
  /**
4
4
  * Asserts given condition
@@ -6,7 +6,7 @@
6
6
  function assert(condition, message) {
7
7
  if (!condition) throw new Error(message ?? "Assertion failed");
8
8
  }
9
-
10
9
  //#endregion
11
10
  exports.assert = assert;
11
+
12
12
  //# sourceMappingURL=assert.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"assert.cjs","names":[],"sources":["../src/assert.ts"],"sourcesContent":["/**\n * Asserts given condition\n */\nexport function assert(condition: unknown, message?: string): asserts condition {\n\tif (!condition) {\n\t\t// eslint-disable-next-line n8n-local-rules/no-plain-errors\n\t\tthrow new Error(message ?? 'Assertion failed');\n\t}\n}\n"],"mappings":";;;;;AAGA,SAAgB,OAAO,WAAoB,SAAqC;AAC/E,KAAI,CAAC,UAEJ,OAAM,IAAI,MAAM,WAAW,mBAAmB"}
1
+ {"version":3,"file":"assert.cjs","names":[],"sources":["../src/assert.ts"],"sourcesContent":["/**\n * Asserts given condition\n */\nexport function assert(condition: unknown, message?: string): asserts condition {\n\tif (!condition) {\n\t\t// eslint-disable-next-line n8n-local-rules/no-plain-errors\n\t\tthrow new Error(message ?? 'Assertion failed');\n\t}\n}\n"],"mappings":";;;;;AAGA,SAAgB,OAAO,WAAoB,SAAqC;CAC/E,IAAI,CAAC,WAEJ,MAAM,IAAI,MAAM,WAAW,kBAAkB;AAE/C"}
package/dist/assert.mjs CHANGED
@@ -5,7 +5,7 @@
5
5
  function assert(condition, message) {
6
6
  if (!condition) throw new Error(message ?? "Assertion failed");
7
7
  }
8
-
9
8
  //#endregion
10
9
  export { assert };
10
+
11
11
  //# sourceMappingURL=assert.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"assert.mjs","names":[],"sources":["../src/assert.ts"],"sourcesContent":["/**\n * Asserts given condition\n */\nexport function assert(condition: unknown, message?: string): asserts condition {\n\tif (!condition) {\n\t\t// eslint-disable-next-line n8n-local-rules/no-plain-errors\n\t\tthrow new Error(message ?? 'Assertion failed');\n\t}\n}\n"],"mappings":";;;;AAGA,SAAgB,OAAO,WAAoB,SAAqC;AAC/E,KAAI,CAAC,UAEJ,OAAM,IAAI,MAAM,WAAW,mBAAmB"}
1
+ {"version":3,"file":"assert.mjs","names":[],"sources":["../src/assert.ts"],"sourcesContent":["/**\n * Asserts given condition\n */\nexport function assert(condition: unknown, message?: string): asserts condition {\n\tif (!condition) {\n\t\t// eslint-disable-next-line n8n-local-rules/no-plain-errors\n\t\tthrow new Error(message ?? 'Assertion failed');\n\t}\n}\n"],"mappings":";;;;AAGA,SAAgB,OAAO,WAAoB,SAAqC;CAC/E,IAAI,CAAC,WAEJ,MAAM,IAAI,MAAM,WAAW,kBAAkB;AAE/C"}
@@ -1,6 +1,6 @@
1
- const require_format_pem_block = require('./format-pem-block2.cjs');
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_format_pem_block = require("./format-pem-block.cjs");
2
3
  let node_crypto = require("node:crypto");
3
-
4
4
  //#region src/client-assertion.ts
5
5
  const CLIENT_ASSERTION_TYPE = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer";
6
6
  const ASSERTION_TTL_SECONDS = 300;
@@ -42,8 +42,8 @@ function buildClientAssertion(options) {
42
42
  const signingInput = `${base64url(JSON.stringify(header))}.${base64url(JSON.stringify(payload))}`;
43
43
  return `${signingInput}.${base64url((0, node_crypto.createSign)("RSA-SHA256").update(signingInput).sign(privateKey))}`;
44
44
  }
45
-
46
45
  //#endregion
47
46
  exports.CLIENT_ASSERTION_TYPE = CLIENT_ASSERTION_TYPE;
48
47
  exports.buildClientAssertion = buildClientAssertion;
48
+
49
49
  //# sourceMappingURL=client-assertion.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"client-assertion.cjs","names":["parsed: X509Certificate","X509Certificate","formatPemBlock","privateKey: KeyObject"],"sources":["../src/client-assertion.ts"],"sourcesContent":["import {\n\tcreatePrivateKey,\n\tcreateSign,\n\trandomUUID,\n\tX509Certificate,\n\ttype KeyObject,\n} from 'node:crypto';\n\nimport { formatPemBlock } from './format-pem-block';\n\n// private_key_jwt (RFC 7521/7523): the client proves its identity with a JWT\n// signed by its private key instead of a shared secret. The `x5t` header (SHA-1\n// thumbprint of the certificate) tells the server which public key verifies it.\nexport const CLIENT_ASSERTION_TYPE = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer';\n\nconst ASSERTION_TTL_SECONDS = 300;\n\nfunction base64url(input: Buffer | string): string {\n\treturn Buffer.from(input).toString('base64url');\n}\n\nfunction certificateThumbprint(certificate: string): string {\n\tlet parsed: X509Certificate;\n\ttry {\n\t\tparsed = new X509Certificate(formatPemBlock(certificate));\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t'The Certificate field must contain a PEM certificate (-----BEGIN CERTIFICATE-----).',\n\t\t\t{ cause: error },\n\t\t);\n\t}\n\treturn Buffer.from(parsed.fingerprint.replace(/:/g, ''), 'hex').toString('base64url');\n}\n\nexport interface BuildClientAssertionOptions {\n\tclientId: string;\n\t/** Token endpoint; used as the JWT `aud`. */\n\taccessTokenUri: string;\n\t/** RSA private key (PEM). Signing is RS256-only; EC/Ed25519 keys are not supported. */\n\tprivateKey: string;\n\tcertificate: string;\n}\n\nexport function buildClientAssertion(options: BuildClientAssertionOptions): string {\n\tconst now = Math.floor(Date.now() / 1000);\n\tconst header = { alg: 'RS256', typ: 'JWT', x5t: certificateThumbprint(options.certificate) };\n\tconst payload = {\n\t\taud: options.accessTokenUri,\n\t\tiss: options.clientId,\n\t\tsub: options.clientId,\n\t\tjti: randomUUID(),\n\t\tiat: now,\n\t\tnbf: now,\n\t\texp: now + ASSERTION_TTL_SECONDS,\n\t};\n\n\tlet privateKey: KeyObject;\n\ttry {\n\t\tprivateKey = createPrivateKey(formatPemBlock(options.privateKey));\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t'The Private Key field must contain a PEM private key (-----BEGIN PRIVATE KEY-----).',\n\t\t\t{ cause: error },\n\t\t);\n\t}\n\n\t// `createSign('RSA-SHA256')` also signs EC/Ed25519 keys, producing a signature\n\t// that contradicts the pinned `alg: RS256` header. Reject non-RSA keys up front.\n\tif (privateKey.asymmetricKeyType !== 'rsa') {\n\t\tthrow new Error('Certificate authentication requires an RSA private key');\n\t}\n\n\tconst signingInput = `${base64url(JSON.stringify(header))}.${base64url(JSON.stringify(payload))}`;\n\tconst signature = createSign('RSA-SHA256').update(signingInput).sign(privateKey);\n\treturn `${signingInput}.${base64url(signature)}`;\n}\n"],"mappings":";;;;AAaA,MAAa,wBAAwB;AAErC,MAAM,wBAAwB;AAE9B,SAAS,UAAU,OAAgC;AAClD,QAAO,OAAO,KAAK,MAAM,CAAC,SAAS,YAAY;;AAGhD,SAAS,sBAAsB,aAA6B;CAC3D,IAAIA;AACJ,KAAI;AACH,WAAS,IAAIC,4BAAgBC,wCAAe,YAAY,CAAC;UACjD,OAAO;AACf,QAAM,IAAI,MACT,uFACA,EAAE,OAAO,OAAO,CAChB;;AAEF,QAAO,OAAO,KAAK,OAAO,YAAY,QAAQ,MAAM,GAAG,EAAE,MAAM,CAAC,SAAS,YAAY;;AAYtF,SAAgB,qBAAqB,SAA8C;CAClF,MAAM,MAAM,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK;CACzC,MAAM,SAAS;EAAE,KAAK;EAAS,KAAK;EAAO,KAAK,sBAAsB,QAAQ,YAAY;EAAE;CAC5F,MAAM,UAAU;EACf,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,kCAAiB;EACjB,KAAK;EACL,KAAK;EACL,KAAK,MAAM;EACX;CAED,IAAIC;AACJ,KAAI;AACH,iDAA8BD,wCAAe,QAAQ,WAAW,CAAC;UACzD,OAAO;AACf,QAAM,IAAI,MACT,uFACA,EAAE,OAAO,OAAO,CAChB;;AAKF,KAAI,WAAW,sBAAsB,MACpC,OAAM,IAAI,MAAM,yDAAyD;CAG1E,MAAM,eAAe,GAAG,UAAU,KAAK,UAAU,OAAO,CAAC,CAAC,GAAG,UAAU,KAAK,UAAU,QAAQ,CAAC;AAE/F,QAAO,GAAG,aAAa,GAAG,sCADG,aAAa,CAAC,OAAO,aAAa,CAAC,KAAK,WAAW,CAClC"}
1
+ {"version":3,"file":"client-assertion.cjs","names":["X509Certificate","formatPemBlock"],"sources":["../src/client-assertion.ts"],"sourcesContent":["import {\n\tcreatePrivateKey,\n\tcreateSign,\n\trandomUUID,\n\tX509Certificate,\n\ttype KeyObject,\n} from 'node:crypto';\n\nimport { formatPemBlock } from './format-pem-block';\n\n// private_key_jwt (RFC 7521/7523): the client proves its identity with a JWT\n// signed by its private key instead of a shared secret. The `x5t` header (SHA-1\n// thumbprint of the certificate) tells the server which public key verifies it.\nexport const CLIENT_ASSERTION_TYPE = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer';\n\nconst ASSERTION_TTL_SECONDS = 300;\n\nfunction base64url(input: Buffer | string): string {\n\treturn Buffer.from(input).toString('base64url');\n}\n\nfunction certificateThumbprint(certificate: string): string {\n\tlet parsed: X509Certificate;\n\ttry {\n\t\tparsed = new X509Certificate(formatPemBlock(certificate));\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t'The Certificate field must contain a PEM certificate (-----BEGIN CERTIFICATE-----).',\n\t\t\t{ cause: error },\n\t\t);\n\t}\n\treturn Buffer.from(parsed.fingerprint.replace(/:/g, ''), 'hex').toString('base64url');\n}\n\nexport interface BuildClientAssertionOptions {\n\tclientId: string;\n\t/** Token endpoint; used as the JWT `aud`. */\n\taccessTokenUri: string;\n\t/** RSA private key (PEM). Signing is RS256-only; EC/Ed25519 keys are not supported. */\n\tprivateKey: string;\n\tcertificate: string;\n}\n\nexport function buildClientAssertion(options: BuildClientAssertionOptions): string {\n\tconst now = Math.floor(Date.now() / 1000);\n\tconst header = { alg: 'RS256', typ: 'JWT', x5t: certificateThumbprint(options.certificate) };\n\tconst payload = {\n\t\taud: options.accessTokenUri,\n\t\tiss: options.clientId,\n\t\tsub: options.clientId,\n\t\tjti: randomUUID(),\n\t\tiat: now,\n\t\tnbf: now,\n\t\texp: now + ASSERTION_TTL_SECONDS,\n\t};\n\n\tlet privateKey: KeyObject;\n\ttry {\n\t\tprivateKey = createPrivateKey(formatPemBlock(options.privateKey));\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t'The Private Key field must contain a PEM private key (-----BEGIN PRIVATE KEY-----).',\n\t\t\t{ cause: error },\n\t\t);\n\t}\n\n\t// `createSign('RSA-SHA256')` also signs EC/Ed25519 keys, producing a signature\n\t// that contradicts the pinned `alg: RS256` header. Reject non-RSA keys up front.\n\tif (privateKey.asymmetricKeyType !== 'rsa') {\n\t\tthrow new Error('Certificate authentication requires an RSA private key');\n\t}\n\n\tconst signingInput = `${base64url(JSON.stringify(header))}.${base64url(JSON.stringify(payload))}`;\n\tconst signature = createSign('RSA-SHA256').update(signingInput).sign(privateKey);\n\treturn `${signingInput}.${base64url(signature)}`;\n}\n"],"mappings":";;;;AAaA,MAAa,wBAAwB;AAErC,MAAM,wBAAwB;AAE9B,SAAS,UAAU,OAAgC;CAClD,OAAO,OAAO,KAAK,KAAK,CAAC,CAAC,SAAS,WAAW;AAC/C;AAEA,SAAS,sBAAsB,aAA6B;CAC3D,IAAI;CACJ,IAAI;EACH,SAAS,IAAIA,YAAAA,gBAAgBC,yBAAAA,eAAe,WAAW,CAAC;CACzD,SAAS,OAAO;EACf,MAAM,IAAI,MACT,uFACA,EAAE,OAAO,MAAM,CAChB;CACD;CACA,OAAO,OAAO,KAAK,OAAO,YAAY,QAAQ,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,SAAS,WAAW;AACrF;AAWA,SAAgB,qBAAqB,SAA8C;CAClF,MAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;CACxC,MAAM,SAAS;EAAE,KAAK;EAAS,KAAK;EAAO,KAAK,sBAAsB,QAAQ,WAAW;CAAE;CAC3F,MAAM,UAAU;EACf,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,MAAA,GAAA,YAAA,WAAA,CAAgB;EAChB,KAAK;EACL,KAAK;EACL,KAAK,MAAM;CACZ;CAEA,IAAI;CACJ,IAAI;EACH,cAAA,GAAA,YAAA,iBAAA,CAA8BA,yBAAAA,eAAe,QAAQ,UAAU,CAAC;CACjE,SAAS,OAAO;EACf,MAAM,IAAI,MACT,uFACA,EAAE,OAAO,MAAM,CAChB;CACD;CAIA,IAAI,WAAW,sBAAsB,OACpC,MAAM,IAAI,MAAM,wDAAwD;CAGzE,MAAM,eAAe,GAAG,UAAU,KAAK,UAAU,MAAM,CAAC,EAAE,GAAG,UAAU,KAAK,UAAU,OAAO,CAAC;CAE9F,OAAO,GAAG,aAAa,GAAG,WAAA,GAAA,YAAA,WAAA,CADG,YAAY,CAAC,CAAC,OAAO,YAAY,CAAC,CAAC,KAAK,UACzB,CAAC;AAC9C"}
@@ -1,6 +1,5 @@
1
- import { t as formatPemBlock } from "./format-pem-block2.mjs";
1
+ import { formatPemBlock } from "./format-pem-block.mjs";
2
2
  import { X509Certificate, createPrivateKey, createSign, randomUUID } from "node:crypto";
3
-
4
3
  //#region src/client-assertion.ts
5
4
  const CLIENT_ASSERTION_TYPE = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer";
6
5
  const ASSERTION_TTL_SECONDS = 300;
@@ -42,7 +41,7 @@ function buildClientAssertion(options) {
42
41
  const signingInput = `${base64url(JSON.stringify(header))}.${base64url(JSON.stringify(payload))}`;
43
42
  return `${signingInput}.${base64url(createSign("RSA-SHA256").update(signingInput).sign(privateKey))}`;
44
43
  }
45
-
46
44
  //#endregion
47
45
  export { CLIENT_ASSERTION_TYPE, buildClientAssertion };
46
+
48
47
  //# sourceMappingURL=client-assertion.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"client-assertion.mjs","names":["parsed: X509Certificate","privateKey: KeyObject"],"sources":["../src/client-assertion.ts"],"sourcesContent":["import {\n\tcreatePrivateKey,\n\tcreateSign,\n\trandomUUID,\n\tX509Certificate,\n\ttype KeyObject,\n} from 'node:crypto';\n\nimport { formatPemBlock } from './format-pem-block';\n\n// private_key_jwt (RFC 7521/7523): the client proves its identity with a JWT\n// signed by its private key instead of a shared secret. The `x5t` header (SHA-1\n// thumbprint of the certificate) tells the server which public key verifies it.\nexport const CLIENT_ASSERTION_TYPE = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer';\n\nconst ASSERTION_TTL_SECONDS = 300;\n\nfunction base64url(input: Buffer | string): string {\n\treturn Buffer.from(input).toString('base64url');\n}\n\nfunction certificateThumbprint(certificate: string): string {\n\tlet parsed: X509Certificate;\n\ttry {\n\t\tparsed = new X509Certificate(formatPemBlock(certificate));\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t'The Certificate field must contain a PEM certificate (-----BEGIN CERTIFICATE-----).',\n\t\t\t{ cause: error },\n\t\t);\n\t}\n\treturn Buffer.from(parsed.fingerprint.replace(/:/g, ''), 'hex').toString('base64url');\n}\n\nexport interface BuildClientAssertionOptions {\n\tclientId: string;\n\t/** Token endpoint; used as the JWT `aud`. */\n\taccessTokenUri: string;\n\t/** RSA private key (PEM). Signing is RS256-only; EC/Ed25519 keys are not supported. */\n\tprivateKey: string;\n\tcertificate: string;\n}\n\nexport function buildClientAssertion(options: BuildClientAssertionOptions): string {\n\tconst now = Math.floor(Date.now() / 1000);\n\tconst header = { alg: 'RS256', typ: 'JWT', x5t: certificateThumbprint(options.certificate) };\n\tconst payload = {\n\t\taud: options.accessTokenUri,\n\t\tiss: options.clientId,\n\t\tsub: options.clientId,\n\t\tjti: randomUUID(),\n\t\tiat: now,\n\t\tnbf: now,\n\t\texp: now + ASSERTION_TTL_SECONDS,\n\t};\n\n\tlet privateKey: KeyObject;\n\ttry {\n\t\tprivateKey = createPrivateKey(formatPemBlock(options.privateKey));\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t'The Private Key field must contain a PEM private key (-----BEGIN PRIVATE KEY-----).',\n\t\t\t{ cause: error },\n\t\t);\n\t}\n\n\t// `createSign('RSA-SHA256')` also signs EC/Ed25519 keys, producing a signature\n\t// that contradicts the pinned `alg: RS256` header. Reject non-RSA keys up front.\n\tif (privateKey.asymmetricKeyType !== 'rsa') {\n\t\tthrow new Error('Certificate authentication requires an RSA private key');\n\t}\n\n\tconst signingInput = `${base64url(JSON.stringify(header))}.${base64url(JSON.stringify(payload))}`;\n\tconst signature = createSign('RSA-SHA256').update(signingInput).sign(privateKey);\n\treturn `${signingInput}.${base64url(signature)}`;\n}\n"],"mappings":";;;;AAaA,MAAa,wBAAwB;AAErC,MAAM,wBAAwB;AAE9B,SAAS,UAAU,OAAgC;AAClD,QAAO,OAAO,KAAK,MAAM,CAAC,SAAS,YAAY;;AAGhD,SAAS,sBAAsB,aAA6B;CAC3D,IAAIA;AACJ,KAAI;AACH,WAAS,IAAI,gBAAgB,eAAe,YAAY,CAAC;UACjD,OAAO;AACf,QAAM,IAAI,MACT,uFACA,EAAE,OAAO,OAAO,CAChB;;AAEF,QAAO,OAAO,KAAK,OAAO,YAAY,QAAQ,MAAM,GAAG,EAAE,MAAM,CAAC,SAAS,YAAY;;AAYtF,SAAgB,qBAAqB,SAA8C;CAClF,MAAM,MAAM,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK;CACzC,MAAM,SAAS;EAAE,KAAK;EAAS,KAAK;EAAO,KAAK,sBAAsB,QAAQ,YAAY;EAAE;CAC5F,MAAM,UAAU;EACf,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,KAAK,YAAY;EACjB,KAAK;EACL,KAAK;EACL,KAAK,MAAM;EACX;CAED,IAAIC;AACJ,KAAI;AACH,eAAa,iBAAiB,eAAe,QAAQ,WAAW,CAAC;UACzD,OAAO;AACf,QAAM,IAAI,MACT,uFACA,EAAE,OAAO,OAAO,CAChB;;AAKF,KAAI,WAAW,sBAAsB,MACpC,OAAM,IAAI,MAAM,yDAAyD;CAG1E,MAAM,eAAe,GAAG,UAAU,KAAK,UAAU,OAAO,CAAC,CAAC,GAAG,UAAU,KAAK,UAAU,QAAQ,CAAC;AAE/F,QAAO,GAAG,aAAa,GAAG,UADR,WAAW,aAAa,CAAC,OAAO,aAAa,CAAC,KAAK,WAAW,CAClC"}
1
+ {"version":3,"file":"client-assertion.mjs","names":[],"sources":["../src/client-assertion.ts"],"sourcesContent":["import {\n\tcreatePrivateKey,\n\tcreateSign,\n\trandomUUID,\n\tX509Certificate,\n\ttype KeyObject,\n} from 'node:crypto';\n\nimport { formatPemBlock } from './format-pem-block';\n\n// private_key_jwt (RFC 7521/7523): the client proves its identity with a JWT\n// signed by its private key instead of a shared secret. The `x5t` header (SHA-1\n// thumbprint of the certificate) tells the server which public key verifies it.\nexport const CLIENT_ASSERTION_TYPE = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer';\n\nconst ASSERTION_TTL_SECONDS = 300;\n\nfunction base64url(input: Buffer | string): string {\n\treturn Buffer.from(input).toString('base64url');\n}\n\nfunction certificateThumbprint(certificate: string): string {\n\tlet parsed: X509Certificate;\n\ttry {\n\t\tparsed = new X509Certificate(formatPemBlock(certificate));\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t'The Certificate field must contain a PEM certificate (-----BEGIN CERTIFICATE-----).',\n\t\t\t{ cause: error },\n\t\t);\n\t}\n\treturn Buffer.from(parsed.fingerprint.replace(/:/g, ''), 'hex').toString('base64url');\n}\n\nexport interface BuildClientAssertionOptions {\n\tclientId: string;\n\t/** Token endpoint; used as the JWT `aud`. */\n\taccessTokenUri: string;\n\t/** RSA private key (PEM). Signing is RS256-only; EC/Ed25519 keys are not supported. */\n\tprivateKey: string;\n\tcertificate: string;\n}\n\nexport function buildClientAssertion(options: BuildClientAssertionOptions): string {\n\tconst now = Math.floor(Date.now() / 1000);\n\tconst header = { alg: 'RS256', typ: 'JWT', x5t: certificateThumbprint(options.certificate) };\n\tconst payload = {\n\t\taud: options.accessTokenUri,\n\t\tiss: options.clientId,\n\t\tsub: options.clientId,\n\t\tjti: randomUUID(),\n\t\tiat: now,\n\t\tnbf: now,\n\t\texp: now + ASSERTION_TTL_SECONDS,\n\t};\n\n\tlet privateKey: KeyObject;\n\ttry {\n\t\tprivateKey = createPrivateKey(formatPemBlock(options.privateKey));\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t'The Private Key field must contain a PEM private key (-----BEGIN PRIVATE KEY-----).',\n\t\t\t{ cause: error },\n\t\t);\n\t}\n\n\t// `createSign('RSA-SHA256')` also signs EC/Ed25519 keys, producing a signature\n\t// that contradicts the pinned `alg: RS256` header. Reject non-RSA keys up front.\n\tif (privateKey.asymmetricKeyType !== 'rsa') {\n\t\tthrow new Error('Certificate authentication requires an RSA private key');\n\t}\n\n\tconst signingInput = `${base64url(JSON.stringify(header))}.${base64url(JSON.stringify(payload))}`;\n\tconst signature = createSign('RSA-SHA256').update(signingInput).sign(privateKey);\n\treturn `${signingInput}.${base64url(signature)}`;\n}\n"],"mappings":";;;AAaA,MAAa,wBAAwB;AAErC,MAAM,wBAAwB;AAE9B,SAAS,UAAU,OAAgC;CAClD,OAAO,OAAO,KAAK,KAAK,CAAC,CAAC,SAAS,WAAW;AAC/C;AAEA,SAAS,sBAAsB,aAA6B;CAC3D,IAAI;CACJ,IAAI;EACH,SAAS,IAAI,gBAAgB,eAAe,WAAW,CAAC;CACzD,SAAS,OAAO;EACf,MAAM,IAAI,MACT,uFACA,EAAE,OAAO,MAAM,CAChB;CACD;CACA,OAAO,OAAO,KAAK,OAAO,YAAY,QAAQ,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,SAAS,WAAW;AACrF;AAWA,SAAgB,qBAAqB,SAA8C;CAClF,MAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;CACxC,MAAM,SAAS;EAAE,KAAK;EAAS,KAAK;EAAO,KAAK,sBAAsB,QAAQ,WAAW;CAAE;CAC3F,MAAM,UAAU;EACf,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,KAAK,WAAW;EAChB,KAAK;EACL,KAAK;EACL,KAAK,MAAM;CACZ;CAEA,IAAI;CACJ,IAAI;EACH,aAAa,iBAAiB,eAAe,QAAQ,UAAU,CAAC;CACjE,SAAS,OAAO;EACf,MAAM,IAAI,MACT,uFACA,EAAE,OAAO,MAAM,CAChB;CACD;CAIA,IAAI,WAAW,sBAAsB,OACpC,MAAM,IAAI,MAAM,wDAAwD;CAGzE,MAAM,eAAe,GAAG,UAAU,KAAK,UAAU,MAAM,CAAC,EAAE,GAAG,UAAU,KAAK,UAAU,OAAO,CAAC;CAE9F,OAAO,GAAG,aAAa,GAAG,UADR,WAAW,YAAY,CAAC,CAAC,OAAO,YAAY,CAAC,CAAC,KAAK,UACzB,CAAC;AAC9C"}
@@ -1,4 +1,4 @@
1
-
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#region src/create-event-queue.ts
3
3
  /**
4
4
  * Create an event queue that processes events sequentially.
@@ -35,7 +35,7 @@ function createEventQueue(processEvent) {
35
35
  }
36
36
  return { enqueue };
37
37
  }
38
-
39
38
  //#endregion
40
39
  exports.createEventQueue = createEventQueue;
40
+
41
41
  //# sourceMappingURL=create-event-queue.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-event-queue.cjs","names":["queue: T[]"],"sources":["../src/create-event-queue.ts"],"sourcesContent":["/**\n * Create an event queue that processes events sequentially.\n *\n * @param processEvent - Async function that processes a single event.\n * @returns A function that enqueues events for processing.\n */\nexport function createEventQueue<T>(processEvent: (event: T) => Promise<void>) {\n\t// The internal queue holding events.\n\tconst queue: T[] = [];\n\n\t// Flag to indicate whether an event is currently being processed.\n\tlet processing = false;\n\n\t/**\n\t * Process the next event in the queue (if not already processing).\n\t */\n\tasync function processNext(): Promise<void> {\n\t\tif (processing || queue.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tprocessing = true;\n\t\tconst currentEvent = queue.shift();\n\n\t\tif (currentEvent !== undefined) {\n\t\t\ttry {\n\t\t\t\tawait processEvent(currentEvent);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('Error processing event:', error);\n\t\t\t}\n\t\t}\n\n\t\tprocessing = false;\n\n\t\t// Recursively process the next event.\n\t\tawait processNext();\n\t}\n\n\t/**\n\t * Enqueue an event and trigger processing.\n\t *\n\t * @param event - The event to enqueue.\n\t */\n\tfunction enqueue(event: T): void {\n\t\tqueue.push(event);\n\t\tvoid processNext();\n\t}\n\n\treturn { enqueue };\n}\n"],"mappings":";;;;;;;;AAMA,SAAgB,iBAAoB,cAA2C;CAE9E,MAAMA,QAAa,EAAE;CAGrB,IAAI,aAAa;;;;CAKjB,eAAe,cAA6B;AAC3C,MAAI,cAAc,MAAM,WAAW,EAClC;AAGD,eAAa;EACb,MAAM,eAAe,MAAM,OAAO;AAElC,MAAI,iBAAiB,OACpB,KAAI;AACH,SAAM,aAAa,aAAa;WACxB,OAAO;AACf,WAAQ,MAAM,2BAA2B,MAAM;;AAIjD,eAAa;AAGb,QAAM,aAAa;;;;;;;CAQpB,SAAS,QAAQ,OAAgB;AAChC,QAAM,KAAK,MAAM;AACjB,EAAK,aAAa;;AAGnB,QAAO,EAAE,SAAS"}
1
+ {"version":3,"file":"create-event-queue.cjs","names":[],"sources":["../src/create-event-queue.ts"],"sourcesContent":["/**\n * Create an event queue that processes events sequentially.\n *\n * @param processEvent - Async function that processes a single event.\n * @returns A function that enqueues events for processing.\n */\nexport function createEventQueue<T>(processEvent: (event: T) => Promise<void>) {\n\t// The internal queue holding events.\n\tconst queue: T[] = [];\n\n\t// Flag to indicate whether an event is currently being processed.\n\tlet processing = false;\n\n\t/**\n\t * Process the next event in the queue (if not already processing).\n\t */\n\tasync function processNext(): Promise<void> {\n\t\tif (processing || queue.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tprocessing = true;\n\t\tconst currentEvent = queue.shift();\n\n\t\tif (currentEvent !== undefined) {\n\t\t\ttry {\n\t\t\t\tawait processEvent(currentEvent);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('Error processing event:', error);\n\t\t\t}\n\t\t}\n\n\t\tprocessing = false;\n\n\t\t// Recursively process the next event.\n\t\tawait processNext();\n\t}\n\n\t/**\n\t * Enqueue an event and trigger processing.\n\t *\n\t * @param event - The event to enqueue.\n\t */\n\tfunction enqueue(event: T): void {\n\t\tqueue.push(event);\n\t\tvoid processNext();\n\t}\n\n\treturn { enqueue };\n}\n"],"mappings":";;;;;;;;AAMA,SAAgB,iBAAoB,cAA2C;CAE9E,MAAM,QAAa,CAAC;CAGpB,IAAI,aAAa;;;;CAKjB,eAAe,cAA6B;EAC3C,IAAI,cAAc,MAAM,WAAW,GAClC;EAGD,aAAa;EACb,MAAM,eAAe,MAAM,MAAM;EAEjC,IAAI,iBAAiB,KAAA,GACpB,IAAI;GACH,MAAM,aAAa,YAAY;EAChC,SAAS,OAAO;GACf,QAAQ,MAAM,2BAA2B,KAAK;EAC/C;EAGD,aAAa;EAGb,MAAM,YAAY;CACnB;;;;;;CAOA,SAAS,QAAQ,OAAgB;EAChC,MAAM,KAAK,KAAK;EAChB,YAAiB;CAClB;CAEA,OAAO,EAAE,QAAQ;AAClB"}
@@ -34,7 +34,7 @@ function createEventQueue(processEvent) {
34
34
  }
35
35
  return { enqueue };
36
36
  }
37
-
38
37
  //#endregion
39
38
  export { createEventQueue };
39
+
40
40
  //# sourceMappingURL=create-event-queue.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-event-queue.mjs","names":["queue: T[]"],"sources":["../src/create-event-queue.ts"],"sourcesContent":["/**\n * Create an event queue that processes events sequentially.\n *\n * @param processEvent - Async function that processes a single event.\n * @returns A function that enqueues events for processing.\n */\nexport function createEventQueue<T>(processEvent: (event: T) => Promise<void>) {\n\t// The internal queue holding events.\n\tconst queue: T[] = [];\n\n\t// Flag to indicate whether an event is currently being processed.\n\tlet processing = false;\n\n\t/**\n\t * Process the next event in the queue (if not already processing).\n\t */\n\tasync function processNext(): Promise<void> {\n\t\tif (processing || queue.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tprocessing = true;\n\t\tconst currentEvent = queue.shift();\n\n\t\tif (currentEvent !== undefined) {\n\t\t\ttry {\n\t\t\t\tawait processEvent(currentEvent);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('Error processing event:', error);\n\t\t\t}\n\t\t}\n\n\t\tprocessing = false;\n\n\t\t// Recursively process the next event.\n\t\tawait processNext();\n\t}\n\n\t/**\n\t * Enqueue an event and trigger processing.\n\t *\n\t * @param event - The event to enqueue.\n\t */\n\tfunction enqueue(event: T): void {\n\t\tqueue.push(event);\n\t\tvoid processNext();\n\t}\n\n\treturn { enqueue };\n}\n"],"mappings":";;;;;;;AAMA,SAAgB,iBAAoB,cAA2C;CAE9E,MAAMA,QAAa,EAAE;CAGrB,IAAI,aAAa;;;;CAKjB,eAAe,cAA6B;AAC3C,MAAI,cAAc,MAAM,WAAW,EAClC;AAGD,eAAa;EACb,MAAM,eAAe,MAAM,OAAO;AAElC,MAAI,iBAAiB,OACpB,KAAI;AACH,SAAM,aAAa,aAAa;WACxB,OAAO;AACf,WAAQ,MAAM,2BAA2B,MAAM;;AAIjD,eAAa;AAGb,QAAM,aAAa;;;;;;;CAQpB,SAAS,QAAQ,OAAgB;AAChC,QAAM,KAAK,MAAM;AACjB,EAAK,aAAa;;AAGnB,QAAO,EAAE,SAAS"}
1
+ {"version":3,"file":"create-event-queue.mjs","names":[],"sources":["../src/create-event-queue.ts"],"sourcesContent":["/**\n * Create an event queue that processes events sequentially.\n *\n * @param processEvent - Async function that processes a single event.\n * @returns A function that enqueues events for processing.\n */\nexport function createEventQueue<T>(processEvent: (event: T) => Promise<void>) {\n\t// The internal queue holding events.\n\tconst queue: T[] = [];\n\n\t// Flag to indicate whether an event is currently being processed.\n\tlet processing = false;\n\n\t/**\n\t * Process the next event in the queue (if not already processing).\n\t */\n\tasync function processNext(): Promise<void> {\n\t\tif (processing || queue.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tprocessing = true;\n\t\tconst currentEvent = queue.shift();\n\n\t\tif (currentEvent !== undefined) {\n\t\t\ttry {\n\t\t\t\tawait processEvent(currentEvent);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('Error processing event:', error);\n\t\t\t}\n\t\t}\n\n\t\tprocessing = false;\n\n\t\t// Recursively process the next event.\n\t\tawait processNext();\n\t}\n\n\t/**\n\t * Enqueue an event and trigger processing.\n\t *\n\t * @param event - The event to enqueue.\n\t */\n\tfunction enqueue(event: T): void {\n\t\tqueue.push(event);\n\t\tvoid processNext();\n\t}\n\n\treturn { enqueue };\n}\n"],"mappings":";;;;;;;AAMA,SAAgB,iBAAoB,cAA2C;CAE9E,MAAM,QAAa,CAAC;CAGpB,IAAI,aAAa;;;;CAKjB,eAAe,cAA6B;EAC3C,IAAI,cAAc,MAAM,WAAW,GAClC;EAGD,aAAa;EACb,MAAM,eAAe,MAAM,MAAM;EAEjC,IAAI,iBAAiB,KAAA,GACpB,IAAI;GACH,MAAM,aAAa,YAAY;EAChC,SAAS,OAAO;GACf,QAAQ,MAAM,2BAA2B,KAAK;EAC/C;EAGD,aAAa;EAGb,MAAM,YAAY;CACnB;;;;;;CAOA,SAAS,QAAQ,OAAgB;EAChC,MAAM,KAAK,KAAK;EAChB,YAAiB;CAClB;CAEA,OAAO,EAAE,QAAQ;AAClB"}
@@ -1,3 +1,10 @@
1
- const require_ensure_error = require('../ensure-error.cjs');
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/errors/ensure-error.ts
3
+ /** Ensures `error` is an `Error */
4
+ function ensureError(error) {
5
+ return error instanceof Error ? error : new Error("Error that was not an instance of Error was thrown", { cause: error });
6
+ }
7
+ //#endregion
8
+ exports.ensureError = ensureError;
2
9
 
3
- exports.ensureError = require_ensure_error.ensureError;
10
+ //# sourceMappingURL=ensure-error.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ensure-error.cjs","names":[],"sources":["../../src/errors/ensure-error.ts"],"sourcesContent":["/** Ensures `error` is an `Error */\nexport function ensureError(error: unknown): Error {\n\treturn error instanceof Error\n\t\t? error\n\t\t: new Error('Error that was not an instance of Error was thrown', {\n\t\t\t\t// We should never throw anything except something that derives from Error\n\t\t\t\tcause: error,\n\t\t\t});\n}\n"],"mappings":";;;AACA,SAAgB,YAAY,OAAuB;CAClD,OAAO,iBAAiB,QACrB,QACA,IAAI,MAAM,sDAAsD,EAEhE,OAAO,MACR,CAAC;AACJ"}
@@ -1,3 +1,9 @@
1
- import { t as ensureError } from "../ensure-error.mjs";
1
+ //#region src/errors/ensure-error.ts
2
+ /** Ensures `error` is an `Error */
3
+ function ensureError(error) {
4
+ return error instanceof Error ? error : new Error("Error that was not an instance of Error was thrown", { cause: error });
5
+ }
6
+ //#endregion
7
+ export { ensureError };
2
8
 
3
- export { ensureError };
9
+ //# sourceMappingURL=ensure-error.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ensure-error.mjs","names":[],"sources":["../../src/errors/ensure-error.ts"],"sourcesContent":["/** Ensures `error` is an `Error */\nexport function ensureError(error: unknown): Error {\n\treturn error instanceof Error\n\t\t? error\n\t\t: new Error('Error that was not an instance of Error was thrown', {\n\t\t\t\t// We should never throw anything except something that derives from Error\n\t\t\t\tcause: error,\n\t\t\t});\n}\n"],"mappings":";;AACA,SAAgB,YAAY,OAAuB;CAClD,OAAO,iBAAiB,QACrB,QACA,IAAI,MAAM,sDAAsD,EAEhE,OAAO,MACR,CAAC;AACJ"}
@@ -1,4 +1,4 @@
1
-
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#region src/event-bus.ts
3
3
  /**
4
4
  * Creates an event bus with the given listener map.
@@ -38,7 +38,7 @@ function createEventBus() {
38
38
  }
39
39
  };
40
40
  }
41
-
42
41
  //#endregion
43
42
  exports.createEventBus = createEventBus;
43
+
44
44
  //# sourceMappingURL=event-bus.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"event-bus.cjs","names":["handler: typeof fn"],"sources":["../src/event-bus.ts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type CallbackFn = (...args: any[]) => any;\n\ntype Payloads<ListenerMap> = {\n\t[E in keyof ListenerMap]: unknown;\n};\n\ntype Listener<Payload> = (payload: Payload) => void;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface EventBus<ListenerMap extends Payloads<ListenerMap> = Record<string, any>> {\n\ton<EventName extends keyof ListenerMap & string>(\n\t\teventName: EventName,\n\t\tfn: Listener<ListenerMap[EventName]>,\n\t): void;\n\n\tonce<EventName extends keyof ListenerMap & string>(\n\t\teventName: EventName,\n\t\tfn: Listener<ListenerMap[EventName]>,\n\t): void;\n\n\toff<EventName extends keyof ListenerMap & string>(\n\t\teventName: EventName,\n\t\tfn: Listener<ListenerMap[EventName]>,\n\t): void;\n\n\temit<EventName extends keyof ListenerMap & string>(\n\t\teventName: EventName,\n\t\tevent?: ListenerMap[EventName],\n\t): void;\n}\n\n/**\n * Creates an event bus with the given listener map.\n *\n * @example\n * ```ts\n * const eventBus = createEventBus<{\n * 'user-logged-in': { username: string };\n * 'user-logged-out': never;\n * }>();\n */\nexport function createEventBus<\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tListenerMap extends Payloads<ListenerMap> = Record<string, any>,\n>(): EventBus<ListenerMap> {\n\tconst handlers = new Map<string, CallbackFn[]>();\n\n\treturn {\n\t\ton(eventName, fn) {\n\t\t\tlet eventFns = handlers.get(eventName);\n\t\t\tif (!eventFns) {\n\t\t\t\teventFns = [fn];\n\t\t\t} else {\n\t\t\t\teventFns.push(fn);\n\t\t\t}\n\t\t\thandlers.set(eventName, eventFns);\n\t\t},\n\n\t\tonce(eventName, fn) {\n\t\t\tconst handler: typeof fn = (payload) => {\n\t\t\t\tthis.off(eventName, handler);\n\t\t\t\tfn(payload);\n\t\t\t};\n\t\t\tthis.on(eventName, handler);\n\t\t},\n\n\t\toff(eventName, fn) {\n\t\t\tconst eventFns = handlers.get(eventName);\n\t\t\tif (eventFns) {\n\t\t\t\teventFns.splice(eventFns.indexOf(fn) >>> 0, 1);\n\t\t\t}\n\t\t},\n\n\t\temit(eventName, event) {\n\t\t\tconst eventFns = handlers.get(eventName);\n\t\t\tif (eventFns) {\n\t\t\t\teventFns.slice().forEach((handler) => {\n\t\t\t\t\thandler(event);\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;;;;;AA0CA,SAAgB,iBAGW;CAC1B,MAAM,2BAAW,IAAI,KAA2B;AAEhD,QAAO;EACN,GAAG,WAAW,IAAI;GACjB,IAAI,WAAW,SAAS,IAAI,UAAU;AACtC,OAAI,CAAC,SACJ,YAAW,CAAC,GAAG;OAEf,UAAS,KAAK,GAAG;AAElB,YAAS,IAAI,WAAW,SAAS;;EAGlC,KAAK,WAAW,IAAI;GACnB,MAAMA,WAAsB,YAAY;AACvC,SAAK,IAAI,WAAW,QAAQ;AAC5B,OAAG,QAAQ;;AAEZ,QAAK,GAAG,WAAW,QAAQ;;EAG5B,IAAI,WAAW,IAAI;GAClB,MAAM,WAAW,SAAS,IAAI,UAAU;AACxC,OAAI,SACH,UAAS,OAAO,SAAS,QAAQ,GAAG,KAAK,GAAG,EAAE;;EAIhD,KAAK,WAAW,OAAO;GACtB,MAAM,WAAW,SAAS,IAAI,UAAU;AACxC,OAAI,SACH,UAAS,OAAO,CAAC,SAAS,YAAY;AACrC,YAAQ,MAAM;KACb;;EAGJ"}
1
+ {"version":3,"file":"event-bus.cjs","names":[],"sources":["../src/event-bus.ts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type CallbackFn = (...args: any[]) => any;\n\ntype Payloads<ListenerMap> = {\n\t[E in keyof ListenerMap]: unknown;\n};\n\ntype Listener<Payload> = (payload: Payload) => void;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface EventBus<ListenerMap extends Payloads<ListenerMap> = Record<string, any>> {\n\ton<EventName extends keyof ListenerMap & string>(\n\t\teventName: EventName,\n\t\tfn: Listener<ListenerMap[EventName]>,\n\t): void;\n\n\tonce<EventName extends keyof ListenerMap & string>(\n\t\teventName: EventName,\n\t\tfn: Listener<ListenerMap[EventName]>,\n\t): void;\n\n\toff<EventName extends keyof ListenerMap & string>(\n\t\teventName: EventName,\n\t\tfn: Listener<ListenerMap[EventName]>,\n\t): void;\n\n\temit<EventName extends keyof ListenerMap & string>(\n\t\teventName: EventName,\n\t\tevent?: ListenerMap[EventName],\n\t): void;\n}\n\n/**\n * Creates an event bus with the given listener map.\n *\n * @example\n * ```ts\n * const eventBus = createEventBus<{\n * 'user-logged-in': { username: string };\n * 'user-logged-out': never;\n * }>();\n */\nexport function createEventBus<\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tListenerMap extends Payloads<ListenerMap> = Record<string, any>,\n>(): EventBus<ListenerMap> {\n\tconst handlers = new Map<string, CallbackFn[]>();\n\n\treturn {\n\t\ton(eventName, fn) {\n\t\t\tlet eventFns = handlers.get(eventName);\n\t\t\tif (!eventFns) {\n\t\t\t\teventFns = [fn];\n\t\t\t} else {\n\t\t\t\teventFns.push(fn);\n\t\t\t}\n\t\t\thandlers.set(eventName, eventFns);\n\t\t},\n\n\t\tonce(eventName, fn) {\n\t\t\tconst handler: typeof fn = (payload) => {\n\t\t\t\tthis.off(eventName, handler);\n\t\t\t\tfn(payload);\n\t\t\t};\n\t\t\tthis.on(eventName, handler);\n\t\t},\n\n\t\toff(eventName, fn) {\n\t\t\tconst eventFns = handlers.get(eventName);\n\t\t\tif (eventFns) {\n\t\t\t\teventFns.splice(eventFns.indexOf(fn) >>> 0, 1);\n\t\t\t}\n\t\t},\n\n\t\temit(eventName, event) {\n\t\t\tconst eventFns = handlers.get(eventName);\n\t\t\tif (eventFns) {\n\t\t\t\teventFns.slice().forEach((handler) => {\n\t\t\t\t\thandler(event);\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;;;;;AA0CA,SAAgB,iBAGW;CAC1B,MAAM,2BAAW,IAAI,IAA0B;CAE/C,OAAO;EACN,GAAG,WAAW,IAAI;GACjB,IAAI,WAAW,SAAS,IAAI,SAAS;GACrC,IAAI,CAAC,UACJ,WAAW,CAAC,EAAE;QAEd,SAAS,KAAK,EAAE;GAEjB,SAAS,IAAI,WAAW,QAAQ;EACjC;EAEA,KAAK,WAAW,IAAI;GACnB,MAAM,WAAsB,YAAY;IACvC,KAAK,IAAI,WAAW,OAAO;IAC3B,GAAG,OAAO;GACX;GACA,KAAK,GAAG,WAAW,OAAO;EAC3B;EAEA,IAAI,WAAW,IAAI;GAClB,MAAM,WAAW,SAAS,IAAI,SAAS;GACvC,IAAI,UACH,SAAS,OAAO,SAAS,QAAQ,EAAE,MAAM,GAAG,CAAC;EAE/C;EAEA,KAAK,WAAW,OAAO;GACtB,MAAM,WAAW,SAAS,IAAI,SAAS;GACvC,IAAI,UACH,SAAS,MAAM,CAAC,CAAC,SAAS,YAAY;IACrC,QAAQ,KAAK;GACd,CAAC;EAEH;CACD;AACD"}
@@ -1,6 +1,6 @@
1
1
  //#region src/event-bus.d.ts
2
2
  type CallbackFn = (...args: any[]) => any;
3
- type Payloads<ListenerMap> = { [E in keyof ListenerMap]: unknown };
3
+ type Payloads<ListenerMap> = { [E in keyof ListenerMap]: unknown; };
4
4
  type Listener<Payload> = (payload: Payload) => void;
5
5
  interface EventBus<ListenerMap extends Payloads<ListenerMap> = Record<string, any>> {
6
6
  on<EventName extends keyof ListenerMap & string>(eventName: EventName, fn: Listener<ListenerMap[EventName]>): void;
@@ -1,6 +1,6 @@
1
1
  //#region src/event-bus.d.ts
2
2
  type CallbackFn = (...args: any[]) => any;
3
- type Payloads<ListenerMap> = { [E in keyof ListenerMap]: unknown };
3
+ type Payloads<ListenerMap> = { [E in keyof ListenerMap]: unknown; };
4
4
  type Listener<Payload> = (payload: Payload) => void;
5
5
  interface EventBus<ListenerMap extends Payloads<ListenerMap> = Record<string, any>> {
6
6
  on<EventName extends keyof ListenerMap & string>(eventName: EventName, fn: Listener<ListenerMap[EventName]>): void;
@@ -37,7 +37,7 @@ function createEventBus() {
37
37
  }
38
38
  };
39
39
  }
40
-
41
40
  //#endregion
42
41
  export { createEventBus };
42
+
43
43
  //# sourceMappingURL=event-bus.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"event-bus.mjs","names":["handler: typeof fn"],"sources":["../src/event-bus.ts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type CallbackFn = (...args: any[]) => any;\n\ntype Payloads<ListenerMap> = {\n\t[E in keyof ListenerMap]: unknown;\n};\n\ntype Listener<Payload> = (payload: Payload) => void;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface EventBus<ListenerMap extends Payloads<ListenerMap> = Record<string, any>> {\n\ton<EventName extends keyof ListenerMap & string>(\n\t\teventName: EventName,\n\t\tfn: Listener<ListenerMap[EventName]>,\n\t): void;\n\n\tonce<EventName extends keyof ListenerMap & string>(\n\t\teventName: EventName,\n\t\tfn: Listener<ListenerMap[EventName]>,\n\t): void;\n\n\toff<EventName extends keyof ListenerMap & string>(\n\t\teventName: EventName,\n\t\tfn: Listener<ListenerMap[EventName]>,\n\t): void;\n\n\temit<EventName extends keyof ListenerMap & string>(\n\t\teventName: EventName,\n\t\tevent?: ListenerMap[EventName],\n\t): void;\n}\n\n/**\n * Creates an event bus with the given listener map.\n *\n * @example\n * ```ts\n * const eventBus = createEventBus<{\n * 'user-logged-in': { username: string };\n * 'user-logged-out': never;\n * }>();\n */\nexport function createEventBus<\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tListenerMap extends Payloads<ListenerMap> = Record<string, any>,\n>(): EventBus<ListenerMap> {\n\tconst handlers = new Map<string, CallbackFn[]>();\n\n\treturn {\n\t\ton(eventName, fn) {\n\t\t\tlet eventFns = handlers.get(eventName);\n\t\t\tif (!eventFns) {\n\t\t\t\teventFns = [fn];\n\t\t\t} else {\n\t\t\t\teventFns.push(fn);\n\t\t\t}\n\t\t\thandlers.set(eventName, eventFns);\n\t\t},\n\n\t\tonce(eventName, fn) {\n\t\t\tconst handler: typeof fn = (payload) => {\n\t\t\t\tthis.off(eventName, handler);\n\t\t\t\tfn(payload);\n\t\t\t};\n\t\t\tthis.on(eventName, handler);\n\t\t},\n\n\t\toff(eventName, fn) {\n\t\t\tconst eventFns = handlers.get(eventName);\n\t\t\tif (eventFns) {\n\t\t\t\teventFns.splice(eventFns.indexOf(fn) >>> 0, 1);\n\t\t\t}\n\t\t},\n\n\t\temit(eventName, event) {\n\t\t\tconst eventFns = handlers.get(eventName);\n\t\t\tif (eventFns) {\n\t\t\t\teventFns.slice().forEach((handler) => {\n\t\t\t\t\thandler(event);\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;;;;AA0CA,SAAgB,iBAGW;CAC1B,MAAM,2BAAW,IAAI,KAA2B;AAEhD,QAAO;EACN,GAAG,WAAW,IAAI;GACjB,IAAI,WAAW,SAAS,IAAI,UAAU;AACtC,OAAI,CAAC,SACJ,YAAW,CAAC,GAAG;OAEf,UAAS,KAAK,GAAG;AAElB,YAAS,IAAI,WAAW,SAAS;;EAGlC,KAAK,WAAW,IAAI;GACnB,MAAMA,WAAsB,YAAY;AACvC,SAAK,IAAI,WAAW,QAAQ;AAC5B,OAAG,QAAQ;;AAEZ,QAAK,GAAG,WAAW,QAAQ;;EAG5B,IAAI,WAAW,IAAI;GAClB,MAAM,WAAW,SAAS,IAAI,UAAU;AACxC,OAAI,SACH,UAAS,OAAO,SAAS,QAAQ,GAAG,KAAK,GAAG,EAAE;;EAIhD,KAAK,WAAW,OAAO;GACtB,MAAM,WAAW,SAAS,IAAI,UAAU;AACxC,OAAI,SACH,UAAS,OAAO,CAAC,SAAS,YAAY;AACrC,YAAQ,MAAM;KACb;;EAGJ"}
1
+ {"version":3,"file":"event-bus.mjs","names":[],"sources":["../src/event-bus.ts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type CallbackFn = (...args: any[]) => any;\n\ntype Payloads<ListenerMap> = {\n\t[E in keyof ListenerMap]: unknown;\n};\n\ntype Listener<Payload> = (payload: Payload) => void;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface EventBus<ListenerMap extends Payloads<ListenerMap> = Record<string, any>> {\n\ton<EventName extends keyof ListenerMap & string>(\n\t\teventName: EventName,\n\t\tfn: Listener<ListenerMap[EventName]>,\n\t): void;\n\n\tonce<EventName extends keyof ListenerMap & string>(\n\t\teventName: EventName,\n\t\tfn: Listener<ListenerMap[EventName]>,\n\t): void;\n\n\toff<EventName extends keyof ListenerMap & string>(\n\t\teventName: EventName,\n\t\tfn: Listener<ListenerMap[EventName]>,\n\t): void;\n\n\temit<EventName extends keyof ListenerMap & string>(\n\t\teventName: EventName,\n\t\tevent?: ListenerMap[EventName],\n\t): void;\n}\n\n/**\n * Creates an event bus with the given listener map.\n *\n * @example\n * ```ts\n * const eventBus = createEventBus<{\n * 'user-logged-in': { username: string };\n * 'user-logged-out': never;\n * }>();\n */\nexport function createEventBus<\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tListenerMap extends Payloads<ListenerMap> = Record<string, any>,\n>(): EventBus<ListenerMap> {\n\tconst handlers = new Map<string, CallbackFn[]>();\n\n\treturn {\n\t\ton(eventName, fn) {\n\t\t\tlet eventFns = handlers.get(eventName);\n\t\t\tif (!eventFns) {\n\t\t\t\teventFns = [fn];\n\t\t\t} else {\n\t\t\t\teventFns.push(fn);\n\t\t\t}\n\t\t\thandlers.set(eventName, eventFns);\n\t\t},\n\n\t\tonce(eventName, fn) {\n\t\t\tconst handler: typeof fn = (payload) => {\n\t\t\t\tthis.off(eventName, handler);\n\t\t\t\tfn(payload);\n\t\t\t};\n\t\t\tthis.on(eventName, handler);\n\t\t},\n\n\t\toff(eventName, fn) {\n\t\t\tconst eventFns = handlers.get(eventName);\n\t\t\tif (eventFns) {\n\t\t\t\teventFns.splice(eventFns.indexOf(fn) >>> 0, 1);\n\t\t\t}\n\t\t},\n\n\t\temit(eventName, event) {\n\t\t\tconst eventFns = handlers.get(eventName);\n\t\t\tif (eventFns) {\n\t\t\t\teventFns.slice().forEach((handler) => {\n\t\t\t\t\thandler(event);\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;;;;AA0CA,SAAgB,iBAGW;CAC1B,MAAM,2BAAW,IAAI,IAA0B;CAE/C,OAAO;EACN,GAAG,WAAW,IAAI;GACjB,IAAI,WAAW,SAAS,IAAI,SAAS;GACrC,IAAI,CAAC,UACJ,WAAW,CAAC,EAAE;QAEd,SAAS,KAAK,EAAE;GAEjB,SAAS,IAAI,WAAW,QAAQ;EACjC;EAEA,KAAK,WAAW,IAAI;GACnB,MAAM,WAAsB,YAAY;IACvC,KAAK,IAAI,WAAW,OAAO;IAC3B,GAAG,OAAO;GACX;GACA,KAAK,GAAG,WAAW,OAAO;EAC3B;EAEA,IAAI,WAAW,IAAI;GAClB,MAAM,WAAW,SAAS,IAAI,SAAS;GACvC,IAAI,UACH,SAAS,OAAO,SAAS,QAAQ,EAAE,MAAM,GAAG,CAAC;EAE/C;EAEA,KAAK,WAAW,OAAO;GACtB,MAAM,WAAW,SAAS,IAAI,SAAS;GACvC,IAAI,UACH,SAAS,MAAM,CAAC,CAAC,SAAS,YAAY;IACrC,QAAQ,KAAK;GACd,CAAC;EAEH;CACD;AACD"}
@@ -1,4 +1,4 @@
1
-
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#region src/files/is-windows-file-path.ts
3
3
  /**
4
4
  * Fast check if file path starts with a windows drive letter, e.g. 'C:/' or 'C:\\'
@@ -6,7 +6,7 @@
6
6
  function isWindowsFilePath(str) {
7
7
  return /^[a-zA-Z]:[\\/]/.test(str);
8
8
  }
9
-
10
9
  //#endregion
11
10
  exports.isWindowsFilePath = isWindowsFilePath;
11
+
12
12
  //# sourceMappingURL=is-windows-file-path.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"is-windows-file-path.cjs","names":[],"sources":["../../src/files/is-windows-file-path.ts"],"sourcesContent":["/**\n * Fast check if file path starts with a windows drive letter, e.g. 'C:/' or 'C:\\\\'\n */\nexport function isWindowsFilePath(str: string) {\n\treturn /^[a-zA-Z]:[\\\\/]/.test(str);\n}\n"],"mappings":";;;;;AAGA,SAAgB,kBAAkB,KAAa;AAC9C,QAAO,kBAAkB,KAAK,IAAI"}
1
+ {"version":3,"file":"is-windows-file-path.cjs","names":[],"sources":["../../src/files/is-windows-file-path.ts"],"sourcesContent":["/**\n * Fast check if file path starts with a windows drive letter, e.g. 'C:/' or 'C:\\\\'\n */\nexport function isWindowsFilePath(str: string) {\n\treturn /^[a-zA-Z]:[\\\\/]/.test(str);\n}\n"],"mappings":";;;;;AAGA,SAAgB,kBAAkB,KAAa;CAC9C,OAAO,kBAAkB,KAAK,GAAG;AAClC"}
@@ -5,7 +5,7 @@
5
5
  function isWindowsFilePath(str) {
6
6
  return /^[a-zA-Z]:[\\/]/.test(str);
7
7
  }
8
-
9
8
  //#endregion
10
9
  export { isWindowsFilePath };
10
+
11
11
  //# sourceMappingURL=is-windows-file-path.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"is-windows-file-path.mjs","names":[],"sources":["../../src/files/is-windows-file-path.ts"],"sourcesContent":["/**\n * Fast check if file path starts with a windows drive letter, e.g. 'C:/' or 'C:\\\\'\n */\nexport function isWindowsFilePath(str: string) {\n\treturn /^[a-zA-Z]:[\\\\/]/.test(str);\n}\n"],"mappings":";;;;AAGA,SAAgB,kBAAkB,KAAa;AAC9C,QAAO,kBAAkB,KAAK,IAAI"}
1
+ {"version":3,"file":"is-windows-file-path.mjs","names":[],"sources":["../../src/files/is-windows-file-path.ts"],"sourcesContent":["/**\n * Fast check if file path starts with a windows drive letter, e.g. 'C:/' or 'C:\\\\'\n */\nexport function isWindowsFilePath(str: string) {\n\treturn /^[a-zA-Z]:[\\\\/]/.test(str);\n}\n"],"mappings":";;;;AAGA,SAAgB,kBAAkB,KAAa;CAC9C,OAAO,kBAAkB,KAAK,GAAG;AAClC"}
@@ -1,10 +1,10 @@
1
-
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#region src/files/sanitize-filename.ts
3
3
  const INVALID_CHARS_REGEX = /[<>:"/\\|?*\u0000-\u001F\u007F-\u009F]/g;
4
4
  const ZERO_WIDTH_CHARS_REGEX = /[\u200B-\u200D\u2060\uFEFF]/g;
5
5
  const UNICODE_SPACES_REGEX = /[\u00A0\u2000-\u200A]/g;
6
6
  const LEADING_TRAILING_DOTS_SPACES_REGEX = /^[\s.]+|[\s.]+$/g;
7
- const WINDOWS_RESERVED_NAMES = new Set([
7
+ const WINDOWS_RESERVED_NAMES = /* @__PURE__ */ new Set([
8
8
  "CON",
9
9
  "PRN",
10
10
  "AUX",
@@ -56,7 +56,7 @@ const sanitizeFilename = (filename, maxLength = MAX_FILENAME_LENGTH) => {
56
56
  if (baseName.length > maxLength) baseName = baseName.slice(0, maxLength);
57
57
  return baseName;
58
58
  };
59
-
60
59
  //#endregion
61
60
  exports.sanitizeFilename = sanitizeFilename;
61
+
62
62
  //# sourceMappingURL=sanitize-filename.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize-filename.cjs","names":[],"sources":["../../src/files/sanitize-filename.ts"],"sourcesContent":["// Constants definition\n/* eslint-disable no-control-regex */\nconst INVALID_CHARS_REGEX = /[<>:\"/\\\\|?*\\u0000-\\u001F\\u007F-\\u009F]/g;\nconst ZERO_WIDTH_CHARS_REGEX = /[\\u200B-\\u200D\\u2060\\uFEFF]/g;\nconst UNICODE_SPACES_REGEX = /[\\u00A0\\u2000-\\u200A]/g;\nconst LEADING_TRAILING_DOTS_SPACES_REGEX = /^[\\s.]+|[\\s.]+$/g;\n/* eslint-enable no-control-regex */\n\nconst WINDOWS_RESERVED_NAMES = new Set([\n\t'CON',\n\t'PRN',\n\t'AUX',\n\t'NUL',\n\t'COM1',\n\t'COM2',\n\t'COM3',\n\t'COM4',\n\t'COM5',\n\t'COM6',\n\t'COM7',\n\t'COM8',\n\t'COM9',\n\t'LPT1',\n\t'LPT2',\n\t'LPT3',\n\t'LPT4',\n\t'LPT5',\n\t'LPT6',\n\t'LPT7',\n\t'LPT8',\n\t'LPT9',\n]);\n\nconst DEFAULT_FALLBACK_NAME = 'untitled';\nconst MAX_FILENAME_LENGTH = 200;\n\n/**\n * Sanitizes a filename to be compatible with Mac, Linux, and Windows file systems\n *\n * Main features:\n * - Replace invalid characters (e.g. \":\" in hello:world)\n * - Handle Windows reserved names\n * - Limit filename length\n * - Normalize Unicode characters\n *\n * @param filename - The filename to sanitize (without extension)\n * @param maxLength - Maximum filename length (default: 200)\n * @returns A sanitized filename (without extension)\n *\n * @example\n * sanitizeFilename('hello:world') // returns 'hello_world'\n * sanitizeFilename('CON') // returns '_CON'\n * sanitizeFilename('') // returns 'untitled'\n */\nexport const sanitizeFilename = (\n\tfilename: string,\n\tmaxLength: number = MAX_FILENAME_LENGTH,\n): string => {\n\t// Input validation\n\tif (!filename) {\n\t\treturn DEFAULT_FALLBACK_NAME;\n\t}\n\n\tlet baseName = filename\n\t\t.trim()\n\t\t.replace(INVALID_CHARS_REGEX, '_')\n\t\t.replace(ZERO_WIDTH_CHARS_REGEX, '')\n\t\t.replace(UNICODE_SPACES_REGEX, ' ')\n\t\t.replace(LEADING_TRAILING_DOTS_SPACES_REGEX, '');\n\n\t// Handle empty or invalid filenames after cleaning\n\tif (!baseName) {\n\t\tbaseName = DEFAULT_FALLBACK_NAME;\n\t}\n\n\t// Handle Windows reserved names\n\tif (WINDOWS_RESERVED_NAMES.has(baseName.toUpperCase())) {\n\t\tbaseName = `_${baseName}`;\n\t}\n\n\t// Truncate if too long\n\tif (baseName.length > maxLength) {\n\t\tbaseName = baseName.slice(0, maxLength);\n\t}\n\n\treturn baseName;\n};\n"],"mappings":";;AAEA,MAAM,sBAAsB;AAC5B,MAAM,yBAAyB;AAC/B,MAAM,uBAAuB;AAC7B,MAAM,qCAAqC;AAG3C,MAAM,yBAAyB,IAAI,IAAI;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,CAAC;AAEF,MAAM,wBAAwB;AAC9B,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;AAoB5B,MAAa,oBACZ,UACA,YAAoB,wBACR;AAEZ,KAAI,CAAC,SACJ,QAAO;CAGR,IAAI,WAAW,SACb,MAAM,CACN,QAAQ,qBAAqB,IAAI,CACjC,QAAQ,wBAAwB,GAAG,CACnC,QAAQ,sBAAsB,IAAI,CAClC,QAAQ,oCAAoC,GAAG;AAGjD,KAAI,CAAC,SACJ,YAAW;AAIZ,KAAI,uBAAuB,IAAI,SAAS,aAAa,CAAC,CACrD,YAAW,IAAI;AAIhB,KAAI,SAAS,SAAS,UACrB,YAAW,SAAS,MAAM,GAAG,UAAU;AAGxC,QAAO"}
1
+ {"version":3,"file":"sanitize-filename.cjs","names":[],"sources":["../../src/files/sanitize-filename.ts"],"sourcesContent":["// Constants definition\n/* eslint-disable no-control-regex */\nconst INVALID_CHARS_REGEX = /[<>:\"/\\\\|?*\\u0000-\\u001F\\u007F-\\u009F]/g;\nconst ZERO_WIDTH_CHARS_REGEX = /[\\u200B-\\u200D\\u2060\\uFEFF]/g;\nconst UNICODE_SPACES_REGEX = /[\\u00A0\\u2000-\\u200A]/g;\nconst LEADING_TRAILING_DOTS_SPACES_REGEX = /^[\\s.]+|[\\s.]+$/g;\n/* eslint-enable no-control-regex */\n\nconst WINDOWS_RESERVED_NAMES = new Set([\n\t'CON',\n\t'PRN',\n\t'AUX',\n\t'NUL',\n\t'COM1',\n\t'COM2',\n\t'COM3',\n\t'COM4',\n\t'COM5',\n\t'COM6',\n\t'COM7',\n\t'COM8',\n\t'COM9',\n\t'LPT1',\n\t'LPT2',\n\t'LPT3',\n\t'LPT4',\n\t'LPT5',\n\t'LPT6',\n\t'LPT7',\n\t'LPT8',\n\t'LPT9',\n]);\n\nconst DEFAULT_FALLBACK_NAME = 'untitled';\nconst MAX_FILENAME_LENGTH = 200;\n\n/**\n * Sanitizes a filename to be compatible with Mac, Linux, and Windows file systems\n *\n * Main features:\n * - Replace invalid characters (e.g. \":\" in hello:world)\n * - Handle Windows reserved names\n * - Limit filename length\n * - Normalize Unicode characters\n *\n * @param filename - The filename to sanitize (without extension)\n * @param maxLength - Maximum filename length (default: 200)\n * @returns A sanitized filename (without extension)\n *\n * @example\n * sanitizeFilename('hello:world') // returns 'hello_world'\n * sanitizeFilename('CON') // returns '_CON'\n * sanitizeFilename('') // returns 'untitled'\n */\nexport const sanitizeFilename = (\n\tfilename: string,\n\tmaxLength: number = MAX_FILENAME_LENGTH,\n): string => {\n\t// Input validation\n\tif (!filename) {\n\t\treturn DEFAULT_FALLBACK_NAME;\n\t}\n\n\tlet baseName = filename\n\t\t.trim()\n\t\t.replace(INVALID_CHARS_REGEX, '_')\n\t\t.replace(ZERO_WIDTH_CHARS_REGEX, '')\n\t\t.replace(UNICODE_SPACES_REGEX, ' ')\n\t\t.replace(LEADING_TRAILING_DOTS_SPACES_REGEX, '');\n\n\t// Handle empty or invalid filenames after cleaning\n\tif (!baseName) {\n\t\tbaseName = DEFAULT_FALLBACK_NAME;\n\t}\n\n\t// Handle Windows reserved names\n\tif (WINDOWS_RESERVED_NAMES.has(baseName.toUpperCase())) {\n\t\tbaseName = `_${baseName}`;\n\t}\n\n\t// Truncate if too long\n\tif (baseName.length > maxLength) {\n\t\tbaseName = baseName.slice(0, maxLength);\n\t}\n\n\treturn baseName;\n};\n"],"mappings":";;AAEA,MAAM,sBAAsB;AAC5B,MAAM,yBAAyB;AAC/B,MAAM,uBAAuB;AAC7B,MAAM,qCAAqC;AAG3C,MAAM,yCAAyB,IAAI,IAAI;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD,CAAC;AAED,MAAM,wBAAwB;AAC9B,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;AAoB5B,MAAa,oBACZ,UACA,YAAoB,wBACR;CAEZ,IAAI,CAAC,UACJ,OAAO;CAGR,IAAI,WAAW,SACb,KAAK,CAAC,CACN,QAAQ,qBAAqB,GAAG,CAAC,CACjC,QAAQ,wBAAwB,EAAE,CAAC,CACnC,QAAQ,sBAAsB,GAAG,CAAC,CAClC,QAAQ,oCAAoC,EAAE;CAGhD,IAAI,CAAC,UACJ,WAAW;CAIZ,IAAI,uBAAuB,IAAI,SAAS,YAAY,CAAC,GACpD,WAAW,IAAI;CAIhB,IAAI,SAAS,SAAS,WACrB,WAAW,SAAS,MAAM,GAAG,SAAS;CAGvC,OAAO;AACR"}
@@ -3,7 +3,7 @@ const INVALID_CHARS_REGEX = /[<>:"/\\|?*\u0000-\u001F\u007F-\u009F]/g;
3
3
  const ZERO_WIDTH_CHARS_REGEX = /[\u200B-\u200D\u2060\uFEFF]/g;
4
4
  const UNICODE_SPACES_REGEX = /[\u00A0\u2000-\u200A]/g;
5
5
  const LEADING_TRAILING_DOTS_SPACES_REGEX = /^[\s.]+|[\s.]+$/g;
6
- const WINDOWS_RESERVED_NAMES = new Set([
6
+ const WINDOWS_RESERVED_NAMES = /* @__PURE__ */ new Set([
7
7
  "CON",
8
8
  "PRN",
9
9
  "AUX",
@@ -55,7 +55,7 @@ const sanitizeFilename = (filename, maxLength = MAX_FILENAME_LENGTH) => {
55
55
  if (baseName.length > maxLength) baseName = baseName.slice(0, maxLength);
56
56
  return baseName;
57
57
  };
58
-
59
58
  //#endregion
60
59
  export { sanitizeFilename };
60
+
61
61
  //# sourceMappingURL=sanitize-filename.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize-filename.mjs","names":[],"sources":["../../src/files/sanitize-filename.ts"],"sourcesContent":["// Constants definition\n/* eslint-disable no-control-regex */\nconst INVALID_CHARS_REGEX = /[<>:\"/\\\\|?*\\u0000-\\u001F\\u007F-\\u009F]/g;\nconst ZERO_WIDTH_CHARS_REGEX = /[\\u200B-\\u200D\\u2060\\uFEFF]/g;\nconst UNICODE_SPACES_REGEX = /[\\u00A0\\u2000-\\u200A]/g;\nconst LEADING_TRAILING_DOTS_SPACES_REGEX = /^[\\s.]+|[\\s.]+$/g;\n/* eslint-enable no-control-regex */\n\nconst WINDOWS_RESERVED_NAMES = new Set([\n\t'CON',\n\t'PRN',\n\t'AUX',\n\t'NUL',\n\t'COM1',\n\t'COM2',\n\t'COM3',\n\t'COM4',\n\t'COM5',\n\t'COM6',\n\t'COM7',\n\t'COM8',\n\t'COM9',\n\t'LPT1',\n\t'LPT2',\n\t'LPT3',\n\t'LPT4',\n\t'LPT5',\n\t'LPT6',\n\t'LPT7',\n\t'LPT8',\n\t'LPT9',\n]);\n\nconst DEFAULT_FALLBACK_NAME = 'untitled';\nconst MAX_FILENAME_LENGTH = 200;\n\n/**\n * Sanitizes a filename to be compatible with Mac, Linux, and Windows file systems\n *\n * Main features:\n * - Replace invalid characters (e.g. \":\" in hello:world)\n * - Handle Windows reserved names\n * - Limit filename length\n * - Normalize Unicode characters\n *\n * @param filename - The filename to sanitize (without extension)\n * @param maxLength - Maximum filename length (default: 200)\n * @returns A sanitized filename (without extension)\n *\n * @example\n * sanitizeFilename('hello:world') // returns 'hello_world'\n * sanitizeFilename('CON') // returns '_CON'\n * sanitizeFilename('') // returns 'untitled'\n */\nexport const sanitizeFilename = (\n\tfilename: string,\n\tmaxLength: number = MAX_FILENAME_LENGTH,\n): string => {\n\t// Input validation\n\tif (!filename) {\n\t\treturn DEFAULT_FALLBACK_NAME;\n\t}\n\n\tlet baseName = filename\n\t\t.trim()\n\t\t.replace(INVALID_CHARS_REGEX, '_')\n\t\t.replace(ZERO_WIDTH_CHARS_REGEX, '')\n\t\t.replace(UNICODE_SPACES_REGEX, ' ')\n\t\t.replace(LEADING_TRAILING_DOTS_SPACES_REGEX, '');\n\n\t// Handle empty or invalid filenames after cleaning\n\tif (!baseName) {\n\t\tbaseName = DEFAULT_FALLBACK_NAME;\n\t}\n\n\t// Handle Windows reserved names\n\tif (WINDOWS_RESERVED_NAMES.has(baseName.toUpperCase())) {\n\t\tbaseName = `_${baseName}`;\n\t}\n\n\t// Truncate if too long\n\tif (baseName.length > maxLength) {\n\t\tbaseName = baseName.slice(0, maxLength);\n\t}\n\n\treturn baseName;\n};\n"],"mappings":";AAEA,MAAM,sBAAsB;AAC5B,MAAM,yBAAyB;AAC/B,MAAM,uBAAuB;AAC7B,MAAM,qCAAqC;AAG3C,MAAM,yBAAyB,IAAI,IAAI;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,CAAC;AAEF,MAAM,wBAAwB;AAC9B,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;AAoB5B,MAAa,oBACZ,UACA,YAAoB,wBACR;AAEZ,KAAI,CAAC,SACJ,QAAO;CAGR,IAAI,WAAW,SACb,MAAM,CACN,QAAQ,qBAAqB,IAAI,CACjC,QAAQ,wBAAwB,GAAG,CACnC,QAAQ,sBAAsB,IAAI,CAClC,QAAQ,oCAAoC,GAAG;AAGjD,KAAI,CAAC,SACJ,YAAW;AAIZ,KAAI,uBAAuB,IAAI,SAAS,aAAa,CAAC,CACrD,YAAW,IAAI;AAIhB,KAAI,SAAS,SAAS,UACrB,YAAW,SAAS,MAAM,GAAG,UAAU;AAGxC,QAAO"}
1
+ {"version":3,"file":"sanitize-filename.mjs","names":[],"sources":["../../src/files/sanitize-filename.ts"],"sourcesContent":["// Constants definition\n/* eslint-disable no-control-regex */\nconst INVALID_CHARS_REGEX = /[<>:\"/\\\\|?*\\u0000-\\u001F\\u007F-\\u009F]/g;\nconst ZERO_WIDTH_CHARS_REGEX = /[\\u200B-\\u200D\\u2060\\uFEFF]/g;\nconst UNICODE_SPACES_REGEX = /[\\u00A0\\u2000-\\u200A]/g;\nconst LEADING_TRAILING_DOTS_SPACES_REGEX = /^[\\s.]+|[\\s.]+$/g;\n/* eslint-enable no-control-regex */\n\nconst WINDOWS_RESERVED_NAMES = new Set([\n\t'CON',\n\t'PRN',\n\t'AUX',\n\t'NUL',\n\t'COM1',\n\t'COM2',\n\t'COM3',\n\t'COM4',\n\t'COM5',\n\t'COM6',\n\t'COM7',\n\t'COM8',\n\t'COM9',\n\t'LPT1',\n\t'LPT2',\n\t'LPT3',\n\t'LPT4',\n\t'LPT5',\n\t'LPT6',\n\t'LPT7',\n\t'LPT8',\n\t'LPT9',\n]);\n\nconst DEFAULT_FALLBACK_NAME = 'untitled';\nconst MAX_FILENAME_LENGTH = 200;\n\n/**\n * Sanitizes a filename to be compatible with Mac, Linux, and Windows file systems\n *\n * Main features:\n * - Replace invalid characters (e.g. \":\" in hello:world)\n * - Handle Windows reserved names\n * - Limit filename length\n * - Normalize Unicode characters\n *\n * @param filename - The filename to sanitize (without extension)\n * @param maxLength - Maximum filename length (default: 200)\n * @returns A sanitized filename (without extension)\n *\n * @example\n * sanitizeFilename('hello:world') // returns 'hello_world'\n * sanitizeFilename('CON') // returns '_CON'\n * sanitizeFilename('') // returns 'untitled'\n */\nexport const sanitizeFilename = (\n\tfilename: string,\n\tmaxLength: number = MAX_FILENAME_LENGTH,\n): string => {\n\t// Input validation\n\tif (!filename) {\n\t\treturn DEFAULT_FALLBACK_NAME;\n\t}\n\n\tlet baseName = filename\n\t\t.trim()\n\t\t.replace(INVALID_CHARS_REGEX, '_')\n\t\t.replace(ZERO_WIDTH_CHARS_REGEX, '')\n\t\t.replace(UNICODE_SPACES_REGEX, ' ')\n\t\t.replace(LEADING_TRAILING_DOTS_SPACES_REGEX, '');\n\n\t// Handle empty or invalid filenames after cleaning\n\tif (!baseName) {\n\t\tbaseName = DEFAULT_FALLBACK_NAME;\n\t}\n\n\t// Handle Windows reserved names\n\tif (WINDOWS_RESERVED_NAMES.has(baseName.toUpperCase())) {\n\t\tbaseName = `_${baseName}`;\n\t}\n\n\t// Truncate if too long\n\tif (baseName.length > maxLength) {\n\t\tbaseName = baseName.slice(0, maxLength);\n\t}\n\n\treturn baseName;\n};\n"],"mappings":";AAEA,MAAM,sBAAsB;AAC5B,MAAM,yBAAyB;AAC/B,MAAM,uBAAuB;AAC7B,MAAM,qCAAqC;AAG3C,MAAM,yCAAyB,IAAI,IAAI;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD,CAAC;AAED,MAAM,wBAAwB;AAC9B,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;AAoB5B,MAAa,oBACZ,UACA,YAAoB,wBACR;CAEZ,IAAI,CAAC,UACJ,OAAO;CAGR,IAAI,WAAW,SACb,KAAK,CAAC,CACN,QAAQ,qBAAqB,GAAG,CAAC,CACjC,QAAQ,wBAAwB,EAAE,CAAC,CACnC,QAAQ,sBAAsB,GAAG,CAAC,CAClC,QAAQ,oCAAoC,EAAE;CAGhD,IAAI,CAAC,UACJ,WAAW;CAIZ,IAAI,uBAAuB,IAAI,SAAS,YAAY,CAAC,GACpD,WAAW,IAAI;CAIhB,IAAI,SAAS,SAAS,WACrB,WAAW,SAAS,MAAM,GAAG,SAAS;CAGvC,OAAO;AACR"}
@@ -1,3 +1,42 @@
1
- const require_format_pem_block = require('./format-pem-block2.cjs');
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/format-pem-block.ts
3
+ const PEM_BODY_LINE_LENGTH = 64;
4
+ function formatCompactPem(pem, isPublic) {
5
+ const trimmed = pem.trim();
6
+ if ((trimmed.match(/-----BEGIN /g) ?? []).length !== 1) return void 0;
7
+ const labelPattern = isPublic ? "[A-Z0-9 ]*PUBLIC KEY" : "[A-Z0-9 ]*PRIVATE KEY|CERTIFICATE";
8
+ const pemMatch = trimmed.match(new RegExp(`^-----BEGIN (${labelPattern})-----([\\s\\S]*?)-----END \\1-----$`));
9
+ if (!pemMatch) return void 0;
10
+ const [, label, body] = pemMatch;
11
+ const normalizedBody = body.replace(/\\n/g, "\n").trim();
12
+ return `-----BEGIN ${label}-----\n${/\s/.test(normalizedBody) ? normalizedBody.replace(/:\s+/g, ":").replace(/\s+/g, "\n") : (normalizedBody.match(new RegExp(`.{1,${PEM_BODY_LINE_LENGTH}}`, "g")) ?? []).join("\n")}\n-----END ${label}-----`;
13
+ }
14
+ /**
15
+ * Normalize a single PEM-encoded block (private key, public key, or certificate)
16
+ * by collapsing whitespace and wrapping the body at 64 chars. Multi-block PEM
17
+ * chains are returned unchanged.
18
+ *
19
+ * @param pem - The PEM-encoded block to format.
20
+ * @param isPublic - When true, match `PUBLIC KEY` labels instead of the default `PRIVATE KEY` / `CERTIFICATE`.
21
+ * @returns The formatted PEM block.
22
+ */
23
+ function formatPemBlock(pem, isPublic = false) {
24
+ let regex = /(PRIVATE KEY|CERTIFICATE)/;
25
+ if (isPublic) regex = /(PUBLIC KEY)/;
26
+ if (!pem || /\n/.test(pem)) return pem;
27
+ const compactPem = formatCompactPem(pem, isPublic);
28
+ if (compactPem !== void 0) return compactPem;
29
+ let formattedPem = "";
30
+ pem.split("-----").filter((item) => item !== "").forEach((part) => {
31
+ if (regex.test(part)) formattedPem += `-----${part}-----`;
32
+ else if (/Proc-Type|DEK-Info/.test(part)) {
33
+ part = part.replace(/:\s+/g, ":");
34
+ formattedPem += part.replace(/\\n/g, "\n").replace(/\s+/g, "\n");
35
+ } else formattedPem += part.replace(/\\n/g, "\n").replace(/\s+/g, "\n");
36
+ });
37
+ return formattedPem;
38
+ }
39
+ //#endregion
40
+ exports.formatPemBlock = formatPemBlock;
2
41
 
3
- exports.formatPemBlock = require_format_pem_block.formatPemBlock;
42
+ //# sourceMappingURL=format-pem-block.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-pem-block.cjs","names":[],"sources":["../src/format-pem-block.ts"],"sourcesContent":["const PEM_BODY_LINE_LENGTH = 64;\n\nfunction formatCompactPem(pem: string, isPublic: boolean): string | undefined {\n\tconst trimmed = pem.trim();\n\tif ((trimmed.match(/-----BEGIN /g) ?? []).length !== 1) return undefined;\n\n\tconst labelPattern = isPublic ? '[A-Z0-9 ]*PUBLIC KEY' : '[A-Z0-9 ]*PRIVATE KEY|CERTIFICATE';\n\tconst pemMatch = trimmed.match(\n\t\tnew RegExp(`^-----BEGIN (${labelPattern})-----([\\\\s\\\\S]*?)-----END \\\\1-----$`),\n\t);\n\n\tif (!pemMatch) return undefined;\n\n\tconst [, label, body] = pemMatch;\n\tconst normalizedBody = body.replace(/\\\\n/g, '\\n').trim();\n\tconst formattedBody = /\\s/.test(normalizedBody)\n\t\t? normalizedBody.replace(/:\\s+/g, ':').replace(/\\s+/g, '\\n')\n\t\t: (normalizedBody.match(new RegExp(`.{1,${PEM_BODY_LINE_LENGTH}}`, 'g')) ?? []).join('\\n');\n\n\treturn `-----BEGIN ${label}-----\\n${formattedBody}\\n-----END ${label}-----`;\n}\n\n/**\n * Normalize a single PEM-encoded block (private key, public key, or certificate)\n * by collapsing whitespace and wrapping the body at 64 chars. Multi-block PEM\n * chains are returned unchanged.\n *\n * @param pem - The PEM-encoded block to format.\n * @param isPublic - When true, match `PUBLIC KEY` labels instead of the default `PRIVATE KEY` / `CERTIFICATE`.\n * @returns The formatted PEM block.\n */\nexport function formatPemBlock(pem: string, isPublic = false): string {\n\tlet regex = /(PRIVATE KEY|CERTIFICATE)/;\n\tif (isPublic) {\n\t\tregex = /(PUBLIC KEY)/;\n\t}\n\tif (!pem || /\\n/.test(pem)) {\n\t\treturn pem;\n\t}\n\tconst compactPem = formatCompactPem(pem, isPublic);\n\tif (compactPem !== undefined) {\n\t\treturn compactPem;\n\t}\n\n\tlet formattedPem = '';\n\tconst parts = pem.split('-----').filter((item) => item !== '');\n\tparts.forEach((part) => {\n\t\tif (regex.test(part)) {\n\t\t\tformattedPem += `-----${part}-----`;\n\t\t} else {\n\t\t\tconst passRegex = /Proc-Type|DEK-Info/;\n\t\t\tif (passRegex.test(part)) {\n\t\t\t\tpart = part.replace(/:\\s+/g, ':');\n\t\t\t\tformattedPem += part.replace(/\\\\n/g, '\\n').replace(/\\s+/g, '\\n');\n\t\t\t} else {\n\t\t\t\tformattedPem += part.replace(/\\\\n/g, '\\n').replace(/\\s+/g, '\\n');\n\t\t\t}\n\t\t}\n\t});\n\treturn formattedPem;\n}\n"],"mappings":";;AAAA,MAAM,uBAAuB;AAE7B,SAAS,iBAAiB,KAAa,UAAuC;CAC7E,MAAM,UAAU,IAAI,KAAK;CACzB,KAAK,QAAQ,MAAM,cAAc,KAAK,CAAC,EAAA,CAAG,WAAW,GAAG,OAAO,KAAA;CAE/D,MAAM,eAAe,WAAW,yBAAyB;CACzD,MAAM,WAAW,QAAQ,MACxB,IAAI,OAAO,gBAAgB,aAAa,qCAAqC,CAC9E;CAEA,IAAI,CAAC,UAAU,OAAO,KAAA;CAEtB,MAAM,GAAG,OAAO,QAAQ;CACxB,MAAM,iBAAiB,KAAK,QAAQ,QAAQ,IAAI,CAAC,CAAC,KAAK;CAKvD,OAAO,cAAc,MAAM,SAJL,KAAK,KAAK,cAAc,IAC3C,eAAe,QAAQ,SAAS,GAAG,CAAC,CAAC,QAAQ,QAAQ,IAAI,KACxD,eAAe,MAAM,IAAI,OAAO,OAAO,qBAAqB,IAAI,GAAG,CAAC,KAAK,CAAC,EAAA,CAAG,KAAK,IAAI,EAExC,aAAa,MAAM;AACtE;;;;;;;;;;AAWA,SAAgB,eAAe,KAAa,WAAW,OAAe;CACrE,IAAI,QAAQ;CACZ,IAAI,UACH,QAAQ;CAET,IAAI,CAAC,OAAO,KAAK,KAAK,GAAG,GACxB,OAAO;CAER,MAAM,aAAa,iBAAiB,KAAK,QAAQ;CACjD,IAAI,eAAe,KAAA,GAClB,OAAO;CAGR,IAAI,eAAe;CAEnB,IADkB,MAAM,OAAO,CAAC,CAAC,QAAQ,SAAS,SAAS,EACvD,CAAC,CAAC,SAAS,SAAS;EACvB,IAAI,MAAM,KAAK,IAAI,GAClB,gBAAgB,QAAQ,KAAK;OAG7B,IAAI,qBAAU,KAAK,IAAI,GAAG;GACzB,OAAO,KAAK,QAAQ,SAAS,GAAG;GAChC,gBAAgB,KAAK,QAAQ,QAAQ,IAAI,CAAC,CAAC,QAAQ,QAAQ,IAAI;EAChE,OACC,gBAAgB,KAAK,QAAQ,QAAQ,IAAI,CAAC,CAAC,QAAQ,QAAQ,IAAI;CAGlE,CAAC;CACD,OAAO;AACR"}
@@ -1,3 +1,41 @@
1
- import { t as formatPemBlock } from "./format-pem-block2.mjs";
1
+ //#region src/format-pem-block.ts
2
+ const PEM_BODY_LINE_LENGTH = 64;
3
+ function formatCompactPem(pem, isPublic) {
4
+ const trimmed = pem.trim();
5
+ if ((trimmed.match(/-----BEGIN /g) ?? []).length !== 1) return void 0;
6
+ const labelPattern = isPublic ? "[A-Z0-9 ]*PUBLIC KEY" : "[A-Z0-9 ]*PRIVATE KEY|CERTIFICATE";
7
+ const pemMatch = trimmed.match(new RegExp(`^-----BEGIN (${labelPattern})-----([\\s\\S]*?)-----END \\1-----$`));
8
+ if (!pemMatch) return void 0;
9
+ const [, label, body] = pemMatch;
10
+ const normalizedBody = body.replace(/\\n/g, "\n").trim();
11
+ return `-----BEGIN ${label}-----\n${/\s/.test(normalizedBody) ? normalizedBody.replace(/:\s+/g, ":").replace(/\s+/g, "\n") : (normalizedBody.match(new RegExp(`.{1,${PEM_BODY_LINE_LENGTH}}`, "g")) ?? []).join("\n")}\n-----END ${label}-----`;
12
+ }
13
+ /**
14
+ * Normalize a single PEM-encoded block (private key, public key, or certificate)
15
+ * by collapsing whitespace and wrapping the body at 64 chars. Multi-block PEM
16
+ * chains are returned unchanged.
17
+ *
18
+ * @param pem - The PEM-encoded block to format.
19
+ * @param isPublic - When true, match `PUBLIC KEY` labels instead of the default `PRIVATE KEY` / `CERTIFICATE`.
20
+ * @returns The formatted PEM block.
21
+ */
22
+ function formatPemBlock(pem, isPublic = false) {
23
+ let regex = /(PRIVATE KEY|CERTIFICATE)/;
24
+ if (isPublic) regex = /(PUBLIC KEY)/;
25
+ if (!pem || /\n/.test(pem)) return pem;
26
+ const compactPem = formatCompactPem(pem, isPublic);
27
+ if (compactPem !== void 0) return compactPem;
28
+ let formattedPem = "";
29
+ pem.split("-----").filter((item) => item !== "").forEach((part) => {
30
+ if (regex.test(part)) formattedPem += `-----${part}-----`;
31
+ else if (/Proc-Type|DEK-Info/.test(part)) {
32
+ part = part.replace(/:\s+/g, ":");
33
+ formattedPem += part.replace(/\\n/g, "\n").replace(/\s+/g, "\n");
34
+ } else formattedPem += part.replace(/\\n/g, "\n").replace(/\s+/g, "\n");
35
+ });
36
+ return formattedPem;
37
+ }
38
+ //#endregion
39
+ export { formatPemBlock };
2
40
 
3
- export { formatPemBlock };
41
+ //# sourceMappingURL=format-pem-block.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-pem-block.mjs","names":[],"sources":["../src/format-pem-block.ts"],"sourcesContent":["const PEM_BODY_LINE_LENGTH = 64;\n\nfunction formatCompactPem(pem: string, isPublic: boolean): string | undefined {\n\tconst trimmed = pem.trim();\n\tif ((trimmed.match(/-----BEGIN /g) ?? []).length !== 1) return undefined;\n\n\tconst labelPattern = isPublic ? '[A-Z0-9 ]*PUBLIC KEY' : '[A-Z0-9 ]*PRIVATE KEY|CERTIFICATE';\n\tconst pemMatch = trimmed.match(\n\t\tnew RegExp(`^-----BEGIN (${labelPattern})-----([\\\\s\\\\S]*?)-----END \\\\1-----$`),\n\t);\n\n\tif (!pemMatch) return undefined;\n\n\tconst [, label, body] = pemMatch;\n\tconst normalizedBody = body.replace(/\\\\n/g, '\\n').trim();\n\tconst formattedBody = /\\s/.test(normalizedBody)\n\t\t? normalizedBody.replace(/:\\s+/g, ':').replace(/\\s+/g, '\\n')\n\t\t: (normalizedBody.match(new RegExp(`.{1,${PEM_BODY_LINE_LENGTH}}`, 'g')) ?? []).join('\\n');\n\n\treturn `-----BEGIN ${label}-----\\n${formattedBody}\\n-----END ${label}-----`;\n}\n\n/**\n * Normalize a single PEM-encoded block (private key, public key, or certificate)\n * by collapsing whitespace and wrapping the body at 64 chars. Multi-block PEM\n * chains are returned unchanged.\n *\n * @param pem - The PEM-encoded block to format.\n * @param isPublic - When true, match `PUBLIC KEY` labels instead of the default `PRIVATE KEY` / `CERTIFICATE`.\n * @returns The formatted PEM block.\n */\nexport function formatPemBlock(pem: string, isPublic = false): string {\n\tlet regex = /(PRIVATE KEY|CERTIFICATE)/;\n\tif (isPublic) {\n\t\tregex = /(PUBLIC KEY)/;\n\t}\n\tif (!pem || /\\n/.test(pem)) {\n\t\treturn pem;\n\t}\n\tconst compactPem = formatCompactPem(pem, isPublic);\n\tif (compactPem !== undefined) {\n\t\treturn compactPem;\n\t}\n\n\tlet formattedPem = '';\n\tconst parts = pem.split('-----').filter((item) => item !== '');\n\tparts.forEach((part) => {\n\t\tif (regex.test(part)) {\n\t\t\tformattedPem += `-----${part}-----`;\n\t\t} else {\n\t\t\tconst passRegex = /Proc-Type|DEK-Info/;\n\t\t\tif (passRegex.test(part)) {\n\t\t\t\tpart = part.replace(/:\\s+/g, ':');\n\t\t\t\tformattedPem += part.replace(/\\\\n/g, '\\n').replace(/\\s+/g, '\\n');\n\t\t\t} else {\n\t\t\t\tformattedPem += part.replace(/\\\\n/g, '\\n').replace(/\\s+/g, '\\n');\n\t\t\t}\n\t\t}\n\t});\n\treturn formattedPem;\n}\n"],"mappings":";AAAA,MAAM,uBAAuB;AAE7B,SAAS,iBAAiB,KAAa,UAAuC;CAC7E,MAAM,UAAU,IAAI,KAAK;CACzB,KAAK,QAAQ,MAAM,cAAc,KAAK,CAAC,EAAA,CAAG,WAAW,GAAG,OAAO,KAAA;CAE/D,MAAM,eAAe,WAAW,yBAAyB;CACzD,MAAM,WAAW,QAAQ,MACxB,IAAI,OAAO,gBAAgB,aAAa,qCAAqC,CAC9E;CAEA,IAAI,CAAC,UAAU,OAAO,KAAA;CAEtB,MAAM,GAAG,OAAO,QAAQ;CACxB,MAAM,iBAAiB,KAAK,QAAQ,QAAQ,IAAI,CAAC,CAAC,KAAK;CAKvD,OAAO,cAAc,MAAM,SAJL,KAAK,KAAK,cAAc,IAC3C,eAAe,QAAQ,SAAS,GAAG,CAAC,CAAC,QAAQ,QAAQ,IAAI,KACxD,eAAe,MAAM,IAAI,OAAO,OAAO,qBAAqB,IAAI,GAAG,CAAC,KAAK,CAAC,EAAA,CAAG,KAAK,IAAI,EAExC,aAAa,MAAM;AACtE;;;;;;;;;;AAWA,SAAgB,eAAe,KAAa,WAAW,OAAe;CACrE,IAAI,QAAQ;CACZ,IAAI,UACH,QAAQ;CAET,IAAI,CAAC,OAAO,KAAK,KAAK,GAAG,GACxB,OAAO;CAER,MAAM,aAAa,iBAAiB,KAAK,QAAQ;CACjD,IAAI,eAAe,KAAA,GAClB,OAAO;CAGR,IAAI,eAAe;CAEnB,IADkB,MAAM,OAAO,CAAC,CAAC,QAAQ,SAAS,SAAS,EACvD,CAAC,CAAC,SAAS,SAAS;EACvB,IAAI,MAAM,KAAK,IAAI,GAClB,gBAAgB,QAAQ,KAAK;OAG7B,IAAI,qBAAU,KAAK,IAAI,GAAG;GACzB,OAAO,KAAK,QAAQ,SAAS,GAAG;GAChC,gBAAgB,KAAK,QAAQ,QAAQ,IAAI,CAAC,CAAC,QAAQ,QAAQ,IAAI;EAChE,OACC,gBAAgB,KAAK,QAAQ,QAAQ,IAAI,CAAC,CAAC,QAAQ,QAAQ,IAAI;CAGlE,CAAC;CACD,OAAO;AACR"}
@@ -1,6 +1,5 @@
1
- let __n8n_constants = require("@n8n/constants");
2
- let nanoid = require("nanoid");
3
-
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let _n8n_constants = require("@n8n/constants");
4
3
  //#region src/generate-nano-id.ts
5
4
  /**
6
5
  * Generates a unique 16-character nanoid.
@@ -22,8 +21,8 @@ let nanoid = require("nanoid");
22
21
  * // => 'aBcDeFgHiJkLmNoP' (16 characters)
23
22
  * ```
24
23
  */
25
- const generateNanoId = (0, nanoid.customAlphabet)(__n8n_constants.NANOID_ALPHABET, 16);
26
-
24
+ const generateNanoId = (0, require("nanoid").customAlphabet)(_n8n_constants.NANOID_ALPHABET, 16);
27
25
  //#endregion
28
26
  exports.generateNanoId = generateNanoId;
27
+
29
28
  //# sourceMappingURL=generate-nano-id.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"generate-nano-id.cjs","names":["NANOID_ALPHABET"],"sources":["../src/generate-nano-id.ts"],"sourcesContent":["import { NANOID_ALPHABET } from '@n8n/constants';\nimport { customAlphabet } from 'nanoid';\n\n/**\n * Generates a unique 16-character nanoid.\n *\n * This is the canonical ID generator used across the entire n8n codebase for:\n * - Workflow IDs\n * - Project IDs\n * - Variable IDs\n * - API Key IDs\n * - And other entity IDs\n *\n * Both frontend and backend MUST use this function to ensure consistency.\n *\n * @returns A 16-character ID\n *\n * @example\n * ```ts\n * const id = generateNanoId();\n * // => 'aBcDeFgHiJkLmNoP' (16 characters)\n * ```\n */\nexport const generateNanoId = customAlphabet(NANOID_ALPHABET, 16);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,4CAAgCA,iCAAiB,GAAG"}
1
+ {"version":3,"file":"generate-nano-id.cjs","names":["NANOID_ALPHABET"],"sources":["../src/generate-nano-id.ts"],"sourcesContent":["import { NANOID_ALPHABET } from '@n8n/constants';\nimport { customAlphabet } from 'nanoid';\n\n/**\n * Generates a unique 16-character nanoid.\n *\n * This is the canonical ID generator used across the entire n8n codebase for:\n * - Workflow IDs\n * - Project IDs\n * - Variable IDs\n * - API Key IDs\n * - And other entity IDs\n *\n * Both frontend and backend MUST use this function to ensure consistency.\n *\n * @returns A 16-character ID\n *\n * @example\n * ```ts\n * const id = generateNanoId();\n * // => 'aBcDeFgHiJkLmNoP' (16 characters)\n * ```\n */\nexport const generateNanoId = customAlphabet(NANOID_ALPHABET, 16);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,kBAAA,mBAAA,CAAA,CAAA,eAAA,CAAgCA,eAAAA,iBAAiB,EAAE"}
@@ -1,6 +1,5 @@
1
1
  import { NANOID_ALPHABET } from "@n8n/constants";
2
2
  import { customAlphabet } from "nanoid";
3
-
4
3
  //#region src/generate-nano-id.ts
5
4
  /**
6
5
  * Generates a unique 16-character nanoid.
@@ -23,7 +22,7 @@ import { customAlphabet } from "nanoid";
23
22
  * ```
24
23
  */
25
24
  const generateNanoId = customAlphabet(NANOID_ALPHABET, 16);
26
-
27
25
  //#endregion
28
26
  export { generateNanoId };
27
+
29
28
  //# sourceMappingURL=generate-nano-id.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"generate-nano-id.mjs","names":[],"sources":["../src/generate-nano-id.ts"],"sourcesContent":["import { NANOID_ALPHABET } from '@n8n/constants';\nimport { customAlphabet } from 'nanoid';\n\n/**\n * Generates a unique 16-character nanoid.\n *\n * This is the canonical ID generator used across the entire n8n codebase for:\n * - Workflow IDs\n * - Project IDs\n * - Variable IDs\n * - API Key IDs\n * - And other entity IDs\n *\n * Both frontend and backend MUST use this function to ensure consistency.\n *\n * @returns A 16-character ID\n *\n * @example\n * ```ts\n * const id = generateNanoId();\n * // => 'aBcDeFgHiJkLmNoP' (16 characters)\n * ```\n */\nexport const generateNanoId = customAlphabet(NANOID_ALPHABET, 16);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,iBAAiB,eAAe,iBAAiB,GAAG"}
1
+ {"version":3,"file":"generate-nano-id.mjs","names":[],"sources":["../src/generate-nano-id.ts"],"sourcesContent":["import { NANOID_ALPHABET } from '@n8n/constants';\nimport { customAlphabet } from 'nanoid';\n\n/**\n * Generates a unique 16-character nanoid.\n *\n * This is the canonical ID generator used across the entire n8n codebase for:\n * - Workflow IDs\n * - Project IDs\n * - Variable IDs\n * - API Key IDs\n * - And other entity IDs\n *\n * Both frontend and backend MUST use this function to ensure consistency.\n *\n * @returns A 16-character ID\n *\n * @example\n * ```ts\n * const id = generateNanoId();\n * // => 'aBcDeFgHiJkLmNoP' (16 characters)\n * ```\n */\nexport const generateNanoId = customAlphabet(NANOID_ALPHABET, 16);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,iBAAiB,eAAe,iBAAiB,EAAE"}
@@ -1,4 +1,4 @@
1
-
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#region src/get-jwt-expiry.ts
3
3
  /**
4
4
  * Decode the payload of a JWT without verifying the signature.
@@ -17,7 +17,7 @@ function getJwtExpiry(jwt) {
17
17
  return;
18
18
  }
19
19
  }
20
-
21
20
  //#endregion
22
21
  exports.getJwtExpiry = getJwtExpiry;
22
+
23
23
  //# sourceMappingURL=get-jwt-expiry.cjs.map