@inai-dev/shared 0.1.0 → 1.1.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @inai-dev/shared
2
2
 
3
- Shared utilities for the InAI Auth SDK. Includes validators, error classes, JWT helpers, URL utilities, and constants.
3
+ Shared utilities for the InAI Auth SDK. Includes error class, JWT helpers, validators, URL utilities, and constants.
4
4
 
5
5
  ## Installation
6
6
 
@@ -10,25 +10,82 @@ npm install @inai-dev/shared
10
10
 
11
11
  > **Note:** You typically don't need to install this directly. It's included as a dependency of higher-level packages.
12
12
 
13
- ## Usage
13
+ ## Exports
14
+
15
+ ### Error Class
14
16
 
15
17
  ```ts
16
- import { InAIError, isInAIError } from "@inai-dev/shared";
17
- import { validateEmail, validatePassword } from "@inai-dev/shared";
18
- import { AUTH_COOKIE_NAME, REFRESH_COOKIE_NAME } from "@inai-dev/shared";
18
+ import { InAIAuthError } from "@inai-dev/shared";
19
+
20
+ try {
21
+ // ...
22
+ } catch (err) {
23
+ if (err instanceof InAIAuthError) {
24
+ console.error(err.status, err.message, err.body);
25
+ }
26
+ }
19
27
  ```
20
28
 
21
- ## Exports
29
+ ### JWT Utilities
30
+
31
+ ```ts
32
+ import { decodeJWTPayload, isTokenExpired, getClaimsFromToken } from "@inai-dev/shared";
33
+
34
+ const payload = decodeJWTPayload(token); // Raw JWT payload or null
35
+ const expired = isTokenExpired(token); // boolean
36
+ const claims = getClaimsFromToken(token); // JWTClaims or null
37
+ ```
38
+
39
+ ### Validators
40
+
41
+ ```ts
42
+ import { isValidEmail, isStrongPassword } from "@inai-dev/shared";
43
+
44
+ isValidEmail("user@example.com"); // true
45
+ isStrongPassword("MyP@ss1234"); // true
46
+ ```
47
+
48
+ ### Constants
49
+
50
+ ```ts
51
+ import {
52
+ COOKIE_AUTH_TOKEN, // "auth_token"
53
+ COOKIE_REFRESH_TOKEN, // "refresh_token"
54
+ COOKIE_AUTH_SESSION, // "auth_session"
55
+ DEFAULT_SIGN_IN_URL, // "/login"
56
+ DEFAULT_SIGN_UP_URL, // "/register"
57
+ DEFAULT_AFTER_SIGN_IN_URL, // "/"
58
+ DEFAULT_AFTER_SIGN_OUT_URL, // "/login"
59
+ HEADER_PUBLISHABLE_KEY, // "X-Publishable-Key"
60
+ HEADER_AUTHORIZATION, // "Authorization"
61
+ HEADER_INAI_AUTH, // "x-inai-auth"
62
+ DEFAULT_API_URL, // Internal — not for public use
63
+ } from "@inai-dev/shared";
64
+ ```
65
+
66
+ ### URL Utilities
22
67
 
23
- - **Errors**: `InAIError`, `isInAIError`, error codes
24
- - **Validators**: Email, password, and input validation
25
- - **JWT**: Token decode and verification utilities
26
- - **URL**: API URL builder helpers
27
- - **Constants**: Cookie names, header names, default values
68
+ ```ts
69
+ import { normalizeApiUrl, buildEndpoint } from "@inai-dev/shared";
70
+ ```
28
71
 
29
- ## Documentation
72
+ ## Exports Reference
30
73
 
31
- See the full [API Reference](https://github.com/inai-dev/sdk/blob/main/docs/api-reference.md).
74
+ | Export | Kind | Description |
75
+ |---|---|---|
76
+ | `InAIAuthError` | Class | Auth error with status and body |
77
+ | `decodeJWTPayload` | Function | Decode JWT payload (no verification) |
78
+ | `isTokenExpired` | Function | Check if JWT is expired |
79
+ | `getClaimsFromToken` | Function | Extract typed JWTClaims from token |
80
+ | `isValidEmail` | Function | Email format validation |
81
+ | `isStrongPassword` | Function | Password strength validation |
82
+ | `normalizeApiUrl` | Function | Normalize API URL (trailing slash) |
83
+ | `buildEndpoint` | Function | Build full API endpoint URL |
84
+ | `COOKIE_AUTH_TOKEN` | Constant | Auth token cookie name |
85
+ | `COOKIE_REFRESH_TOKEN` | Constant | Refresh token cookie name |
86
+ | `COOKIE_AUTH_SESSION` | Constant | Session cookie name |
87
+ | `DEFAULT_API_URL` | Constant | Default API URL (internal) |
88
+ | `HEADER_PUBLISHABLE_KEY` | Constant | Publishable key header name |
32
89
 
33
90
  ## License
34
91
 
package/dist/index.cjs CHANGED
@@ -25,6 +25,7 @@ __export(index_exports, {
25
25
  COOKIE_REFRESH_TOKEN: () => COOKIE_REFRESH_TOKEN,
26
26
  DEFAULT_AFTER_SIGN_IN_URL: () => DEFAULT_AFTER_SIGN_IN_URL,
27
27
  DEFAULT_AFTER_SIGN_OUT_URL: () => DEFAULT_AFTER_SIGN_OUT_URL,
28
+ DEFAULT_API_URL: () => DEFAULT_API_URL,
28
29
  DEFAULT_SIGN_IN_URL: () => DEFAULT_SIGN_IN_URL,
29
30
  DEFAULT_SIGN_UP_URL: () => DEFAULT_SIGN_UP_URL,
30
31
  HEADER_AUTHORIZATION: () => HEADER_AUTHORIZATION,
@@ -92,6 +93,7 @@ var DEFAULT_AFTER_SIGN_OUT_URL = "/login";
92
93
  var HEADER_PUBLISHABLE_KEY = "X-Publishable-Key";
93
94
  var HEADER_AUTHORIZATION = "Authorization";
94
95
  var HEADER_INAI_AUTH = "x-inai-auth";
96
+ var DEFAULT_API_URL = "https://apiauth.inai.dev";
95
97
 
96
98
  // src/url.ts
97
99
  function normalizeApiUrl(url) {
@@ -120,6 +122,7 @@ function isStrongPassword(password) {
120
122
  COOKIE_REFRESH_TOKEN,
121
123
  DEFAULT_AFTER_SIGN_IN_URL,
122
124
  DEFAULT_AFTER_SIGN_OUT_URL,
125
+ DEFAULT_API_URL,
123
126
  DEFAULT_SIGN_IN_URL,
124
127
  DEFAULT_SIGN_UP_URL,
125
128
  HEADER_AUTHORIZATION,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/jwt.ts","../src/constants.ts","../src/url.ts","../src/validators.ts"],"sourcesContent":["export { InAIAuthError } from \"./errors\";\nexport {\n decodeJWTPayload,\n isTokenExpired,\n getClaimsFromToken,\n} from \"./jwt\";\nexport {\n COOKIE_AUTH_TOKEN,\n COOKIE_REFRESH_TOKEN,\n COOKIE_AUTH_SESSION,\n DEFAULT_SIGN_IN_URL,\n DEFAULT_SIGN_UP_URL,\n DEFAULT_AFTER_SIGN_IN_URL,\n DEFAULT_AFTER_SIGN_OUT_URL,\n HEADER_PUBLISHABLE_KEY,\n HEADER_AUTHORIZATION,\n HEADER_INAI_AUTH,\n} from \"./constants\";\nexport { normalizeApiUrl, buildEndpoint } from \"./url\";\nexport { isValidEmail, isStrongPassword } from \"./validators\";\n","import type { InAIAuthErrorBody } from \"@inai-dev/types\";\n\nexport class InAIAuthError extends Error {\n status: number;\n body: InAIAuthErrorBody;\n code: string;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.name = \"InAIAuthError\";\n this.status = status;\n const parsed = body as Record<string, unknown> | null;\n this.body = {\n code: (parsed?.code as string) ?? \"UNKNOWN_ERROR\",\n detail: (parsed?.detail as string) ?? message,\n field: (parsed?.field as string) ?? undefined,\n };\n this.code = this.body.code;\n }\n}\n","import type { JWTClaims } from \"@inai-dev/types\";\n\nexport function decodeJWTPayload(token: string): JWTClaims | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n const payload = parts[1].replace(/-/g, \"+\").replace(/_/g, \"/\");\n const decoded = atob(payload);\n return JSON.parse(decoded);\n } catch {\n return null;\n }\n}\n\nexport function isTokenExpired(token: string): boolean {\n const claims = decodeJWTPayload(token);\n if (!claims?.exp) return true;\n return Date.now() >= claims.exp * 1000;\n}\n\nexport function getClaimsFromToken(token: string): JWTClaims | null {\n return decodeJWTPayload(token);\n}\n","export const COOKIE_AUTH_TOKEN = \"auth_token\";\nexport const COOKIE_REFRESH_TOKEN = \"refresh_token\";\nexport const COOKIE_AUTH_SESSION = \"auth_session\";\n\nexport const DEFAULT_SIGN_IN_URL = \"/login\";\nexport const DEFAULT_SIGN_UP_URL = \"/register\";\nexport const DEFAULT_AFTER_SIGN_IN_URL = \"/\";\nexport const DEFAULT_AFTER_SIGN_OUT_URL = \"/login\";\n\nexport const HEADER_PUBLISHABLE_KEY = \"X-Publishable-Key\";\nexport const HEADER_AUTHORIZATION = \"Authorization\";\nexport const HEADER_INAI_AUTH = \"x-inai-auth\";\n","export function normalizeApiUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nexport function buildEndpoint(apiUrl: string, path: string): string {\n return `${normalizeApiUrl(apiUrl)}${path}`;\n}\n","export function isValidEmail(email: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n}\n\nexport function isStrongPassword(password: string): {\n valid: boolean;\n errors: string[];\n} {\n const errors: string[] = [];\n if (password.length < 8) errors.push(\"Password must be at least 8 characters\");\n if (!/[A-Z]/.test(password)) errors.push(\"Password must contain an uppercase letter\");\n if (!/[a-z]/.test(password)) errors.push(\"Password must contain a lowercase letter\");\n if (!/[0-9]/.test(password)) errors.push(\"Password must contain a number\");\n return { valid: errors.length === 0, errors };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,IAAM,gBAAN,cAA4B,MAAM;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,SAAiB,QAAgB,MAAe;AAC1D,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,UAAM,SAAS;AACf,SAAK,OAAO;AAAA,MACV,MAAO,QAAQ,QAAmB;AAAA,MAClC,QAAS,QAAQ,UAAqB;AAAA,MACtC,OAAQ,QAAQ,SAAoB;AAAA,IACtC;AACA,SAAK,OAAO,KAAK,KAAK;AAAA,EACxB;AACF;;;ACjBO,SAAS,iBAAiB,OAAiC;AAChE,MAAI;AACF,UAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,QAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,UAAM,UAAU,MAAM,CAAC,EAAE,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG;AAC7D,UAAM,UAAU,KAAK,OAAO;AAC5B,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,eAAe,OAAwB;AACrD,QAAM,SAAS,iBAAiB,KAAK;AACrC,MAAI,CAAC,QAAQ,IAAK,QAAO;AACzB,SAAO,KAAK,IAAI,KAAK,OAAO,MAAM;AACpC;AAEO,SAAS,mBAAmB,OAAiC;AAClE,SAAO,iBAAiB,KAAK;AAC/B;;;ACtBO,IAAM,oBAAoB;AAC1B,IAAM,uBAAuB;AAC7B,IAAM,sBAAsB;AAE5B,IAAM,sBAAsB;AAC5B,IAAM,sBAAsB;AAC5B,IAAM,4BAA4B;AAClC,IAAM,6BAA6B;AAEnC,IAAM,yBAAyB;AAC/B,IAAM,uBAAuB;AAC7B,IAAM,mBAAmB;;;ACXzB,SAAS,gBAAgB,KAAqB;AACnD,SAAO,IAAI,QAAQ,OAAO,EAAE;AAC9B;AAEO,SAAS,cAAc,QAAgB,MAAsB;AAClE,SAAO,GAAG,gBAAgB,MAAM,CAAC,GAAG,IAAI;AAC1C;;;ACNO,SAAS,aAAa,OAAwB;AACnD,SAAO,6BAA6B,KAAK,KAAK;AAChD;AAEO,SAAS,iBAAiB,UAG/B;AACA,QAAM,SAAmB,CAAC;AAC1B,MAAI,SAAS,SAAS,EAAG,QAAO,KAAK,wCAAwC;AAC7E,MAAI,CAAC,QAAQ,KAAK,QAAQ,EAAG,QAAO,KAAK,2CAA2C;AACpF,MAAI,CAAC,QAAQ,KAAK,QAAQ,EAAG,QAAO,KAAK,0CAA0C;AACnF,MAAI,CAAC,QAAQ,KAAK,QAAQ,EAAG,QAAO,KAAK,gCAAgC;AACzE,SAAO,EAAE,OAAO,OAAO,WAAW,GAAG,OAAO;AAC9C;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/jwt.ts","../src/constants.ts","../src/url.ts","../src/validators.ts"],"sourcesContent":["export { InAIAuthError } from \"./errors\";\nexport {\n decodeJWTPayload,\n isTokenExpired,\n getClaimsFromToken,\n} from \"./jwt\";\nexport {\n COOKIE_AUTH_TOKEN,\n COOKIE_REFRESH_TOKEN,\n COOKIE_AUTH_SESSION,\n DEFAULT_SIGN_IN_URL,\n DEFAULT_SIGN_UP_URL,\n DEFAULT_AFTER_SIGN_IN_URL,\n DEFAULT_AFTER_SIGN_OUT_URL,\n HEADER_PUBLISHABLE_KEY,\n HEADER_AUTHORIZATION,\n HEADER_INAI_AUTH,\n DEFAULT_API_URL,\n} from \"./constants\";\nexport { normalizeApiUrl, buildEndpoint } from \"./url\";\nexport { isValidEmail, isStrongPassword } from \"./validators\";\n","import type { InAIAuthErrorBody } from \"@inai-dev/types\";\n\nexport class InAIAuthError extends Error {\n status: number;\n body: InAIAuthErrorBody;\n code: string;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.name = \"InAIAuthError\";\n this.status = status;\n const parsed = body as Record<string, unknown> | null;\n this.body = {\n code: (parsed?.code as string) ?? \"UNKNOWN_ERROR\",\n detail: (parsed?.detail as string) ?? message,\n field: (parsed?.field as string) ?? undefined,\n };\n this.code = this.body.code;\n }\n}\n","import type { JWTClaims } from \"@inai-dev/types\";\n\nexport function decodeJWTPayload(token: string): JWTClaims | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n const payload = parts[1].replace(/-/g, \"+\").replace(/_/g, \"/\");\n const decoded = atob(payload);\n return JSON.parse(decoded);\n } catch {\n return null;\n }\n}\n\nexport function isTokenExpired(token: string): boolean {\n const claims = decodeJWTPayload(token);\n if (!claims?.exp) return true;\n return Date.now() >= claims.exp * 1000;\n}\n\nexport function getClaimsFromToken(token: string): JWTClaims | null {\n return decodeJWTPayload(token);\n}\n","export const COOKIE_AUTH_TOKEN = \"auth_token\";\nexport const COOKIE_REFRESH_TOKEN = \"refresh_token\";\nexport const COOKIE_AUTH_SESSION = \"auth_session\";\n\nexport const DEFAULT_SIGN_IN_URL = \"/login\";\nexport const DEFAULT_SIGN_UP_URL = \"/register\";\nexport const DEFAULT_AFTER_SIGN_IN_URL = \"/\";\nexport const DEFAULT_AFTER_SIGN_OUT_URL = \"/login\";\n\nexport const HEADER_PUBLISHABLE_KEY = \"X-Publishable-Key\";\nexport const HEADER_AUTHORIZATION = \"Authorization\";\nexport const HEADER_INAI_AUTH = \"x-inai-auth\";\n\nexport const DEFAULT_API_URL = \"https://apiauth.inai.dev\";\n","export function normalizeApiUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nexport function buildEndpoint(apiUrl: string, path: string): string {\n return `${normalizeApiUrl(apiUrl)}${path}`;\n}\n","export function isValidEmail(email: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n}\n\nexport function isStrongPassword(password: string): {\n valid: boolean;\n errors: string[];\n} {\n const errors: string[] = [];\n if (password.length < 8) errors.push(\"Password must be at least 8 characters\");\n if (!/[A-Z]/.test(password)) errors.push(\"Password must contain an uppercase letter\");\n if (!/[a-z]/.test(password)) errors.push(\"Password must contain a lowercase letter\");\n if (!/[0-9]/.test(password)) errors.push(\"Password must contain a number\");\n return { valid: errors.length === 0, errors };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,IAAM,gBAAN,cAA4B,MAAM;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,SAAiB,QAAgB,MAAe;AAC1D,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,UAAM,SAAS;AACf,SAAK,OAAO;AAAA,MACV,MAAO,QAAQ,QAAmB;AAAA,MAClC,QAAS,QAAQ,UAAqB;AAAA,MACtC,OAAQ,QAAQ,SAAoB;AAAA,IACtC;AACA,SAAK,OAAO,KAAK,KAAK;AAAA,EACxB;AACF;;;ACjBO,SAAS,iBAAiB,OAAiC;AAChE,MAAI;AACF,UAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,QAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,UAAM,UAAU,MAAM,CAAC,EAAE,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG;AAC7D,UAAM,UAAU,KAAK,OAAO;AAC5B,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,eAAe,OAAwB;AACrD,QAAM,SAAS,iBAAiB,KAAK;AACrC,MAAI,CAAC,QAAQ,IAAK,QAAO;AACzB,SAAO,KAAK,IAAI,KAAK,OAAO,MAAM;AACpC;AAEO,SAAS,mBAAmB,OAAiC;AAClE,SAAO,iBAAiB,KAAK;AAC/B;;;ACtBO,IAAM,oBAAoB;AAC1B,IAAM,uBAAuB;AAC7B,IAAM,sBAAsB;AAE5B,IAAM,sBAAsB;AAC5B,IAAM,sBAAsB;AAC5B,IAAM,4BAA4B;AAClC,IAAM,6BAA6B;AAEnC,IAAM,yBAAyB;AAC/B,IAAM,uBAAuB;AAC7B,IAAM,mBAAmB;AAEzB,IAAM,kBAAkB;;;ACbxB,SAAS,gBAAgB,KAAqB;AACnD,SAAO,IAAI,QAAQ,OAAO,EAAE;AAC9B;AAEO,SAAS,cAAc,QAAgB,MAAsB;AAClE,SAAO,GAAG,gBAAgB,MAAM,CAAC,GAAG,IAAI;AAC1C;;;ACNO,SAAS,aAAa,OAAwB;AACnD,SAAO,6BAA6B,KAAK,KAAK;AAChD;AAEO,SAAS,iBAAiB,UAG/B;AACA,QAAM,SAAmB,CAAC;AAC1B,MAAI,SAAS,SAAS,EAAG,QAAO,KAAK,wCAAwC;AAC7E,MAAI,CAAC,QAAQ,KAAK,QAAQ,EAAG,QAAO,KAAK,2CAA2C;AACpF,MAAI,CAAC,QAAQ,KAAK,QAAQ,EAAG,QAAO,KAAK,0CAA0C;AACnF,MAAI,CAAC,QAAQ,KAAK,QAAQ,EAAG,QAAO,KAAK,gCAAgC;AACzE,SAAO,EAAE,OAAO,OAAO,WAAW,GAAG,OAAO;AAC9C;","names":[]}
package/dist/index.d.cts CHANGED
@@ -21,6 +21,7 @@ declare const DEFAULT_AFTER_SIGN_OUT_URL = "/login";
21
21
  declare const HEADER_PUBLISHABLE_KEY = "X-Publishable-Key";
22
22
  declare const HEADER_AUTHORIZATION = "Authorization";
23
23
  declare const HEADER_INAI_AUTH = "x-inai-auth";
24
+ declare const DEFAULT_API_URL = "https://apiauth.inai.dev";
24
25
 
25
26
  declare function normalizeApiUrl(url: string): string;
26
27
  declare function buildEndpoint(apiUrl: string, path: string): string;
@@ -31,4 +32,4 @@ declare function isStrongPassword(password: string): {
31
32
  errors: string[];
32
33
  };
33
34
 
34
- export { COOKIE_AUTH_SESSION, COOKIE_AUTH_TOKEN, COOKIE_REFRESH_TOKEN, DEFAULT_AFTER_SIGN_IN_URL, DEFAULT_AFTER_SIGN_OUT_URL, DEFAULT_SIGN_IN_URL, DEFAULT_SIGN_UP_URL, HEADER_AUTHORIZATION, HEADER_INAI_AUTH, HEADER_PUBLISHABLE_KEY, InAIAuthError, buildEndpoint, decodeJWTPayload, getClaimsFromToken, isStrongPassword, isTokenExpired, isValidEmail, normalizeApiUrl };
35
+ export { COOKIE_AUTH_SESSION, COOKIE_AUTH_TOKEN, COOKIE_REFRESH_TOKEN, DEFAULT_AFTER_SIGN_IN_URL, DEFAULT_AFTER_SIGN_OUT_URL, DEFAULT_API_URL, DEFAULT_SIGN_IN_URL, DEFAULT_SIGN_UP_URL, HEADER_AUTHORIZATION, HEADER_INAI_AUTH, HEADER_PUBLISHABLE_KEY, InAIAuthError, buildEndpoint, decodeJWTPayload, getClaimsFromToken, isStrongPassword, isTokenExpired, isValidEmail, normalizeApiUrl };
package/dist/index.d.ts CHANGED
@@ -21,6 +21,7 @@ declare const DEFAULT_AFTER_SIGN_OUT_URL = "/login";
21
21
  declare const HEADER_PUBLISHABLE_KEY = "X-Publishable-Key";
22
22
  declare const HEADER_AUTHORIZATION = "Authorization";
23
23
  declare const HEADER_INAI_AUTH = "x-inai-auth";
24
+ declare const DEFAULT_API_URL = "https://apiauth.inai.dev";
24
25
 
25
26
  declare function normalizeApiUrl(url: string): string;
26
27
  declare function buildEndpoint(apiUrl: string, path: string): string;
@@ -31,4 +32,4 @@ declare function isStrongPassword(password: string): {
31
32
  errors: string[];
32
33
  };
33
34
 
34
- export { COOKIE_AUTH_SESSION, COOKIE_AUTH_TOKEN, COOKIE_REFRESH_TOKEN, DEFAULT_AFTER_SIGN_IN_URL, DEFAULT_AFTER_SIGN_OUT_URL, DEFAULT_SIGN_IN_URL, DEFAULT_SIGN_UP_URL, HEADER_AUTHORIZATION, HEADER_INAI_AUTH, HEADER_PUBLISHABLE_KEY, InAIAuthError, buildEndpoint, decodeJWTPayload, getClaimsFromToken, isStrongPassword, isTokenExpired, isValidEmail, normalizeApiUrl };
35
+ export { COOKIE_AUTH_SESSION, COOKIE_AUTH_TOKEN, COOKIE_REFRESH_TOKEN, DEFAULT_AFTER_SIGN_IN_URL, DEFAULT_AFTER_SIGN_OUT_URL, DEFAULT_API_URL, DEFAULT_SIGN_IN_URL, DEFAULT_SIGN_UP_URL, HEADER_AUTHORIZATION, HEADER_INAI_AUTH, HEADER_PUBLISHABLE_KEY, InAIAuthError, buildEndpoint, decodeJWTPayload, getClaimsFromToken, isStrongPassword, isTokenExpired, isValidEmail, normalizeApiUrl };
package/dist/index.js CHANGED
@@ -49,6 +49,7 @@ var DEFAULT_AFTER_SIGN_OUT_URL = "/login";
49
49
  var HEADER_PUBLISHABLE_KEY = "X-Publishable-Key";
50
50
  var HEADER_AUTHORIZATION = "Authorization";
51
51
  var HEADER_INAI_AUTH = "x-inai-auth";
52
+ var DEFAULT_API_URL = "https://apiauth.inai.dev";
52
53
 
53
54
  // src/url.ts
54
55
  function normalizeApiUrl(url) {
@@ -76,6 +77,7 @@ export {
76
77
  COOKIE_REFRESH_TOKEN,
77
78
  DEFAULT_AFTER_SIGN_IN_URL,
78
79
  DEFAULT_AFTER_SIGN_OUT_URL,
80
+ DEFAULT_API_URL,
79
81
  DEFAULT_SIGN_IN_URL,
80
82
  DEFAULT_SIGN_UP_URL,
81
83
  HEADER_AUTHORIZATION,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/jwt.ts","../src/constants.ts","../src/url.ts","../src/validators.ts"],"sourcesContent":["import type { InAIAuthErrorBody } from \"@inai-dev/types\";\n\nexport class InAIAuthError extends Error {\n status: number;\n body: InAIAuthErrorBody;\n code: string;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.name = \"InAIAuthError\";\n this.status = status;\n const parsed = body as Record<string, unknown> | null;\n this.body = {\n code: (parsed?.code as string) ?? \"UNKNOWN_ERROR\",\n detail: (parsed?.detail as string) ?? message,\n field: (parsed?.field as string) ?? undefined,\n };\n this.code = this.body.code;\n }\n}\n","import type { JWTClaims } from \"@inai-dev/types\";\n\nexport function decodeJWTPayload(token: string): JWTClaims | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n const payload = parts[1].replace(/-/g, \"+\").replace(/_/g, \"/\");\n const decoded = atob(payload);\n return JSON.parse(decoded);\n } catch {\n return null;\n }\n}\n\nexport function isTokenExpired(token: string): boolean {\n const claims = decodeJWTPayload(token);\n if (!claims?.exp) return true;\n return Date.now() >= claims.exp * 1000;\n}\n\nexport function getClaimsFromToken(token: string): JWTClaims | null {\n return decodeJWTPayload(token);\n}\n","export const COOKIE_AUTH_TOKEN = \"auth_token\";\nexport const COOKIE_REFRESH_TOKEN = \"refresh_token\";\nexport const COOKIE_AUTH_SESSION = \"auth_session\";\n\nexport const DEFAULT_SIGN_IN_URL = \"/login\";\nexport const DEFAULT_SIGN_UP_URL = \"/register\";\nexport const DEFAULT_AFTER_SIGN_IN_URL = \"/\";\nexport const DEFAULT_AFTER_SIGN_OUT_URL = \"/login\";\n\nexport const HEADER_PUBLISHABLE_KEY = \"X-Publishable-Key\";\nexport const HEADER_AUTHORIZATION = \"Authorization\";\nexport const HEADER_INAI_AUTH = \"x-inai-auth\";\n","export function normalizeApiUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nexport function buildEndpoint(apiUrl: string, path: string): string {\n return `${normalizeApiUrl(apiUrl)}${path}`;\n}\n","export function isValidEmail(email: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n}\n\nexport function isStrongPassword(password: string): {\n valid: boolean;\n errors: string[];\n} {\n const errors: string[] = [];\n if (password.length < 8) errors.push(\"Password must be at least 8 characters\");\n if (!/[A-Z]/.test(password)) errors.push(\"Password must contain an uppercase letter\");\n if (!/[a-z]/.test(password)) errors.push(\"Password must contain a lowercase letter\");\n if (!/[0-9]/.test(password)) errors.push(\"Password must contain a number\");\n return { valid: errors.length === 0, errors };\n}\n"],"mappings":";AAEO,IAAM,gBAAN,cAA4B,MAAM;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,SAAiB,QAAgB,MAAe;AAC1D,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,UAAM,SAAS;AACf,SAAK,OAAO;AAAA,MACV,MAAO,QAAQ,QAAmB;AAAA,MAClC,QAAS,QAAQ,UAAqB;AAAA,MACtC,OAAQ,QAAQ,SAAoB;AAAA,IACtC;AACA,SAAK,OAAO,KAAK,KAAK;AAAA,EACxB;AACF;;;ACjBO,SAAS,iBAAiB,OAAiC;AAChE,MAAI;AACF,UAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,QAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,UAAM,UAAU,MAAM,CAAC,EAAE,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG;AAC7D,UAAM,UAAU,KAAK,OAAO;AAC5B,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,eAAe,OAAwB;AACrD,QAAM,SAAS,iBAAiB,KAAK;AACrC,MAAI,CAAC,QAAQ,IAAK,QAAO;AACzB,SAAO,KAAK,IAAI,KAAK,OAAO,MAAM;AACpC;AAEO,SAAS,mBAAmB,OAAiC;AAClE,SAAO,iBAAiB,KAAK;AAC/B;;;ACtBO,IAAM,oBAAoB;AAC1B,IAAM,uBAAuB;AAC7B,IAAM,sBAAsB;AAE5B,IAAM,sBAAsB;AAC5B,IAAM,sBAAsB;AAC5B,IAAM,4BAA4B;AAClC,IAAM,6BAA6B;AAEnC,IAAM,yBAAyB;AAC/B,IAAM,uBAAuB;AAC7B,IAAM,mBAAmB;;;ACXzB,SAAS,gBAAgB,KAAqB;AACnD,SAAO,IAAI,QAAQ,OAAO,EAAE;AAC9B;AAEO,SAAS,cAAc,QAAgB,MAAsB;AAClE,SAAO,GAAG,gBAAgB,MAAM,CAAC,GAAG,IAAI;AAC1C;;;ACNO,SAAS,aAAa,OAAwB;AACnD,SAAO,6BAA6B,KAAK,KAAK;AAChD;AAEO,SAAS,iBAAiB,UAG/B;AACA,QAAM,SAAmB,CAAC;AAC1B,MAAI,SAAS,SAAS,EAAG,QAAO,KAAK,wCAAwC;AAC7E,MAAI,CAAC,QAAQ,KAAK,QAAQ,EAAG,QAAO,KAAK,2CAA2C;AACpF,MAAI,CAAC,QAAQ,KAAK,QAAQ,EAAG,QAAO,KAAK,0CAA0C;AACnF,MAAI,CAAC,QAAQ,KAAK,QAAQ,EAAG,QAAO,KAAK,gCAAgC;AACzE,SAAO,EAAE,OAAO,OAAO,WAAW,GAAG,OAAO;AAC9C;","names":[]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/jwt.ts","../src/constants.ts","../src/url.ts","../src/validators.ts"],"sourcesContent":["import type { InAIAuthErrorBody } from \"@inai-dev/types\";\n\nexport class InAIAuthError extends Error {\n status: number;\n body: InAIAuthErrorBody;\n code: string;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.name = \"InAIAuthError\";\n this.status = status;\n const parsed = body as Record<string, unknown> | null;\n this.body = {\n code: (parsed?.code as string) ?? \"UNKNOWN_ERROR\",\n detail: (parsed?.detail as string) ?? message,\n field: (parsed?.field as string) ?? undefined,\n };\n this.code = this.body.code;\n }\n}\n","import type { JWTClaims } from \"@inai-dev/types\";\n\nexport function decodeJWTPayload(token: string): JWTClaims | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n const payload = parts[1].replace(/-/g, \"+\").replace(/_/g, \"/\");\n const decoded = atob(payload);\n return JSON.parse(decoded);\n } catch {\n return null;\n }\n}\n\nexport function isTokenExpired(token: string): boolean {\n const claims = decodeJWTPayload(token);\n if (!claims?.exp) return true;\n return Date.now() >= claims.exp * 1000;\n}\n\nexport function getClaimsFromToken(token: string): JWTClaims | null {\n return decodeJWTPayload(token);\n}\n","export const COOKIE_AUTH_TOKEN = \"auth_token\";\nexport const COOKIE_REFRESH_TOKEN = \"refresh_token\";\nexport const COOKIE_AUTH_SESSION = \"auth_session\";\n\nexport const DEFAULT_SIGN_IN_URL = \"/login\";\nexport const DEFAULT_SIGN_UP_URL = \"/register\";\nexport const DEFAULT_AFTER_SIGN_IN_URL = \"/\";\nexport const DEFAULT_AFTER_SIGN_OUT_URL = \"/login\";\n\nexport const HEADER_PUBLISHABLE_KEY = \"X-Publishable-Key\";\nexport const HEADER_AUTHORIZATION = \"Authorization\";\nexport const HEADER_INAI_AUTH = \"x-inai-auth\";\n\nexport const DEFAULT_API_URL = \"https://apiauth.inai.dev\";\n","export function normalizeApiUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nexport function buildEndpoint(apiUrl: string, path: string): string {\n return `${normalizeApiUrl(apiUrl)}${path}`;\n}\n","export function isValidEmail(email: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n}\n\nexport function isStrongPassword(password: string): {\n valid: boolean;\n errors: string[];\n} {\n const errors: string[] = [];\n if (password.length < 8) errors.push(\"Password must be at least 8 characters\");\n if (!/[A-Z]/.test(password)) errors.push(\"Password must contain an uppercase letter\");\n if (!/[a-z]/.test(password)) errors.push(\"Password must contain a lowercase letter\");\n if (!/[0-9]/.test(password)) errors.push(\"Password must contain a number\");\n return { valid: errors.length === 0, errors };\n}\n"],"mappings":";AAEO,IAAM,gBAAN,cAA4B,MAAM;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,SAAiB,QAAgB,MAAe;AAC1D,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,UAAM,SAAS;AACf,SAAK,OAAO;AAAA,MACV,MAAO,QAAQ,QAAmB;AAAA,MAClC,QAAS,QAAQ,UAAqB;AAAA,MACtC,OAAQ,QAAQ,SAAoB;AAAA,IACtC;AACA,SAAK,OAAO,KAAK,KAAK;AAAA,EACxB;AACF;;;ACjBO,SAAS,iBAAiB,OAAiC;AAChE,MAAI;AACF,UAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,QAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,UAAM,UAAU,MAAM,CAAC,EAAE,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG;AAC7D,UAAM,UAAU,KAAK,OAAO;AAC5B,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,eAAe,OAAwB;AACrD,QAAM,SAAS,iBAAiB,KAAK;AACrC,MAAI,CAAC,QAAQ,IAAK,QAAO;AACzB,SAAO,KAAK,IAAI,KAAK,OAAO,MAAM;AACpC;AAEO,SAAS,mBAAmB,OAAiC;AAClE,SAAO,iBAAiB,KAAK;AAC/B;;;ACtBO,IAAM,oBAAoB;AAC1B,IAAM,uBAAuB;AAC7B,IAAM,sBAAsB;AAE5B,IAAM,sBAAsB;AAC5B,IAAM,sBAAsB;AAC5B,IAAM,4BAA4B;AAClC,IAAM,6BAA6B;AAEnC,IAAM,yBAAyB;AAC/B,IAAM,uBAAuB;AAC7B,IAAM,mBAAmB;AAEzB,IAAM,kBAAkB;;;ACbxB,SAAS,gBAAgB,KAAqB;AACnD,SAAO,IAAI,QAAQ,OAAO,EAAE;AAC9B;AAEO,SAAS,cAAc,QAAgB,MAAsB;AAClE,SAAO,GAAG,gBAAgB,MAAM,CAAC,GAAG,IAAI;AAC1C;;;ACNO,SAAS,aAAa,OAAwB;AACnD,SAAO,6BAA6B,KAAK,KAAK;AAChD;AAEO,SAAS,iBAAiB,UAG/B;AACA,QAAM,SAAmB,CAAC;AAC1B,MAAI,SAAS,SAAS,EAAG,QAAO,KAAK,wCAAwC;AAC7E,MAAI,CAAC,QAAQ,KAAK,QAAQ,EAAG,QAAO,KAAK,2CAA2C;AACpF,MAAI,CAAC,QAAQ,KAAK,QAAQ,EAAG,QAAO,KAAK,0CAA0C;AACnF,MAAI,CAAC,QAAQ,KAAK,QAAQ,EAAG,QAAO,KAAK,gCAAgC;AACzE,SAAO,EAAE,OAAO,OAAO,WAAW,GAAG,OAAO;AAC9C;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inai-dev/shared",
3
- "version": "0.1.0",
3
+ "version": "1.1.0",
4
4
  "description": "Shared utilities for the InAI Auth SDK",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -12,7 +12,9 @@
12
12
  "require": "./dist/index.cjs"
13
13
  }
14
14
  },
15
- "files": ["dist"],
15
+ "files": [
16
+ "dist"
17
+ ],
16
18
  "scripts": {
17
19
  "build": "tsup",
18
20
  "dev": "tsup --watch",
@@ -22,7 +24,7 @@
22
24
  "prepublishOnly": "npm run build"
23
25
  },
24
26
  "dependencies": {
25
- "@inai-dev/types": "^0.1.0"
27
+ "@inai-dev/types": "^1.1.0"
26
28
  },
27
29
  "sideEffects": false,
28
30
  "publishConfig": {
@@ -37,5 +39,11 @@
37
39
  },
38
40
  "homepage": "https://inai.dev/",
39
41
  "bugs": "https://github.com/InAI-Team/inai-auth-sdk/issues",
40
- "keywords": ["inai", "auth", "shared", "utilities", "validation"]
42
+ "keywords": [
43
+ "inai",
44
+ "auth",
45
+ "shared",
46
+ "utilities",
47
+ "validation"
48
+ ]
41
49
  }