@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.
- package/dist/assert.cjs +2 -2
- package/dist/assert.cjs.map +1 -1
- package/dist/assert.mjs +1 -1
- package/dist/assert.mjs.map +1 -1
- package/dist/client-assertion.cjs +3 -3
- package/dist/client-assertion.cjs.map +1 -1
- package/dist/client-assertion.mjs +2 -3
- package/dist/client-assertion.mjs.map +1 -1
- package/dist/create-event-queue.cjs +2 -2
- package/dist/create-event-queue.cjs.map +1 -1
- package/dist/create-event-queue.mjs +1 -1
- package/dist/create-event-queue.mjs.map +1 -1
- package/dist/errors/ensure-error.cjs +9 -2
- package/dist/errors/ensure-error.cjs.map +1 -0
- package/dist/errors/ensure-error.mjs +8 -2
- package/dist/errors/ensure-error.mjs.map +1 -0
- package/dist/event-bus.cjs +2 -2
- package/dist/event-bus.cjs.map +1 -1
- package/dist/event-bus.d.cts +1 -1
- package/dist/event-bus.d.mts +1 -1
- package/dist/event-bus.mjs +1 -1
- package/dist/event-bus.mjs.map +1 -1
- package/dist/files/is-windows-file-path.cjs +2 -2
- package/dist/files/is-windows-file-path.cjs.map +1 -1
- package/dist/files/is-windows-file-path.mjs +1 -1
- package/dist/files/is-windows-file-path.mjs.map +1 -1
- package/dist/files/sanitize-filename.cjs +3 -3
- package/dist/files/sanitize-filename.cjs.map +1 -1
- package/dist/files/sanitize-filename.mjs +2 -2
- package/dist/files/sanitize-filename.mjs.map +1 -1
- package/dist/format-pem-block.cjs +41 -2
- package/dist/format-pem-block.cjs.map +1 -0
- package/dist/format-pem-block.mjs +40 -2
- package/dist/format-pem-block.mjs.map +1 -0
- package/dist/generate-nano-id.cjs +4 -5
- package/dist/generate-nano-id.cjs.map +1 -1
- package/dist/generate-nano-id.mjs +1 -2
- package/dist/generate-nano-id.mjs.map +1 -1
- package/dist/get-jwt-expiry.cjs +2 -2
- package/dist/get-jwt-expiry.cjs.map +1 -1
- package/dist/get-jwt-expiry.mjs +1 -1
- package/dist/get-jwt-expiry.mjs.map +1 -1
- package/dist/is-record.cjs +2 -2
- package/dist/is-record.cjs.map +1 -1
- package/dist/is-record.mjs +1 -1
- package/dist/is-record.mjs.map +1 -1
- package/dist/json/to-json-value.cjs +40 -0
- package/dist/json/to-json-value.cjs.map +1 -0
- package/dist/json/to-json-value.d.cts +10 -0
- package/dist/json/to-json-value.d.mts +10 -0
- package/dist/json/to-json-value.mjs +39 -0
- package/dist/json/to-json-value.mjs.map +1 -0
- package/dist/lazy-import.cjs +23 -0
- package/dist/lazy-import.cjs.map +1 -0
- package/dist/lazy-import.d.cts +5 -0
- package/dist/lazy-import.d.mts +5 -0
- package/dist/lazy-import.mjs +22 -0
- package/dist/lazy-import.mjs.map +1 -0
- package/dist/number/smart-decimal.cjs +2 -2
- package/dist/number/smart-decimal.cjs.map +1 -1
- package/dist/number/smart-decimal.mjs +1 -1
- package/dist/number/smart-decimal.mjs.map +1 -1
- package/dist/placeholder.cjs +2 -2
- package/dist/placeholder.cjs.map +1 -1
- package/dist/placeholder.mjs +1 -1
- package/dist/placeholder.mjs.map +1 -1
- package/dist/promise/deferred-promise.cjs +2 -2
- package/dist/promise/deferred-promise.cjs.map +1 -1
- package/dist/promise/deferred-promise.mjs +1 -1
- package/dist/promise/deferred-promise.mjs.map +1 -1
- package/dist/result.cjs +5 -4
- package/dist/result.cjs.map +1 -1
- package/dist/result.mjs +4 -4
- package/dist/result.mjs.map +1 -1
- package/dist/retry.cjs +2 -2
- package/dist/retry.cjs.map +1 -1
- package/dist/retry.mjs +1 -1
- package/dist/retry.mjs.map +1 -1
- package/dist/scrub-secrets.cjs +2 -2
- package/dist/scrub-secrets.cjs.map +1 -1
- package/dist/scrub-secrets.mjs +1 -1
- package/dist/scrub-secrets.mjs.map +1 -1
- package/dist/search/re-rank-search-results.cjs +2 -2
- package/dist/search/re-rank-search-results.cjs.map +1 -1
- package/dist/search/re-rank-search-results.mjs +1 -1
- package/dist/search/re-rank-search-results.mjs.map +1 -1
- package/dist/search/sublime-search.cjs +2 -2
- package/dist/search/sublime-search.cjs.map +1 -1
- package/dist/search/sublime-search.mjs +1 -1
- package/dist/search/sublime-search.mjs.map +1 -1
- package/dist/sort/sort-by-property.cjs +2 -2
- package/dist/sort/sort-by-property.cjs.map +1 -1
- package/dist/sort/sort-by-property.d.cts +1 -1
- package/dist/sort/sort-by-property.d.mts +1 -1
- package/dist/sort/sort-by-property.mjs +1 -1
- package/dist/sort/sort-by-property.mjs.map +1 -1
- package/dist/string/truncate.cjs +2 -2
- package/dist/string/truncate.cjs.map +1 -1
- package/dist/string/truncate.mjs +1 -1
- package/dist/string/truncate.mjs.map +1 -1
- package/dist/types.mjs +1 -1
- package/package.json +8 -8
- package/dist/ensure-error.cjs +0 -15
- package/dist/ensure-error.cjs.map +0 -1
- package/dist/ensure-error.mjs +0 -9
- package/dist/ensure-error.mjs.map +0 -1
- package/dist/format-pem-block2.cjs +0 -47
- package/dist/format-pem-block2.cjs.map +0 -1
- package/dist/format-pem-block2.mjs +0 -41
- 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
|
package/dist/assert.cjs.map
CHANGED
|
@@ -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;
|
|
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
package/dist/assert.mjs.map
CHANGED
|
@@ -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;
|
|
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
|
-
|
|
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":["
|
|
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 {
|
|
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":[
|
|
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":[
|
|
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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-event-queue.mjs","names":[
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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"}
|
package/dist/event-bus.cjs
CHANGED
|
@@ -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
|
package/dist/event-bus.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-bus.cjs","names":[
|
|
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"}
|
package/dist/event-bus.d.cts
CHANGED
|
@@ -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;
|
package/dist/event-bus.d.mts
CHANGED
|
@@ -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;
|
package/dist/event-bus.mjs
CHANGED
package/dist/event-bus.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-bus.mjs","names":[
|
|
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;
|
|
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"}
|
|
@@ -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;
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2
|
-
let
|
|
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)(
|
|
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":"
|
|
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":"
|
|
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"}
|
package/dist/get-jwt-expiry.cjs
CHANGED
|
@@ -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
|