@checkstack/common 0.4.0 → 0.5.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 +27 -0
- package/package.json +1 -1
- package/src/access-utils.ts +57 -31
- package/src/types.ts +29 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @checkstack/common
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 8a87cd4: Refactored `accessPair` interface for cleaner access rule definitions
|
|
8
|
+
|
|
9
|
+
The `accessPair` function now uses a more intuitive interface where each level (read/manage) has its own configuration object:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
accessPair(
|
|
13
|
+
"incident",
|
|
14
|
+
{
|
|
15
|
+
read: {
|
|
16
|
+
description: "View incidents",
|
|
17
|
+
isDefault: true,
|
|
18
|
+
isPublic: true,
|
|
19
|
+
},
|
|
20
|
+
manage: {
|
|
21
|
+
description: "Manage incidents",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
{ idParam: "systemId" }
|
|
25
|
+
);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Also added `instanceAccess` field to `ProcedureMetadata` allowing bulk endpoints to share the same access rule as single endpoints with different filtering strategies.
|
|
29
|
+
|
|
3
30
|
## 0.4.0
|
|
4
31
|
|
|
5
32
|
### Minor Changes
|
package/package.json
CHANGED
package/src/access-utils.ts
CHANGED
|
@@ -120,7 +120,7 @@ export interface AccessRule {
|
|
|
120
120
|
*/
|
|
121
121
|
export function qualifyAccessRuleId(
|
|
122
122
|
pluginMetadata: Pick<PluginMetadata, "pluginId">,
|
|
123
|
-
rule: Pick<AccessRule, "id"
|
|
123
|
+
rule: Pick<AccessRule, "id">,
|
|
124
124
|
): string {
|
|
125
125
|
return `${pluginMetadata.pluginId}.${rule.id}`;
|
|
126
126
|
}
|
|
@@ -164,7 +164,7 @@ export function access(
|
|
|
164
164
|
recordKey?: string;
|
|
165
165
|
isDefault?: boolean;
|
|
166
166
|
isPublic?: boolean;
|
|
167
|
-
}
|
|
167
|
+
},
|
|
168
168
|
): AccessRule {
|
|
169
169
|
const hasInstanceAccess =
|
|
170
170
|
options?.idParam || options?.listKey || options?.recordKey;
|
|
@@ -186,55 +186,81 @@ export function access(
|
|
|
186
186
|
};
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
+
/**
|
|
190
|
+
* Configuration for a single access level in an accessPair.
|
|
191
|
+
*/
|
|
192
|
+
export interface AccessLevelConfig {
|
|
193
|
+
/**
|
|
194
|
+
* Human-readable description of what this access level allows.
|
|
195
|
+
*/
|
|
196
|
+
description: string;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Whether this access rule is granted by default to authenticated users ("users" role).
|
|
200
|
+
*/
|
|
201
|
+
isDefault?: boolean;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Whether this access rule is granted to anonymous/public users ("anonymous" role).
|
|
205
|
+
*/
|
|
206
|
+
isPublic?: boolean;
|
|
207
|
+
}
|
|
208
|
+
|
|
189
209
|
/**
|
|
190
210
|
* Creates a read/manage pair for a resource.
|
|
191
211
|
* Most resources need both access levels, so this reduces boilerplate.
|
|
192
212
|
*
|
|
193
213
|
* @param resource - The resource name (e.g., "system", "incident")
|
|
194
|
-
* @param
|
|
195
|
-
* @param
|
|
214
|
+
* @param levels - Configuration for read and manage levels
|
|
215
|
+
* @param instanceAccess - Optional configuration for instance-level (team-based) access
|
|
196
216
|
* @returns An object with `read` and `manage` AccessRule properties
|
|
197
217
|
*
|
|
198
218
|
* @example
|
|
199
219
|
* ```typescript
|
|
200
|
-
* const
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
220
|
+
* const incidentAccess = accessPair(
|
|
221
|
+
* "incident",
|
|
222
|
+
* {
|
|
223
|
+
* read: {
|
|
224
|
+
* description: "View incidents",
|
|
225
|
+
* isDefault: true,
|
|
226
|
+
* isPublic: true,
|
|
227
|
+
* },
|
|
228
|
+
* manage: {
|
|
229
|
+
* description: "Manage incidents - create, edit, resolve, and delete",
|
|
230
|
+
* },
|
|
231
|
+
* },
|
|
232
|
+
* {
|
|
233
|
+
* idParam: "systemId",
|
|
234
|
+
* }
|
|
235
|
+
* );
|
|
209
236
|
*
|
|
210
237
|
* // Usage in contract:
|
|
211
|
-
*
|
|
212
|
-
*
|
|
238
|
+
* getIncidents: proc({ access: [incidentAccess.read] }),
|
|
239
|
+
* updateIncident: proc({ access: [incidentAccess.manage] }),
|
|
213
240
|
* ```
|
|
214
241
|
*/
|
|
215
242
|
export function accessPair(
|
|
216
243
|
resource: string,
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
readIsDefault?: boolean;
|
|
223
|
-
readIsPublic?: boolean;
|
|
224
|
-
}
|
|
244
|
+
levels: {
|
|
245
|
+
read: AccessLevelConfig;
|
|
246
|
+
manage: AccessLevelConfig;
|
|
247
|
+
},
|
|
248
|
+
instanceAccess?: InstanceAccessConfig,
|
|
225
249
|
): { read: AccessRule; manage: AccessRule } {
|
|
226
250
|
return {
|
|
227
|
-
read: access(resource, "read",
|
|
228
|
-
idParam:
|
|
229
|
-
listKey:
|
|
230
|
-
recordKey:
|
|
231
|
-
isDefault:
|
|
232
|
-
isPublic:
|
|
251
|
+
read: access(resource, "read", levels.read.description, {
|
|
252
|
+
idParam: instanceAccess?.idParam,
|
|
253
|
+
listKey: instanceAccess?.listKey,
|
|
254
|
+
recordKey: instanceAccess?.recordKey,
|
|
255
|
+
isDefault: levels.read.isDefault,
|
|
256
|
+
isPublic: levels.read.isPublic,
|
|
233
257
|
}),
|
|
234
|
-
manage: access(resource, "manage",
|
|
235
|
-
idParam:
|
|
258
|
+
manage: access(resource, "manage", levels.manage.description, {
|
|
259
|
+
idParam: instanceAccess?.idParam,
|
|
236
260
|
// Note: manage doesn't typically use listKey (you don't "manage" a list in bulk)
|
|
237
261
|
// but we include idParam for single-resource manage checks
|
|
262
|
+
isDefault: levels.manage.isDefault,
|
|
263
|
+
isPublic: levels.manage.isPublic,
|
|
238
264
|
}),
|
|
239
265
|
};
|
|
240
266
|
}
|
package/src/types.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// RPC PROCEDURE METADATA
|
|
3
3
|
// =============================================================================
|
|
4
4
|
|
|
5
|
-
import type { AccessRule } from "./access-utils";
|
|
5
|
+
import type { AccessRule, InstanceAccessConfig } from "./access-utils";
|
|
6
6
|
|
|
7
7
|
// =============================================================================
|
|
8
8
|
// EDITOR TYPES - Used for multi-type editor fields
|
|
@@ -92,4 +92,32 @@ export interface ProcedureMetadata {
|
|
|
92
92
|
* ```
|
|
93
93
|
*/
|
|
94
94
|
access: AccessRule[];
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Override the instance access configuration from the access rules.
|
|
98
|
+
* Use this when a procedure needs different instance access handling than
|
|
99
|
+
* what's defined on its access rules.
|
|
100
|
+
*
|
|
101
|
+
* This is useful for bulk endpoints that share the same permission as single endpoints
|
|
102
|
+
* but use recordKey instead of idParam for filtering.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```typescript
|
|
106
|
+
* // Single endpoint using idParam from access rule
|
|
107
|
+
* getIncidentsForSystem: proc({
|
|
108
|
+
* userType: "public",
|
|
109
|
+
* operationType: "query",
|
|
110
|
+
* access: [incidentAccess.incident.read], // has idParam: "systemId"
|
|
111
|
+
* })
|
|
112
|
+
*
|
|
113
|
+
* // Bulk endpoint overriding to use recordKey
|
|
114
|
+
* getBulkIncidentsForSystems: proc({
|
|
115
|
+
* userType: "public",
|
|
116
|
+
* operationType: "query",
|
|
117
|
+
* access: [incidentAccess.incident.read], // same access rule
|
|
118
|
+
* instanceAccess: { recordKey: "incidents" }, // override for bulk
|
|
119
|
+
* })
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
instanceAccess?: InstanceAccessConfig;
|
|
95
123
|
}
|