@critical-path/core 0.23.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @critical-path/core
2
2
 
3
+ ## 0.24.0
4
+
5
+ ### Minor Changes
6
+
7
+ - b54e22c: Validate request bodies with shared zod schemas and publish an OpenAPI document.
8
+
9
+ **@critical-path/core**
10
+ - New `@critical-path/core/schemas` subpath with create/update schemas for every resource and `parsePayload(schema, data)`. Kept off the package root so browser bundles do not include zod. `zod` is now a dependency of core.
11
+ - `ValidationError` carries an optional `issues: { path, message }[]`.
12
+
13
+ **@critical-path/server**
14
+ - All request bodies are validated. Invalid bodies return `400` with `issues`. Server-assigned fields (`id`, `createdAt`, `updatedAt`, task `key`, owning `projectId` on updates) and unknown keys are stripped, so a `PATCH` can no longer move a task to another project.
15
+ - Comments, reactions and attachments require an author unless `getContext` resolves the caller. Attachment `mimeType` and `sizeBytes` default to `application/octet-stream` and `0` for linked files.
16
+ - New `GET /openapi.json` and `buildOpenApiDocument()` (OpenAPI 3.1, request bodies generated from the validation schemas).
17
+
18
+ **@critical-path/mcp**
19
+ - Tool `inputSchema`s are generated from their zod schemas via the new `defineTool`, removing the hand-written JSON copies.
20
+
21
+ **@critical-path/svelte**
22
+ - Rebuilt with the bundled `@critical-path/mcp` changes.
23
+
3
24
  ## 0.23.0
4
25
 
5
26
  ### Minor Changes
package/README.md CHANGED
@@ -122,6 +122,17 @@ try {
122
122
 
123
123
  Cycle detection follows the full upstream chain, so indirect cycles (A → B → C → D → A) are rejected as well as direct ones.
124
124
 
125
+ #### Request Payload Schemas (`@critical-path/core/schemas`)
126
+
127
+ ```ts
128
+ import { CreateTaskSchema, UpdateTaskSchema, parsePayload } from '@critical-path/core/schemas';
129
+
130
+ const input = parsePayload(CreateTaskSchema, await request.json()); // throws ValidationError with `issues`
131
+ await engine.createTask(input);
132
+ ```
133
+
134
+ Create and update schemas exist for workflows, projects, tasks, dependencies, deliverables, teams, containers, iterations, comments, reactions, attachments and time entries. They strip server-assigned fields and unknown keys. The schemas live on a subpath so importing `@critical-path/core` in a browser bundle does not pull in zod. A compile-time test fails the build if a domain type gains a field its schema lacks.
135
+
125
136
  #### Attributing Mutations to a User (`withActor`)
126
137
 
127
138
  ```ts
@@ -1,8 +1,14 @@
1
1
  /**
2
2
  * Thrown when input fails a domain rule. Route handlers map it to HTTP 400.
3
3
  */
4
+ export interface ValidationIssue {
5
+ /** Dot-separated path to the invalid field, e.g. `todos.0.title`. Empty for the whole payload. */
6
+ path: string;
7
+ message: string;
8
+ }
4
9
  export declare class ValidationError extends Error {
5
- constructor(message: string);
10
+ readonly issues?: ValidationIssue[];
11
+ constructor(message: string, issues?: ValidationIssue[]);
6
12
  }
7
13
  /**
8
14
  * Thrown when a referenced entity does not exist. Route handlers map it to HTTP 404.
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/domain/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;gBAC1B,OAAO,EAAE,MAAM;CAI5B"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/domain/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kGAAkG;IAClG,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,eAAgB,SAAQ,KAAK;IACxC,SAAgB,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;gBAE/B,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,eAAe,EAAE;CAKxD;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;gBAC1B,OAAO,EAAE,MAAM;CAI5B"}
@@ -1,10 +1,9 @@
1
- /**
2
- * Thrown when input fails a domain rule. Route handlers map it to HTTP 400.
3
- */
4
1
  export class ValidationError extends Error {
5
- constructor(message) {
2
+ issues;
3
+ constructor(message, issues) {
6
4
  super(message);
7
5
  this.name = 'ValidationError';
6
+ this.issues = issues;
8
7
  }
9
8
  }
10
9
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/domain/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/domain/errors.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxB,MAAM,CAAqB;IAE3C,YAAY,OAAe,EAAE,MAA0B;QACrD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF"}