@drawbridge/drawbridge-utils 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  // Simple circuit breaker for wrapped async operations.
2
2
  //
3
- // const breaker = circuit({ name : 'kinde-auth', threshold : 5, timeout : 30000 });
4
- // const result = await breaker( () => validateToken( ... ) );
3
+ // const breaker = circuit({ name : 'google-auth', threshold : 5, timeout : 30000 });
4
+ // const result = await breaker( () => verifyIdToken( ... ) );
5
5
  //
6
6
  // States: CLOSED → OPEN (after `threshold` consecutive failures) → HALF_OPEN
7
7
  // (after `timeout` ms; next call probes recovery) → CLOSED (on success).
package/dist/circuit.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  // Simple circuit breaker for wrapped async operations.
2
2
  //
3
- // const breaker = circuit({ name : 'kinde-auth', threshold : 5, timeout : 30000 });
4
- // const result = await breaker( () => validateToken( ... ) );
3
+ // const breaker = circuit({ name : 'google-auth', threshold : 5, timeout : 30000 });
4
+ // const result = await breaker( () => verifyIdToken( ... ) );
5
5
  //
6
6
  // States: CLOSED → OPEN (after `threshold` consecutive failures) → HALF_OPEN
7
7
  // (after `timeout` ms; next call probes recovery) → CLOSED (on success).
@@ -0,0 +1,53 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // nanoid.js
20
+ var nanoid_exports = {};
21
+ __export(nanoid_exports, {
22
+ nanoid: () => nanoid,
23
+ retry: () => retry
24
+ });
25
+ module.exports = __toCommonJS(nanoid_exports);
26
+ var import_nanoid = require("nanoid");
27
+ var nanoid = (0, import_nanoid.customAlphabet)("0123456789abcdefghijklmnopqrstuvwxyz", 8);
28
+ var DEFAULT_MAX_RETRIES = 5;
29
+ var retry = async ({
30
+ field,
31
+ operation,
32
+ maxRetries = DEFAULT_MAX_RETRIES
33
+ }) => {
34
+ var _a;
35
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
36
+ try {
37
+ return await operation(nanoid());
38
+ } catch (error) {
39
+ const isCollision = (error == null ? void 0 : error.code) === 11e3 && ((_a = error == null ? void 0 : error.keyPattern) == null ? void 0 : _a[field]);
40
+ if (!isCollision || attempt === maxRetries - 1) {
41
+ throw error;
42
+ }
43
+ ;
44
+ }
45
+ ;
46
+ }
47
+ ;
48
+ };
49
+ // Annotate the CommonJS export names for ESM import in node:
50
+ 0 && (module.exports = {
51
+ nanoid,
52
+ retry
53
+ });
@@ -0,0 +1,63 @@
1
+ import { customAlphabet } from 'nanoid';
2
+
3
+ // 8-char base36 nanoid (36⁸ ≈ 2.8T entropy). Used as the short-id / slug
4
+ // generator across drawbridge collections with unique indexes (page.shortId,
5
+ // organization.shortId, affiliate.shortId, link.slug, prize.slug,
6
+ // advertisement.slug, etc.).
7
+ //
8
+ // Also exported from the main entrypoint for back-compat:
9
+ // const { nanoid } = require( '@drawbridge/drawbridge-utils' );
10
+ //
11
+ // New code should prefer this subpath, which also exposes `retry`:
12
+ // const { nanoid, retry } = require( '@drawbridge/drawbridge-utils/nanoid' );
13
+
14
+ const nanoid = customAlphabet( '0123456789abcdefghijklmnopqrstuvwxyz', 8 );
15
+
16
+ // Retry an async operation when Mongo rejects an insert because of a
17
+ // duplicate-key error on a specific field. The operation receives a fresh
18
+ // nanoid() on each attempt — typically used for shortId / slug fields where
19
+ // a unique index is in place and the value is randomly generated.
20
+ //
21
+ // const result = await retry({
22
+ // field : 'shortId',
23
+ // operation : ( shortId ) => controller.create({
24
+ // collection : 'page',
25
+ // data : { ..., shortId }
26
+ // })
27
+ // });
28
+ //
29
+ // Throws immediately if the error is anything other than E11000 on the named
30
+ // field. Throws the last error if retries are exhausted (extremely unlikely
31
+ // at 36⁸ entropy — 5 consecutive collisions are astronomically improbable).
32
+
33
+ const DEFAULT_MAX_RETRIES = 5;
34
+
35
+ const retry = async ({
36
+ field,
37
+ operation,
38
+ maxRetries = DEFAULT_MAX_RETRIES
39
+ }) => {
40
+
41
+ for( let attempt = 0; attempt < maxRetries; attempt++ ){
42
+
43
+ try {
44
+
45
+ return await operation( nanoid() );
46
+
47
+ } catch ( error ){
48
+
49
+ const isCollision = (
50
+ error?.code === 11000 &&
51
+ error?.keyPattern?.[ field ]
52
+ );
53
+
54
+ if( ! isCollision || attempt === maxRetries - 1 ){
55
+
56
+ throw error;
57
+
58
+ }
59
+ }
60
+ }
61
+ };
62
+
63
+ export { nanoid, retry };
@@ -0,0 +1,63 @@
1
+ import { customAlphabet } from 'nanoid';
2
+
3
+ // 8-char base36 nanoid (36⁸ ≈ 2.8T entropy). Used as the short-id / slug
4
+ // generator across drawbridge collections with unique indexes (page.shortId,
5
+ // organization.shortId, affiliate.shortId, link.slug, prize.slug,
6
+ // advertisement.slug, etc.).
7
+ //
8
+ // Also exported from the main entrypoint for back-compat:
9
+ // const { nanoid } = require( '@drawbridge/drawbridge-utils' );
10
+ //
11
+ // New code should prefer this subpath, which also exposes `retry`:
12
+ // const { nanoid, retry } = require( '@drawbridge/drawbridge-utils/nanoid' );
13
+
14
+ const nanoid = customAlphabet( '0123456789abcdefghijklmnopqrstuvwxyz', 8 );
15
+
16
+ // Retry an async operation when Mongo rejects an insert because of a
17
+ // duplicate-key error on a specific field. The operation receives a fresh
18
+ // nanoid() on each attempt — typically used for shortId / slug fields where
19
+ // a unique index is in place and the value is randomly generated.
20
+ //
21
+ // const result = await retry({
22
+ // field : 'shortId',
23
+ // operation : ( shortId ) => controller.create({
24
+ // collection : 'page',
25
+ // data : { ..., shortId }
26
+ // })
27
+ // });
28
+ //
29
+ // Throws immediately if the error is anything other than E11000 on the named
30
+ // field. Throws the last error if retries are exhausted (extremely unlikely
31
+ // at 36⁸ entropy — 5 consecutive collisions are astronomically improbable).
32
+
33
+ const DEFAULT_MAX_RETRIES = 5;
34
+
35
+ const retry = async ({
36
+ field,
37
+ operation,
38
+ maxRetries = DEFAULT_MAX_RETRIES
39
+ }) => {
40
+
41
+ for( let attempt = 0; attempt < maxRetries; attempt++ ){
42
+
43
+ try {
44
+
45
+ return await operation( nanoid() );
46
+
47
+ } catch ( error ){
48
+
49
+ const isCollision = (
50
+ error?.code === 11000 &&
51
+ error?.keyPattern?.[ field ]
52
+ );
53
+
54
+ if( ! isCollision || attempt === maxRetries - 1 ){
55
+
56
+ throw error;
57
+
58
+ }
59
+ }
60
+ }
61
+ };
62
+
63
+ export { nanoid, retry };
package/dist/nanoid.js ADDED
@@ -0,0 +1,28 @@
1
+ // nanoid.js
2
+ import { customAlphabet } from "nanoid";
3
+ var nanoid = customAlphabet("0123456789abcdefghijklmnopqrstuvwxyz", 8);
4
+ var DEFAULT_MAX_RETRIES = 5;
5
+ var retry = async ({
6
+ field,
7
+ operation,
8
+ maxRetries = DEFAULT_MAX_RETRIES
9
+ }) => {
10
+ var _a;
11
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
12
+ try {
13
+ return await operation(nanoid());
14
+ } catch (error) {
15
+ const isCollision = (error == null ? void 0 : error.code) === 11e3 && ((_a = error == null ? void 0 : error.keyPattern) == null ? void 0 : _a[field]);
16
+ if (!isCollision || attempt === maxRetries - 1) {
17
+ throw error;
18
+ }
19
+ ;
20
+ }
21
+ ;
22
+ }
23
+ ;
24
+ };
25
+ export {
26
+ nanoid,
27
+ retry
28
+ };
package/package.json CHANGED
@@ -1,8 +1,6 @@
1
1
  {
2
2
  "type": "module",
3
3
  "dependencies": {
4
- "@kinde/jwt-decoder": "0.2.1",
5
- "@kinde/jwt-validator": "0.4.1",
6
4
  "axios": "1.16.0",
7
5
  "currency-codes": "2.2.0",
8
6
  "nanoid": "3.3.8",
@@ -20,11 +18,6 @@
20
18
  "import": "./dist/encrypt.js",
21
19
  "require": "./dist/encrypt.cjs"
22
20
  },
23
- "./kinde": {
24
- "types": "./dist/kinde.d.ts",
25
- "import": "./dist/kinde.js",
26
- "require": "./dist/kinde.cjs"
27
- },
28
21
  "./axios": {
29
22
  "types": "./dist/axios.d.ts",
30
23
  "import": "./dist/axios.js",
@@ -39,6 +32,11 @@
39
32
  "types": "./dist/upload.d.ts",
40
33
  "import": "./dist/upload.js",
41
34
  "require": "./dist/upload.cjs"
35
+ },
36
+ "./nanoid": {
37
+ "types": "./dist/nanoid.d.ts",
38
+ "import": "./dist/nanoid.js",
39
+ "require": "./dist/nanoid.cjs"
42
40
  }
43
41
  },
44
42
  "files": [
@@ -55,5 +53,5 @@
55
53
  "build": "tsup && npm publish"
56
54
  },
57
55
  "types": "dist/index.d.ts",
58
- "version": "0.0.7"
56
+ "version": "0.0.9"
59
57
  }
package/dist/kinde.cjs DELETED
@@ -1,56 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __export = (target, all) => {
6
- for (var name in all)
7
- __defProp(target, name, { get: all[name], enumerable: true });
8
- };
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") {
11
- for (let key of __getOwnPropNames(from))
12
- if (!__hasOwnProp.call(to, key) && key !== except)
13
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
- }
15
- return to;
16
- };
17
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
-
19
- // kinde.js
20
- var kinde_exports = {};
21
- __export(kinde_exports, {
22
- verifyToken: () => verifyToken
23
- });
24
- module.exports = __toCommonJS(kinde_exports);
25
- var import_jwt_decoder = require("@kinde/jwt-decoder");
26
- var import_jwt_validator = require("@kinde/jwt-validator");
27
- var normalizeDomain = (raw) => {
28
- const trimmed = (raw || "").trim().replace(/\/+$/, "");
29
- if (!trimmed) return trimmed;
30
- return /^https?:\/\//.test(trimmed) ? trimmed : "https://" + trimmed;
31
- };
32
- var verifyToken = async (rawToken, { domain } = {}) => {
33
- if (!rawToken) {
34
- throw new Error("No token");
35
- }
36
- ;
37
- const token = rawToken.startsWith("Bearer ") ? rawToken.slice(7) : rawToken;
38
- const validation = await (0, import_jwt_validator.validateToken)({
39
- domain: normalizeDomain(domain),
40
- token
41
- });
42
- if (!(validation == null ? void 0 : validation.valid)) {
43
- throw new Error((validation == null ? void 0 : validation.message) || "Invalid token");
44
- }
45
- ;
46
- const decoded = (0, import_jwt_decoder.jwtDecoder)(token);
47
- if (!(decoded == null ? void 0 : decoded.sub)) {
48
- throw new Error("Invalid token payload");
49
- }
50
- ;
51
- return decoded;
52
- };
53
- // Annotate the CommonJS export names for ESM import in node:
54
- 0 && (module.exports = {
55
- verifyToken
56
- });
package/dist/kinde.d.cts DELETED
@@ -1,52 +0,0 @@
1
- import { jwtDecoder } from '@kinde/jwt-decoder';
2
- import { validateToken } from '@kinde/jwt-validator';
3
-
4
- const normalizeDomain = ( raw ) => {
5
-
6
- const trimmed = ( raw || '' ).trim().replace( /\/+$/, '' );
7
-
8
- if( ! trimmed ) return trimmed;
9
-
10
- return /^https?:\/\//.test( trimmed ) ? trimmed : 'https://' + trimmed;
11
-
12
- };
13
-
14
- // Verifies a Kinde access token cryptographically via JWKS and returns the decoded
15
- // payload. Throws on any failure (missing/invalid signature, missing sub claim, etc.).
16
- // Caller does user lookup + service-specific glue around this.
17
- //
18
- // const decoded = await verifyToken( token, { domain : process.env.KINDE_DOMAIN } );
19
- // decoded.sub // Kinde user id
20
- // decoded.org_code // org code
21
- // decoded.permissions // permissions array
22
- const verifyToken = async ( rawToken, { domain } = {} ) => {
23
-
24
- if( ! rawToken ){
25
-
26
- throw new Error( 'No token' );
27
-
28
- }
29
- const token = rawToken.startsWith( 'Bearer ' ) ? rawToken.slice( 7 ) : rawToken;
30
-
31
- const validation = await validateToken({
32
- domain : normalizeDomain( domain ),
33
- token
34
- });
35
-
36
- if( ! validation?.valid ){
37
-
38
- throw new Error( validation?.message || 'Invalid token' );
39
-
40
- }
41
- const decoded = jwtDecoder( token );
42
-
43
- if( ! decoded?.sub ){
44
-
45
- throw new Error( 'Invalid token payload' );
46
-
47
- }
48
- return decoded;
49
-
50
- };
51
-
52
- export { verifyToken };
package/dist/kinde.d.ts DELETED
@@ -1,52 +0,0 @@
1
- import { jwtDecoder } from '@kinde/jwt-decoder';
2
- import { validateToken } from '@kinde/jwt-validator';
3
-
4
- const normalizeDomain = ( raw ) => {
5
-
6
- const trimmed = ( raw || '' ).trim().replace( /\/+$/, '' );
7
-
8
- if( ! trimmed ) return trimmed;
9
-
10
- return /^https?:\/\//.test( trimmed ) ? trimmed : 'https://' + trimmed;
11
-
12
- };
13
-
14
- // Verifies a Kinde access token cryptographically via JWKS and returns the decoded
15
- // payload. Throws on any failure (missing/invalid signature, missing sub claim, etc.).
16
- // Caller does user lookup + service-specific glue around this.
17
- //
18
- // const decoded = await verifyToken( token, { domain : process.env.KINDE_DOMAIN } );
19
- // decoded.sub // Kinde user id
20
- // decoded.org_code // org code
21
- // decoded.permissions // permissions array
22
- const verifyToken = async ( rawToken, { domain } = {} ) => {
23
-
24
- if( ! rawToken ){
25
-
26
- throw new Error( 'No token' );
27
-
28
- }
29
- const token = rawToken.startsWith( 'Bearer ' ) ? rawToken.slice( 7 ) : rawToken;
30
-
31
- const validation = await validateToken({
32
- domain : normalizeDomain( domain ),
33
- token
34
- });
35
-
36
- if( ! validation?.valid ){
37
-
38
- throw new Error( validation?.message || 'Invalid token' );
39
-
40
- }
41
- const decoded = jwtDecoder( token );
42
-
43
- if( ! decoded?.sub ){
44
-
45
- throw new Error( 'Invalid token payload' );
46
-
47
- }
48
- return decoded;
49
-
50
- };
51
-
52
- export { verifyToken };
package/dist/kinde.js DELETED
@@ -1,32 +0,0 @@
1
- // kinde.js
2
- import { jwtDecoder } from "@kinde/jwt-decoder";
3
- import { validateToken } from "@kinde/jwt-validator";
4
- var normalizeDomain = (raw) => {
5
- const trimmed = (raw || "").trim().replace(/\/+$/, "");
6
- if (!trimmed) return trimmed;
7
- return /^https?:\/\//.test(trimmed) ? trimmed : "https://" + trimmed;
8
- };
9
- var verifyToken = async (rawToken, { domain } = {}) => {
10
- if (!rawToken) {
11
- throw new Error("No token");
12
- }
13
- ;
14
- const token = rawToken.startsWith("Bearer ") ? rawToken.slice(7) : rawToken;
15
- const validation = await validateToken({
16
- domain: normalizeDomain(domain),
17
- token
18
- });
19
- if (!(validation == null ? void 0 : validation.valid)) {
20
- throw new Error((validation == null ? void 0 : validation.message) || "Invalid token");
21
- }
22
- ;
23
- const decoded = jwtDecoder(token);
24
- if (!(decoded == null ? void 0 : decoded.sub)) {
25
- throw new Error("Invalid token payload");
26
- }
27
- ;
28
- return decoded;
29
- };
30
- export {
31
- verifyToken
32
- };