@guinetik/primitives-ts 0.8.2 → 0.8.3
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 +28 -38
- package/dist/access.types.d.ts +98 -0
- package/dist/access.types.d.ts.map +1 -0
- package/dist/access.types.js +105 -0
- package/dist/access.types.spec.d.ts +2 -0
- package/dist/access.types.spec.d.ts.map +1 -0
- package/dist/access.types.spec.js +38 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -151,62 +151,52 @@ Available type guards:
|
|
|
151
151
|
|
|
152
152
|
### Publishing Process
|
|
153
153
|
|
|
154
|
-
|
|
154
|
+
Releases are published to the public npm registry by **GitHub Actions using npm
|
|
155
|
+
trusted publishing (OIDC)** — there is no npm token to fetch or set, and
|
|
156
|
+
`npm publish` is never run by hand.
|
|
155
157
|
|
|
156
|
-
1. **
|
|
158
|
+
1. **Make and test your changes** in `src/`, then check the consumers compile:
|
|
157
159
|
```bash
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
npm version major # for breaking changes (0.2.5 -> 1.0.0)
|
|
160
|
+
npm test && npm run build
|
|
161
|
+
# temporary overlay for a quick type-check; the real install replaces it later
|
|
162
|
+
cp -r dist/* ../api/node_modules/@guinetik/primitives-ts/dist/ && (cd ../api && npx tsc --noEmit)
|
|
162
163
|
```
|
|
163
164
|
|
|
164
|
-
2. **
|
|
165
|
-
|
|
166
|
-
|
|
165
|
+
2. **Cut the release** from the monorepo root (bumps `package.json`, commits,
|
|
166
|
+
tags `primitives-v<version>`, pushes branch + tag):
|
|
167
|
+
```powershell
|
|
168
|
+
.\scripts\release-primitives.ps1 # patch: 0.8.1 -> 0.8.2
|
|
169
|
+
.\scripts\release-primitives.ps1 -Bump minor # 0.8.1 -> 0.9.0
|
|
167
170
|
```
|
|
168
171
|
|
|
169
|
-
3. **
|
|
172
|
+
3. **Wait for the workflow** (`.github/workflows/publish-primitives.yml`,
|
|
173
|
+
about a minute) and confirm the registry has it:
|
|
170
174
|
```bash
|
|
171
|
-
|
|
172
|
-
# Set it with: $env:NPM_KEY = "your-npm-access-token"
|
|
173
|
-
npm publish --access public
|
|
175
|
+
npm view @guinetik/primitives-ts version
|
|
174
176
|
```
|
|
175
177
|
|
|
176
|
-
4. **
|
|
178
|
+
4. **Pin the new version in dependent projects** (exact, no `^`/`~`):
|
|
177
179
|
```bash
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
# Then install in each project
|
|
182
|
-
cd ../api
|
|
183
|
-
npm install
|
|
184
|
-
|
|
185
|
-
cd ../admin
|
|
186
|
-
npm install
|
|
180
|
+
cd ../api && npm install --save-exact @guinetik/primitives-ts@<version>
|
|
181
|
+
cd ../admin && npm install --save-exact @guinetik/primitives-ts@<version>
|
|
182
|
+
cd ../db && npm install --save-exact @guinetik/primitives-ts@<version>
|
|
187
183
|
```
|
|
188
184
|
|
|
185
|
+
Full details, one-time trusted-publisher setup and troubleshooting:
|
|
186
|
+
[`docs/development/primitives-publishing.md`](../docs/development/primitives-publishing.md).
|
|
187
|
+
|
|
189
188
|
### Why No Local Linking?
|
|
190
189
|
|
|
191
190
|
- **Prevents version drift** - Ensures all projects use exact versions
|
|
192
191
|
- **Avoids build issues** - npm link can cause TypeScript declaration file problems
|
|
193
|
-
- **Deployment consistency** -
|
|
194
|
-
- **Simple workflow** -
|
|
195
|
-
|
|
196
|
-
### NPM Authentication
|
|
192
|
+
- **Deployment consistency** - Docker build contexts are the app folders, so `../primitives` does not exist there
|
|
193
|
+
- **Simple workflow** - A tag push publishes; consumers just `npm install`
|
|
197
194
|
|
|
198
|
-
|
|
199
|
-
- Stored in: Bitwarden Secrets Manager
|
|
200
|
-
- Secret name: `NPM_KEY`
|
|
201
|
-
- Used by: Local development, CI/CD, and autonomous agents
|
|
195
|
+
### Authentication
|
|
202
196
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
# Or set manually if you have the token
|
|
208
|
-
$env:NPM_KEY = "npm_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
209
|
-
```
|
|
197
|
+
None. Installing the package needs no credentials (it is public), and
|
|
198
|
+
publishing is authenticated by the GitHub Actions workflow's OIDC identity,
|
|
199
|
+
registered on npmjs.com as the package's trusted publisher.
|
|
210
200
|
|
|
211
201
|
## License
|
|
212
202
|
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feature-based access control types shared between API and Admin.
|
|
3
|
+
*/
|
|
4
|
+
import type { User } from './auth.types';
|
|
5
|
+
/** Application roles for admin panel users. */
|
|
6
|
+
export type AdminRole = 'admin' | 'guest';
|
|
7
|
+
/** Lifecycle status for admin directory records. */
|
|
8
|
+
export type AdminUserStatus = 'invited' | 'active' | 'disabled';
|
|
9
|
+
/** Avatar resolution strategy for admin users. */
|
|
10
|
+
export type AvatarSource = 'gravatar' | 'google' | 'custom';
|
|
11
|
+
/** Feature keys that gate admin panel pages and API areas. */
|
|
12
|
+
export type FeatureKey = 'dashboard' | 'site' | 'runtime' | 'files' | 'launchpad' | 'users' | 'system' | 'chat' | 'agents';
|
|
13
|
+
/** Canonical ordered list of grantable features. */
|
|
14
|
+
export declare const FEATURE_CATALOG: readonly FeatureKey[];
|
|
15
|
+
/** Human-readable labels for feature checklist UI. */
|
|
16
|
+
export declare const FEATURE_LABELS: Record<FeatureKey, string>;
|
|
17
|
+
/**
|
|
18
|
+
* Returns true when the value is a known feature key.
|
|
19
|
+
*
|
|
20
|
+
* @param value - Candidate feature key.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isFeatureKey(value: unknown): value is FeatureKey;
|
|
23
|
+
/**
|
|
24
|
+
* Normalizes and validates a feature grant list.
|
|
25
|
+
*
|
|
26
|
+
* @param features - Raw feature keys from input or Firestore.
|
|
27
|
+
* @returns Deduplicated feature keys in catalog order.
|
|
28
|
+
* @throws Error when an unknown or duplicate value is present.
|
|
29
|
+
*/
|
|
30
|
+
export declare function normalizeFeatureKeys(features: unknown): FeatureKey[];
|
|
31
|
+
/** Authenticated admin panel user returned by `/auth/me` and login flows. */
|
|
32
|
+
export interface AuthenticatedUser extends User {
|
|
33
|
+
role?: AdminRole;
|
|
34
|
+
features?: FeatureKey[];
|
|
35
|
+
status?: AdminUserStatus;
|
|
36
|
+
avatarSource?: AvatarSource;
|
|
37
|
+
}
|
|
38
|
+
/** Admin directory user exposed by `/users` management APIs. */
|
|
39
|
+
export interface AdminUser {
|
|
40
|
+
id: string;
|
|
41
|
+
uid?: string;
|
|
42
|
+
email: string;
|
|
43
|
+
displayName?: string;
|
|
44
|
+
role: AdminRole;
|
|
45
|
+
features: FeatureKey[];
|
|
46
|
+
status: AdminUserStatus;
|
|
47
|
+
avatarSource: AvatarSource;
|
|
48
|
+
photoURL: string;
|
|
49
|
+
customPhotoURL?: string;
|
|
50
|
+
emailVerified: boolean;
|
|
51
|
+
invitedByUid?: string;
|
|
52
|
+
createdAt: string;
|
|
53
|
+
updatedAt: string;
|
|
54
|
+
lastSignInAt?: string;
|
|
55
|
+
}
|
|
56
|
+
/** Payload for inviting a new admin panel user. */
|
|
57
|
+
export interface InviteAdminUserInput {
|
|
58
|
+
email: string;
|
|
59
|
+
displayName?: string;
|
|
60
|
+
role?: AdminRole;
|
|
61
|
+
features?: FeatureKey[];
|
|
62
|
+
}
|
|
63
|
+
/** Payload for updating an admin directory user. */
|
|
64
|
+
export interface UpdateAdminUserInput {
|
|
65
|
+
displayName?: string;
|
|
66
|
+
status?: AdminUserStatus;
|
|
67
|
+
avatarSource?: AvatarSource;
|
|
68
|
+
customPhotoURL?: string;
|
|
69
|
+
role?: AdminRole;
|
|
70
|
+
features?: FeatureKey[];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Resolves the effective role for legacy documents without an explicit role.
|
|
74
|
+
*
|
|
75
|
+
* @param role - Stored role, if any.
|
|
76
|
+
*/
|
|
77
|
+
export declare function resolveAdminRole(role?: AdminRole): AdminRole;
|
|
78
|
+
/**
|
|
79
|
+
* Returns whether the user has admin-level unrestricted access.
|
|
80
|
+
*
|
|
81
|
+
* @param user - Authenticated or directory user.
|
|
82
|
+
*/
|
|
83
|
+
export declare function isAdminUser(user: Pick<AuthenticatedUser, 'role'>): boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Checks whether a user may access a feature.
|
|
86
|
+
*
|
|
87
|
+
* @param user - Authenticated user with role and feature grants.
|
|
88
|
+
* @param feature - Required feature key.
|
|
89
|
+
*/
|
|
90
|
+
export declare function userHasFeature(user: Pick<AuthenticatedUser, 'role' | 'features'>, feature: FeatureKey): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Checks whether a user may access at least one of the given features.
|
|
93
|
+
*
|
|
94
|
+
* @param user - Authenticated user with role and feature grants.
|
|
95
|
+
* @param features - Candidate feature keys.
|
|
96
|
+
*/
|
|
97
|
+
export declare function userHasAnyFeature(user: Pick<AuthenticatedUser, 'role' | 'features'>, features: readonly FeatureKey[]): boolean;
|
|
98
|
+
//# sourceMappingURL=access.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access.types.d.ts","sourceRoot":"","sources":["../src/access.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Feature-based access control types shared between API and Admin.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.FEATURE_LABELS = exports.FEATURE_CATALOG = void 0;
|
|
7
|
+
exports.isFeatureKey = isFeatureKey;
|
|
8
|
+
exports.normalizeFeatureKeys = normalizeFeatureKeys;
|
|
9
|
+
exports.resolveAdminRole = resolveAdminRole;
|
|
10
|
+
exports.isAdminUser = isAdminUser;
|
|
11
|
+
exports.userHasFeature = userHasFeature;
|
|
12
|
+
exports.userHasAnyFeature = userHasAnyFeature;
|
|
13
|
+
/** Canonical ordered list of grantable features. */
|
|
14
|
+
exports.FEATURE_CATALOG = [
|
|
15
|
+
'dashboard',
|
|
16
|
+
'site',
|
|
17
|
+
'runtime',
|
|
18
|
+
'files',
|
|
19
|
+
'launchpad',
|
|
20
|
+
'users',
|
|
21
|
+
'system',
|
|
22
|
+
'chat',
|
|
23
|
+
'agents',
|
|
24
|
+
];
|
|
25
|
+
/** Human-readable labels for feature checklist UI. */
|
|
26
|
+
exports.FEATURE_LABELS = {
|
|
27
|
+
dashboard: 'Dashboard',
|
|
28
|
+
site: 'Site',
|
|
29
|
+
runtime: 'Runtime',
|
|
30
|
+
files: 'File uploads',
|
|
31
|
+
launchpad: 'Launchpad',
|
|
32
|
+
users: 'Users',
|
|
33
|
+
system: 'System monitoring',
|
|
34
|
+
chat: 'Chat',
|
|
35
|
+
agents: 'Agents',
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Returns true when the value is a known feature key.
|
|
39
|
+
*
|
|
40
|
+
* @param value - Candidate feature key.
|
|
41
|
+
*/
|
|
42
|
+
function isFeatureKey(value) {
|
|
43
|
+
return typeof value === 'string' && exports.FEATURE_CATALOG.includes(value);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Normalizes and validates a feature grant list.
|
|
47
|
+
*
|
|
48
|
+
* @param features - Raw feature keys from input or Firestore.
|
|
49
|
+
* @returns Deduplicated feature keys in catalog order.
|
|
50
|
+
* @throws Error when an unknown or duplicate value is present.
|
|
51
|
+
*/
|
|
52
|
+
function normalizeFeatureKeys(features) {
|
|
53
|
+
if (!Array.isArray(features)) {
|
|
54
|
+
throw new Error('Features must be an array');
|
|
55
|
+
}
|
|
56
|
+
const seen = new Set();
|
|
57
|
+
for (const value of features) {
|
|
58
|
+
if (!isFeatureKey(value)) {
|
|
59
|
+
throw new Error(`Unknown feature key: ${String(value)}`);
|
|
60
|
+
}
|
|
61
|
+
if (seen.has(value)) {
|
|
62
|
+
throw new Error(`Duplicate feature key: ${value}`);
|
|
63
|
+
}
|
|
64
|
+
seen.add(value);
|
|
65
|
+
}
|
|
66
|
+
return exports.FEATURE_CATALOG.filter((key) => seen.has(key));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Resolves the effective role for legacy documents without an explicit role.
|
|
70
|
+
*
|
|
71
|
+
* @param role - Stored role, if any.
|
|
72
|
+
*/
|
|
73
|
+
function resolveAdminRole(role) {
|
|
74
|
+
return role ?? 'admin';
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Returns whether the user has admin-level unrestricted access.
|
|
78
|
+
*
|
|
79
|
+
* @param user - Authenticated or directory user.
|
|
80
|
+
*/
|
|
81
|
+
function isAdminUser(user) {
|
|
82
|
+
return resolveAdminRole(user.role) === 'admin';
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Checks whether a user may access a feature.
|
|
86
|
+
*
|
|
87
|
+
* @param user - Authenticated user with role and feature grants.
|
|
88
|
+
* @param feature - Required feature key.
|
|
89
|
+
*/
|
|
90
|
+
function userHasFeature(user, feature) {
|
|
91
|
+
if (isAdminUser(user))
|
|
92
|
+
return true;
|
|
93
|
+
return user.features?.includes(feature) ?? false;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Checks whether a user may access at least one of the given features.
|
|
97
|
+
*
|
|
98
|
+
* @param user - Authenticated user with role and feature grants.
|
|
99
|
+
* @param features - Candidate feature keys.
|
|
100
|
+
*/
|
|
101
|
+
function userHasAnyFeature(user, features) {
|
|
102
|
+
if (isAdminUser(user))
|
|
103
|
+
return true;
|
|
104
|
+
return features.some((feature) => user.features?.includes(feature));
|
|
105
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access.types.spec.d.ts","sourceRoot":"","sources":["../src/access.types.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const access_types_1 = require("./access.types");
|
|
4
|
+
describe('access.types', () => {
|
|
5
|
+
it('recognizes valid feature keys', () => {
|
|
6
|
+
expect((0, access_types_1.isFeatureKey)('dashboard')).toBe(true);
|
|
7
|
+
expect((0, access_types_1.isFeatureKey)('unknown')).toBe(false);
|
|
8
|
+
});
|
|
9
|
+
it('normalizes feature keys in catalog order', () => {
|
|
10
|
+
expect((0, access_types_1.normalizeFeatureKeys)(['chat', 'site'])).toEqual(['site', 'chat']);
|
|
11
|
+
});
|
|
12
|
+
it('rejects duplicate feature keys', () => {
|
|
13
|
+
expect(() => (0, access_types_1.normalizeFeatureKeys)(['chat', 'site', 'chat'])).toThrow(/Duplicate feature key/);
|
|
14
|
+
});
|
|
15
|
+
it('rejects unknown feature keys', () => {
|
|
16
|
+
expect(() => (0, access_types_1.normalizeFeatureKeys)(['dashboard', 'billing'])).toThrow(/Unknown feature key/);
|
|
17
|
+
});
|
|
18
|
+
it('defaults missing roles to admin for legacy users', () => {
|
|
19
|
+
expect((0, access_types_1.resolveAdminRole)(undefined)).toBe('admin');
|
|
20
|
+
expect((0, access_types_1.resolveAdminRole)('guest')).toBe('guest');
|
|
21
|
+
});
|
|
22
|
+
it('grants admins every feature without explicit grants', () => {
|
|
23
|
+
const admin = { role: 'admin', features: [] };
|
|
24
|
+
expect((0, access_types_1.userHasFeature)(admin, 'system')).toBe(true);
|
|
25
|
+
expect((0, access_types_1.userHasAnyFeature)(admin, ['dashboard', 'launchpad'])).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
it('requires explicit grants for guests', () => {
|
|
28
|
+
const guest = { role: 'guest', features: ['dashboard'] };
|
|
29
|
+
expect((0, access_types_1.userHasFeature)(guest, 'dashboard')).toBe(true);
|
|
30
|
+
expect((0, access_types_1.userHasFeature)(guest, 'system')).toBe(false);
|
|
31
|
+
expect((0, access_types_1.userHasAnyFeature)(guest, ['dashboard', 'launchpad'])).toBe(true);
|
|
32
|
+
expect((0, access_types_1.userHasAnyFeature)(guest, ['system', 'chat'])).toBe(false);
|
|
33
|
+
});
|
|
34
|
+
it('exposes a stable feature catalog', () => {
|
|
35
|
+
expect(access_types_1.FEATURE_CATALOG).toContain('users');
|
|
36
|
+
expect(access_types_1.FEATURE_CATALOG.length).toBe(9);
|
|
37
|
+
});
|
|
38
|
+
});
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,cAAc,cAAc,CAAC;AAG7B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,iBAAiB,CAAC;AAGhC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,2BAA2B,CAAC;AAG1C,cAAc,cAAc,CAAC;AAG7B,cAAc,4BAA4B,CAAC;AAG3C,cAAc,gBAAgB,CAAC;AAG/B,cAAc,cAAc,CAAC;AAG7B,cAAc,eAAe,CAAC;AAG9B,cAAc,eAAe,CAAC;AAG9B,cAAc,cAAc,CAAC;AAG7B,cAAc,mBAAmB,CAAC;AAGlC,YAAY,EAAE,QAAQ,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACxG,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,cAAc,cAAc,CAAC;AAG7B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,iBAAiB,CAAC;AAGhC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,2BAA2B,CAAC;AAG1C,cAAc,cAAc,CAAC;AAG7B,cAAc,4BAA4B,CAAC;AAG3C,cAAc,gBAAgB,CAAC;AAG/B,cAAc,cAAc,CAAC;AAG7B,cAAc,eAAe,CAAC;AAG9B,cAAc,eAAe,CAAC;AAG9B,cAAc,cAAc,CAAC;AAG7B,cAAc,mBAAmB,CAAC;AAGlC,YAAY,EAAE,QAAQ,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACxG,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -26,6 +26,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
26
26
|
exports.SecurityLevel = void 0;
|
|
27
27
|
// Auth types
|
|
28
28
|
__exportStar(require("./auth.types"), exports);
|
|
29
|
+
// Access control types
|
|
30
|
+
__exportStar(require("./access.types"), exports);
|
|
29
31
|
// System monitoring types
|
|
30
32
|
__exportStar(require("./system.types"), exports);
|
|
31
33
|
// Website/Site content types
|