@owlmeans/planning 0.1.18-rc.0 → 0.1.18-rc.1
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 +2 -2
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/planning/SKILL.md +24 -15
- package/build/errors.d.ts +30 -0
- package/build/errors.d.ts.map +1 -1
- package/build/errors.js +30 -0
- package/build/errors.js.map +1 -1
- package/package.json +10 -10
- package/src/errors.ts +30 -0
- package/tests/error-status.spec.ts +55 -0
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ the executor with `@owlmeans/server-planning` and reads remotely with `@owlmeans
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
|
-
bun add @owlmeans/planning@^0.1.18-rc.
|
|
12
|
+
bun add @owlmeans/planning@^0.1.18-rc.1 ajv ajv-formats
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Concepts
|
|
@@ -160,7 +160,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
160
160
|
your project's skill store (`.agents/skills/`):
|
|
161
161
|
|
|
162
162
|
```sh
|
|
163
|
-
npx @owlmeans/agent-skills@^0.1.18-rc.
|
|
163
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.28
|
|
164
164
|
```
|
|
165
165
|
|
|
166
166
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/planning",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-09-
|
|
4
|
+
"version": "0.1.18-rc.1",
|
|
5
|
+
"generatedAt": "2026-09-17T08:16:11.225Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -8,7 +8,7 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/planning
|
|
9
9
|
|
|
10
10
|
**Layer:** Cross-cutting domain
|
|
11
|
-
**Install:** `"@owlmeans/planning": "^0.1.18-rc.
|
|
11
|
+
**Install:** `"@owlmeans/planning": "^0.1.18-rc.1"` in `dependencies` (`ajv` and `ajv-formats` are peers)
|
|
12
12
|
|
|
13
13
|
The contracts of project planning: record shapes, schemas, refusals, the protocol tree, the pure
|
|
14
14
|
fold and the models. No database, no fastify, no React. The executor, the plugin registry, the
|
|
@@ -202,23 +202,32 @@ by kind) is the same object on a server and in a browser. `schema`, `flow`, `sta
|
|
|
202
202
|
Every refusal is a registered `ResilientError` whose message is `planning:<marker>:<detail>` —
|
|
203
203
|
the marker survives a hop where the class is unknown, so match on it there:
|
|
204
204
|
|
|
205
|
-
| Class | Marker |
|
|
206
|
-
|
|
207
|
-
| `PlanningError` | `planning:` (`fold:out-of-order`, `immutable:<field>`, `malformed:<what>`) |
|
|
208
|
-
| `WorkcardNotFound` | `workcard-not-found:` — also the answer for another entity's card |
|
|
209
|
-
| `UnknownWorkcardType` / `UnknownStatusFlow` | `unknown-type:` / `unknown-flow:` |
|
|
210
|
-
| `ParentNotFound` / `CardTypeNotAllowed` | `parent-not-found:` / `card-type-not-allowed:` |
|
|
211
|
-
| `PlanningRefused` | `refused:` — a plugin middleware said no |
|
|
212
|
-
| `IllegalTransition` | `illegal-transition:<flow>:<transition>:<from>` |
|
|
213
|
-
| `FieldsInvalid` / `LabelNotAllowed` | `fields-invalid:` / `label-not-allowed:` |
|
|
214
|
-
| `SpecificationSlotUnknown` / `SpecificationRevisionConflict` | `specification-slot-unknown:` / `specification-revision-conflict:` |
|
|
215
|
-
| `RelationshipRefused` / `CodeTaken` | `relationship-refused:` / `code-taken:` |
|
|
216
|
-
| `WorkcardConflict` | `workcard-conflict:` — stale `expectSeq` |
|
|
217
|
-
| `CommitTimeout` / `CommitFailed` | `commit-timeout:` (still pending, nothing undone) / `commit-failed:` |
|
|
218
|
-
| `PlanningScopeMismatch` / `PlanningUnsupported` | `scope-mismatch:` / `unsupported:` |
|
|
205
|
+
| Class | Marker | HTTP |
|
|
206
|
+
|---|---|---|
|
|
207
|
+
| `PlanningError` | `planning:` (`fold:out-of-order`, `immutable:<field>`, `malformed:<what>`) | 500 |
|
|
208
|
+
| `WorkcardNotFound` | `workcard-not-found:` — also the answer for another entity's card | 404 |
|
|
209
|
+
| `UnknownWorkcardType` / `UnknownStatusFlow` | `unknown-type:` / `unknown-flow:` | 422 |
|
|
210
|
+
| `ParentNotFound` / `CardTypeNotAllowed` | `parent-not-found:` / `card-type-not-allowed:` | 422 |
|
|
211
|
+
| `PlanningRefused` | `refused:` — a plugin middleware said no | 422 |
|
|
212
|
+
| `IllegalTransition` | `illegal-transition:<flow>:<transition>:<from>` | 409 |
|
|
213
|
+
| `FieldsInvalid` / `LabelNotAllowed` | `fields-invalid:` / `label-not-allowed:` | 422 |
|
|
214
|
+
| `SpecificationSlotUnknown` / `SpecificationRevisionConflict` | `specification-slot-unknown:` / `specification-revision-conflict:` | 422 / 409 |
|
|
215
|
+
| `RelationshipRefused` / `CodeTaken` | `relationship-refused:` / `code-taken:` | 422 / 409 |
|
|
216
|
+
| `WorkcardConflict` | `workcard-conflict:` — stale `expectSeq` | 409 |
|
|
217
|
+
| `CommitTimeout` / `CommitFailed` | `commit-timeout:` (still pending, nothing undone) / `commit-failed:` | 500 |
|
|
218
|
+
| `PlanningScopeMismatch` / `PlanningUnsupported` | `scope-mismatch:` / `unsupported:` | 404 / 500 |
|
|
219
219
|
|
|
220
220
|
Type names are `PlanningError<Suffix>` (`PlanningErrorWorkcardNotFound`).
|
|
221
221
|
|
|
222
|
+
**The HTTP column is each class's `static httpStatus`** (the `error` skill's principle; 500 = none
|
|
223
|
+
declared): an addressed card that is absent or another entity's is 404, a card whose state or head
|
|
224
|
+
refuses the write is 409, a body naming what the registry, the parent or a schema refuses is 422.
|
|
225
|
+
Faults declare nothing, and so does `PlanningError` itself — its three causes share one class, and
|
|
226
|
+
a base's static would reach every subclass. A new refusal declares on its own leaf class, and
|
|
227
|
+
`tests/error-status.spec.ts` refuses an exported refusal whose status was not decided. A plugin's
|
|
228
|
+
plain `throw` inside `before` becomes `PlanningRefused` and answers 422, so a plugin FAULT must
|
|
229
|
+
throw a `ResilientError` that declares nothing.
|
|
230
|
+
|
|
222
231
|
## i18n
|
|
223
232
|
|
|
224
233
|
Importing the package registers, in all seven languages, `lib:planning.*` labels (`kind.*`,
|
package/build/errors.d.ts
CHANGED
|
@@ -13,63 +13,91 @@ export declare class PlanningError extends ResilientError {
|
|
|
13
13
|
/** The card does not exist — or belongs to another entity, which is deliberately the same answer. */
|
|
14
14
|
export declare class WorkcardNotFound extends PlanningError {
|
|
15
15
|
static typeName: string;
|
|
16
|
+
/** The addressed card is absent or another entity's: answered 404. */
|
|
17
|
+
static httpStatus: number;
|
|
16
18
|
constructor(message?: string);
|
|
17
19
|
}
|
|
18
20
|
export declare class UnknownWorkcardType extends PlanningError {
|
|
19
21
|
static typeName: string;
|
|
22
|
+
/** The execution names a type the registry does not declare: answered 422. */
|
|
23
|
+
static httpStatus: number;
|
|
20
24
|
constructor(message?: string);
|
|
21
25
|
}
|
|
22
26
|
export declare class UnknownStatusFlow extends PlanningError {
|
|
23
27
|
static typeName: string;
|
|
28
|
+
/** The execution names a flow the type does not run: answered 422. */
|
|
29
|
+
static httpStatus: number;
|
|
24
30
|
constructor(message?: string);
|
|
25
31
|
}
|
|
26
32
|
export declare class ParentNotFound extends PlanningError {
|
|
27
33
|
static typeName: string;
|
|
34
|
+
/** A parent the body references does not resolve: answered 422. */
|
|
35
|
+
static httpStatus: number;
|
|
28
36
|
constructor(message?: string);
|
|
29
37
|
}
|
|
30
38
|
/** The parent project's type does not list this card (or project) type. */
|
|
31
39
|
export declare class CardTypeNotAllowed extends PlanningError {
|
|
32
40
|
static typeName: string;
|
|
41
|
+
/** The parent refuses a child of this type: answered 422. */
|
|
42
|
+
static httpStatus: number;
|
|
33
43
|
constructor(message?: string);
|
|
34
44
|
}
|
|
35
45
|
/** A plugin's `before` middleware refused the execution without a class of its own. */
|
|
36
46
|
export declare class PlanningRefused extends PlanningError {
|
|
37
47
|
static typeName: string;
|
|
48
|
+
/** A plugin refused what was submitted: answered 422. */
|
|
49
|
+
static httpStatus: number;
|
|
38
50
|
constructor(message?: string);
|
|
39
51
|
}
|
|
40
52
|
/** The flow offers no rule of that name from the card's current status. */
|
|
41
53
|
export declare class IllegalTransition extends PlanningError {
|
|
42
54
|
static typeName: string;
|
|
55
|
+
/** The card's current status offers no such rule: answered 409. */
|
|
56
|
+
static httpStatus: number;
|
|
43
57
|
constructor(message?: string);
|
|
44
58
|
}
|
|
45
59
|
export declare class FieldsInvalid extends PlanningError {
|
|
46
60
|
static typeName: string;
|
|
61
|
+
/** The submitted fields fail the type's schema: answered 422. */
|
|
62
|
+
static httpStatus: number;
|
|
47
63
|
constructor(message?: string);
|
|
48
64
|
}
|
|
49
65
|
export declare class LabelNotAllowed extends PlanningError {
|
|
50
66
|
static typeName: string;
|
|
67
|
+
/** The submitted label is refused: answered 422. */
|
|
68
|
+
static httpStatus: number;
|
|
51
69
|
constructor(message?: string);
|
|
52
70
|
}
|
|
53
71
|
export declare class SpecificationSlotUnknown extends PlanningError {
|
|
54
72
|
static typeName: string;
|
|
73
|
+
/** The body names a slot the parent type does not declare: answered 422. */
|
|
74
|
+
static httpStatus: number;
|
|
55
75
|
constructor(message?: string);
|
|
56
76
|
}
|
|
57
77
|
/** A second document for a slot that holds one — revise the existing record instead. */
|
|
58
78
|
export declare class SpecificationRevisionConflict extends PlanningError {
|
|
59
79
|
static typeName: string;
|
|
80
|
+
/** The slot already holds its document: answered 409. */
|
|
81
|
+
static httpStatus: number;
|
|
60
82
|
constructor(message?: string);
|
|
61
83
|
}
|
|
62
84
|
export declare class RelationshipRefused extends PlanningError {
|
|
63
85
|
static typeName: string;
|
|
86
|
+
/** The submitted link is refused: answered 422. */
|
|
87
|
+
static httpStatus: number;
|
|
64
88
|
constructor(message?: string);
|
|
65
89
|
}
|
|
66
90
|
export declare class CodeTaken extends PlanningError {
|
|
67
91
|
static typeName: string;
|
|
92
|
+
/** Another card holds the code: answered 409. */
|
|
93
|
+
static httpStatus: number;
|
|
68
94
|
constructor(message?: string);
|
|
69
95
|
}
|
|
70
96
|
/** `expectSeq` no longer matches the card's head — somebody else wrote first. Re-read and retry. */
|
|
71
97
|
export declare class WorkcardConflict extends PlanningError {
|
|
72
98
|
static typeName: string;
|
|
99
|
+
/** The card moved past the expected head: answered 409. */
|
|
100
|
+
static httpStatus: number;
|
|
73
101
|
constructor(message?: string);
|
|
74
102
|
}
|
|
75
103
|
/** The transition was appended but did not commit in time. It stays pending — nothing is undone. */
|
|
@@ -84,6 +112,8 @@ export declare class CommitFailed extends PlanningError {
|
|
|
84
112
|
/** A card of another entity was addressed. Handlers answer it as {@link WorkcardNotFound}. */
|
|
85
113
|
export declare class PlanningScopeMismatch extends PlanningError {
|
|
86
114
|
static typeName: string;
|
|
115
|
+
/** Another entity's card, answered as absent: answered 404. */
|
|
116
|
+
static httpStatus: number;
|
|
87
117
|
constructor(message?: string);
|
|
88
118
|
}
|
|
89
119
|
/** The store behind this type cannot do what was asked (a foreign provider without a log). */
|
package/build/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD;;;;;;GAMG;AACH,qBAAa,aAAc,SAAQ,cAAc;IAC/C,OAAuB,QAAQ,EAAE,MAAM,CAAkB;IAEzD,YAAY,OAAO,GAAE,MAAgB,EAEpC;CACF;AAED,qGAAqG;AACrG,qBAAa,gBAAiB,SAAQ,aAAa;IACjD,OAAuB,QAAQ,EAAE,MAAM,CAA8C;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/build/errors.js
CHANGED
|
@@ -15,6 +15,8 @@ export class PlanningError extends ResilientError {
|
|
|
15
15
|
/** The card does not exist — or belongs to another entity, which is deliberately the same answer. */
|
|
16
16
|
export class WorkcardNotFound extends PlanningError {
|
|
17
17
|
static typeName = `${PlanningError.typeName}WorkcardNotFound`;
|
|
18
|
+
/** The addressed card is absent or another entity's: answered 404. */
|
|
19
|
+
static httpStatus = 404;
|
|
18
20
|
constructor(message = 'error') {
|
|
19
21
|
super(`workcard-not-found:${message}`);
|
|
20
22
|
this.type = WorkcardNotFound.typeName;
|
|
@@ -22,6 +24,8 @@ export class WorkcardNotFound extends PlanningError {
|
|
|
22
24
|
}
|
|
23
25
|
export class UnknownWorkcardType extends PlanningError {
|
|
24
26
|
static typeName = `${PlanningError.typeName}UnknownWorkcardType`;
|
|
27
|
+
/** The execution names a type the registry does not declare: answered 422. */
|
|
28
|
+
static httpStatus = 422;
|
|
25
29
|
constructor(message = 'error') {
|
|
26
30
|
super(`unknown-type:${message}`);
|
|
27
31
|
this.type = UnknownWorkcardType.typeName;
|
|
@@ -29,6 +33,8 @@ export class UnknownWorkcardType extends PlanningError {
|
|
|
29
33
|
}
|
|
30
34
|
export class UnknownStatusFlow extends PlanningError {
|
|
31
35
|
static typeName = `${PlanningError.typeName}UnknownStatusFlow`;
|
|
36
|
+
/** The execution names a flow the type does not run: answered 422. */
|
|
37
|
+
static httpStatus = 422;
|
|
32
38
|
constructor(message = 'error') {
|
|
33
39
|
super(`unknown-flow:${message}`);
|
|
34
40
|
this.type = UnknownStatusFlow.typeName;
|
|
@@ -36,6 +42,8 @@ export class UnknownStatusFlow extends PlanningError {
|
|
|
36
42
|
}
|
|
37
43
|
export class ParentNotFound extends PlanningError {
|
|
38
44
|
static typeName = `${PlanningError.typeName}ParentNotFound`;
|
|
45
|
+
/** A parent the body references does not resolve: answered 422. */
|
|
46
|
+
static httpStatus = 422;
|
|
39
47
|
constructor(message = 'error') {
|
|
40
48
|
super(`parent-not-found:${message}`);
|
|
41
49
|
this.type = ParentNotFound.typeName;
|
|
@@ -44,6 +52,8 @@ export class ParentNotFound extends PlanningError {
|
|
|
44
52
|
/** The parent project's type does not list this card (or project) type. */
|
|
45
53
|
export class CardTypeNotAllowed extends PlanningError {
|
|
46
54
|
static typeName = `${PlanningError.typeName}CardTypeNotAllowed`;
|
|
55
|
+
/** The parent refuses a child of this type: answered 422. */
|
|
56
|
+
static httpStatus = 422;
|
|
47
57
|
constructor(message = 'error') {
|
|
48
58
|
super(`card-type-not-allowed:${message}`);
|
|
49
59
|
this.type = CardTypeNotAllowed.typeName;
|
|
@@ -52,6 +62,8 @@ export class CardTypeNotAllowed extends PlanningError {
|
|
|
52
62
|
/** A plugin's `before` middleware refused the execution without a class of its own. */
|
|
53
63
|
export class PlanningRefused extends PlanningError {
|
|
54
64
|
static typeName = `${PlanningError.typeName}Refused`;
|
|
65
|
+
/** A plugin refused what was submitted: answered 422. */
|
|
66
|
+
static httpStatus = 422;
|
|
55
67
|
constructor(message = 'error') {
|
|
56
68
|
super(`refused:${message}`);
|
|
57
69
|
this.type = PlanningRefused.typeName;
|
|
@@ -60,6 +72,8 @@ export class PlanningRefused extends PlanningError {
|
|
|
60
72
|
/** The flow offers no rule of that name from the card's current status. */
|
|
61
73
|
export class IllegalTransition extends PlanningError {
|
|
62
74
|
static typeName = `${PlanningError.typeName}IllegalTransition`;
|
|
75
|
+
/** The card's current status offers no such rule: answered 409. */
|
|
76
|
+
static httpStatus = 409;
|
|
63
77
|
constructor(message = 'error') {
|
|
64
78
|
super(`illegal-transition:${message}`);
|
|
65
79
|
this.type = IllegalTransition.typeName;
|
|
@@ -67,6 +81,8 @@ export class IllegalTransition extends PlanningError {
|
|
|
67
81
|
}
|
|
68
82
|
export class FieldsInvalid extends PlanningError {
|
|
69
83
|
static typeName = `${PlanningError.typeName}FieldsInvalid`;
|
|
84
|
+
/** The submitted fields fail the type's schema: answered 422. */
|
|
85
|
+
static httpStatus = 422;
|
|
70
86
|
constructor(message = 'error') {
|
|
71
87
|
super(`fields-invalid:${message}`);
|
|
72
88
|
this.type = FieldsInvalid.typeName;
|
|
@@ -74,6 +90,8 @@ export class FieldsInvalid extends PlanningError {
|
|
|
74
90
|
}
|
|
75
91
|
export class LabelNotAllowed extends PlanningError {
|
|
76
92
|
static typeName = `${PlanningError.typeName}LabelNotAllowed`;
|
|
93
|
+
/** The submitted label is refused: answered 422. */
|
|
94
|
+
static httpStatus = 422;
|
|
77
95
|
constructor(message = 'error') {
|
|
78
96
|
super(`label-not-allowed:${message}`);
|
|
79
97
|
this.type = LabelNotAllowed.typeName;
|
|
@@ -81,6 +99,8 @@ export class LabelNotAllowed extends PlanningError {
|
|
|
81
99
|
}
|
|
82
100
|
export class SpecificationSlotUnknown extends PlanningError {
|
|
83
101
|
static typeName = `${PlanningError.typeName}SpecificationSlotUnknown`;
|
|
102
|
+
/** The body names a slot the parent type does not declare: answered 422. */
|
|
103
|
+
static httpStatus = 422;
|
|
84
104
|
constructor(message = 'error') {
|
|
85
105
|
super(`specification-slot-unknown:${message}`);
|
|
86
106
|
this.type = SpecificationSlotUnknown.typeName;
|
|
@@ -89,6 +109,8 @@ export class SpecificationSlotUnknown extends PlanningError {
|
|
|
89
109
|
/** A second document for a slot that holds one — revise the existing record instead. */
|
|
90
110
|
export class SpecificationRevisionConflict extends PlanningError {
|
|
91
111
|
static typeName = `${PlanningError.typeName}SpecificationRevisionConflict`;
|
|
112
|
+
/** The slot already holds its document: answered 409. */
|
|
113
|
+
static httpStatus = 409;
|
|
92
114
|
constructor(message = 'error') {
|
|
93
115
|
super(`specification-revision-conflict:${message}`);
|
|
94
116
|
this.type = SpecificationRevisionConflict.typeName;
|
|
@@ -96,6 +118,8 @@ export class SpecificationRevisionConflict extends PlanningError {
|
|
|
96
118
|
}
|
|
97
119
|
export class RelationshipRefused extends PlanningError {
|
|
98
120
|
static typeName = `${PlanningError.typeName}RelationshipRefused`;
|
|
121
|
+
/** The submitted link is refused: answered 422. */
|
|
122
|
+
static httpStatus = 422;
|
|
99
123
|
constructor(message = 'error') {
|
|
100
124
|
super(`relationship-refused:${message}`);
|
|
101
125
|
this.type = RelationshipRefused.typeName;
|
|
@@ -103,6 +127,8 @@ export class RelationshipRefused extends PlanningError {
|
|
|
103
127
|
}
|
|
104
128
|
export class CodeTaken extends PlanningError {
|
|
105
129
|
static typeName = `${PlanningError.typeName}CodeTaken`;
|
|
130
|
+
/** Another card holds the code: answered 409. */
|
|
131
|
+
static httpStatus = 409;
|
|
106
132
|
constructor(message = 'error') {
|
|
107
133
|
super(`code-taken:${message}`);
|
|
108
134
|
this.type = CodeTaken.typeName;
|
|
@@ -111,6 +137,8 @@ export class CodeTaken extends PlanningError {
|
|
|
111
137
|
/** `expectSeq` no longer matches the card's head — somebody else wrote first. Re-read and retry. */
|
|
112
138
|
export class WorkcardConflict extends PlanningError {
|
|
113
139
|
static typeName = `${PlanningError.typeName}WorkcardConflict`;
|
|
140
|
+
/** The card moved past the expected head: answered 409. */
|
|
141
|
+
static httpStatus = 409;
|
|
114
142
|
constructor(message = 'error') {
|
|
115
143
|
super(`workcard-conflict:${message}`);
|
|
116
144
|
this.type = WorkcardConflict.typeName;
|
|
@@ -134,6 +162,8 @@ export class CommitFailed extends PlanningError {
|
|
|
134
162
|
/** A card of another entity was addressed. Handlers answer it as {@link WorkcardNotFound}. */
|
|
135
163
|
export class PlanningScopeMismatch extends PlanningError {
|
|
136
164
|
static typeName = `${PlanningError.typeName}ScopeMismatch`;
|
|
165
|
+
/** Another entity's card, answered as absent: answered 404. */
|
|
166
|
+
static httpStatus = 404;
|
|
137
167
|
constructor(message = 'error') {
|
|
138
168
|
super(`scope-mismatch:${message}`);
|
|
139
169
|
this.type = PlanningScopeMismatch.typeName;
|
package/build/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD;;;;;;GAMG;AACH,MAAM,OAAO,aAAc,SAAQ,cAAc;IACxC,MAAM,CAAU,QAAQ,GAAW,eAAe,CAAA;IAEzD,YAAY,OAAO,GAAW,OAAO;QACnC,KAAK,CAAC,aAAa,CAAC,QAAQ,EAAE,YAAY,OAAO,EAAE,CAAC,CAAA;IACtD,CAAC;CACF;AAED,qGAAqG;AACrG,MAAM,OAAO,gBAAiB,SAAQ,aAAa;IAC1C,MAAM,CAAU,QAAQ,GAAW,GAAG,aAAa,CAAC,QAAQ,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/planning",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Runtime-free project-planning contracts — the workcard super type, projects, specifications, typed relationships, status flows with three intrinsic states, the transition event and its pure fold, the schema registry, the models and the protocol tree.",
|
|
6
6
|
"type": "module",
|
|
@@ -30,15 +30,15 @@
|
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
34
|
-
"@owlmeans/basic-ids": "^0.1.18-rc.
|
|
35
|
-
"@owlmeans/context": "^0.1.18-rc.
|
|
36
|
-
"@owlmeans/entrypoint": "^0.1.18-rc.
|
|
37
|
-
"@owlmeans/error": "^0.1.18-rc.
|
|
38
|
-
"@owlmeans/i18n": "^0.1.18-rc.
|
|
39
|
-
"@owlmeans/queue": "^0.1.18-rc.
|
|
40
|
-
"@owlmeans/resource": "^0.1.18-rc.
|
|
41
|
-
"@owlmeans/route": "^0.1.18-rc.
|
|
33
|
+
"@owlmeans/auth": "^0.1.18-rc.27",
|
|
34
|
+
"@owlmeans/basic-ids": "^0.1.18-rc.26",
|
|
35
|
+
"@owlmeans/context": "^0.1.18-rc.25",
|
|
36
|
+
"@owlmeans/entrypoint": "^0.1.18-rc.28",
|
|
37
|
+
"@owlmeans/error": "^0.1.18-rc.27",
|
|
38
|
+
"@owlmeans/i18n": "^0.1.18-rc.28",
|
|
39
|
+
"@owlmeans/queue": "^0.1.18-rc.23",
|
|
40
|
+
"@owlmeans/resource": "^0.1.18-rc.27",
|
|
41
|
+
"@owlmeans/route": "^0.1.18-rc.26"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"ajv": "*",
|
package/src/errors.ts
CHANGED
|
@@ -18,6 +18,8 @@ export class PlanningError extends ResilientError {
|
|
|
18
18
|
/** The card does not exist — or belongs to another entity, which is deliberately the same answer. */
|
|
19
19
|
export class WorkcardNotFound extends PlanningError {
|
|
20
20
|
public static override typeName: string = `${PlanningError.typeName}WorkcardNotFound`
|
|
21
|
+
/** The addressed card is absent or another entity's: answered 404. */
|
|
22
|
+
public static httpStatus = 404
|
|
21
23
|
|
|
22
24
|
constructor(message: string = 'error') {
|
|
23
25
|
super(`workcard-not-found:${message}`)
|
|
@@ -27,6 +29,8 @@ export class WorkcardNotFound extends PlanningError {
|
|
|
27
29
|
|
|
28
30
|
export class UnknownWorkcardType extends PlanningError {
|
|
29
31
|
public static override typeName: string = `${PlanningError.typeName}UnknownWorkcardType`
|
|
32
|
+
/** The execution names a type the registry does not declare: answered 422. */
|
|
33
|
+
public static httpStatus = 422
|
|
30
34
|
|
|
31
35
|
constructor(message: string = 'error') {
|
|
32
36
|
super(`unknown-type:${message}`)
|
|
@@ -36,6 +40,8 @@ export class UnknownWorkcardType extends PlanningError {
|
|
|
36
40
|
|
|
37
41
|
export class UnknownStatusFlow extends PlanningError {
|
|
38
42
|
public static override typeName: string = `${PlanningError.typeName}UnknownStatusFlow`
|
|
43
|
+
/** The execution names a flow the type does not run: answered 422. */
|
|
44
|
+
public static httpStatus = 422
|
|
39
45
|
|
|
40
46
|
constructor(message: string = 'error') {
|
|
41
47
|
super(`unknown-flow:${message}`)
|
|
@@ -45,6 +51,8 @@ export class UnknownStatusFlow extends PlanningError {
|
|
|
45
51
|
|
|
46
52
|
export class ParentNotFound extends PlanningError {
|
|
47
53
|
public static override typeName: string = `${PlanningError.typeName}ParentNotFound`
|
|
54
|
+
/** A parent the body references does not resolve: answered 422. */
|
|
55
|
+
public static httpStatus = 422
|
|
48
56
|
|
|
49
57
|
constructor(message: string = 'error') {
|
|
50
58
|
super(`parent-not-found:${message}`)
|
|
@@ -55,6 +63,8 @@ export class ParentNotFound extends PlanningError {
|
|
|
55
63
|
/** The parent project's type does not list this card (or project) type. */
|
|
56
64
|
export class CardTypeNotAllowed extends PlanningError {
|
|
57
65
|
public static override typeName: string = `${PlanningError.typeName}CardTypeNotAllowed`
|
|
66
|
+
/** The parent refuses a child of this type: answered 422. */
|
|
67
|
+
public static httpStatus = 422
|
|
58
68
|
|
|
59
69
|
constructor(message: string = 'error') {
|
|
60
70
|
super(`card-type-not-allowed:${message}`)
|
|
@@ -65,6 +75,8 @@ export class CardTypeNotAllowed extends PlanningError {
|
|
|
65
75
|
/** A plugin's `before` middleware refused the execution without a class of its own. */
|
|
66
76
|
export class PlanningRefused extends PlanningError {
|
|
67
77
|
public static override typeName: string = `${PlanningError.typeName}Refused`
|
|
78
|
+
/** A plugin refused what was submitted: answered 422. */
|
|
79
|
+
public static httpStatus = 422
|
|
68
80
|
|
|
69
81
|
constructor(message: string = 'error') {
|
|
70
82
|
super(`refused:${message}`)
|
|
@@ -75,6 +87,8 @@ export class PlanningRefused extends PlanningError {
|
|
|
75
87
|
/** The flow offers no rule of that name from the card's current status. */
|
|
76
88
|
export class IllegalTransition extends PlanningError {
|
|
77
89
|
public static override typeName: string = `${PlanningError.typeName}IllegalTransition`
|
|
90
|
+
/** The card's current status offers no such rule: answered 409. */
|
|
91
|
+
public static httpStatus = 409
|
|
78
92
|
|
|
79
93
|
constructor(message: string = 'error') {
|
|
80
94
|
super(`illegal-transition:${message}`)
|
|
@@ -84,6 +98,8 @@ export class IllegalTransition extends PlanningError {
|
|
|
84
98
|
|
|
85
99
|
export class FieldsInvalid extends PlanningError {
|
|
86
100
|
public static override typeName: string = `${PlanningError.typeName}FieldsInvalid`
|
|
101
|
+
/** The submitted fields fail the type's schema: answered 422. */
|
|
102
|
+
public static httpStatus = 422
|
|
87
103
|
|
|
88
104
|
constructor(message: string = 'error') {
|
|
89
105
|
super(`fields-invalid:${message}`)
|
|
@@ -93,6 +109,8 @@ export class FieldsInvalid extends PlanningError {
|
|
|
93
109
|
|
|
94
110
|
export class LabelNotAllowed extends PlanningError {
|
|
95
111
|
public static override typeName: string = `${PlanningError.typeName}LabelNotAllowed`
|
|
112
|
+
/** The submitted label is refused: answered 422. */
|
|
113
|
+
public static httpStatus = 422
|
|
96
114
|
|
|
97
115
|
constructor(message: string = 'error') {
|
|
98
116
|
super(`label-not-allowed:${message}`)
|
|
@@ -102,6 +120,8 @@ export class LabelNotAllowed extends PlanningError {
|
|
|
102
120
|
|
|
103
121
|
export class SpecificationSlotUnknown extends PlanningError {
|
|
104
122
|
public static override typeName: string = `${PlanningError.typeName}SpecificationSlotUnknown`
|
|
123
|
+
/** The body names a slot the parent type does not declare: answered 422. */
|
|
124
|
+
public static httpStatus = 422
|
|
105
125
|
|
|
106
126
|
constructor(message: string = 'error') {
|
|
107
127
|
super(`specification-slot-unknown:${message}`)
|
|
@@ -112,6 +132,8 @@ export class SpecificationSlotUnknown extends PlanningError {
|
|
|
112
132
|
/** A second document for a slot that holds one — revise the existing record instead. */
|
|
113
133
|
export class SpecificationRevisionConflict extends PlanningError {
|
|
114
134
|
public static override typeName: string = `${PlanningError.typeName}SpecificationRevisionConflict`
|
|
135
|
+
/** The slot already holds its document: answered 409. */
|
|
136
|
+
public static httpStatus = 409
|
|
115
137
|
|
|
116
138
|
constructor(message: string = 'error') {
|
|
117
139
|
super(`specification-revision-conflict:${message}`)
|
|
@@ -121,6 +143,8 @@ export class SpecificationRevisionConflict extends PlanningError {
|
|
|
121
143
|
|
|
122
144
|
export class RelationshipRefused extends PlanningError {
|
|
123
145
|
public static override typeName: string = `${PlanningError.typeName}RelationshipRefused`
|
|
146
|
+
/** The submitted link is refused: answered 422. */
|
|
147
|
+
public static httpStatus = 422
|
|
124
148
|
|
|
125
149
|
constructor(message: string = 'error') {
|
|
126
150
|
super(`relationship-refused:${message}`)
|
|
@@ -130,6 +154,8 @@ export class RelationshipRefused extends PlanningError {
|
|
|
130
154
|
|
|
131
155
|
export class CodeTaken extends PlanningError {
|
|
132
156
|
public static override typeName: string = `${PlanningError.typeName}CodeTaken`
|
|
157
|
+
/** Another card holds the code: answered 409. */
|
|
158
|
+
public static httpStatus = 409
|
|
133
159
|
|
|
134
160
|
constructor(message: string = 'error') {
|
|
135
161
|
super(`code-taken:${message}`)
|
|
@@ -140,6 +166,8 @@ export class CodeTaken extends PlanningError {
|
|
|
140
166
|
/** `expectSeq` no longer matches the card's head — somebody else wrote first. Re-read and retry. */
|
|
141
167
|
export class WorkcardConflict extends PlanningError {
|
|
142
168
|
public static override typeName: string = `${PlanningError.typeName}WorkcardConflict`
|
|
169
|
+
/** The card moved past the expected head: answered 409. */
|
|
170
|
+
public static httpStatus = 409
|
|
143
171
|
|
|
144
172
|
constructor(message: string = 'error') {
|
|
145
173
|
super(`workcard-conflict:${message}`)
|
|
@@ -169,6 +197,8 @@ export class CommitFailed extends PlanningError {
|
|
|
169
197
|
/** A card of another entity was addressed. Handlers answer it as {@link WorkcardNotFound}. */
|
|
170
198
|
export class PlanningScopeMismatch extends PlanningError {
|
|
171
199
|
public static override typeName: string = `${PlanningError.typeName}ScopeMismatch`
|
|
200
|
+
/** Another entity's card, answered as absent: answered 404. */
|
|
201
|
+
public static httpStatus = 404
|
|
172
202
|
|
|
173
203
|
constructor(message: string = 'error') {
|
|
174
204
|
super(`scope-mismatch:${message}`)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test'
|
|
2
|
+
import { ResilientError } from '@owlmeans/error'
|
|
3
|
+
import * as errors from '../src/errors.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The status an HTTP boundary (`@owlmeans/server-api` `errorStatus`) reads off a class: a static
|
|
7
|
+
* `httpStatus` inherited through the constructor chain. A refusal of the caller's condition declares
|
|
8
|
+
* a 4xx; a fault declares nothing and answers 500.
|
|
9
|
+
*/
|
|
10
|
+
const statusOf = (error: Error): unknown => (error.constructor as { httpStatus?: unknown }).httpStatus
|
|
11
|
+
|
|
12
|
+
const DECLARED: Record<string, number | undefined> = {
|
|
13
|
+
PlanningError: undefined,
|
|
14
|
+
WorkcardNotFound: 404,
|
|
15
|
+
PlanningScopeMismatch: 404,
|
|
16
|
+
IllegalTransition: 409,
|
|
17
|
+
SpecificationRevisionConflict: 409,
|
|
18
|
+
CodeTaken: 409,
|
|
19
|
+
WorkcardConflict: 409,
|
|
20
|
+
UnknownWorkcardType: 422,
|
|
21
|
+
UnknownStatusFlow: 422,
|
|
22
|
+
ParentNotFound: 422,
|
|
23
|
+
CardTypeNotAllowed: 422,
|
|
24
|
+
PlanningRefused: 422,
|
|
25
|
+
FieldsInvalid: 422,
|
|
26
|
+
LabelNotAllowed: 422,
|
|
27
|
+
SpecificationSlotUnknown: 422,
|
|
28
|
+
RelationshipRefused: 422,
|
|
29
|
+
CommitTimeout: undefined,
|
|
30
|
+
CommitFailed: undefined,
|
|
31
|
+
PlanningUnsupported: undefined,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const classes = Object.entries(errors).filter(([, value]) =>
|
|
35
|
+
typeof value === 'function' && value.prototype instanceof ResilientError
|
|
36
|
+
) as [string, new (message?: string) => ResilientError][]
|
|
37
|
+
|
|
38
|
+
describe('planning refusals — declared HTTP statuses', () => {
|
|
39
|
+
test('every refusal class has decided its status', () => {
|
|
40
|
+
expect(classes.map(([name]) => name).sort()).toEqual(Object.keys(DECLARED).sort())
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('an absent card is 404, a card in another state 409, refused content 422; faults declare nothing', () => {
|
|
44
|
+
for (const [name, Class] of classes) {
|
|
45
|
+
expect([name, statusOf(new Class('x'))]).toEqual([name, DECLARED[name]])
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('a refusal rebuilt from its marshalled form keeps its class and its status', () => {
|
|
50
|
+
for (const [name, Class] of classes) {
|
|
51
|
+
const back = ResilientError.ensure(new Class('x').marshal())
|
|
52
|
+
expect([name, back.constructor === Class, statusOf(back)]).toEqual([name, true, DECLARED[name]])
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
})
|