@astrale-domains/shell 0.1.0-beta.23 → 0.1.0-beta.24

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.
Files changed (238) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +83 -79
  3. package/dist/application.d.ts +6 -5
  4. package/dist/application.js +20 -51
  5. package/dist/functions/group/assign-user-to-group.d.ts +27 -0
  6. package/dist/functions/group/assign-user-to-group.js +4 -0
  7. package/dist/functions/group/change-user-group-membership.d.ts +7 -0
  8. package/dist/functions/group/change-user-group-membership.js +34 -0
  9. package/dist/functions/group/group-membership-errors.d.ts +28 -0
  10. package/dist/functions/group/group-membership-errors.js +23 -0
  11. package/dist/functions/group/index.d.ts +2 -3
  12. package/dist/functions/group/index.js +2 -3
  13. package/dist/functions/group/unassign-user-from-group.d.ts +27 -0
  14. package/dist/functions/group/unassign-user-from-group.js +4 -0
  15. package/dist/functions/user/index.d.ts +1 -3
  16. package/dist/functions/user/index.js +1 -3
  17. package/dist/functions/user/invite-user.d.ts +30 -0
  18. package/dist/functions/user/invite-user.js +39 -0
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.js +1 -1
  21. package/dist/integrations/index.d.ts +1 -0
  22. package/dist/integrations/index.js +1 -0
  23. package/dist/integrations/integrations.d.ts +9 -0
  24. package/dist/integrations/integrations.js +2 -0
  25. package/dist/integrations/user-invitation/index.d.ts +4 -0
  26. package/dist/integrations/user-invitation/index.js +3 -0
  27. package/dist/integrations/user-invitation/invitation-request-failure.d.ts +5 -0
  28. package/dist/integrations/user-invitation/invitation-request-failure.js +9 -0
  29. package/dist/integrations/user-invitation/invite-user-request.d.ts +6 -0
  30. package/dist/integrations/user-invitation/invite-user-request.js +1 -0
  31. package/dist/integrations/user-invitation/request-user-invitation.d.ts +8 -0
  32. package/dist/integrations/user-invitation/request-user-invitation.js +9 -0
  33. package/dist/mutations/group/index.d.ts +1 -1
  34. package/dist/mutations/group/index.js +1 -1
  35. package/dist/mutations/group/set-user-group-membership.d.ts +26 -0
  36. package/dist/mutations/group/set-user-group-membership.js +29 -0
  37. package/dist/providers/admin-enrollment/create-admin-enrollment-provider.d.ts +7 -0
  38. package/dist/providers/admin-enrollment/create-admin-enrollment-provider.js +78 -0
  39. package/dist/providers/admin-enrollment/decode-admin-invitation-response.d.ts +7 -0
  40. package/dist/providers/admin-enrollment/decode-admin-invitation-response.js +20 -0
  41. package/dist/providers/admin-enrollment/index.d.ts +1 -0
  42. package/dist/providers/admin-enrollment/index.js +1 -0
  43. package/dist/providers/admin-enrollment/read-enrollment-response.d.ts +1 -0
  44. package/dist/providers/admin-enrollment/read-enrollment-response.js +34 -0
  45. package/dist/queries/group/index.d.ts +2 -0
  46. package/dist/queries/group/index.js +2 -0
  47. package/dist/queries/group/read-group-membership-endpoints.d.ts +13 -0
  48. package/dist/queries/group/read-group-membership-endpoints.js +18 -0
  49. package/dist/queries/group/read-user-group-membership.d.ts +15 -0
  50. package/dist/queries/group/read-user-group-membership.js +35 -0
  51. package/dist/runtime.d.ts +94 -9
  52. package/dist/runtime.js +9 -5
  53. package/dist/schema/index.d.ts +4 -4
  54. package/dist/schema/index.js +3 -4
  55. package/dist/schema/modules/group/classes/group.d.ts +4 -6
  56. package/dist/schema/modules/group/classes/group.js +4 -6
  57. package/dist/schema/modules/group/classes/index.d.ts +2 -0
  58. package/dist/schema/modules/group/classes/index.js +2 -0
  59. package/dist/schema/modules/group/classes/member-of-group.js +2 -3
  60. package/dist/schema/modules/group/core/administrators-group.js +6 -0
  61. package/dist/schema/modules/group/core/index.d.ts +2 -0
  62. package/dist/schema/modules/group/core/index.js +2 -0
  63. package/dist/schema/modules/group/core/members-group.js +6 -0
  64. package/dist/schema/modules/group/functions/assign-user-to-group.d.ts +7 -0
  65. package/dist/schema/modules/group/functions/assign-user-to-group.js +11 -0
  66. package/dist/schema/modules/group/functions/index.d.ts +2 -0
  67. package/dist/schema/modules/group/functions/index.js +2 -0
  68. package/dist/schema/modules/group/functions/unassign-user-from-group.d.ts +7 -0
  69. package/dist/schema/modules/group/functions/unassign-user-from-group.js +11 -0
  70. package/dist/schema/modules/group/index.d.ts +3 -9
  71. package/dist/schema/modules/group/index.js +3 -9
  72. package/dist/schema/modules/group/policies/belongs-to-group.d.ts +1 -0
  73. package/dist/schema/modules/group/policies/belongs-to-group.js +5 -0
  74. package/dist/schema/modules/group/policies/index.d.ts +1 -0
  75. package/dist/schema/modules/group/policies/index.js +1 -0
  76. package/dist/schema/modules/group/types/group-user-reference.d.ts +6 -0
  77. package/dist/schema/modules/group/types/group-user-reference.js +8 -0
  78. package/dist/schema/modules/group/types/index.d.ts +1 -0
  79. package/dist/schema/modules/group/types/index.js +1 -0
  80. package/dist/schema/modules/user/classes/index.d.ts +1 -0
  81. package/dist/schema/modules/user/classes/index.js +1 -0
  82. package/dist/schema/modules/user/classes/user.d.ts +5 -8
  83. package/dist/schema/modules/user/classes/user.js +7 -7
  84. package/dist/schema/modules/user/functions/index.d.ts +1 -0
  85. package/dist/schema/modules/user/functions/index.js +1 -0
  86. package/dist/schema/modules/user/functions/invite-user.d.ts +11 -0
  87. package/dist/schema/modules/user/functions/invite-user.js +12 -0
  88. package/dist/schema/modules/user/index.d.ts +2 -6
  89. package/dist/schema/modules/user/index.js +2 -6
  90. package/dist/schema/modules/user/types/index.d.ts +1 -0
  91. package/dist/schema/modules/user/types/index.js +1 -0
  92. package/dist/schema/modules/user/types/invitation-summary.d.ts +16 -0
  93. package/dist/schema/modules/user/types/invitation-summary.js +15 -0
  94. package/dist/schema/policies/administers-shell-class.d.ts +2 -0
  95. package/dist/schema/policies/administers-shell-class.js +11 -0
  96. package/dist/schema/policies/index.d.ts +2 -0
  97. package/dist/schema/policies/index.js +2 -0
  98. package/dist/schema/policies/owns-class.d.ts +1 -0
  99. package/dist/schema/policies/owns-class.js +7 -0
  100. package/dist/schema/schema.d.ts +14 -69
  101. package/dist/schema/schema.js +10 -27
  102. package/dist/schema/views/application-view.d.ts +1 -0
  103. package/dist/schema/views/application-view.js +4 -0
  104. package/dist/schema/views/index.d.ts +1 -0
  105. package/dist/schema/views/index.js +1 -0
  106. package/dist/utils/canonical-node-path/index.d.ts +1 -0
  107. package/dist/utils/canonical-node-path/index.js +1 -0
  108. package/dist/utils/canonical-node-path/parse-canonical-node-path.d.ts +2 -0
  109. package/dist/utils/canonical-node-path/parse-canonical-node-path.js +8 -0
  110. package/package.json +16 -7
  111. package/dist/functions/group/assign.d.ts +0 -3
  112. package/dist/functions/group/assign.js +0 -3
  113. package/dist/functions/group/change.d.ts +0 -6
  114. package/dist/functions/group/change.js +0 -41
  115. package/dist/functions/group/unassign.d.ts +0 -3
  116. package/dist/functions/group/unassign.js +0 -3
  117. package/dist/functions/registry/index.d.ts +0 -12
  118. package/dist/functions/registry/index.js +0 -12
  119. package/dist/functions/setup/admin.d.ts +0 -3
  120. package/dist/functions/setup/admin.js +0 -3
  121. package/dist/functions/setup/index.d.ts +0 -4
  122. package/dist/functions/setup/index.js +0 -4
  123. package/dist/functions/setup/member.d.ts +0 -3
  124. package/dist/functions/setup/member.js +0 -3
  125. package/dist/functions/setup/provision.d.ts +0 -5
  126. package/dist/functions/setup/provision.js +0 -70
  127. package/dist/functions/setup/run.d.ts +0 -7
  128. package/dist/functions/setup/run.js +0 -82
  129. package/dist/functions/space/access.d.ts +0 -7
  130. package/dist/functions/space/access.js +0 -41
  131. package/dist/functions/space/add.d.ts +0 -3
  132. package/dist/functions/space/add.js +0 -3
  133. package/dist/functions/space/default.d.ts +0 -3
  134. package/dist/functions/space/default.js +0 -37
  135. package/dist/functions/space/index.d.ts +0 -4
  136. package/dist/functions/space/index.js +0 -4
  137. package/dist/functions/space/remove.d.ts +0 -3
  138. package/dist/functions/space/remove.js +0 -3
  139. package/dist/functions/user/resolve-home.d.ts +0 -3
  140. package/dist/functions/user/resolve-home.js +0 -19
  141. package/dist/mutations/group/membership.d.ts +0 -23
  142. package/dist/mutations/group/membership.js +0 -32
  143. package/dist/mutations/space/access.d.ts +0 -25
  144. package/dist/mutations/space/access.js +0 -23
  145. package/dist/mutations/space/default.d.ts +0 -19
  146. package/dist/mutations/space/default.js +0 -23
  147. package/dist/mutations/space/index.d.ts +0 -2
  148. package/dist/mutations/space/index.js +0 -2
  149. package/dist/mutations/user/index.d.ts +0 -1
  150. package/dist/mutations/user/index.js +0 -1
  151. package/dist/mutations/user/repair.d.ts +0 -22
  152. package/dist/mutations/user/repair.js +0 -104
  153. package/dist/queries/space/access.d.ts +0 -9
  154. package/dist/queries/space/access.js +0 -12
  155. package/dist/queries/space/admin.d.ts +0 -9
  156. package/dist/queries/space/admin.js +0 -20
  157. package/dist/queries/space/index.d.ts +0 -3
  158. package/dist/queries/space/index.js +0 -3
  159. package/dist/queries/space/member.d.ts +0 -9
  160. package/dist/queries/space/member.js +0 -17
  161. package/dist/queries/user/groups.d.ts +0 -10
  162. package/dist/queries/user/groups.js +0 -41
  163. package/dist/queries/user/home.d.ts +0 -9
  164. package/dist/queries/user/home.js +0 -21
  165. package/dist/queries/user/index.d.ts +0 -5
  166. package/dist/queries/user/index.js +0 -5
  167. package/dist/queries/user/owned-spaces.d.ts +0 -9
  168. package/dist/queries/user/owned-spaces.js +0 -17
  169. package/dist/queries/user/profile.d.ts +0 -4
  170. package/dist/queries/user/profile.js +0 -16
  171. package/dist/queries/user/setup.d.ts +0 -13
  172. package/dist/queries/user/setup.js +0 -16
  173. package/dist/rules/user/index.d.ts +0 -1
  174. package/dist/rules/user/index.js +0 -1
  175. package/dist/rules/user/setup.d.ts +0 -38
  176. package/dist/rules/user/setup.js +0 -95
  177. package/dist/schema/modules/group/core/admin-group.js +0 -2
  178. package/dist/schema/modules/group/core/core.d.ts +0 -8
  179. package/dist/schema/modules/group/core/core.js +0 -6
  180. package/dist/schema/modules/group/core/identity.d.ts +0 -1
  181. package/dist/schema/modules/group/core/identity.js +0 -10
  182. package/dist/schema/modules/group/core/member-group.js +0 -2
  183. package/dist/schema/modules/group/functions/assign-user.d.ts +0 -7
  184. package/dist/schema/modules/group/functions/assign-user.js +0 -12
  185. package/dist/schema/modules/group/functions/unassign-user.d.ts +0 -7
  186. package/dist/schema/modules/group/functions/unassign-user.js +0 -12
  187. package/dist/schema/modules/group/policies/may-setup-users.d.ts +0 -1
  188. package/dist/schema/modules/group/policies/may-setup-users.js +0 -6
  189. package/dist/schema/modules/group/types/membership.d.ts +0 -276
  190. package/dist/schema/modules/group/types/membership.js +0 -5
  191. package/dist/schema/modules/group/views/group.d.ts +0 -1
  192. package/dist/schema/modules/group/views/group.js +0 -6
  193. package/dist/schema/modules/space/classes/administers-space.d.ts +0 -16
  194. package/dist/schema/modules/space/classes/administers-space.js +0 -9
  195. package/dist/schema/modules/space/classes/default-space.d.ts +0 -16
  196. package/dist/schema/modules/space/classes/default-space.js +0 -8
  197. package/dist/schema/modules/space/classes/member-of-space.d.ts +0 -16
  198. package/dist/schema/modules/space/classes/member-of-space.js +0 -9
  199. package/dist/schema/modules/space/classes/owns-space.d.ts +0 -16
  200. package/dist/schema/modules/space/classes/owns-space.js +0 -9
  201. package/dist/schema/modules/space/classes/space.d.ts +0 -15
  202. package/dist/schema/modules/space/classes/space.js +0 -15
  203. package/dist/schema/modules/space/core/core.d.ts +0 -7
  204. package/dist/schema/modules/space/core/core.js +0 -12
  205. package/dist/schema/modules/space/core/default-space.d.ts +0 -1
  206. package/dist/schema/modules/space/core/default-space.js +0 -6
  207. package/dist/schema/modules/space/functions/add-user.d.ts +0 -8
  208. package/dist/schema/modules/space/functions/add-user.js +0 -12
  209. package/dist/schema/modules/space/functions/remove-user.d.ts +0 -7
  210. package/dist/schema/modules/space/functions/remove-user.js +0 -11
  211. package/dist/schema/modules/space/functions/set-default.d.ts +0 -5
  212. package/dist/schema/modules/space/functions/set-default.js +0 -11
  213. package/dist/schema/modules/space/index.d.ts +0 -14
  214. package/dist/schema/modules/space/index.js +0 -14
  215. package/dist/schema/modules/space/policies/belongs-to-space.d.ts +0 -1
  216. package/dist/schema/modules/space/policies/belongs-to-space.js +0 -9
  217. package/dist/schema/modules/space/policies/may-administer-space.d.ts +0 -1
  218. package/dist/schema/modules/space/policies/may-administer-space.js +0 -8
  219. package/dist/schema/modules/space/policies/owns-space.d.ts +0 -1
  220. package/dist/schema/modules/space/policies/owns-space.js +0 -7
  221. package/dist/schema/modules/space/types/access.d.ts +0 -280
  222. package/dist/schema/modules/space/types/access.js +0 -12
  223. package/dist/schema/modules/space/views/space.d.ts +0 -1
  224. package/dist/schema/modules/space/views/space.js +0 -6
  225. package/dist/schema/modules/user/functions/resolve-home.d.ts +0 -7
  226. package/dist/schema/modules/user/functions/resolve-home.js +0 -11
  227. package/dist/schema/modules/user/functions/setup-admin.d.ts +0 -15
  228. package/dist/schema/modules/user/functions/setup-admin.js +0 -11
  229. package/dist/schema/modules/user/functions/setup-member.d.ts +0 -15
  230. package/dist/schema/modules/user/functions/setup-member.js +0 -11
  231. package/dist/schema/modules/user/types/setup-user.d.ts +0 -13
  232. package/dist/schema/modules/user/types/setup-user.js +0 -14
  233. package/dist/schema/modules/user/views/home.d.ts +0 -1
  234. package/dist/schema/modules/user/views/home.js +0 -4
  235. package/dist/schema/modules/user/views/user.d.ts +0 -1
  236. package/dist/schema/modules/user/views/user.js +0 -6
  237. /package/dist/schema/modules/group/core/{admin-group.d.ts → administrators-group.d.ts} +0 -0
  238. /package/dist/schema/modules/group/core/{member-group.d.ts → members-group.d.ts} +0 -0
@@ -1,12 +0,0 @@
1
- import { assignGroupUserWorkflow, unassignGroupUserWorkflow } from '../group/index.js';
2
- import { setupAdminWorkflow, setupMemberWorkflow } from '../setup/index.js';
3
- import { addSpaceUserWorkflow, removeSpaceUserWorkflow, setDefaultSpaceWorkflow } from '../space/index.js';
4
- export declare const workflows: readonly [
5
- typeof setupAdminWorkflow,
6
- typeof setupMemberWorkflow,
7
- typeof assignGroupUserWorkflow,
8
- typeof unassignGroupUserWorkflow,
9
- typeof addSpaceUserWorkflow,
10
- typeof removeSpaceUserWorkflow,
11
- typeof setDefaultSpaceWorkflow
12
- ];
@@ -1,12 +0,0 @@
1
- import { assignGroupUserWorkflow, unassignGroupUserWorkflow } from '#functions/group';
2
- import { setupAdminWorkflow, setupMemberWorkflow } from '#functions/setup';
3
- import { addSpaceUserWorkflow, removeSpaceUserWorkflow, setDefaultSpaceWorkflow, } from '#functions/space';
4
- export const workflows = [
5
- setupAdminWorkflow,
6
- setupMemberWorkflow,
7
- assignGroupUserWorkflow,
8
- unassignGroupUserWorkflow,
9
- addSpaceUserWorkflow,
10
- removeSpaceUserWorkflow,
11
- setDefaultSpaceWorkflow,
12
- ];
@@ -1,3 +0,0 @@
1
- import { type WorkflowDefinition } from '@astrale-os/sdk/workflow';
2
- import type { ShellSchema } from '../../schema/index.js';
3
- export declare const setupAdminWorkflow: WorkflowDefinition<typeof ShellSchema, 'setupAdmin'>;
@@ -1,3 +0,0 @@
1
- import { defineWorkflow } from '@astrale-os/sdk/workflow';
2
- import { runSetup } from './run.js';
3
- export const setupAdminWorkflow = defineWorkflow()('setupAdmin', (context) => runSetup(context, 'admin'));
@@ -1,4 +0,0 @@
1
- export { setupAdminWorkflow } from './admin.js';
2
- export { setupMemberWorkflow } from './member.js';
3
- export { provisioningRequest, provisioningResult } from './provision.js';
4
- export { runSetup } from './run.js';
@@ -1,4 +0,0 @@
1
- export { setupAdminWorkflow } from './admin.js';
2
- export { setupMemberWorkflow } from './member.js';
3
- export { provisioningRequest, provisioningResult } from './provision.js';
4
- export { runSetup } from './run.js';
@@ -1,3 +0,0 @@
1
- import { type WorkflowDefinition } from '@astrale-os/sdk/workflow';
2
- import type { ShellSchema } from '../../schema/index.js';
3
- export declare const setupMemberWorkflow: WorkflowDefinition<typeof ShellSchema, 'setupMember'>;
@@ -1,3 +0,0 @@
1
- import { defineWorkflow } from '@astrale-os/sdk/workflow';
2
- import { runSetup } from './run.js';
3
- export const setupMemberWorkflow = defineWorkflow()('setupMember', (context) => runSetup(context, 'member'));
@@ -1,5 +0,0 @@
1
- import type { ProvisionRequest, ProvisionResult } from '@astrale-os/sdk/auth';
2
- import type { SetupRole } from '../../rules/user/index.js';
3
- import type { SetupUserInput, SetupUserResult, Shell } from '../../schema/index.js';
4
- export declare function provisioningRequest(domain: Shell, input: SetupUserInput, role: SetupRole): ProvisionRequest;
5
- export declare function provisioningResult(result: ProvisionResult): SetupUserResult;
@@ -1,70 +0,0 @@
1
- import { issuer } from '@astrale-os/sdk/auth';
2
- import { LocalBinding } from '@astrale-os/sdk/graph';
3
- import { Path } from '@astrale-os/sdk/graph/path';
4
- import { MutationAST } from '@astrale-os/sdk/mutation';
5
- const user = LocalBinding('user');
6
- const personalSpace = LocalBinding('personalSpace');
7
- export function provisioningRequest(domain, input, role) {
8
- const mutation = MutationAST.build((change) => {
9
- const createdUser = change.createNode({
10
- as: user,
11
- class: domain.classes.User.key,
12
- props: domain.classes.User.properties.from({ displayName: input.displayName }),
13
- });
14
- const createdSpace = change.createNode({
15
- as: personalSpace,
16
- class: domain.classes.Space.key,
17
- props: domain.classes.Space.properties.from({ name: input.personalSpaceName }),
18
- });
19
- change.createEdge({
20
- class: domain.classes.owns_space.key,
21
- source: createdUser,
22
- target: createdSpace,
23
- });
24
- change.createEdge({
25
- class: domain.classes.default_space.key,
26
- source: createdUser,
27
- target: createdSpace,
28
- });
29
- change.createEdge({
30
- class: domain.classes.member_of_group.key,
31
- source: createdUser,
32
- target: Path.project(domain.core.nodes.member.ref),
33
- });
34
- change.createEdge({
35
- class: domain.dependencies.kernel.classes.extends_with.key,
36
- source: createdUser,
37
- target: Path.project(domain.core.nodes.member.ref),
38
- });
39
- if (role === 'admin') {
40
- change.createEdge({
41
- class: domain.classes.member_of_group.key,
42
- source: createdUser,
43
- target: Path.project(domain.core.nodes.admin.ref),
44
- });
45
- change.createEdge({
46
- class: domain.dependencies.kernel.classes.extends_with.key,
47
- source: createdUser,
48
- target: Path.project(domain.core.nodes.admin.ref),
49
- });
50
- }
51
- });
52
- return Object.freeze({
53
- idempotencyKey: input.operationId,
54
- mutation,
55
- identities: Object.freeze([
56
- Object.freeze({
57
- identity: Object.freeze({ created: user }),
58
- authentication: Object.freeze({ iss: issuer.accept(input.issuer), sub: input.subject }),
59
- }),
60
- ]),
61
- });
62
- }
63
- export function provisioningResult(result) {
64
- const userId = result.createdNodes[user];
65
- const personalSpaceId = result.createdNodes[personalSpace];
66
- if (userId === undefined || personalSpaceId === undefined) {
67
- throw new TypeError('Shell provisioning omitted its User or personal Space identity.');
68
- }
69
- return Object.freeze({ userId, personalSpaceId, changed: true });
70
- }
@@ -1,7 +0,0 @@
1
- import type { WorkflowContext } from '@astrale-os/sdk/workflow';
2
- import type { S, SetupUserResult, Shell } from '../../schema/index.js';
3
- import { type SetupRole } from '../../rules/user/index.js';
4
- type SetupCallable = typeof S.functions.setupAdmin | typeof S.functions.setupMember;
5
- type SetupContext = WorkflowContext<SetupCallable, Shell>;
6
- export declare function runSetup(context: SetupContext, role: SetupRole): Promise<SetupUserResult>;
7
- export {};
@@ -1,82 +0,0 @@
1
- import { issuer } from '@astrale-os/sdk/auth';
2
- import { ResponseError, TransportError } from '@astrale-os/sdk/client';
3
- import { InvocationError } from '@astrale-os/sdk/execution';
4
- import { Path } from '@astrale-os/sdk/graph/path';
5
- import { repairUser } from '#mutations/user';
6
- import { observeUserSetup } from '#queries/user';
7
- import { planUserSetup } from '#rules/user';
8
- import { provisioningRequest, provisioningResult } from './provision.js';
9
- export async function runSetup(context, role) {
10
- const { input, step } = context;
11
- const client = context.kernel.self;
12
- const identity = Object.freeze({
13
- iss: issuer.accept(input.issuer),
14
- sub: input.subject,
15
- });
16
- const existing = await step.run('resolve-identity', () => client.auth.whois(identity));
17
- if (existing === null) {
18
- try {
19
- const provisioned = await step.run('provision-identity', () => client.auth.provision(provisioningRequest(context.domain, input, role)));
20
- return provisioningResult(provisioned);
21
- }
22
- catch (cause) {
23
- if (!recoverableProvisionFailure(cause))
24
- throw cause;
25
- const recovered = await step.run('recover-provisioned-identity', () => client.auth.whois(identity));
26
- if (recovered === null)
27
- throw cause;
28
- return convergeExisting(context, role, recovered.id, true);
29
- }
30
- }
31
- return convergeExisting(context, role, existing.id, false);
32
- }
33
- async function convergeExisting(context, role, userId, changedBeforeObservation) {
34
- const observed = await context.step.run('observe-user-setup', () => context.graph.self.query(observeUserSetup, Path.id(userId).raw));
35
- const plan = planUserSetup(context.domain, context.input, role, observed);
36
- if (plan.kind === 'conflict')
37
- return setupConflict(plan);
38
- if (plan.kind === 'unchanged') {
39
- return Object.freeze({
40
- userId,
41
- personalSpaceId: plan.personalSpaceId,
42
- changed: changedBeforeObservation,
43
- });
44
- }
45
- const repaired = await context.step.run('repair-user-setup', () => context.graph.self.mutate(repairUser, {
46
- ...plan.repair,
47
- guards: {
48
- home: observed.home.guard,
49
- ownedSpaces: observed.ownedSpaces.guard,
50
- groups: observed.groups.guard,
51
- },
52
- }));
53
- if (repaired.ok) {
54
- return Object.freeze({ userId, personalSpaceId: repaired.personalSpaceId, changed: true });
55
- }
56
- if (repaired.outcomeKnown) {
57
- throw new InvocationError('CONFLICT', 'Shell User setup conflicted with concurrent graph state.', {
58
- reason: { code: repaired.code, details: {} },
59
- });
60
- }
61
- const recovered = await context.step.run('recover-user-repair', () => context.graph.self.query(observeUserSetup, Path.id(userId).raw));
62
- const recoveredPlan = planUserSetup(context.domain, context.input, role, recovered);
63
- if (recoveredPlan.kind === 'conflict')
64
- return setupConflict(recoveredPlan);
65
- if (recoveredPlan.kind === 'unchanged') {
66
- return Object.freeze({ userId, personalSpaceId: recoveredPlan.personalSpaceId, changed: true });
67
- }
68
- throw new InvocationError('BACKEND_UNAVAILABLE', 'Shell User setup outcome remains unknown after exact state observation.', { reason: { code: repaired.code, details: {} } });
69
- }
70
- function setupConflict(plan) {
71
- throw new InvocationError('CONFLICT', plan.message, {
72
- reason: { code: plan.reason, details: {} },
73
- });
74
- }
75
- function recoverableProvisionFailure(cause) {
76
- if (cause instanceof TransportError) {
77
- return cause.context.kind === 'invocation' && cause.context.delivery === 'unknown';
78
- }
79
- return (cause instanceof ResponseError &&
80
- (cause.reason?.code === 'PROVISION_CONFLICT' ||
81
- cause.reason?.code === 'PROVISION_PRECONDITION_FAILED'));
82
- }
@@ -1,7 +0,0 @@
1
- import type { WorkflowContext } from '@astrale-os/sdk/workflow';
2
- import type { S, Shell } from '../../schema/index.js';
3
- export type DesiredSpaceAccess = 'member' | 'admin' | null;
4
- type SpaceAccessCallable = typeof S.classes.Space.self.methods.addUser | typeof S.classes.Space.self.methods.removeUser;
5
- type SpaceAccessContext = WorkflowContext<SpaceAccessCallable, Shell>;
6
- export declare function setUserAccess(context: SpaceAccessContext, desired: DesiredSpaceAccess): Promise<Readonly<Record<never, never>>>;
7
- export {};
@@ -1,41 +0,0 @@
1
- import { InvocationError } from '@astrale-os/sdk/execution';
2
- import { changeSpaceAccess } from '#mutations/space';
3
- import { observeDirectSpaceAccess } from '#queries/space';
4
- export async function setUserAccess(context, desired) {
5
- const observed = await context.step.run('observe-space-access', () => context.graph.self.query(observeDirectSpaceAccess, context.input.user));
6
- const current = state(observed, context.self);
7
- if (current === desired)
8
- return Object.freeze({});
9
- const result = await context.step.run('change-space-access', () => context.graph.self.mutate(changeSpaceAccess, {
10
- user: context.input.user,
11
- space: context.self,
12
- addMember: desired === 'member' && current !== 'member',
13
- removeMember: current === 'member' && desired !== 'member',
14
- addAdmin: desired === 'admin' && current !== 'admin',
15
- removeAdmin: current === 'admin' && desired !== 'admin',
16
- guards: { member: observed.member.guard, admin: observed.admin.guard },
17
- }));
18
- if (result.ok)
19
- return Object.freeze({});
20
- if (result.outcomeKnown)
21
- return accessConflict(result.code);
22
- const recovered = await context.step.run('recover-space-access', () => context.graph.self.query(observeDirectSpaceAccess, context.input.user));
23
- if (state(recovered, context.self) === desired)
24
- return Object.freeze({});
25
- throw new InvocationError('BACKEND_UNAVAILABLE', 'Space access outcome remains unknown after exact observation.', { reason: { code: result.code, details: {} } });
26
- }
27
- function state(observation, space) {
28
- const member = observation.member.spaces.some(({ id }) => id === space);
29
- const admin = observation.admin.spaces.some(({ id }) => id === space);
30
- if (member && admin) {
31
- throw new InvocationError('CONFLICT', 'The User has conflicting direct Space access edges.', {
32
- reason: { code: 'SPACE_ACCESS_AMBIGUOUS', details: {} },
33
- });
34
- }
35
- return admin ? 'admin' : member ? 'member' : null;
36
- }
37
- function accessConflict(code) {
38
- throw new InvocationError('CONFLICT', 'Space access conflicted with concurrent graph state.', {
39
- reason: { code, details: {} },
40
- });
41
- }
@@ -1,3 +0,0 @@
1
- import { type WorkflowDefinition } from '@astrale-os/sdk/workflow';
2
- import type { ShellSchema } from '../../schema/index.js';
3
- export declare const addSpaceUserWorkflow: WorkflowDefinition<typeof ShellSchema, 'Space.addUser'>;
@@ -1,3 +0,0 @@
1
- import { defineWorkflow } from '@astrale-os/sdk/workflow';
2
- import { setUserAccess } from './access.js';
3
- export const addSpaceUserWorkflow = defineWorkflow()('Space.addUser', (context) => setUserAccess(context, context.input.access));
@@ -1,3 +0,0 @@
1
- import { type WorkflowDefinition } from '@astrale-os/sdk/workflow';
2
- import type { ShellSchema } from '../../schema/index.js';
3
- export declare const setDefaultSpaceWorkflow: WorkflowDefinition<typeof ShellSchema, 'Space.setDefault'>;
@@ -1,37 +0,0 @@
1
- import { InvocationError } from '@astrale-os/sdk/execution';
2
- import { Path } from '@astrale-os/sdk/graph/path';
3
- import { defineWorkflow, } from '@astrale-os/sdk/workflow';
4
- import { changeDefaultSpace } from '#mutations/space';
5
- import { observeHome } from '#queries/user';
6
- async function setDefault(context) {
7
- const user = context.caller.principal;
8
- const observed = await context.step.run('observe-default-space', () => context.graph.self.query(observeHome, Path.id(user).raw));
9
- if (observed.spaces.length > 1) {
10
- throw new InvocationError('CONFLICT', 'The Shell User has more than one default Space.', {
11
- reason: { code: 'MULTIPLE_DEFAULT_SPACES', details: {} },
12
- });
13
- }
14
- if (observed.spaces[0]?.id === context.self)
15
- return Object.freeze({});
16
- const result = await context.step.run('change-default-space', () => context.graph.self.mutate(changeDefaultSpace, {
17
- user,
18
- ...(observed.spaces[0] === undefined ? {} : { previous: observed.spaces[0].id }),
19
- next: context.self,
20
- guard: observed.guard,
21
- }));
22
- if (result.ok)
23
- return Object.freeze({});
24
- if (result.outcomeKnown)
25
- return defaultConflict(result.code);
26
- const recovered = await context.step.run('recover-default-space', () => context.graph.self.query(observeHome, Path.id(user).raw));
27
- if (recovered.spaces.length === 1 && recovered.spaces[0]?.id === context.self) {
28
- return Object.freeze({});
29
- }
30
- throw new InvocationError('BACKEND_UNAVAILABLE', 'Default Space outcome remains unknown after exact observation.', { reason: { code: result.code, details: {} } });
31
- }
32
- function defaultConflict(code) {
33
- throw new InvocationError('CONFLICT', 'Default Space conflicted with concurrent graph state.', {
34
- reason: { code, details: {} },
35
- });
36
- }
37
- export const setDefaultSpaceWorkflow = defineWorkflow()('Space.setDefault', setDefault);
@@ -1,4 +0,0 @@
1
- export { setUserAccess, type DesiredSpaceAccess } from './access.js';
2
- export { addSpaceUserWorkflow } from './add.js';
3
- export { setDefaultSpaceWorkflow } from './default.js';
4
- export { removeSpaceUserWorkflow } from './remove.js';
@@ -1,4 +0,0 @@
1
- export { setUserAccess } from './access.js';
2
- export { addSpaceUserWorkflow } from './add.js';
3
- export { setDefaultSpaceWorkflow } from './default.js';
4
- export { removeSpaceUserWorkflow } from './remove.js';
@@ -1,3 +0,0 @@
1
- import { type WorkflowDefinition } from '@astrale-os/sdk/workflow';
2
- import type { ShellSchema } from '../../schema/index.js';
3
- export declare const removeSpaceUserWorkflow: WorkflowDefinition<typeof ShellSchema, 'Space.removeUser'>;
@@ -1,3 +0,0 @@
1
- import { defineWorkflow } from '@astrale-os/sdk/workflow';
2
- import { setUserAccess } from './access.js';
3
- export const removeSpaceUserWorkflow = defineWorkflow()('Space.removeUser', (context) => setUserAccess(context, null));
@@ -1,3 +0,0 @@
1
- import { type ActionDefinition } from '@astrale-os/sdk/action';
2
- import type { ShellSchema } from '../../schema/index.js';
3
- export declare const resolveHomeAction: ActionDefinition<typeof ShellSchema, 'User.resolveHome'>;
@@ -1,19 +0,0 @@
1
- import { defineAction } from '@astrale-os/sdk/action';
2
- import { InvocationError } from '@astrale-os/sdk/execution';
3
- import { Path } from '@astrale-os/sdk/graph/path';
4
- import { observeHome } from '#queries/user';
5
- export const resolveHomeAction = defineAction()('User.resolveHome', async ({ domain, query, self }) => {
6
- const observed = await query(observeHome, Path.id(self).raw);
7
- if (observed.spaces.length > 1) {
8
- throw new InvocationError('CONFLICT', 'The Shell User has more than one default Space.', {
9
- reason: { code: 'MULTIPLE_DEFAULT_SPACES', details: {} },
10
- });
11
- }
12
- const home = observed.spaces[0];
13
- if (home !== undefined && home.class !== domain.classes.Space.key) {
14
- throw new InvocationError('CONFLICT', 'The Shell User default target is not a Shell Space.', {
15
- reason: { code: 'DEFAULT_SPACE_CLASS_CONFLICT', details: {} },
16
- });
17
- }
18
- return Object.freeze({ userId: self, personalSpaceId: home?.id ?? null });
19
- });
@@ -1,23 +0,0 @@
1
- import type { NodeId } from '@astrale-os/sdk/graph/node';
2
- import type { QueryPrecondition } from '@astrale-os/sdk/mutation';
3
- import type { QueryEdgeAST } from '@astrale-os/sdk/query';
4
- import { type Mutation } from '@astrale-os/sdk/mutation';
5
- import type { Shell } from '../../schema/index.js';
6
- export interface GroupMembershipChange {
7
- readonly user: string;
8
- readonly group: NodeId;
9
- readonly present: boolean;
10
- readonly current: {
11
- readonly membership: boolean;
12
- readonly authority: boolean;
13
- };
14
- readonly guard: QueryPrecondition<QueryEdgeAST>;
15
- }
16
- export type GroupMembershipChangeResult = {
17
- readonly ok: true;
18
- } | {
19
- readonly ok: false;
20
- readonly code: string;
21
- readonly outcomeKnown: boolean;
22
- };
23
- export declare const changeGroupMembership: Mutation<Shell, GroupMembershipChange, GroupMembershipChangeResult>;
@@ -1,32 +0,0 @@
1
- import { Path } from '@astrale-os/sdk/graph/path';
2
- import { defineMutation } from '@astrale-os/sdk/mutation';
3
- export const changeGroupMembership = defineMutation()((domain) => ({
4
- id: 'shell.group.membership',
5
- build(change, mutation) {
6
- mutation.expect.query(change.guard);
7
- const membership = {
8
- class: domain.classes.member_of_group,
9
- source: Path.parse(change.user),
10
- target: Path.id(change.group),
11
- };
12
- const authority = {
13
- class: domain.dependencies.kernel.classes.extends_with,
14
- source: Path.parse(change.user),
15
- target: Path.id(change.group),
16
- };
17
- if (change.current.membership !== change.present) {
18
- if (change.present)
19
- mutation.createEdge(membership);
20
- else
21
- mutation.deleteEdge(membership);
22
- }
23
- if (change.current.authority !== change.present) {
24
- if (change.present)
25
- mutation.createEdge(authority);
26
- else
27
- mutation.deleteEdge(authority);
28
- }
29
- },
30
- project: () => Object.freeze({ ok: true }),
31
- reject: (failure) => Object.freeze({ ok: false, code: failure.code, outcomeKnown: failure.outcomeKnown }),
32
- }));
@@ -1,25 +0,0 @@
1
- import type { NodeId } from '@astrale-os/sdk/graph/node';
2
- import type { QueryPrecondition } from '@astrale-os/sdk/mutation';
3
- import type { QueryNodeAST } from '@astrale-os/sdk/query';
4
- import { type Mutation } from '@astrale-os/sdk/mutation';
5
- import type { Shell } from '../../schema/index.js';
6
- export interface SpaceAccessChange {
7
- readonly user: string;
8
- readonly space: NodeId;
9
- readonly addMember: boolean;
10
- readonly removeMember: boolean;
11
- readonly addAdmin: boolean;
12
- readonly removeAdmin: boolean;
13
- readonly guards: {
14
- readonly member: QueryPrecondition<QueryNodeAST>;
15
- readonly admin: QueryPrecondition<QueryNodeAST>;
16
- };
17
- }
18
- export type SpaceAccessChangeResult = {
19
- readonly ok: true;
20
- } | {
21
- readonly ok: false;
22
- readonly code: string;
23
- readonly outcomeKnown: boolean;
24
- };
25
- export declare const changeSpaceAccess: Mutation<Shell, SpaceAccessChange, SpaceAccessChangeResult>;
@@ -1,23 +0,0 @@
1
- import { Path } from '@astrale-os/sdk/graph/path';
2
- import { defineMutation } from '@astrale-os/sdk/mutation';
3
- export const changeSpaceAccess = defineMutation()((domain) => ({
4
- id: 'shell.space.access',
5
- build(change, mutation) {
6
- mutation.expect.query(change.guards.member);
7
- mutation.expect.query(change.guards.admin);
8
- const source = Path.parse(change.user);
9
- const target = Path.id(change.space);
10
- const member = { class: domain.classes.member_of_space, source, target };
11
- const admin = { class: domain.classes.administers_space, source, target };
12
- if (change.removeMember)
13
- mutation.deleteEdge(member);
14
- if (change.removeAdmin)
15
- mutation.deleteEdge(admin);
16
- if (change.addMember)
17
- mutation.createEdge(member);
18
- if (change.addAdmin)
19
- mutation.createEdge(admin);
20
- },
21
- project: () => Object.freeze({ ok: true }),
22
- reject: (failure) => Object.freeze({ ok: false, code: failure.code, outcomeKnown: failure.outcomeKnown }),
23
- }));
@@ -1,19 +0,0 @@
1
- import type { NodeId } from '@astrale-os/sdk/graph/node';
2
- import type { QueryPrecondition } from '@astrale-os/sdk/mutation';
3
- import type { QueryNodeAST } from '@astrale-os/sdk/query';
4
- import { type Mutation } from '@astrale-os/sdk/mutation';
5
- import type { Shell } from '../../schema/index.js';
6
- export interface DefaultSpaceChange {
7
- readonly user: NodeId;
8
- readonly previous?: NodeId;
9
- readonly next: NodeId;
10
- readonly guard: QueryPrecondition<QueryNodeAST>;
11
- }
12
- export type DefaultSpaceChangeResult = {
13
- readonly ok: true;
14
- } | {
15
- readonly ok: false;
16
- readonly code: string;
17
- readonly outcomeKnown: boolean;
18
- };
19
- export declare const changeDefaultSpace: Mutation<Shell, DefaultSpaceChange, DefaultSpaceChangeResult>;
@@ -1,23 +0,0 @@
1
- import { Path } from '@astrale-os/sdk/graph/path';
2
- import { defineMutation } from '@astrale-os/sdk/mutation';
3
- export const changeDefaultSpace = defineMutation()((domain) => ({
4
- id: 'shell.space.default',
5
- build(change, mutation) {
6
- mutation.expect.query(change.guard);
7
- const source = Path.id(change.user);
8
- if (change.previous !== undefined) {
9
- mutation.deleteEdge({
10
- class: domain.classes.default_space,
11
- source,
12
- target: Path.id(change.previous),
13
- });
14
- }
15
- mutation.createEdge({
16
- class: domain.classes.default_space,
17
- source,
18
- target: Path.id(change.next),
19
- });
20
- },
21
- project: () => Object.freeze({ ok: true }),
22
- reject: (failure) => Object.freeze({ ok: false, code: failure.code, outcomeKnown: failure.outcomeKnown }),
23
- }));
@@ -1,2 +0,0 @@
1
- export { changeSpaceAccess, type SpaceAccessChange, type SpaceAccessChangeResult, } from './access.js';
2
- export { changeDefaultSpace, type DefaultSpaceChange, type DefaultSpaceChangeResult, } from './default.js';
@@ -1,2 +0,0 @@
1
- export { changeSpaceAccess, } from './access.js';
2
- export { changeDefaultSpace, } from './default.js';
@@ -1 +0,0 @@
1
- export { repairUser, type UserRepair, type UserRepairResult } from './repair.js';
@@ -1 +0,0 @@
1
- export { repairUser } from './repair.js';
@@ -1,22 +0,0 @@
1
- import type { NodeId } from '@astrale-os/sdk/graph/node';
2
- import type { QueryPrecondition } from '@astrale-os/sdk/mutation';
3
- import type { QueryEdgeAST, QueryNodeAST } from '@astrale-os/sdk/query';
4
- import { type Mutation } from '@astrale-os/sdk/mutation';
5
- import type { UserSetupRepair } from '../../rules/user/index.js';
6
- import type { Shell } from '../../schema/index.js';
7
- export interface UserRepair extends UserSetupRepair {
8
- readonly guards: {
9
- readonly home: QueryPrecondition<QueryNodeAST>;
10
- readonly ownedSpaces: QueryPrecondition<QueryNodeAST>;
11
- readonly groups: QueryPrecondition<QueryEdgeAST>;
12
- };
13
- }
14
- export type UserRepairResult = {
15
- readonly ok: true;
16
- readonly personalSpaceId: NodeId;
17
- } | {
18
- readonly ok: false;
19
- readonly code: string;
20
- readonly outcomeKnown: boolean;
21
- };
22
- export declare const repairUser: Mutation<Shell, UserRepair, UserRepairResult>;