@owlmeans/viable-common 0.0.46 → 0.0.47
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 +163 -14
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/agent-presentation/SKILL.md +1 -1
- package/agent-meta/skills/viable-common/SKILL.md +122 -30
- package/build/connect/account/types.d.ts +81 -0
- package/build/connect/account/types.d.ts.map +1 -0
- package/build/connect/account/types.js +2 -0
- package/build/connect/account/types.js.map +1 -0
- package/build/connect/branding/types.d.ts +26 -4
- package/build/connect/branding/types.d.ts.map +1 -1
- package/build/connect/call/types.d.ts +28 -0
- package/build/connect/call/types.d.ts.map +1 -0
- package/build/connect/call/types.js +2 -0
- package/build/connect/call/types.js.map +1 -0
- package/build/connect/config/types.d.ts +45 -0
- package/build/connect/config/types.d.ts.map +1 -0
- package/build/connect/config/types.js +2 -0
- package/build/connect/config/types.js.map +1 -0
- package/build/connect/consts.d.ts +383 -1
- package/build/connect/consts.d.ts.map +1 -1
- package/build/connect/consts.js +387 -1
- package/build/connect/consts.js.map +1 -1
- package/build/connect/conversion/types.d.ts +24 -0
- package/build/connect/conversion/types.d.ts.map +1 -1
- package/build/connect/entrypoints/types.d.ts +22 -13
- package/build/connect/entrypoints/types.d.ts.map +1 -1
- package/build/connect/entrypoints.d.ts +441 -8
- package/build/connect/entrypoints.d.ts.map +1 -1
- package/build/connect/entrypoints.js +292 -9
- package/build/connect/entrypoints.js.map +1 -1
- package/build/connect/errors.d.ts +12 -0
- package/build/connect/errors.d.ts.map +1 -1
- package/build/connect/errors.js +16 -0
- package/build/connect/errors.js.map +1 -1
- package/build/connect/feed/types.d.ts +71 -0
- package/build/connect/feed/types.d.ts.map +1 -0
- package/build/connect/feed/types.js +2 -0
- package/build/connect/feed/types.js.map +1 -0
- package/build/connect/files/types.d.ts +34 -0
- package/build/connect/files/types.d.ts.map +1 -0
- package/build/connect/files/types.js +2 -0
- package/build/connect/files/types.js.map +1 -0
- package/build/connect/git/types.d.ts +170 -0
- package/build/connect/git/types.d.ts.map +1 -0
- package/build/connect/git/types.js +14 -0
- package/build/connect/git/types.js.map +1 -0
- package/build/connect/iam/types.d.ts +25 -0
- package/build/connect/iam/types.d.ts.map +1 -0
- package/build/connect/iam/types.js +8 -0
- package/build/connect/iam/types.js.map +1 -0
- package/build/connect/index.d.ts +9 -0
- package/build/connect/index.d.ts.map +1 -1
- package/build/connect/production/types.d.ts +65 -0
- package/build/connect/production/types.d.ts.map +1 -0
- package/build/connect/production/types.js +2 -0
- package/build/connect/production/types.js.map +1 -0
- package/build/connect/project/types.d.ts +23 -16
- package/build/connect/project/types.d.ts.map +1 -1
- package/build/connect/references/types.d.ts +424 -2
- package/build/connect/references/types.d.ts.map +1 -1
- package/build/connect/references.d.ts.map +1 -1
- package/build/connect/references.js +122 -0
- package/build/connect/references.js.map +1 -1
- package/build/connect/schemas.d.ts +65 -2
- package/build/connect/schemas.d.ts.map +1 -1
- package/build/connect/schemas.js +306 -1
- package/build/connect/schemas.js.map +1 -1
- package/build/connect/settings/types.d.ts +0 -25
- package/build/connect/settings/types.d.ts.map +1 -1
- package/build/connect/slot/types.d.ts +24 -0
- package/build/connect/slot/types.d.ts.map +1 -0
- package/build/connect/slot/types.js +2 -0
- package/build/connect/slot/types.js.map +1 -0
- package/build/convert/record/types.d.ts +0 -9
- package/build/convert/record/types.d.ts.map +1 -1
- package/build/convert/schemas.d.ts +2 -5
- package/build/convert/schemas.d.ts.map +1 -1
- package/build/convert/schemas.js +2 -15
- package/build/convert/schemas.js.map +1 -1
- package/build/iam-console/consts.d.ts +13 -0
- package/build/iam-console/consts.d.ts.map +1 -0
- package/build/iam-console/consts.js +13 -0
- package/build/iam-console/consts.js.map +1 -0
- package/build/iam-console/consts.local.d.ts +123 -0
- package/build/iam-console/consts.local.d.ts.map +1 -0
- package/build/iam-console/consts.local.js +50 -0
- package/build/iam-console/consts.local.js.map +1 -0
- package/build/iam-console/index.d.ts +4 -0
- package/build/iam-console/index.d.ts.map +1 -0
- package/build/iam-console/index.js +3 -0
- package/build/iam-console/index.js.map +1 -0
- package/build/iam-console/schemas.d.ts +38 -0
- package/build/iam-console/schemas.d.ts.map +1 -0
- package/build/iam-console/schemas.js +217 -0
- package/build/iam-console/schemas.js.map +1 -0
- package/build/iam-console/types.d.ts +140 -0
- package/build/iam-console/types.d.ts.map +1 -0
- package/build/iam-console/types.js +2 -0
- package/build/iam-console/types.js.map +1 -0
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/legal/consts.d.ts +33 -2
- package/build/legal/consts.d.ts.map +1 -1
- package/build/legal/consts.js +11 -3
- package/build/legal/consts.js.map +1 -1
- package/build/legal/types.d.ts +8 -1
- package/build/legal/types.d.ts.map +1 -1
- package/build/planning/schemas.d.ts.map +1 -1
- package/build/planning/schemas.js +0 -1
- package/build/planning/schemas.js.map +1 -1
- package/build/planning/types.d.ts +0 -2
- package/build/planning/types.d.ts.map +1 -1
- package/package.json +11 -2
- package/src/connect/account/types.ts +91 -0
- package/src/connect/branding/types.ts +28 -4
- package/src/connect/call/types.ts +31 -0
- package/src/connect/config/types.ts +51 -0
- package/src/connect/consts.ts +400 -1
- package/src/connect/conversion/types.ts +25 -0
- package/src/connect/entrypoints/types.ts +22 -7
- package/src/connect/entrypoints.ts +592 -15
- package/src/connect/errors.ts +18 -0
- package/src/connect/feed/types.ts +76 -0
- package/src/connect/files/types.ts +38 -0
- package/src/connect/git/types.ts +187 -0
- package/src/connect/iam/types.ts +28 -0
- package/src/connect/index.ts +9 -0
- package/src/connect/production/types.ts +71 -0
- package/src/connect/project/types.ts +25 -12
- package/src/connect/references/types.ts +166 -5
- package/src/connect/references.ts +210 -5
- package/src/connect/schemas.ts +366 -5
- package/src/connect/settings/types.ts +0 -25
- package/src/connect/slot/types.ts +24 -0
- package/src/convert/record/types.ts +0 -11
- package/src/convert/schemas.ts +3 -19
- package/src/iam-console/consts.local.ts +64 -0
- package/src/iam-console/consts.ts +15 -0
- package/src/iam-console/index.ts +3 -0
- package/src/iam-console/schemas.ts +251 -0
- package/src/iam-console/types.ts +165 -0
- package/src/index.ts +1 -0
- package/src/legal/consts.ts +13 -5
- package/src/legal/types.ts +12 -1
- package/src/planning/schemas.ts +0 -1
- package/src/planning/types.ts +0 -2
- package/tests/connect-convert.spec.ts +6 -2
- package/tests/connect-entrypoints.spec.ts +554 -16
- package/tests/error-status.spec.ts +2 -1
- package/tests/iam-console.spec.ts +89 -0
- package/tests/planning.spec.ts +8 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import type { JSONSchemaType } from 'ajv'
|
|
2
|
+
import { IamDefaultClass, type IamGroupRef } from '@owlmeans/iam'
|
|
3
|
+
import {
|
|
4
|
+
EmailSchema, EntitySlugSchema, GroupBundleSchema, GroupKeySchema, ModeProp, NameSchema,
|
|
5
|
+
PermissionNameSchema, ProfileIdSchema, ProfileIdsSchema, ProjectIdProp, ResourceIdSchema, RoleSchema, ScopeProp,
|
|
6
|
+
TitleSchema,
|
|
7
|
+
} from './consts.local.js'
|
|
8
|
+
import type {
|
|
9
|
+
IamAssignGrant, IamDefinitionUpdate, IamGrantsQuery, IamGroupCreate, IamGroupEdit, IamGroupMembersChange,
|
|
10
|
+
IamGroupParams, IamMemberParams, IamOrganizationEdit, IamOrganizationParams, IamProjectMemberInvite,
|
|
11
|
+
IamProjectMemberUpdate, IamProjectParams, IamProjectUserInvite, IamProjectUserParams, IamProjectUserUpdate,
|
|
12
|
+
IamRevokeGrant, IamScoped, IamStaffSync,
|
|
13
|
+
} from './types.js'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The owner console's IAM schemas — one set for both doors: the browser's `back.iam` routes and the
|
|
17
|
+
* connector's `connect.iam` twins validate the same bodies, so a field cannot be admitted on one and
|
|
18
|
+
* refused on the other. Every object is closed (`additionalProperties: false`): an organization's
|
|
19
|
+
* record id (`entityId`) is refused wherever it is offered.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
export const IamProjectParamsSchema: JSONSchemaType<IamProjectParams> = {
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: { ...ProjectIdProp },
|
|
25
|
+
required: ['projectId'],
|
|
26
|
+
additionalProperties: false,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const IamProjectUserParamsSchema: JSONSchemaType<IamProjectUserParams> = {
|
|
30
|
+
type: 'object',
|
|
31
|
+
properties: { ...ProjectIdProp, profileId: ProfileIdSchema },
|
|
32
|
+
required: ['projectId', 'profileId'],
|
|
33
|
+
additionalProperties: false,
|
|
34
|
+
} as unknown as JSONSchemaType<IamProjectUserParams>
|
|
35
|
+
|
|
36
|
+
export const IamOrganizationParamsSchema: JSONSchemaType<IamOrganizationParams> = {
|
|
37
|
+
type: 'object',
|
|
38
|
+
properties: { ...ProjectIdProp, entitySlug: EntitySlugSchema },
|
|
39
|
+
required: ['projectId', 'entitySlug'],
|
|
40
|
+
additionalProperties: false,
|
|
41
|
+
} as unknown as JSONSchemaType<IamOrganizationParams>
|
|
42
|
+
|
|
43
|
+
export const IamMemberParamsSchema: JSONSchemaType<IamMemberParams> = {
|
|
44
|
+
type: 'object',
|
|
45
|
+
properties: { ...ProjectIdProp, entitySlug: EntitySlugSchema, profileId: ProfileIdSchema },
|
|
46
|
+
required: ['projectId', 'entitySlug', 'profileId'],
|
|
47
|
+
additionalProperties: false,
|
|
48
|
+
} as unknown as JSONSchemaType<IamMemberParams>
|
|
49
|
+
|
|
50
|
+
export const IamGroupRefSchema: JSONSchemaType<IamGroupRef> = {
|
|
51
|
+
type: 'object',
|
|
52
|
+
properties: {
|
|
53
|
+
entitySlug: EntitySlugSchema,
|
|
54
|
+
key: GroupKeySchema,
|
|
55
|
+
},
|
|
56
|
+
required: ['entitySlug', 'key'],
|
|
57
|
+
additionalProperties: false,
|
|
58
|
+
} as unknown as JSONSchemaType<IamGroupRef>
|
|
59
|
+
|
|
60
|
+
export const IamGroupParamsSchema: JSONSchemaType<IamGroupParams> = {
|
|
61
|
+
type: 'object',
|
|
62
|
+
properties: { ...ProjectIdProp, entitySlug: EntitySlugSchema, group: GroupKeySchema },
|
|
63
|
+
required: ['projectId', 'entitySlug', 'group'],
|
|
64
|
+
additionalProperties: false,
|
|
65
|
+
} as unknown as JSONSchemaType<IamGroupParams>
|
|
66
|
+
|
|
67
|
+
/** The client a body-less write addresses, carried in the body where a route has one (`scope`). */
|
|
68
|
+
export const IamScopedSchema: JSONSchemaType<IamScoped> = {
|
|
69
|
+
type: 'object',
|
|
70
|
+
properties: { scope: ScopeProp },
|
|
71
|
+
required: [],
|
|
72
|
+
additionalProperties: false,
|
|
73
|
+
} as unknown as JSONSchemaType<IamScoped>
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* A person or a group, never both; a group always with the organization it lives in.
|
|
77
|
+
*
|
|
78
|
+
* `dependencies` rather than a handler check, so a malformed listing is a validation refusal like
|
|
79
|
+
* every other — and the handler can rely on the shape it was handed.
|
|
80
|
+
*/
|
|
81
|
+
export const IamGrantsQuerySchema: JSONSchemaType<IamGrantsQuery> = {
|
|
82
|
+
type: 'object',
|
|
83
|
+
properties: {
|
|
84
|
+
profileId: { ...ProfileIdSchema, nullable: true },
|
|
85
|
+
group: { ...GroupKeySchema, nullable: true },
|
|
86
|
+
entitySlug: { ...EntitySlugSchema, nullable: true },
|
|
87
|
+
scope: ScopeProp,
|
|
88
|
+
},
|
|
89
|
+
required: [],
|
|
90
|
+
additionalProperties: false,
|
|
91
|
+
dependencies: { group: ['entitySlug'] },
|
|
92
|
+
not: { required: ['profileId', 'group'] },
|
|
93
|
+
} as unknown as JSONSchemaType<IamGrantsQuery>
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Exactly one subject. Each branch excludes the other subject itself, so a body naming both
|
|
97
|
+
* matches neither; the group branch also refuses a binding — a group grant is bound to the group's
|
|
98
|
+
* own organization, and a second organization in the body could only disagree with it. Each branch
|
|
99
|
+
* declares the property it requires, so a reader of the branch alone (a model-schema check) sees it.
|
|
100
|
+
*/
|
|
101
|
+
const OneSubject = [
|
|
102
|
+
{ properties: { profileId: ProfileIdSchema }, required: ['profileId'], not: { required: ['group'] } },
|
|
103
|
+
{
|
|
104
|
+
properties: { group: IamGroupRefSchema },
|
|
105
|
+
required: ['group'],
|
|
106
|
+
not: { anyOf: [{ required: ['profileId'] }, { required: ['entitySlug'] }] },
|
|
107
|
+
},
|
|
108
|
+
] as const
|
|
109
|
+
|
|
110
|
+
const grantSchemaProperties = {
|
|
111
|
+
profileId: { ...ProfileIdSchema, nullable: true },
|
|
112
|
+
group: { ...IamGroupRefSchema, nullable: true },
|
|
113
|
+
permission: PermissionNameSchema,
|
|
114
|
+
resources: { type: 'array', items: ResourceIdSchema, maxItems: 256, nullable: true },
|
|
115
|
+
mode: ModeProp,
|
|
116
|
+
entitySlug: { ...EntitySlugSchema, nullable: true },
|
|
117
|
+
scope: ScopeProp,
|
|
118
|
+
} as const
|
|
119
|
+
|
|
120
|
+
export const IamAssignGrantSchema: JSONSchemaType<IamAssignGrant> = {
|
|
121
|
+
type: 'object',
|
|
122
|
+
properties: grantSchemaProperties,
|
|
123
|
+
required: ['permission'],
|
|
124
|
+
additionalProperties: false,
|
|
125
|
+
oneOf: OneSubject,
|
|
126
|
+
} as unknown as JSONSchemaType<IamAssignGrant>
|
|
127
|
+
|
|
128
|
+
export const IamRevokeGrantSchema: JSONSchemaType<IamRevokeGrant> = {
|
|
129
|
+
type: 'object',
|
|
130
|
+
properties: grantSchemaProperties,
|
|
131
|
+
required: ['permission'],
|
|
132
|
+
additionalProperties: false,
|
|
133
|
+
oneOf: OneSubject,
|
|
134
|
+
} as unknown as JSONSchemaType<IamRevokeGrant>
|
|
135
|
+
|
|
136
|
+
const DefaultClassProp = { type: 'string', enum: [...Object.values(IamDefaultClass), null], nullable: true } as const
|
|
137
|
+
const EntityScopedProp = { type: 'boolean', nullable: true } as const
|
|
138
|
+
|
|
139
|
+
/** At least one setting: an update that changes nothing is a client bug, not a request. */
|
|
140
|
+
export const IamDefinitionUpdateSchema: JSONSchemaType<IamDefinitionUpdate> = {
|
|
141
|
+
type: 'object',
|
|
142
|
+
properties: {
|
|
143
|
+
permission: PermissionNameSchema,
|
|
144
|
+
defaultClass: DefaultClassProp,
|
|
145
|
+
entityScoped: EntityScopedProp,
|
|
146
|
+
scope: ScopeProp,
|
|
147
|
+
},
|
|
148
|
+
required: ['permission'],
|
|
149
|
+
additionalProperties: false,
|
|
150
|
+
// Each branch declares the property it requires, so a reader of the branch alone sees it.
|
|
151
|
+
anyOf: [
|
|
152
|
+
{ properties: { defaultClass: DefaultClassProp }, required: ['defaultClass'] },
|
|
153
|
+
{ properties: { entityScoped: EntityScopedProp }, required: ['entityScoped'] },
|
|
154
|
+
],
|
|
155
|
+
} as unknown as JSONSchemaType<IamDefinitionUpdate>
|
|
156
|
+
|
|
157
|
+
export const IamStaffSyncSchema: JSONSchemaType<IamStaffSync> = {
|
|
158
|
+
type: 'object',
|
|
159
|
+
properties: { scope: ScopeProp },
|
|
160
|
+
required: [],
|
|
161
|
+
additionalProperties: false,
|
|
162
|
+
} as unknown as JSONSchemaType<IamStaffSync>
|
|
163
|
+
|
|
164
|
+
export const IamProjectUserInviteSchema: JSONSchemaType<IamProjectUserInvite> = {
|
|
165
|
+
type: 'object',
|
|
166
|
+
properties: {
|
|
167
|
+
email: EmailSchema,
|
|
168
|
+
name: { ...NameSchema, nullable: true },
|
|
169
|
+
role: { ...RoleSchema, nullable: true },
|
|
170
|
+
scope: ScopeProp,
|
|
171
|
+
},
|
|
172
|
+
required: ['email'],
|
|
173
|
+
additionalProperties: false,
|
|
174
|
+
} as unknown as JSONSchemaType<IamProjectUserInvite>
|
|
175
|
+
|
|
176
|
+
export const IamProjectUserUpdateSchema: JSONSchemaType<IamProjectUserUpdate> = {
|
|
177
|
+
type: 'object',
|
|
178
|
+
properties: {
|
|
179
|
+
name: { ...NameSchema, nullable: true },
|
|
180
|
+
role: { ...RoleSchema, nullable: true },
|
|
181
|
+
disabled: { type: 'boolean', nullable: true },
|
|
182
|
+
scope: ScopeProp,
|
|
183
|
+
},
|
|
184
|
+
required: [],
|
|
185
|
+
additionalProperties: false,
|
|
186
|
+
} as unknown as JSONSchemaType<IamProjectUserUpdate>
|
|
187
|
+
|
|
188
|
+
export const IamOrganizationEditSchema: JSONSchemaType<IamOrganizationEdit> = {
|
|
189
|
+
type: 'object',
|
|
190
|
+
properties: {
|
|
191
|
+
title: TitleSchema,
|
|
192
|
+
scope: ScopeProp,
|
|
193
|
+
},
|
|
194
|
+
required: ['title'],
|
|
195
|
+
additionalProperties: false,
|
|
196
|
+
} as unknown as JSONSchemaType<IamOrganizationEdit>
|
|
197
|
+
|
|
198
|
+
export const IamProjectMemberInviteSchema: JSONSchemaType<IamProjectMemberInvite> = {
|
|
199
|
+
type: 'object',
|
|
200
|
+
properties: {
|
|
201
|
+
email: EmailSchema,
|
|
202
|
+
name: { ...NameSchema, nullable: true },
|
|
203
|
+
owner: { type: 'boolean', nullable: true },
|
|
204
|
+
scope: ScopeProp,
|
|
205
|
+
},
|
|
206
|
+
required: ['email'],
|
|
207
|
+
additionalProperties: false,
|
|
208
|
+
} as unknown as JSONSchemaType<IamProjectMemberInvite>
|
|
209
|
+
|
|
210
|
+
export const IamProjectMemberUpdateSchema: JSONSchemaType<IamProjectMemberUpdate> = {
|
|
211
|
+
type: 'object',
|
|
212
|
+
properties: {
|
|
213
|
+
owner: { type: 'boolean', nullable: true },
|
|
214
|
+
groups: { type: 'array', items: GroupKeySchema, maxItems: 64, nullable: true },
|
|
215
|
+
scope: ScopeProp,
|
|
216
|
+
},
|
|
217
|
+
required: [],
|
|
218
|
+
additionalProperties: false,
|
|
219
|
+
} as unknown as JSONSchemaType<IamProjectMemberUpdate>
|
|
220
|
+
|
|
221
|
+
export const IamGroupCreateSchema: JSONSchemaType<IamGroupCreate> = {
|
|
222
|
+
type: 'object',
|
|
223
|
+
properties: {
|
|
224
|
+
key: GroupKeySchema,
|
|
225
|
+
title: { ...TitleSchema, nullable: true },
|
|
226
|
+
scope: ScopeProp,
|
|
227
|
+
},
|
|
228
|
+
required: ['key'],
|
|
229
|
+
additionalProperties: false,
|
|
230
|
+
} as unknown as JSONSchemaType<IamGroupCreate>
|
|
231
|
+
|
|
232
|
+
export const IamGroupEditSchema: JSONSchemaType<IamGroupEdit> = {
|
|
233
|
+
type: 'object',
|
|
234
|
+
properties: {
|
|
235
|
+
title: { ...TitleSchema, nullable: true },
|
|
236
|
+
bundles: { type: 'array', items: GroupBundleSchema, maxItems: 32, nullable: true },
|
|
237
|
+
scope: ScopeProp,
|
|
238
|
+
},
|
|
239
|
+
required: [],
|
|
240
|
+
additionalProperties: false,
|
|
241
|
+
} as unknown as JSONSchemaType<IamGroupEdit>
|
|
242
|
+
|
|
243
|
+
export const IamGroupMembersChangeSchema: JSONSchemaType<IamGroupMembersChange> = {
|
|
244
|
+
type: 'object',
|
|
245
|
+
properties: {
|
|
246
|
+
profileIds: ProfileIdsSchema,
|
|
247
|
+
scope: ScopeProp,
|
|
248
|
+
},
|
|
249
|
+
required: ['profileIds'],
|
|
250
|
+
additionalProperties: false,
|
|
251
|
+
} as unknown as JSONSchemaType<IamGroupMembersChange>
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
IamDefaultClass, IamGrant, IamGrantMode, IamGroup, IamGroupBundle, IamGroupRef, IamMember, IamMemberInvite,
|
|
3
|
+
IamMemberUpdate, IamOrganization, IamOrganizationUpdate, IamPermissionDefinition, IamUser, IamUserInvite,
|
|
4
|
+
IamUserUpdate,
|
|
5
|
+
} from '@owlmeans/iam'
|
|
6
|
+
import type { WorkloadKind } from '../slot/consts.js'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The owner console's IAM, per project — the contract both doors share: the browser's
|
|
10
|
+
* `managerProtocols.back.iam` and the connector's `connect.iam`. Every route names its project, and
|
|
11
|
+
* `scope` picks the preview (ephemeral, default) or the production OIDC client — two apps with two
|
|
12
|
+
* sets of rows, definitions and groups. Organizations travel by `entitySlug` and groups by their key:
|
|
13
|
+
* an organization's record id never appears on this wire, and neither does the owner's.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/** The IAM vocabulary a consumer of this contract reads and writes, re-exported. */
|
|
17
|
+
export type {
|
|
18
|
+
IamArea, IamGrant, IamGrantBundle, IamGroup, IamGroupBundle, IamGroupRef, IamMember, IamMemberInvite,
|
|
19
|
+
IamMemberUpdate, IamOrganization, IamOrganizationUpdate, IamPermissionDefinition, IamPermissionFilter, IamUser,
|
|
20
|
+
IamUserInvite, IamUserUpdate,
|
|
21
|
+
} from '@owlmeans/iam'
|
|
22
|
+
|
|
23
|
+
/** Route params for the project-scoped IAM management endpoints. */
|
|
24
|
+
export interface IamProjectParams {
|
|
25
|
+
projectId: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** One subject of the project's client, by its pairwise `profileId`. */
|
|
29
|
+
export interface IamProjectUserParams extends IamProjectParams {
|
|
30
|
+
profileId: string
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** One organization the project's client has members in. */
|
|
34
|
+
export interface IamOrganizationParams extends IamProjectParams {
|
|
35
|
+
entitySlug: string
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** One member of an organization, as the project's client sees them. */
|
|
39
|
+
export interface IamMemberParams extends IamOrganizationParams {
|
|
40
|
+
profileId: string
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** One group of (organization, the project's client), by its key. */
|
|
44
|
+
export interface IamGroupParams extends IamOrganizationParams {
|
|
45
|
+
group: string
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Which of the project's two clients a write addresses. A route with a body carries it there; a
|
|
50
|
+
* body-less write (the browser's removes) and every read take it in the query.
|
|
51
|
+
*/
|
|
52
|
+
export interface IamScoped {
|
|
53
|
+
scope?: WorkloadKind
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* A listing. `external` answers a backend that keeps this in a console of its own (keycloak): the
|
|
58
|
+
* list is then empty on purpose, and a screen offers that console instead of reporting "none".
|
|
59
|
+
*/
|
|
60
|
+
export interface IamListResponse<T> {
|
|
61
|
+
items: T[]
|
|
62
|
+
external?: boolean
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface IamUsersResponse extends IamListResponse<IamUser> {}
|
|
66
|
+
|
|
67
|
+
export interface IamGrantsResponse extends IamListResponse<IamGrant> {}
|
|
68
|
+
|
|
69
|
+
export interface IamOrganizationsResponse extends IamListResponse<IamOrganization> {}
|
|
70
|
+
|
|
71
|
+
export interface IamMembersResponse extends IamListResponse<IamMember> {}
|
|
72
|
+
|
|
73
|
+
export interface IamGroupsResponse extends IamListResponse<IamGroup> {}
|
|
74
|
+
|
|
75
|
+
/** Which organizations the client's subjects act in — its registration's two tenancy flags. */
|
|
76
|
+
export interface IamTenancy {
|
|
77
|
+
operators: boolean
|
|
78
|
+
users: boolean
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface IamPermissionsResponse extends IamListResponse<IamPermissionDefinition> {
|
|
82
|
+
tenancy: IamTenancy
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Query for listing grants: everything the client's subjects hold, one person's (`profileId`), or
|
|
87
|
+
* one group's (`group`, the key, with the `entitySlug` of its organization). With a person, an
|
|
88
|
+
* `entitySlug` alone narrows to the grants bound to that organization.
|
|
89
|
+
*/
|
|
90
|
+
export interface IamGrantsQuery extends IamScoped {
|
|
91
|
+
profileId?: string
|
|
92
|
+
group?: string
|
|
93
|
+
entitySlug?: string
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Change a definition's settings: who holds it by default (`defaultClass`) and whether its grants
|
|
98
|
+
* are bound to one organization (`entityScoped`). An omitted field is kept.
|
|
99
|
+
*/
|
|
100
|
+
export interface IamDefinitionUpdate extends IamScoped {
|
|
101
|
+
permission: string
|
|
102
|
+
defaultClass?: IamDefaultClass
|
|
103
|
+
entityScoped?: boolean
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Re-admit the owning organization's staff to the client `scope` names. */
|
|
107
|
+
export interface IamStaffSync extends IamScoped {}
|
|
108
|
+
|
|
109
|
+
/** How many staff rows the synchronization added and removed. */
|
|
110
|
+
export interface IamStaffSyncResponse {
|
|
111
|
+
added: number
|
|
112
|
+
removed: number
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Body to assign a permission grant — to exactly ONE subject: a person (`profileId`) or a group.
|
|
117
|
+
*
|
|
118
|
+
* A resource-scoped permission is grantable two ways under ONE name: with `resources`, bound to
|
|
119
|
+
* those ids; without them, covering every resource. `mode` names which, because the two are stored
|
|
120
|
+
* separately and a screen offering both controls has to be able to address each on its own.
|
|
121
|
+
*
|
|
122
|
+
* `entitySlug` binds a person's grant of an entity-scoped definition to that organization. A group
|
|
123
|
+
* grant is always bound to the group's own organization, so it takes none.
|
|
124
|
+
*/
|
|
125
|
+
export interface IamAssignGrant extends IamScoped {
|
|
126
|
+
profileId?: string
|
|
127
|
+
group?: IamGroupRef
|
|
128
|
+
permission: string
|
|
129
|
+
resources?: string[]
|
|
130
|
+
/** `blanket` (all resources) or `resources`. Inferred from `resources` when omitted. */
|
|
131
|
+
mode?: IamGrantMode
|
|
132
|
+
entitySlug?: string
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Body to revoke a grant, the same shape. With `resources` only those ids are removed; an omitted
|
|
137
|
+
* `mode` means ALL forms, which is what a bare revoke has always meant — narrowing that default
|
|
138
|
+
* would leave a resource-scoped grant standing after a revoke reported success.
|
|
139
|
+
*/
|
|
140
|
+
export interface IamRevokeGrant extends IamAssignGrant {}
|
|
141
|
+
|
|
142
|
+
export interface IamProjectUserInvite extends IamUserInvite, IamScoped {}
|
|
143
|
+
|
|
144
|
+
export interface IamProjectUserUpdate extends IamUserUpdate, IamScoped {}
|
|
145
|
+
|
|
146
|
+
export interface IamOrganizationEdit extends IamOrganizationUpdate, IamScoped {}
|
|
147
|
+
|
|
148
|
+
export interface IamProjectMemberInvite extends IamMemberInvite, IamScoped {}
|
|
149
|
+
|
|
150
|
+
export interface IamProjectMemberUpdate extends IamMemberUpdate, IamScoped {}
|
|
151
|
+
|
|
152
|
+
export interface IamGroupCreate extends IamScoped {
|
|
153
|
+
key: string
|
|
154
|
+
title?: string
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** A group's title and what it grants; an omitted field is kept. */
|
|
158
|
+
export interface IamGroupEdit extends IamScoped {
|
|
159
|
+
title?: string
|
|
160
|
+
bundles?: IamGroupBundle[]
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export interface IamGroupMembersChange extends IamScoped {
|
|
164
|
+
profileIds: string[]
|
|
165
|
+
}
|
package/src/index.ts
CHANGED
package/src/legal/consts.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LegalDocumentDateMetadata, LegalDocumentKey } from './types.js'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* The shared dates for the platform's legal acceptance and the public site's legal pages.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Consumers select the actual agreement keys for acceptance. Optional purposes carry their own
|
|
6
|
+
* wording revisions, independent of this table. Pending documents have no effective/update date;
|
|
7
|
+
* a coordinated publication and acceptance release supplies those dates when activated.
|
|
7
8
|
*/
|
|
8
9
|
export const OWLMEANS_LEGAL_DATES = {
|
|
9
10
|
terms: { effective: '2026-05-30', updated: '2026-05-30' },
|
|
@@ -11,7 +12,14 @@ export const OWLMEANS_LEGAL_DATES = {
|
|
|
11
12
|
cookies: { effective: '2026-09-24', updated: '2026-09-25' },
|
|
12
13
|
'services-agreement': { effective: '2026-10-04', updated: '2026-10-04' },
|
|
13
14
|
'platform-license': { effective: '2026-10-04', updated: '2026-10-04' },
|
|
14
|
-
|
|
15
|
+
'data-processing-agreement': { status: 'pending', effective: null, updated: null },
|
|
16
|
+
subprocessors: { status: 'pending', effective: null, updated: null },
|
|
17
|
+
'company-information': { status: 'pending', effective: null, updated: null },
|
|
18
|
+
'acceptable-use': { status: 'pending', effective: null, updated: null },
|
|
19
|
+
'refund-cancellation': { status: 'pending', effective: null, updated: null },
|
|
20
|
+
'service-level-agreement': { status: 'pending', effective: null, updated: null },
|
|
21
|
+
// Historical acceptance aliases retained for existing records; new Platform configuration uses
|
|
22
|
+
// `platform-license` for billing and Terms for product-use rules.
|
|
15
23
|
billing: { effective: '2026-05-30', updated: '2026-05-30' },
|
|
16
24
|
product: { effective: '2026-05-30', updated: '2026-05-30' },
|
|
17
|
-
} as const satisfies Record<LegalDocumentKey,
|
|
25
|
+
} as const satisfies Record<LegalDocumentKey, LegalDocumentDateMetadata>
|
package/src/legal/types.ts
CHANGED
|
@@ -6,6 +6,17 @@ export interface LegalDocumentDates {
|
|
|
6
6
|
updated: string
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
/** A publication source awaiting activation; preparation dates are not effective dates. */
|
|
10
|
+
export interface PendingLegalDocumentDates {
|
|
11
|
+
status: 'pending'
|
|
12
|
+
effective: null
|
|
13
|
+
updated: null
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type LegalDocumentDateMetadata = LegalDocumentDates | PendingLegalDocumentDates
|
|
17
|
+
|
|
9
18
|
/** The complete document set; the date table must cover every key. */
|
|
10
19
|
// Kept as a type: a union of the document keys.
|
|
11
|
-
export type LegalDocumentKey = 'terms' | 'privacy' | 'cookies' | 'services-agreement' | 'platform-license'
|
|
20
|
+
export type LegalDocumentKey = 'terms' | 'privacy' | 'cookies' | 'services-agreement' | 'platform-license'
|
|
21
|
+
| 'data-processing-agreement' | 'subprocessors' | 'company-information'
|
|
22
|
+
| 'acceptable-use' | 'refund-cancellation' | 'service-level-agreement' | 'billing' | 'product'
|
package/src/planning/schemas.ts
CHANGED
|
@@ -33,7 +33,6 @@ export const ViableProjectFieldsSchema = {
|
|
|
33
33
|
target: { type: 'string', enum: [...Object.values(ConnectTarget), null], nullable: true },
|
|
34
34
|
origin: { ...ProjectOriginSchema, nullable: true },
|
|
35
35
|
connectLlmMode: { type: 'string', enum: [...Object.values(ConnectLlm), null], nullable: true },
|
|
36
|
-
converterLlmMode: { type: 'string', enum: [...Object.values(ConnectLlm), null], nullable: true },
|
|
37
36
|
// `story: null` is a DECIDED "no gate" and must stay spellable; an absent `landing` is "never
|
|
38
37
|
// decided". `at` carries no `format`: the planning registry compiles without ajv-formats.
|
|
39
38
|
landing: {
|
package/src/planning/types.ts
CHANGED
|
@@ -37,8 +37,6 @@ export type ViableProjectFields = {
|
|
|
37
37
|
origin?: ProjectOrigin
|
|
38
38
|
/** Who performs a run's model calls on this project; absent inherits the owner's preference. */
|
|
39
39
|
connectLlmMode?: ConnectLlm
|
|
40
|
-
/** Who performs a conversion's model calls on this project; absent inherits. */
|
|
41
|
-
converterLlmMode?: ConnectLlm
|
|
42
40
|
/**
|
|
43
41
|
* The landing-gate decision: which story a guest can start on the landing page.
|
|
44
42
|
*
|
|
@@ -78,6 +78,10 @@ describe('viable-common - the conversion additions to the connector contract', (
|
|
|
78
78
|
})).toBe(true)
|
|
79
79
|
// A local target the connector is already attached to fetches nothing.
|
|
80
80
|
expect(create({})).toBe(true)
|
|
81
|
+
// The caller's unattached delegated session performs the pre-card checks; a stray key is refused.
|
|
82
|
+
expect(create({ name: 'Deskflow', sessionId: 'session-1' })).toBe(true)
|
|
83
|
+
expect(create({ sessionId: '' })).toBe(false)
|
|
84
|
+
expect(create({ llmMode: 'local' })).toBe(false)
|
|
81
85
|
expect(proceed({ decision: ConversionDecision.Extract })).toBe(true)
|
|
82
86
|
expect(proceed({ decision: 'teleport' })).toBe(false)
|
|
83
87
|
})
|
|
@@ -146,8 +150,8 @@ describe('viable-common - the conversion additions to the connector contract', (
|
|
|
146
150
|
})
|
|
147
151
|
|
|
148
152
|
test('the conversion routes hang under the connector base and carry no paid gate', () => {
|
|
149
|
-
//
|
|
150
|
-
//
|
|
153
|
+
// A conversion carries no inference mode of its own: its model calls follow the session that
|
|
154
|
+
// drives it, and that session's open is the one place the local-LLM gate sits.
|
|
151
155
|
expect(entrypointOf(connect.session.openDelegated).gate?.alias).toBe('test-paid-llm')
|
|
152
156
|
|
|
153
157
|
const gated = [...Object.values(connect.convert), connect.inquiry.answer]
|