@seamless-auth/types 0.2.0 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @seamless-auth/types
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - f180c99: Add a Zod-free entry point for role matching.
8
+
9
+ `ROLE_NAME_PATTERN`, `roleGrantsAccess`, and `hasScopedRole` moved to
10
+ `src/schemas/role/matching.ts`, which imports nothing at runtime. Two subpath
11
+ exports expose it: `@seamless-auth/types/role/matching` for the matchers alone,
12
+ and `@seamless-auth/types/role` for those plus `RoleNameSchema`. Consumers on
13
+ the authorization path can now match roles without loading Zod or the schema
14
+ barrel.
15
+
16
+ The package also declares `"sideEffects": false` so bundlers can tree-shake the
17
+ barrel.
18
+
19
+ This is additive. The package root still exports everything it did before, and
20
+ the matching behavior is unchanged.
21
+
3
22
  ## 0.2.0
4
23
 
5
24
  ### Minor Changes
package/README.md CHANGED
@@ -45,6 +45,23 @@ const user = UserSchema.parse(data);
45
45
  User role schemas accept plain roles such as `admin` and colon-separated scoped roles such as
46
46
  `admin:read` and `admin:write`. Whitespace, underscores, slashes, and backslashes are rejected.
47
47
 
48
+ ### Match roles without Zod
49
+
50
+ `roleGrantsAccess` and `hasScopedRole` are plain string logic, but reaching them through the
51
+ package root loads Zod and every schema in the barrel. Code on the authorization hot path can
52
+ import them from `@seamless-auth/types/role/matching` instead, which has no runtime dependencies:
53
+
54
+ ```ts
55
+ import { hasScopedRole } from '@seamless-auth/types/role/matching';
56
+
57
+ if (!hasScopedRole(user.roles, 'billing:invoices:read')) {
58
+ throw new Error('forbidden');
59
+ }
60
+ ```
61
+
62
+ `@seamless-auth/types/role` adds `RoleNameSchema` on top of the same matchers, and the package
63
+ root still exports all of them, so existing imports keep working.
64
+
48
65
  ### Infer types
49
66
 
50
67
  ```ts
@@ -60,7 +77,7 @@ function handleUser(user: User) {
60
77
  ## Modules
61
78
 
62
79
  Every module is re-exported from the package root, so import from
63
- `@seamless-auth/types` rather than a subpath.
80
+ `@seamless-auth/types` unless one of the subpath exports below fits better.
64
81
 
65
82
  | Module | Covers |
66
83
  | -------------- | ------------------------------------------------------------------- |
@@ -82,6 +99,13 @@ Every module is re-exported from the package root, so import from
82
99
  | `metrics` | Dashboard metrics, timeseries, and security anomalies |
83
100
  | `admin` | Admin-only user detail, anomalies, and device replacement recovery |
84
101
 
102
+ ### Subpath exports
103
+
104
+ | Subpath | Covers |
105
+ | ------------------------------------ | -------------------------------------- |
106
+ | `@seamless-auth/types/role` | Role name schema plus the matchers |
107
+ | `@seamless-auth/types/role/matching` | The matchers alone, with no Zod import |
108
+
85
109
  ---
86
110
 
87
111
  ## Zod as the Source of Truth
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Role matching logic, deliberately free of any Zod import. Consumers on the
3
+ * authorization hot path can reach this through the `./role/matching` subpath
4
+ * export without pulling Zod into their dependency tree.
5
+ */
6
+ /**
7
+ * Roles are colon-scoped (`billing:invoices:read`). Underscores, slashes, and
8
+ * whitespace are excluded so a role name is always safe to embed in a JWT claim,
9
+ * a URL path segment, and a config file without escaping.
10
+ */
11
+ export declare const ROLE_NAME_PATTERN: RegExp;
12
+ /**
13
+ * Whether a granted role satisfies a required role. A `:*` suffix grants every
14
+ * role under that prefix, an unscoped role grants every role beneath it, and a
15
+ * `:write` role implies the matching `:read` role.
16
+ */
17
+ export declare function roleGrantsAccess(grantedRole: string, requiredRole: string): boolean;
18
+ /** Whether any granted role satisfies at least one of the required roles. */
19
+ export declare function hasScopedRole(grantedRoles: unknown, requiredRoles: string | string[]): boolean;
20
+ //# sourceMappingURL=matching.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matching.d.ts","sourceRoot":"","sources":["../../../src/schemas/role/matching.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,QAAiE,CAAC;AAUhG;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAmCnF;AAED,6EAA6E;AAC7E,wBAAgB,aAAa,CAAC,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAW9F"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Role matching logic, deliberately free of any Zod import. Consumers on the
3
+ * authorization hot path can reach this through the `./role/matching` subpath
4
+ * export without pulling Zod into their dependency tree.
5
+ */
6
+ /**
7
+ * Roles are colon-scoped (`billing:invoices:read`). Underscores, slashes, and
8
+ * whitespace are excluded so a role name is always safe to embed in a JWT claim,
9
+ * a URL path segment, and a config file without escaping.
10
+ */
11
+ export const ROLE_NAME_PATTERN = /^(?!.*[_/\\\s])(?=.{1,80}$)[A-Za-z0-9-]+(?::[A-Za-z0-9-]+)*$/;
12
+ function normalizeRole(value) {
13
+ return value.trim();
14
+ }
15
+ function samePrefix(left, right) {
16
+ return left.length === right.length && left.every((part, index) => part === right[index]);
17
+ }
18
+ /**
19
+ * Whether a granted role satisfies a required role. A `:*` suffix grants every
20
+ * role under that prefix, an unscoped role grants every role beneath it, and a
21
+ * `:write` role implies the matching `:read` role.
22
+ */
23
+ export function roleGrantsAccess(grantedRole, requiredRole) {
24
+ const granted = normalizeRole(grantedRole);
25
+ const required = normalizeRole(requiredRole);
26
+ if (!granted || !required) {
27
+ return false;
28
+ }
29
+ if (granted === required) {
30
+ return true;
31
+ }
32
+ if (granted.endsWith(':*')) {
33
+ const prefix = granted.slice(0, -2);
34
+ return required === prefix || required.startsWith(`${prefix}:`);
35
+ }
36
+ if (!required.includes(':')) {
37
+ return false;
38
+ }
39
+ if (!granted.includes(':')) {
40
+ return required.startsWith(`${granted}:`);
41
+ }
42
+ const grantedParts = granted.split(':');
43
+ const requiredParts = required.split(':');
44
+ const grantedAction = grantedParts[grantedParts.length - 1];
45
+ const requiredAction = requiredParts[requiredParts.length - 1];
46
+ return (grantedAction === 'write' &&
47
+ requiredAction === 'read' &&
48
+ samePrefix(grantedParts.slice(0, -1), requiredParts.slice(0, -1)));
49
+ }
50
+ /** Whether any granted role satisfies at least one of the required roles. */
51
+ export function hasScopedRole(grantedRoles, requiredRoles) {
52
+ if (!Array.isArray(grantedRoles)) {
53
+ return false;
54
+ }
55
+ const required = Array.isArray(requiredRoles) ? requiredRoles : [requiredRoles];
56
+ const granted = grantedRoles.filter((role) => typeof role === 'string');
57
+ return required.some((requiredRole) => granted.some((grantedRole) => roleGrantsAccess(grantedRole, requiredRole)));
58
+ }
59
+ //# sourceMappingURL=matching.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matching.js","sourceRoot":"","sources":["../../../src/schemas/role/matching.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,8DAA8D,CAAC;AAEhG,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,SAAS,UAAU,CAAC,IAAc,EAAE,KAAe;IACjD,OAAO,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AAC5F,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAmB,EAAE,YAAoB;IACxE,MAAM,OAAO,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;IAE7C,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACpC,OAAO,QAAQ,KAAK,MAAM,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAC,UAAU,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1C,MAAM,aAAa,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC5D,MAAM,cAAc,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAE/D,OAAO,CACL,aAAa,KAAK,OAAO;QACzB,cAAc,KAAK,MAAM;QACzB,UAAU,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAClE,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,aAAa,CAAC,YAAqB,EAAE,aAAgC;IACnF,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAChF,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC;IAExF,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,EAAE,CACpC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAC3E,CAAC;AACJ,CAAC"}
@@ -1,20 +1,7 @@
1
1
  import { z } from 'zod';
2
- /**
3
- * Roles are colon-scoped (`billing:invoices:read`). Underscores, slashes, and
4
- * whitespace are excluded so a role name is always safe to embed in a JWT claim,
5
- * a URL path segment, and a config file without escaping.
6
- */
7
- export declare const ROLE_NAME_PATTERN: RegExp;
2
+ export * from './matching.js';
8
3
  export declare const RoleNameSchema: z.ZodString;
9
4
  export type RoleName = z.infer<typeof RoleNameSchema>;
10
5
  /** @deprecated Use {@link RoleNameSchema}. */
11
6
  export declare const RoleSchema: z.ZodString;
12
- /**
13
- * Whether a granted role satisfies a required role. A `:*` suffix grants every
14
- * role under that prefix, an unscoped role grants every role beneath it, and a
15
- * `:write` role implies the matching `:read` role.
16
- */
17
- export declare function roleGrantsAccess(grantedRole: string, requiredRole: string): boolean;
18
- /** Whether any granted role satisfies at least one of the required roles. */
19
- export declare function hasScopedRole(grantedRoles: unknown, requiredRoles: string | string[]): boolean;
20
7
  //# sourceMappingURL=schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/schemas/role/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,QAAiE,CAAC;AAEhG,eAAO,MAAM,cAAc,aAA6C,CAAC;AAEzE,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD,8CAA8C;AAC9C,eAAO,MAAM,UAAU,aAAiB,CAAC;AAUzC;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAmCnF;AAED,6EAA6E;AAC7E,wBAAgB,aAAa,CAAC,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAW9F"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/schemas/role/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,cAAc,eAAe,CAAC;AAE9B,eAAO,MAAM,cAAc,aAA6C,CAAC;AAEzE,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD,8CAA8C;AAC9C,eAAO,MAAM,UAAU,aAAiB,CAAC"}
@@ -1,58 +1,7 @@
1
1
  import { z } from 'zod';
2
- /**
3
- * Roles are colon-scoped (`billing:invoices:read`). Underscores, slashes, and
4
- * whitespace are excluded so a role name is always safe to embed in a JWT claim,
5
- * a URL path segment, and a config file without escaping.
6
- */
7
- export const ROLE_NAME_PATTERN = /^(?!.*[_/\\\s])(?=.{1,80}$)[A-Za-z0-9-]+(?::[A-Za-z0-9-]+)*$/;
2
+ import { ROLE_NAME_PATTERN } from './matching.js';
3
+ export * from './matching.js';
8
4
  export const RoleNameSchema = z.string().trim().regex(ROLE_NAME_PATTERN);
9
5
  /** @deprecated Use {@link RoleNameSchema}. */
10
6
  export const RoleSchema = RoleNameSchema;
11
- function normalizeRole(value) {
12
- return value.trim();
13
- }
14
- function samePrefix(left, right) {
15
- return left.length === right.length && left.every((part, index) => part === right[index]);
16
- }
17
- /**
18
- * Whether a granted role satisfies a required role. A `:*` suffix grants every
19
- * role under that prefix, an unscoped role grants every role beneath it, and a
20
- * `:write` role implies the matching `:read` role.
21
- */
22
- export function roleGrantsAccess(grantedRole, requiredRole) {
23
- const granted = normalizeRole(grantedRole);
24
- const required = normalizeRole(requiredRole);
25
- if (!granted || !required) {
26
- return false;
27
- }
28
- if (granted === required) {
29
- return true;
30
- }
31
- if (granted.endsWith(':*')) {
32
- const prefix = granted.slice(0, -2);
33
- return required === prefix || required.startsWith(`${prefix}:`);
34
- }
35
- if (!required.includes(':')) {
36
- return false;
37
- }
38
- if (!granted.includes(':')) {
39
- return required.startsWith(`${granted}:`);
40
- }
41
- const grantedParts = granted.split(':');
42
- const requiredParts = required.split(':');
43
- const grantedAction = grantedParts[grantedParts.length - 1];
44
- const requiredAction = requiredParts[requiredParts.length - 1];
45
- return (grantedAction === 'write' &&
46
- requiredAction === 'read' &&
47
- samePrefix(grantedParts.slice(0, -1), requiredParts.slice(0, -1)));
48
- }
49
- /** Whether any granted role satisfies at least one of the required roles. */
50
- export function hasScopedRole(grantedRoles, requiredRoles) {
51
- if (!Array.isArray(grantedRoles)) {
52
- return false;
53
- }
54
- const required = Array.isArray(requiredRoles) ? requiredRoles : [requiredRoles];
55
- const granted = grantedRoles.filter((role) => typeof role === 'string');
56
- return required.some((requiredRole) => granted.some((grantedRole) => roleGrantsAccess(grantedRole, requiredRole)));
57
- }
58
7
  //# sourceMappingURL=schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/schemas/role/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/schemas/role/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,cAAc,eAAe,CAAC;AAE9B,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;AAIzE,8CAA8C;AAC9C,MAAM,CAAC,MAAM,UAAU,GAAG,cAAc,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seamless-auth/types",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Shared TypeScript types and Zod schemas for SeamlessAuth.",
5
5
  "author": "Fells Code, LLC",
6
6
  "license": "AGPL-3.0-only",
@@ -11,8 +11,17 @@
11
11
  ".": {
12
12
  "types": "./dist/index.d.ts",
13
13
  "import": "./dist/index.js"
14
+ },
15
+ "./role": {
16
+ "types": "./dist/schemas/role/schema.d.ts",
17
+ "import": "./dist/schemas/role/schema.js"
18
+ },
19
+ "./role/matching": {
20
+ "types": "./dist/schemas/role/matching.d.ts",
21
+ "import": "./dist/schemas/role/matching.js"
14
22
  }
15
23
  },
24
+ "sideEffects": false,
16
25
  "files": [
17
26
  "dist",
18
27
  "README.md",