@owlmeans/server-planning 0.1.18-rc.21 → 0.1.18-rc.23

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 (313) hide show
  1. package/README.md +24 -17
  2. package/agent-meta/manifest.json +2 -2
  3. package/agent-meta/skills/server-planning/SKILL.md +28 -28
  4. package/build/actions/apply-schema-request.d.ts +8 -0
  5. package/build/actions/apply-schema-request.d.ts.map +1 -0
  6. package/build/actions/apply-schema-request.js +31 -0
  7. package/build/actions/apply-schema-request.js.map +1 -0
  8. package/build/actions/cards.d.ts +5 -3
  9. package/build/actions/cards.d.ts.map +1 -1
  10. package/build/actions/cards.js +1 -1
  11. package/build/actions/cards.js.map +1 -1
  12. package/build/actions/commit.d.ts +3 -3
  13. package/build/actions/commit.d.ts.map +1 -1
  14. package/build/actions/commit.js +5 -4
  15. package/build/actions/commit.js.map +1 -1
  16. package/build/actions/define-schemas.d.ts +13 -0
  17. package/build/actions/define-schemas.d.ts.map +1 -0
  18. package/build/actions/define-schemas.js +28 -0
  19. package/build/actions/define-schemas.js.map +1 -0
  20. package/build/actions/execute.d.ts +8 -28
  21. package/build/actions/execute.d.ts.map +1 -1
  22. package/build/actions/execute.js +17 -101
  23. package/build/actions/execute.js.map +1 -1
  24. package/build/actions/execution/types.d.ts +34 -0
  25. package/build/actions/execution/types.d.ts.map +1 -0
  26. package/build/actions/execution/types.js +2 -0
  27. package/build/actions/execution/types.js.map +1 -0
  28. package/build/actions/execution.d.ts +4 -0
  29. package/build/actions/execution.d.ts.map +1 -0
  30. package/build/actions/execution.js +79 -0
  31. package/build/actions/execution.js.map +1 -0
  32. package/build/actions/get-card.d.ts +6 -0
  33. package/build/actions/get-card.d.ts.map +1 -0
  34. package/build/actions/get-card.js +9 -0
  35. package/build/actions/get-card.js.map +1 -0
  36. package/build/actions/get-specification.d.ts +6 -0
  37. package/build/actions/get-specification.d.ts.map +1 -0
  38. package/build/actions/get-specification.js +9 -0
  39. package/build/actions/get-specification.js.map +1 -0
  40. package/build/actions/index.d.ts +12 -3
  41. package/build/actions/index.d.ts.map +1 -1
  42. package/build/actions/index.js +11 -3
  43. package/build/actions/index.js.map +1 -1
  44. package/build/actions/links.d.ts +3 -3
  45. package/build/actions/links.d.ts.map +1 -1
  46. package/build/actions/links.js +6 -5
  47. package/build/actions/links.js.map +1 -1
  48. package/build/actions/list-card-specifications.d.ts +6 -0
  49. package/build/actions/list-card-specifications.d.ts.map +1 -0
  50. package/build/actions/list-card-specifications.js +11 -0
  51. package/build/actions/list-card-specifications.js.map +1 -0
  52. package/build/actions/list-card-transitions.d.ts +6 -0
  53. package/build/actions/list-card-transitions.d.ts.map +1 -0
  54. package/build/actions/list-card-transitions.js +11 -0
  55. package/build/actions/list-card-transitions.js.map +1 -0
  56. package/build/actions/list-cards.d.ts +6 -0
  57. package/build/actions/list-cards.d.ts.map +1 -0
  58. package/build/actions/list-cards.js +10 -0
  59. package/build/actions/list-cards.js.map +1 -0
  60. package/build/actions/list-schemas.d.ts +13 -0
  61. package/build/actions/list-schemas.d.ts.map +1 -0
  62. package/build/actions/list-schemas.js +20 -0
  63. package/build/actions/list-schemas.js.map +1 -0
  64. package/build/actions/list-specification-revisions.d.ts +6 -0
  65. package/build/actions/list-specification-revisions.d.ts.map +1 -0
  66. package/build/actions/list-specification-revisions.js +10 -0
  67. package/build/actions/list-specification-revisions.js.map +1 -0
  68. package/build/actions/schemas.d.ts +5 -3
  69. package/build/actions/schemas.d.ts.map +1 -1
  70. package/build/actions/schemas.js.map +1 -1
  71. package/build/actions/specs.d.ts +4 -2
  72. package/build/actions/specs.d.ts.map +1 -1
  73. package/build/actions/specs.js.map +1 -1
  74. package/build/actions/summarize-cards.d.ts +6 -0
  75. package/build/actions/summarize-cards.d.ts.map +1 -0
  76. package/build/actions/summarize-cards.js +11 -0
  77. package/build/actions/summarize-cards.js.map +1 -0
  78. package/build/actions/transitions.d.ts +3 -3
  79. package/build/actions/transitions.d.ts.map +1 -1
  80. package/build/actions/transitions.js +4 -3
  81. package/build/actions/transitions.js.map +1 -1
  82. package/build/actions/types.d.ts +5 -3
  83. package/build/actions/types.d.ts.map +1 -1
  84. package/build/actions/watch.d.ts +2 -2
  85. package/build/actions/watch.d.ts.map +1 -1
  86. package/build/actions/watch.js +2 -2
  87. package/build/actions/watch.js.map +1 -1
  88. package/build/conformance/assert/types.d.ts +19 -0
  89. package/build/conformance/assert/types.d.ts.map +1 -0
  90. package/build/conformance/assert/types.js +2 -0
  91. package/build/conformance/assert/types.js.map +1 -0
  92. package/build/conformance/assert.d.ts +8 -13
  93. package/build/conformance/assert.d.ts.map +1 -1
  94. package/build/conformance/assert.js +41 -43
  95. package/build/conformance/assert.js.map +1 -1
  96. package/build/conformance/cases.d.ts.map +1 -1
  97. package/build/conformance/cases.js +86 -67
  98. package/build/conformance/cases.js.map +1 -1
  99. package/build/conformance/clock.d.ts +6 -0
  100. package/build/conformance/clock.d.ts.map +1 -0
  101. package/build/conformance/clock.js +12 -0
  102. package/build/conformance/clock.js.map +1 -0
  103. package/build/conformance/consts.d.ts +3 -1
  104. package/build/conformance/consts.d.ts.map +1 -1
  105. package/build/conformance/consts.js +84 -1
  106. package/build/conformance/consts.js.map +1 -1
  107. package/build/conformance/errors.d.ts +5 -0
  108. package/build/conformance/errors.d.ts.map +1 -0
  109. package/build/conformance/errors.js +8 -0
  110. package/build/conformance/errors.js.map +1 -0
  111. package/build/conformance/fixtures/types.d.ts +13 -0
  112. package/build/conformance/fixtures/types.d.ts.map +1 -0
  113. package/build/conformance/fixtures/types.js +2 -0
  114. package/build/conformance/fixtures/types.js.map +1 -0
  115. package/build/conformance/fixtures.d.ts +8 -8
  116. package/build/conformance/fixtures.d.ts.map +1 -1
  117. package/build/conformance/fixtures.js +24 -107
  118. package/build/conformance/fixtures.js.map +1 -1
  119. package/build/conformance/index.d.ts +3 -0
  120. package/build/conformance/index.d.ts.map +1 -1
  121. package/build/conformance/index.js +1 -0
  122. package/build/conformance/index.js.map +1 -1
  123. package/build/definitions.d.ts.map +1 -1
  124. package/build/definitions.js +9 -9
  125. package/build/definitions.js.map +1 -1
  126. package/build/executor/changes/types.d.ts +36 -0
  127. package/build/executor/changes/types.d.ts.map +1 -0
  128. package/build/executor/changes/types.js +2 -0
  129. package/build/executor/changes/types.js.map +1 -0
  130. package/build/executor/changes.d.ts +3 -30
  131. package/build/executor/changes.d.ts.map +1 -1
  132. package/build/executor/changes.js +42 -51
  133. package/build/executor/changes.js.map +1 -1
  134. package/build/executor/code/types.d.ts +17 -0
  135. package/build/executor/code/types.d.ts.map +1 -0
  136. package/build/executor/code/types.js +2 -0
  137. package/build/executor/code/types.js.map +1 -0
  138. package/build/executor/code.d.ts +3 -14
  139. package/build/executor/code.d.ts.map +1 -1
  140. package/build/executor/code.js +50 -54
  141. package/build/executor/code.js.map +1 -1
  142. package/build/executor/creator/types.d.ts +33 -0
  143. package/build/executor/creator/types.d.ts.map +1 -0
  144. package/build/executor/creator/types.js +2 -0
  145. package/build/executor/creator/types.js.map +1 -0
  146. package/build/executor/creator.d.ts +6 -25
  147. package/build/executor/creator.d.ts.map +1 -1
  148. package/build/executor/creator.js +26 -41
  149. package/build/executor/creator.js.map +1 -1
  150. package/build/executor/resolve/types.d.ts +30 -0
  151. package/build/executor/resolve/types.d.ts.map +1 -0
  152. package/build/executor/resolve/types.js +2 -0
  153. package/build/executor/resolve/types.js.map +1 -0
  154. package/build/executor/resolve.d.ts +4 -41
  155. package/build/executor/resolve.d.ts.map +1 -1
  156. package/build/executor/resolve.js +142 -157
  157. package/build/executor/resolve.js.map +1 -1
  158. package/build/executor/types.d.ts +0 -2
  159. package/build/executor/types.d.ts.map +1 -1
  160. package/build/executor/validate.d.ts +1 -1
  161. package/build/executor/validate.d.ts.map +1 -1
  162. package/build/executor/validate.js +16 -15
  163. package/build/executor/validate.js.map +1 -1
  164. package/build/executor.d.ts +4 -3
  165. package/build/executor.d.ts.map +1 -1
  166. package/build/executor.js +18 -17
  167. package/build/executor.js.map +1 -1
  168. package/build/facade.d.ts.map +1 -1
  169. package/build/facade.js +16 -16
  170. package/build/facade.js.map +1 -1
  171. package/build/helper.d.ts +1 -6
  172. package/build/helper.d.ts.map +1 -1
  173. package/build/helper.js +3 -8
  174. package/build/helper.js.map +1 -1
  175. package/build/projection.d.ts +2 -0
  176. package/build/projection.d.ts.map +1 -1
  177. package/build/projection.js +6 -4
  178. package/build/projection.js.map +1 -1
  179. package/build/queue/declare.d.ts +5 -0
  180. package/build/queue/declare.d.ts.map +1 -0
  181. package/build/queue/declare.js +5 -0
  182. package/build/queue/declare.js.map +1 -0
  183. package/build/queue/index.d.ts +1 -4
  184. package/build/queue/index.d.ts.map +1 -1
  185. package/build/queue/index.js +1 -4
  186. package/build/queue/index.js.map +1 -1
  187. package/build/store/composite.d.ts.map +1 -1
  188. package/build/store/composite.js +2 -2
  189. package/build/store/composite.js.map +1 -1
  190. package/build/store/fold/types.d.ts +43 -0
  191. package/build/store/fold/types.d.ts.map +1 -0
  192. package/build/store/fold/types.js +2 -0
  193. package/build/store/fold/types.js.map +1 -0
  194. package/build/store/fold.d.ts +7 -30
  195. package/build/store/fold.d.ts.map +1 -1
  196. package/build/store/fold.js +185 -203
  197. package/build/store/fold.js.map +1 -1
  198. package/build/store/index.d.ts +1 -0
  199. package/build/store/index.d.ts.map +1 -1
  200. package/build/store/index.js.map +1 -1
  201. package/build/store/memory.d.ts.map +1 -1
  202. package/build/store/memory.js +0 -0
  203. package/build/store/memory.js.map +1 -1
  204. package/build/store/types.local.d.ts +3 -1
  205. package/build/store/types.local.d.ts.map +1 -1
  206. package/build/types.d.ts +2 -1
  207. package/build/types.d.ts.map +1 -1
  208. package/build/utils/access/types.d.ts +30 -0
  209. package/build/utils/access/types.d.ts.map +1 -0
  210. package/build/utils/access/types.js +2 -0
  211. package/build/utils/access/types.js.map +1 -0
  212. package/build/utils/access.d.ts +4 -0
  213. package/build/utils/access.d.ts.map +1 -0
  214. package/build/utils/access.js +28 -0
  215. package/build/utils/access.js.map +1 -0
  216. package/build/utils/guard/types.d.ts +21 -0
  217. package/build/utils/guard/types.d.ts.map +1 -0
  218. package/build/utils/guard/types.js +2 -0
  219. package/build/utils/guard/types.js.map +1 -0
  220. package/build/utils/guard.d.ts +7 -10
  221. package/build/utils/guard.d.ts.map +1 -1
  222. package/build/utils/guard.js +33 -31
  223. package/build/utils/guard.js.map +1 -1
  224. package/build/utils/handler/types.d.ts +26 -0
  225. package/build/utils/handler/types.d.ts.map +1 -0
  226. package/build/utils/handler/types.js +2 -0
  227. package/build/utils/handler/types.js.map +1 -0
  228. package/build/utils/handler.d.ts +6 -0
  229. package/build/utils/handler.d.ts.map +1 -0
  230. package/build/utils/handler.js +21 -0
  231. package/build/utils/handler.js.map +1 -0
  232. package/build/utils/index.d.ts +8 -1
  233. package/build/utils/index.d.ts.map +1 -1
  234. package/build/utils/index.js +3 -0
  235. package/build/utils/index.js.map +1 -1
  236. package/build/utils/request/types.d.ts +23 -0
  237. package/build/utils/request/types.d.ts.map +1 -0
  238. package/build/utils/request/types.js +2 -0
  239. package/build/utils/request/types.js.map +1 -0
  240. package/build/utils/request.d.ts +4 -0
  241. package/build/utils/request.d.ts.map +1 -0
  242. package/build/utils/request.js +27 -0
  243. package/build/utils/request.js.map +1 -0
  244. package/build/utils/scope.d.ts +10 -43
  245. package/build/utils/scope.d.ts.map +1 -1
  246. package/build/utils/scope.js +21 -99
  247. package/build/utils/scope.js.map +1 -1
  248. package/package.json +18 -18
  249. package/src/actions/apply-schema-request.ts +35 -0
  250. package/src/actions/commit.ts +7 -5
  251. package/src/actions/define-schemas.ts +34 -0
  252. package/src/actions/execute.ts +30 -115
  253. package/src/actions/execution/types.ts +34 -0
  254. package/src/actions/execution.ts +96 -0
  255. package/src/actions/get-card.ts +14 -0
  256. package/src/actions/get-specification.ts +14 -0
  257. package/src/actions/index.ts +13 -3
  258. package/src/actions/links.ts +8 -6
  259. package/src/actions/list-card-specifications.ts +15 -0
  260. package/src/actions/list-card-transitions.ts +15 -0
  261. package/src/actions/list-cards.ts +14 -0
  262. package/src/actions/list-schemas.ts +29 -0
  263. package/src/actions/{specs.ts → list-specification-revisions.ts} +4 -11
  264. package/src/actions/summarize-cards.ts +15 -0
  265. package/src/actions/transitions.ts +6 -4
  266. package/src/actions/types.ts +4 -3
  267. package/src/actions/watch.ts +4 -3
  268. package/src/conformance/assert/types.ts +16 -0
  269. package/src/conformance/assert.ts +49 -41
  270. package/src/conformance/cases.ts +88 -67
  271. package/src/conformance/clock.ts +11 -0
  272. package/src/conformance/consts.ts +87 -1
  273. package/src/conformance/errors.ts +7 -0
  274. package/src/conformance/fixtures/types.ts +11 -0
  275. package/src/conformance/fixtures.ts +32 -107
  276. package/src/conformance/index.ts +3 -0
  277. package/src/definitions.ts +9 -9
  278. package/src/executor/changes/types.ts +38 -0
  279. package/src/executor/changes.ts +48 -63
  280. package/src/executor/code/types.ts +23 -0
  281. package/src/executor/code.ts +60 -61
  282. package/src/executor/creator/types.ts +33 -0
  283. package/src/executor/creator.ts +33 -41
  284. package/src/executor/resolve/types.ts +30 -0
  285. package/src/executor/resolve.ts +153 -167
  286. package/src/executor/types.ts +0 -3
  287. package/src/executor/validate.ts +17 -16
  288. package/src/executor.ts +20 -17
  289. package/src/facade.ts +16 -16
  290. package/src/helper.ts +3 -8
  291. package/src/projection.ts +8 -4
  292. package/src/queue/declare.ts +7 -0
  293. package/src/queue/index.ts +1 -8
  294. package/src/store/composite.ts +2 -2
  295. package/src/store/fold/types.ts +44 -0
  296. package/src/store/fold.ts +209 -212
  297. package/src/store/index.ts +1 -0
  298. package/src/store/memory.ts +0 -0
  299. package/src/store/types.local.ts +1 -1
  300. package/src/types.ts +1 -1
  301. package/src/utils/access/types.ts +30 -0
  302. package/src/utils/access.ts +33 -0
  303. package/src/utils/guard/types.ts +19 -0
  304. package/src/utils/guard.ts +41 -30
  305. package/src/utils/handler/types.ts +28 -0
  306. package/src/utils/handler.ts +35 -0
  307. package/src/utils/index.ts +9 -1
  308. package/src/utils/request/types.ts +23 -0
  309. package/src/utils/request.ts +40 -0
  310. package/src/utils/scope.ts +25 -108
  311. package/tests/creator.spec.ts +18 -18
  312. package/src/actions/cards.ts +0 -48
  313. package/src/actions/schemas.ts +0 -87
@@ -1,57 +1,24 @@
1
1
  import type { BasicConfig, BasicContext } from '@owlmeans/context';
2
2
  import type { AbstractRequest } from '@owlmeans/entrypoint';
3
- import { type PlanningFacade, type PlanningScope, type PlanningService, type TransitionActor, type Workcard } from '@owlmeans/planning';
3
+ import type { PlanningFacade, PlanningScope, PlanningService, TransitionActor, Workcard } from '@owlmeans/planning';
4
4
  import type { PlanningAccess, PlanningAccessGrants, PlanningHandlerOptions } from '../types.js';
5
5
  import type { HandlerScope } from './types.js';
6
- /** The authenticated subject of a request, as a transition names it. */
6
+ /** @deprecated compat:factory-refactor — use `makeRequestScope(req).actorOf()` */
7
7
  export declare const actorOf: (req: AbstractRequest) => TransitionActor;
8
- /**
9
- * The scope a request reads and writes as.
10
- *
11
- * `entityId` is `requireEntityKey(req)` — the resolved organization id, never a value from the
12
- * body or the query — and `extra` cannot replace it; `extra` adds what the deployment derives
13
- * (a `channel`, a `service`). The actor is the authenticated subject plus that channel.
14
- *
15
- * @throws {AuthorizationError} when the request carries no organization
16
- */
8
+ /** @deprecated compat:factory-refactor — use `makeRequestScope(req).scopeOf(…)` */
17
9
  export declare const scopeOf: (req: AbstractRequest, extra?: Partial<PlanningScope>) => PlanningScope;
18
- /**
19
- * The scope of a request under a resolved {@link PlanningAccess}: the organization is the
20
- * resolver's — never the token's, never `extra`'s — and `projects` narrows it.
21
- */
10
+ /** @deprecated compat:factory-refactor — use `makeRequestScope(req).accessScopeOf(…)` */
22
11
  export declare const accessScopeOf: (req: AbstractRequest, access: PlanningAccess, extra?: Partial<PlanningScope>) => PlanningScope;
12
+ /** @deprecated compat:factory-refactor — use `planningHandlerOf(ctx).planningServiceOf(…)` */
23
13
  export declare const planningServiceOf: (ctx: BasicContext<BasicConfig>, opts?: Pick<PlanningHandlerOptions, 'service'>) => PlanningService;
24
- /**
25
- * The facade a handler works through, and the access it was resolved under.
26
- *
27
- * Without `opts.access` it is exactly the request's scope plus what `opts.scope` derives. With it,
28
- * the resolver names the organization and the visible projects; a throw from the resolver is the
29
- * request's error.
30
- */
14
+ /** @deprecated compat:factory-refactor — use `planningHandlerOf(ctx).handlerScopeOf(…)` */
31
15
  export declare const handlerScopeOf: (ctx: BasicContext<BasicConfig>, req: AbstractRequest, opts?: PlanningHandlerOptions) => Promise<HandlerScope>;
32
- /** The facade a handler works through: the request's scope plus what `opts.scope` derives. */
16
+ /** @deprecated compat:factory-refactor — use `planningHandlerOf(ctx).handlerFacade(…)` */
33
17
  export declare const handlerFacade: (ctx: BasicContext<BasicConfig>, req: AbstractRequest, opts?: PlanningHandlerOptions) => Promise<PlanningFacade>;
34
- /**
35
- * Refuse a write the access does not grant. No access, or access without `grants`, gates nothing;
36
- * a `grants` object refuses every flag it leaves out. `true` grants everything; a list grants the
37
- * project ids it names — `target` is the project the write is about (`undefined` for the
38
- * organization's root, which only `true` reaches).
39
- *
40
- * @throws {PlanningForbidden}
41
- */
18
+ /** @deprecated compat:factory-refactor — use `makePlanningAccessModel(access).assertGranted(…)` */
42
19
  export declare const assertGranted: (access: PlanningAccess | undefined, grant: keyof PlanningAccessGrants, target?: string) => void;
43
- /**
44
- * A card the access's `writes` admits — the rule a narrowed read admits, over `writes`: a project
45
- * it names, or a card whose `parents` name one. A specification is admitted through its parent card
46
- * by the caller. No `writes` admits everything.
47
- */
20
+ /** @deprecated compat:factory-refactor — use `makePlanningAccessModel(access).writableIn(…)` */
48
21
  export declare const writableIn: (access: PlanningAccess | undefined, card: Pick<Workcard, 'id' | 'parents'>) => boolean;
49
- /**
50
- * Refuse a write into a project the access's `writes` leaves out. No `writes` refuses nothing;
51
- * `target` is the project the write is in (`undefined` for the organization's root, which a set
52
- * `writes` never admits).
53
- *
54
- * @throws {PlanningForbidden}
55
- */
22
+ /** @deprecated compat:factory-refactor — use `makePlanningAccessModel(access).assertWrites(…)` */
56
23
  export declare const assertWrites: (access: PlanningAccess | undefined, target?: string) => void;
57
24
  //# sourceMappingURL=scope.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/utils/scope.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,EAAuC,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC5K,OAAO,KAAK,EACV,cAAc,EAAE,oBAAoB,EAAE,sBAAsB,EAC7D,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAK9C,wEAAwE;AACxE,eAAO,MAAM,OAAO,QAAS,eAAe,KAAG,eAG7C,CAAA;AAeF;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,QAAS,eAAe,UAAU,OAAO,CAAC,aAAa,CAAC,KAAG,aACjC,CAAA;AAE9C;;;GAGG;AACH,eAAO,MAAM,aAAa,QACnB,eAAe,UAAU,cAAc,UAAU,OAAO,CAAC,aAAa,CAAC,KAC3E,aAKF,CAAA;AAED,eAAO,MAAM,iBAAiB,QACvB,YAAY,CAAC,WAAW,CAAC,SAAS,IAAI,CAAC,sBAAsB,EAAE,SAAS,CAAC,KAC7E,eAAsF,CAAA;AAEzF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,QACpB,YAAY,CAAC,WAAW,CAAC,OAAO,eAAe,SAAS,sBAAsB,KAClF,OAAO,CAAC,YAAY,CAQtB,CAAA;AAED,8FAA8F;AAC9F,eAAO,MAAM,aAAa,QACnB,YAAY,CAAC,WAAW,CAAC,OAAO,eAAe,SAAS,sBAAsB,KAClF,OAAO,CAAC,cAAc,CAAkD,CAAA;AAE3E;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,WAChB,cAAc,GAAG,SAAS,SAAS,MAAM,oBAAoB,WAAW,MAAM,KACrF,IASF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,UAAU,WAAY,cAAc,GAAG,SAAS,QAAQ,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,SAAS,CAAC,KAAG,OAMvG,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,WAAY,cAAc,GAAG,SAAS,WAAW,MAAM,KAAG,IAKlF,CAAA"}
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/utils/scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AACnH,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAI/F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,kFAAkF;AAClF,eAAO,MAAM,OAAO,QAAS,eAAe,KAAG,eAAkD,CAAA;AAEjG,mFAAmF;AACnF,eAAO,MAAM,OAAO,QAAS,eAAe,UAAU,OAAO,CAAC,aAAa,CAAC,KAAG,aACzC,CAAA;AAEtC,yFAAyF;AACzF,eAAO,MAAM,aAAa,QACnB,eAAe,UAAU,cAAc,UAAU,OAAO,CAAC,aAAa,CAAC,KAC3E,aAAmE,CAAA;AAEtE,8FAA8F;AAC9F,eAAO,MAAM,iBAAiB,QACvB,YAAY,CAAC,WAAW,CAAC,SAAS,IAAI,CAAC,sBAAsB,EAAE,SAAS,CAAC,KAC7E,eAAiE,CAAA;AAEpE,2FAA2F;AAC3F,eAAO,MAAM,cAAc,QACpB,YAAY,CAAC,WAAW,CAAC,OAAO,eAAe,SAAS,sBAAsB,KAClF,OAAO,CAAC,YAAY,CAA2D,CAAA;AAElF,0FAA0F;AAC1F,eAAO,MAAM,aAAa,QACnB,YAAY,CAAC,WAAW,CAAC,OAAO,eAAe,SAAS,sBAAsB,KAClF,OAAO,CAAC,cAAc,CAA0D,CAAA;AAEnF,mGAAmG;AACnG,eAAO,MAAM,aAAa,WAChB,cAAc,GAAG,SAAS,SAAS,MAAM,oBAAoB,WAAW,MAAM,KACrF,IAAoE,CAAA;AAEvE,gGAAgG;AAChG,eAAO,MAAM,UAAU,WAAY,cAAc,GAAG,SAAS,QAAQ,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,SAAS,CAAC,KAAG,OACtD,CAAA;AAElD,kGAAkG;AAClG,eAAO,MAAM,YAAY,WAAY,cAAc,GAAG,SAAS,WAAW,MAAM,KAAG,IAC7B,CAAA"}
@@ -1,100 +1,22 @@
1
- import { requireEntityKey } from '@owlmeans/auth-common';
2
- import { PLANNING_SERVICE, PlanningForbidden } from '@owlmeans/planning';
3
- const clean = (record) => Object.fromEntries(Object.entries(record).filter(([, value]) => value != null && value !== ''));
4
- /** The authenticated subject of a request, as a transition names it. */
5
- export const actorOf = (req) => clean({
6
- profileId: req.auth?.profileId,
7
- userId: req.auth?.userId,
8
- });
9
- const scopeWith = (req, entityId, extra) => {
10
- const subject = actorOf(req);
11
- const channel = extra?.channel ?? extra?.actor?.channel;
12
- return clean({
13
- ...extra,
14
- ...subject,
15
- entityId,
16
- channel,
17
- actor: clean({ ...extra?.actor, ...subject, channel }),
18
- });
19
- };
20
- /**
21
- * The scope a request reads and writes as.
22
- *
23
- * `entityId` is `requireEntityKey(req)` — the resolved organization id, never a value from the
24
- * body or the query — and `extra` cannot replace it; `extra` adds what the deployment derives
25
- * (a `channel`, a `service`). The actor is the authenticated subject plus that channel.
26
- *
27
- * @throws {AuthorizationError} when the request carries no organization
28
- */
29
- export const scopeOf = (req, extra) => scopeWith(req, requireEntityKey(req), extra);
30
- /**
31
- * The scope of a request under a resolved {@link PlanningAccess}: the organization is the
32
- * resolver's — never the token's, never `extra`'s — and `projects` narrows it.
33
- */
34
- export const accessScopeOf = (req, access, extra) => {
35
- const { projects: _projects, entityId: _entityId, ...rest } = extra ?? {};
36
- const scope = scopeWith(req, access.entityId, rest);
37
- return access.projects != null ? { ...scope, projects: [...access.projects] } : scope;
38
- };
39
- export const planningServiceOf = (ctx, opts) => ctx.service(opts?.service ?? PLANNING_SERVICE);
40
- /**
41
- * The facade a handler works through, and the access it was resolved under.
42
- *
43
- * Without `opts.access` it is exactly the request's scope plus what `opts.scope` derives. With it,
44
- * the resolver names the organization and the visible projects; a throw from the resolver is the
45
- * request's error.
46
- */
47
- export const handlerScopeOf = async (ctx, req, opts) => {
48
- const extra = await opts?.scope?.(req, ctx);
49
- if (opts?.access == null) {
50
- return { facade: planningServiceOf(ctx, opts).for(scopeOf(req, extra ?? undefined)) };
51
- }
52
- const access = await opts.access(req, ctx);
53
- return { facade: planningServiceOf(ctx, opts).for(accessScopeOf(req, access, extra ?? undefined)), access };
54
- };
55
- /** The facade a handler works through: the request's scope plus what `opts.scope` derives. */
56
- export const handlerFacade = async (ctx, req, opts) => (await handlerScopeOf(ctx, req, opts)).facade;
57
- /**
58
- * Refuse a write the access does not grant. No access, or access without `grants`, gates nothing;
59
- * a `grants` object refuses every flag it leaves out. `true` grants everything; a list grants the
60
- * project ids it names — `target` is the project the write is about (`undefined` for the
61
- * organization's root, which only `true` reaches).
62
- *
63
- * @throws {PlanningForbidden}
64
- */
65
- export const assertGranted = (access, grant, target) => {
66
- if (access?.grants == null) {
67
- return;
68
- }
69
- const granted = access.grants[grant];
70
- if (granted === true || (Array.isArray(granted) && target != null && granted.includes(target))) {
71
- return;
72
- }
73
- throw new PlanningForbidden(`${grant}:${target ?? 'root'}`);
74
- };
75
- /**
76
- * A card the access's `writes` admits — the rule a narrowed read admits, over `writes`: a project
77
- * it names, or a card whose `parents` name one. A specification is admitted through its parent card
78
- * by the caller. No `writes` admits everything.
79
- */
80
- export const writableIn = (access, card) => {
81
- const writes = access?.writes;
82
- if (writes == null) {
83
- return true;
84
- }
85
- return (card.id != null && writes.includes(card.id)) || card.parents.some(parent => writes.includes(parent));
86
- };
87
- /**
88
- * Refuse a write into a project the access's `writes` leaves out. No `writes` refuses nothing;
89
- * `target` is the project the write is in (`undefined` for the organization's root, which a set
90
- * `writes` never admits).
91
- *
92
- * @throws {PlanningForbidden}
93
- */
94
- export const assertWrites = (access, target) => {
95
- if (access?.writes == null || (target != null && access.writes.includes(target))) {
96
- return;
97
- }
98
- throw new PlanningForbidden(`writes:${target ?? 'root'}`);
99
- };
1
+ import { makePlanningAccessModel } from './access.js';
2
+ import { planningHandlerOf } from './handler.js';
3
+ import { makeRequestScope } from './request.js';
4
+ /** @deprecated compat:factory-refactor — use `makeRequestScope(req).actorOf()` */
5
+ export const actorOf = (req) => makeRequestScope(req).actorOf();
6
+ /** @deprecated compat:factory-refactor — use `makeRequestScope(req).scopeOf(…)` */
7
+ export const scopeOf = (req, extra) => makeRequestScope(req).scopeOf(extra);
8
+ /** @deprecated compat:factory-refactor — use `makeRequestScope(req).accessScopeOf(…)` */
9
+ export const accessScopeOf = (req, access, extra) => makeRequestScope(req).accessScopeOf(access, extra);
10
+ /** @deprecated compat:factory-refactor — use `planningHandlerOf(ctx).planningServiceOf(…)` */
11
+ export const planningServiceOf = (ctx, opts) => planningHandlerOf(ctx).planningServiceOf(opts);
12
+ /** @deprecated compat:factory-refactor — use `planningHandlerOf(ctx).handlerScopeOf(…)` */
13
+ export const handlerScopeOf = async (ctx, req, opts) => await planningHandlerOf(ctx).handlerScopeOf(req, opts);
14
+ /** @deprecated compat:factory-refactor — use `planningHandlerOf(ctx).handlerFacade(…)` */
15
+ export const handlerFacade = async (ctx, req, opts) => await planningHandlerOf(ctx).handlerFacade(req, opts);
16
+ /** @deprecated compat:factory-refactor — use `makePlanningAccessModel(access).assertGranted(…)` */
17
+ export const assertGranted = (access, grant, target) => makePlanningAccessModel(access).assertGranted(grant, target);
18
+ /** @deprecated compat:factory-refactor — use `makePlanningAccessModel(access).writableIn(…)` */
19
+ export const writableIn = (access, card) => makePlanningAccessModel(access).writableIn(card);
20
+ /** @deprecated compat:factory-refactor — use `makePlanningAccessModel(access).assertWrites(…)` */
21
+ export const assertWrites = (access, target) => makePlanningAccessModel(access).assertWrites(target);
100
22
  //# sourceMappingURL=scope.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/utils/scope.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/utils/scope.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAG/C,kFAAkF;AAClF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAoB,EAAmB,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAA;AAEjG,mFAAmF;AACnF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAoB,EAAE,KAA8B,EAAiB,EAAE,CAC7F,gBAAgB,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAEtC,yFAAyF;AACzF,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,GAAoB,EAAE,MAAsB,EAAE,KAA8B,EAC7D,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;AAEtE,8FAA8F;AAC9F,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,GAA8B,EAAE,IAA8C,EAC7D,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAA;AAEpE,2FAA2F;AAC3F,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EACjC,GAA8B,EAAE,GAAoB,EAAE,IAA6B,EAC5D,EAAE,CAAC,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;AAElF,0FAA0F;AAC1F,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,GAA8B,EAAE,GAAoB,EAAE,IAA6B,EAC1D,EAAE,CAAC,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;AAEnF,mGAAmG;AACnG,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,MAAkC,EAAE,KAAiC,EAAE,MAAe,EAChF,EAAE,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;AAEvE,gGAAgG;AAChG,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAAkC,EAAE,IAAsC,EAAW,EAAE,CAChH,uBAAuB,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;AAElD,kGAAkG;AAClG,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAkC,EAAE,MAAe,EAAQ,EAAE,CACxF,uBAAuB,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/server-planning",
3
- "version": "0.1.18-rc.21",
3
+ "version": "0.1.18-rc.23",
4
4
  "license": "MIT",
5
5
  "description": "The general planning implementation — the planning service and its plugin/middleware registry, the transition executor, the in-memory store, the protocol handlers and the commit feed.",
6
6
  "type": "module",
@@ -44,22 +44,22 @@
44
44
  }
45
45
  },
46
46
  "dependencies": {
47
- "@owlmeans/auth": "^0.1.18-rc.39",
48
- "@owlmeans/auth-common": "^0.1.18-rc.46",
49
- "@owlmeans/basic-ids": "^0.1.18-rc.36",
50
- "@owlmeans/context": "^0.1.18-rc.33",
51
- "@owlmeans/entrypoint": "^0.1.18-rc.40",
52
- "@owlmeans/error": "^0.1.18-rc.37",
53
- "@owlmeans/planning": "^0.1.18-rc.18",
54
- "@owlmeans/queue": "^0.1.18-rc.40",
55
- "@owlmeans/resource": "^0.1.18-rc.39",
56
- "@owlmeans/log": "^0.1.18-rc.1",
57
- "@owlmeans/route": "^0.1.18-rc.34",
58
- "@owlmeans/server-api": "^0.1.18-rc.50",
59
- "@owlmeans/server-context": "^0.1.18-rc.42",
60
- "@owlmeans/server-entrypoint": "^0.1.18-rc.39",
61
- "@owlmeans/server-socket": "^0.1.18-rc.53",
62
- "@owlmeans/socket": "^0.1.18-rc.39"
47
+ "@owlmeans/auth": "^0.1.18-rc.40",
48
+ "@owlmeans/auth-common": "^0.1.18-rc.48",
49
+ "@owlmeans/basic-ids": "^0.1.18-rc.38",
50
+ "@owlmeans/context": "^0.1.18-rc.34",
51
+ "@owlmeans/entrypoint": "^0.1.18-rc.41",
52
+ "@owlmeans/error": "^0.1.18-rc.38",
53
+ "@owlmeans/planning": "^0.1.18-rc.20",
54
+ "@owlmeans/queue": "^0.1.18-rc.42",
55
+ "@owlmeans/resource": "^0.1.18-rc.40",
56
+ "@owlmeans/log": "^0.1.18-rc.2",
57
+ "@owlmeans/route": "^0.1.18-rc.35",
58
+ "@owlmeans/server-api": "^0.1.18-rc.52",
59
+ "@owlmeans/server-context": "^0.1.18-rc.43",
60
+ "@owlmeans/server-entrypoint": "^0.1.18-rc.40",
61
+ "@owlmeans/server-socket": "^0.1.18-rc.55",
62
+ "@owlmeans/socket": "^0.1.18-rc.41"
63
63
  },
64
64
  "peerDependencies": {
65
65
  "ajv": "*",
@@ -67,7 +67,7 @@
67
67
  },
68
68
  "devDependencies": {
69
69
  "@owlmeans/dep-config": "workspace:*",
70
- "@owlmeans/test": "^0.1.18-rc.34",
70
+ "@owlmeans/test": "^0.1.18-rc.35",
71
71
  "@types/bun": "^1.4.2",
72
72
  "@types/node": "^26.6.4",
73
73
  "ajv": "^8.20.0",
@@ -0,0 +1,35 @@
1
+ import { SchemaWriteMode, type PlanningDefinitions, type SchemaDefineReply, type SchemaDefineRequest, type ScopedSchemaRecord } from '@owlmeans/planning'
2
+
3
+ /**
4
+ * Apply one `schema.define` request to a facade's definitions: the declarations in the request's
5
+ * mode (flows before types), then the retirements — answering what was written and the layer as it
6
+ * resolves afterwards.
7
+ */
8
+ export const applySchemaRequest = async (
9
+ definitions: PlanningDefinitions, request: SchemaDefineRequest
10
+ ): Promise<SchemaDefineReply> => {
11
+ const layer = request.project != null ? { project: request.project } : {}
12
+ const declarations = { types: request.types ?? [], flows: request.flows ?? [] }
13
+ const records: ScopedSchemaRecord[] = []
14
+
15
+ switch (request.mode ?? SchemaWriteMode.Define) {
16
+ case SchemaWriteMode.Put:
17
+ for (const flow of declarations.flows) {
18
+ records.push(await definitions.putFlow(flow, layer))
19
+ }
20
+ for (const type of declarations.types) {
21
+ records.push(await definitions.putType(type, layer))
22
+ }
23
+ break
24
+ case SchemaWriteMode.Seed:
25
+ records.push(...await definitions.seed(declarations, layer))
26
+ break
27
+ default:
28
+ records.push(...await definitions.define(declarations, layer))
29
+ }
30
+ for (const key of request.retire ?? []) {
31
+ records.push(await definitions.retire(key.kind, key.key, layer))
32
+ }
33
+
34
+ return { records, bundle: await definitions.bundle(request.project) }
35
+ }
@@ -2,7 +2,9 @@ import { handlers } from '@owlmeans/server-api'
2
2
  import { CommitState, MAX_COMMIT_POLL } from '@owlmeans/planning'
3
3
  import type { CommitStatus, PlanningProtocols } from '@owlmeans/planning'
4
4
  import type { Context, PlanningHandlerOptions } from '../types.js'
5
- import { clampSeconds, concealed, handlerFacade } from '../utils/index.js'
5
+ import { guardHelper } from '../utils/guard.js'
6
+ import { planningHandlerOf } from '../utils/handler.js'
7
+ import type { RequestHandler } from './types.js'
6
8
 
7
9
  /**
8
10
  * The poll tool: a commit's status, held open up to `wait` seconds (clamped to `maxPoll`).
@@ -15,13 +17,13 @@ import { clampSeconds, concealed, handlerFacade } from '../utils/index.js'
15
17
  */
16
18
  export const getCommit = (
17
19
  protocol: PlanningProtocols['commit']['get'], opts?: PlanningHandlerOptions
18
- ): ReturnType<ReturnType<typeof handlers<Context>>['request']> =>
19
- handlers<Context>().request(protocol, async (req, ctx) => concealed(async (): Promise<CommitStatus> => {
20
- const facade = await handlerFacade(ctx, req, opts)
20
+ ): RequestHandler =>
21
+ handlers<Context>().request(protocol, async (req, ctx) => guardHelper.concealed(async (): Promise<CommitStatus> => {
22
+ const facade = await planningHandlerOf(ctx).handlerFacade(req, opts)
21
23
  const transition = `${req.params.transition}`
22
24
 
23
25
  let status = await facade.commits.status(transition)
24
- const wait = clampSeconds(req.query?.wait, opts?.maxPoll ?? MAX_COMMIT_POLL)
26
+ const wait = guardHelper.clampSeconds(req.query?.wait, opts?.maxPoll ?? MAX_COMMIT_POLL)
25
27
  if (status.state !== CommitState.Pending || wait <= 0) {
26
28
  return status
27
29
  }
@@ -0,0 +1,34 @@
1
+ import { handlers } from '@owlmeans/server-api'
2
+ import { PlanningUnsupported, type PlanningProtocols, type SchemaDefineReply, type SchemaDefineRequest } from '@owlmeans/planning'
3
+ import type { Context, PlanningHandlerOptions } from '../types.js'
4
+ import { makePlanningAccessModel } from '../utils/access.js'
5
+ import { guardHelper } from '../utils/guard.js'
6
+ import { planningHandlerOf } from '../utils/handler.js'
7
+ import { applySchemaRequest } from './apply-schema-request.js'
8
+ import type { RequestHandler } from './types.js'
9
+
10
+ /**
11
+ * The write of data-defined types and flows. A project layer needs the project in the access's
12
+ * `writes` when the resolver answers it; then `grants.defineSchemas` gates when the resolver answers
13
+ * grants (the organization-wide layer needs `true`, a project layer its id).
14
+ *
15
+ * @throws {PlanningUnsupported} where the store holds no data-defined schemas
16
+ * @throws {PlanningForbidden | SchemaConflict | SchemaSealed | SchemaInvalid | SchemaInUse | WorkcardNotFound}
17
+ */
18
+ export const defineSchemas = (
19
+ protocol: NonNullable<PlanningProtocols['schema']['define']>, opts?: PlanningHandlerOptions
20
+ ): RequestHandler =>
21
+ handlers<Context>().request(protocol, async (req, ctx) => guardHelper.concealed(async (): Promise<SchemaDefineReply> => {
22
+ const { facade, access } = await planningHandlerOf(ctx).handlerScopeOf(req, opts)
23
+ const request = (req.body ?? {}) as SchemaDefineRequest
24
+ if (facade.definitions == null) {
25
+ throw new PlanningUnsupported('definitions')
26
+ }
27
+ const model = makePlanningAccessModel(access)
28
+ if (request.project != null) {
29
+ model.assertWrites(request.project)
30
+ }
31
+ model.assertGranted('defineSchemas', request.project)
32
+
33
+ return await applySchemaRequest(facade.definitions, request)
34
+ }))
@@ -1,130 +1,45 @@
1
1
  import { handlers } from '@owlmeans/server-api'
2
- import {
3
- DEFAULT_COMMIT_TIMEOUT, isProject, isSpecification, MAX_COMMIT_POLL, normalizeParents, PlanningForbidden,
4
- TransitionAction, WorkcardKind,
5
- } from '@owlmeans/planning'
2
+ import { MAX_COMMIT_POLL } from '@owlmeans/planning'
6
3
  import type {
7
4
  ExecuteOptions, ExecuteRequest, PlanningFacade, PlanningProtocols, PlanningScope, TransitionExecution,
8
- TransitionReceiptView, Workcard,
5
+ TransitionReceiptView,
9
6
  } from '@owlmeans/planning'
10
- import { withCreator } from '../executor/creator.js'
11
7
  import type { Context, PlanningAccess, PlanningHandlerOptions } from '../types.js'
12
- import { assertGranted, concealed, handlerScopeOf, writableIn } from '../utils/index.js'
13
-
14
- /**
15
- * What a wire execution may say. `actor` is dropped — the scope names the writer — and a create's
16
- * `createdBy` claim is dropped too: the executor's {@link withCreator} stamps the authenticated
17
- * subject, the same rule an in-process create follows. Applied here as well, so the returned
18
- * execution already carries it. A `createdBy` in `changes` or `unset` is not dropped: the executor
19
- * refuses it on every action (`assertCreatorFixed`), so no body moves an owner.
20
- */
21
- export const wireExecution = (body: ExecuteRequest, scope: PlanningScope): TransitionExecution => {
22
- const { wait: _wait, timeout: _timeout, actor: _actor, ...exec } = body
23
- if (exec.action === TransitionAction.Create && exec.card != null && typeof exec.card === 'object') {
24
- const { createdBy: _createdBy, ...draft } = exec.card
25
- exec.card = draft
26
- }
27
- return withCreator(exec, scope)
28
- }
29
-
30
- /** `wait`/`timeout` as a server grants them: the timeout never holds a request past `maxPoll`. */
31
- export const executeOptionsOf = (body: Pick<ExecuteRequest, 'wait' | 'timeout'>, maxPoll: number): ExecuteOptions => {
32
- const ceiling = maxPoll * 1000
33
- if (body.wait !== true) {
34
- return {}
35
- }
36
- const asked = Number(body.timeout ?? DEFAULT_COMMIT_TIMEOUT)
37
- return { wait: true, timeout: Math.min(Number.isFinite(asked) && asked > 0 ? asked : DEFAULT_COMMIT_TIMEOUT, ceiling) }
38
- }
39
-
40
- /**
41
- * Refuse an execution outside the access's `writes`: the card it acts on (a specification through
42
- * its parent card), or every parent a create names, must be one {@link writableIn} admits. A create
43
- * of a project is `grants.createProjects`' alone. A card or parent this scope cannot see is left to
44
- * the executor, which answers it as absent.
45
- *
46
- * @throws {PlanningForbidden}
47
- */
48
- export const assertExecutionWrites = async (
49
- facade: PlanningFacade, exec: TransitionExecution, access?: PlanningAccess
50
- ): Promise<void> => {
51
- if (access?.writes == null) {
52
- return
53
- }
54
- const admitted = async (card: Workcard): Promise<boolean> => {
55
- if (writableIn(access, card)) {
56
- return true
57
- }
58
- if (!isSpecification(card) || card.parent == null) {
59
- return false
60
- }
61
- const parent = await facade.cards.load(card.parent)
62
- return parent == null || writableIn(access, parent)
63
- }
64
-
65
- if (exec.action === TransitionAction.Create && exec.card != null && typeof exec.card === 'object') {
66
- if (exec.card.kind === WorkcardKind.Project) {
67
- return
68
- }
69
- const parents = normalizeParents(exec.card.parent, exec.card.parents)
70
- if (parents.length === 0) {
71
- throw new PlanningForbidden('writes:root')
72
- }
73
- for (const id of parents) {
74
- const parent = await facade.cards.load(id)
75
- if (parent != null && !await admitted(parent)) {
76
- throw new PlanningForbidden(`writes:${id}`)
77
- }
78
- }
79
- return
80
- }
81
- if (typeof exec.card === 'string' && exec.card !== '') {
82
- const card = await facade.cards.load(exec.card)
83
- if (card != null && !await admitted(card)) {
84
- throw new PlanningForbidden(`writes:${exec.card}`)
85
- }
86
- }
87
- }
88
-
89
- /**
90
- * The access a wire execution needs. `writes` first ({@link assertExecutionWrites}); then the
91
- * grants: `createProjects` for a project create (its primary parent, or the root),
92
- * `deleteProjects` for the delete of a project card. A card this scope cannot see is left to the
93
- * executor, which answers it as absent.
94
- *
95
- * @throws {PlanningForbidden}
96
- */
97
- export const assertExecutionGranted = async (
98
- facade: PlanningFacade, exec: TransitionExecution, access?: PlanningAccess
99
- ): Promise<void> => {
100
- await assertExecutionWrites(facade, exec, access)
101
- if (access?.grants == null) {
102
- return
103
- }
104
- if (exec.action === TransitionAction.Create && typeof exec.card === 'object' && exec.card?.kind === WorkcardKind.Project) {
105
- assertGranted(access, 'createProjects', normalizeParents(exec.card.parent, exec.card.parents)[0])
106
- return
107
- }
108
- if (exec.action === TransitionAction.Delete && typeof exec.card === 'string') {
109
- const card = await facade.cards.load(exec.card)
110
- if (card != null && isProject(card)) {
111
- assertGranted(access, 'deleteProjects', card.id)
112
- }
113
- }
114
- }
8
+ import { guardHelper } from '../utils/guard.js'
9
+ import { planningHandlerOf } from '../utils/handler.js'
10
+ import { executionHelper } from './execution.js'
11
+ import type { RequestHandler } from './types.js'
115
12
 
116
13
  /** The one write route. */
117
14
  export const executePlanning = (
118
15
  protocol: PlanningProtocols['execute'], opts?: PlanningHandlerOptions
119
- ): ReturnType<ReturnType<typeof handlers<Context>>['request']> =>
120
- handlers<Context>().request(protocol, async (req, ctx) => concealed(async (): Promise<TransitionReceiptView> => {
121
- const { facade, access } = await handlerScopeOf(ctx, req, opts)
16
+ ): RequestHandler =>
17
+ handlers<Context>().request(protocol, async (req, ctx) => guardHelper.concealed(async (): Promise<TransitionReceiptView> => {
18
+ const { facade, access } = await planningHandlerOf(ctx).handlerScopeOf(req, opts)
122
19
  const body = (req.body ?? {}) as ExecuteRequest
123
- const exec = wireExecution(body, facade.scope)
124
- await assertExecutionGranted(facade, exec, access)
125
- const receipt = await facade.execute(exec, executeOptionsOf(body, opts?.maxPoll ?? MAX_COMMIT_POLL))
20
+ const exec = executionHelper.wireExecution(body, facade.scope)
21
+ await executionHelper.assertExecutionGranted(facade, exec, access)
22
+ const receipt = await facade.execute(exec, executionHelper.executeOptionsOf(body, opts?.maxPoll ?? MAX_COMMIT_POLL))
126
23
 
127
24
  return receipt.card !== undefined
128
25
  ? { transition: receipt.transition, card: receipt.card }
129
26
  : { transition: receipt.transition }
130
27
  }))
28
+
29
+ /** @deprecated compat:factory-refactor — use `executionHelper.wireExecution(…)` */
30
+ export const wireExecution = (body: ExecuteRequest, scope: PlanningScope): TransitionExecution =>
31
+ executionHelper.wireExecution(body, scope)
32
+
33
+ /** @deprecated compat:factory-refactor — use `executionHelper.executeOptionsOf(…)` */
34
+ export const executeOptionsOf = (body: Pick<ExecuteRequest, 'wait' | 'timeout'>, maxPoll: number): ExecuteOptions =>
35
+ executionHelper.executeOptionsOf(body, maxPoll)
36
+
37
+ /** @deprecated compat:factory-refactor — use `executionHelper.assertExecutionWrites(…)` */
38
+ export const assertExecutionWrites = async (
39
+ facade: PlanningFacade, exec: TransitionExecution, access?: PlanningAccess
40
+ ): Promise<void> => await executionHelper.assertExecutionWrites(facade, exec, access)
41
+
42
+ /** @deprecated compat:factory-refactor — use `executionHelper.assertExecutionGranted(…)` */
43
+ export const assertExecutionGranted = async (
44
+ facade: PlanningFacade, exec: TransitionExecution, access?: PlanningAccess
45
+ ): Promise<void> => await executionHelper.assertExecutionGranted(facade, exec, access)
@@ -0,0 +1,34 @@
1
+ import type { ExecuteOptions, ExecuteRequest, PlanningFacade, PlanningScope, TransitionExecution } from '@owlmeans/planning'
2
+ import type { PlanningAccess } from '../../types.js'
3
+
4
+ /** What a wire execution may say, how long it may hold, and what access it needs. */
5
+ export interface ExecutionHelper {
6
+ /**
7
+ * What a wire execution may say. `actor` is dropped — the scope names the writer — and a create's
8
+ * `createdBy` claim is dropped too: the executor's `creatorHelper.withCreator` stamps the
9
+ * authenticated subject, the same rule an in-process create follows. Applied here as well, so the
10
+ * returned execution already carries it. A `createdBy` in `changes` or `unset` is not dropped: the
11
+ * executor refuses it on every action (`assertCreatorFixed`), so no body moves an owner.
12
+ */
13
+ wireExecution: (body: ExecuteRequest, scope: PlanningScope) => TransitionExecution
14
+ /** `wait`/`timeout` as a server grants them: the timeout never holds a request past `maxPoll`. */
15
+ executeOptionsOf: (body: Pick<ExecuteRequest, 'wait' | 'timeout'>, maxPoll: number) => ExecuteOptions
16
+ /**
17
+ * Refuse an execution outside the access's `writes`: the card it acts on (a specification through
18
+ * its parent card), or every parent a create names, must be one `writableIn` admits. A create
19
+ * of a project is `grants.createProjects`' alone. A card or parent this scope cannot see is left to
20
+ * the executor, which answers it as absent.
21
+ *
22
+ * @throws {PlanningForbidden}
23
+ */
24
+ assertExecutionWrites: (facade: PlanningFacade, exec: TransitionExecution, access?: PlanningAccess) => Promise<void>
25
+ /**
26
+ * The access a wire execution needs. `writes` first ({@link ExecutionHelper.assertExecutionWrites});
27
+ * then the grants: `createProjects` for a project create (its primary parent, or the root),
28
+ * `deleteProjects` for the delete of a project card. A card this scope cannot see is left to the
29
+ * executor, which answers it as absent.
30
+ *
31
+ * @throws {PlanningForbidden}
32
+ */
33
+ assertExecutionGranted: (facade: PlanningFacade, exec: TransitionExecution, access?: PlanningAccess) => Promise<void>
34
+ }