@skillsregistry/contracts 1.1.0 → 3.0.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/README.md CHANGED
@@ -4,7 +4,7 @@ Zod schemas + TypeScript types for the SkillsRegistry public API and the
4
4
  local-node ↔ mothership contract.
5
5
 
6
6
  **License:** Apache-2.0. Consumed by both the open-source
7
- [skillsregistry-local](https://github.com/cogniumhq/skillsregistry-local)
7
+ [SkillsRegistry local](https://github.com/cogniumhq/skillsregistry)
8
8
  node and the proprietary mothership. Both sides pin the exact same
9
9
  version so no field ever silently drifts.
10
10
 
@@ -17,6 +17,14 @@ version so no field ever silently drifts.
17
17
  | `@skillsregistry/contracts/responses` | HTTP response envelopes for public REST routes. Depends on `@hono/zod-openapi`. |
18
18
  | `@skillsregistry/contracts/upstream` | Local-node → mothership contract: trust scoring, budget, publish, delta sync, error taxonomy. Plain `zod` — no OpenAPI meta. |
19
19
 
20
+ ## Requirements
21
+
22
+ Since **3.0.0** the schemas are **zod 4** instances and the OpenAPI modules
23
+ use **`@hono/zod-openapi` 1.x** (which needs `hono` >= 4.10). Consumers must
24
+ be on zod `^4.6.6` (the GHSA-mrhx-c7xc-m3w5 fix) and `@hono/zod-openapi`
25
+ `^1.x`; mixing these schemas with zod 3 or `@hono/zod-openapi` 0.x does not
26
+ type-check and breaks OpenAPI generation. Pin `2.x` to stay on zod 3.
27
+
20
28
  ## Install
21
29
 
22
30
  ```bash
package/dist/common.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { z } from '@hono/zod-openapi';
2
- export declare const SkillIdParam: z.ZodString;
2
+ export declare const SkillIdParam: z.ZodGUID;
3
3
  export declare const SkillSlugParam: z.ZodString;
4
4
  export declare const VersionParam: z.ZodString;
5
5
  export declare const HoursQuery: z.ZodDefault<z.ZodOptional<z.ZodString>>;
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,eAAO,MAAM,YAAY,aAGvB,CAAC;AAEH,eAAO,MAAM,cAAc,aAGzB,CAAC;AAEH,eAAO,MAAM,YAAY,aAGvB,CAAC;AAEH,eAAO,MAAM,UAAU,0CAI6C,CAAC;AAErE,eAAO,MAAM,UAAU,0CAI8C,CAAC;AAEtE,eAAO,MAAM,WAAW,0CAI4C,CAAC"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,eAAO,MAAM,YAAY,WAGvB,CAAC;AAEH,eAAO,MAAM,cAAc,aAGzB,CAAC;AAEH,eAAO,MAAM,YAAY,aAGvB,CAAC;AAEH,eAAO,MAAM,UAAU,0CAI6C,CAAC;AAErE,eAAO,MAAM,UAAU,0CAI8C,CAAC;AAEtE,eAAO,MAAM,WAAW,0CAI4C,CAAC"}
package/dist/common.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // Common OpenAPI Schemas — Shared parameters and query schemas
3
3
  // ══════════════════════════════════════════════════════════════════════════════
4
4
  import { z } from '@hono/zod-openapi';
5
- export const SkillIdParam = z.string().uuid().openapi({
5
+ export const SkillIdParam = z.guid().openapi({
6
6
  param: { name: 'id', in: 'path' },
7
7
  example: '550e8400-e29b-41d4-a716-446655440000',
8
8
  });
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,+DAA+D;AAC/D,iFAAiF;AAEjF,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC;IACpD,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE;IACjC,OAAO,EAAE,sCAAsC;CAChD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC;IAC/C,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE;IACnC,OAAO,EAAE,sBAAsB;CAChC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC;IAC7C,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE;IACtC,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC;KACxB,MAAM,EAAE;KACR,QAAQ,EAAE;KACV,OAAO,CAAC,IAAI,CAAC;KACb,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AAErE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC;KACxB,MAAM,EAAE;KACR,QAAQ,EAAE;KACV,OAAO,CAAC,KAAK,CAAC;KACd,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;AAEtE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC;KACzB,MAAM,EAAE;KACR,QAAQ,EAAE;KACV,OAAO,CAAC,GAAG,CAAC;KACZ,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,+DAA+D;AAC/D,iFAAiF;AAEjF,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC;IAC3C,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE;IACjC,OAAO,EAAE,sCAAsC;CAChD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC;IAC/C,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE;IACnC,OAAO,EAAE,sBAAsB;CAChC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC;IAC7C,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE;IACtC,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC;KACxB,MAAM,EAAE;KACR,QAAQ,EAAE;KACV,OAAO,CAAC,IAAI,CAAC;KACb,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AAErE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC;KACxB,MAAM,EAAE;KACR,QAAQ,EAAE;KACV,OAAO,CAAC,KAAK,CAAC;KACd,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;AAEtE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC;KACzB,MAAM,EAAE;KACR,QAAQ,EAAE;KACV,OAAO,CAAC,GAAG,CAAC;KACZ,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=openapi.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi.test.d.ts","sourceRoot":"","sources":["../src/openapi.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,71 @@
1
+ // ══════════════════════════════════════════════════════════════════════════════
2
+ // OpenAPI generation smoke — contracts schemas inside an OpenAPIHono app
3
+ // ══════════════════════════════════════════════════════════════════════════════
4
+ //
5
+ // Guards the 3.0.0 move to zod 4 + @hono/zod-openapi 1.x: the `.openapi()`
6
+ // metadata on `./common` and `./responses` must still produce named
7
+ // components and typed params, and the plain-zod `./upstream` schemas must
8
+ // still be usable as request bodies in a consumer's OpenAPI route (the
9
+ // mothership wraps them that way).
10
+ import { describe, it, expect } from 'vitest';
11
+ import { OpenAPIHono, createRoute, z } from '@hono/zod-openapi';
12
+ import { SkillIdParam, LimitQuery, SkillDetailSchema, ErrorResponseSchema, SearchRequestSchema, SearchResponseSchema, } from './index.js';
13
+ describe('OpenAPI document generation', () => {
14
+ const doc = (() => {
15
+ const a = new OpenAPIHono();
16
+ a.openapi(createRoute({
17
+ method: 'get',
18
+ path: '/v1/skills/{id}',
19
+ request: {
20
+ params: z.object({ id: SkillIdParam }),
21
+ query: z.object({ limit: LimitQuery }),
22
+ },
23
+ responses: {
24
+ 200: {
25
+ content: { 'application/json': { schema: SkillDetailSchema } },
26
+ description: 'Skill detail',
27
+ },
28
+ 404: {
29
+ content: { 'application/json': { schema: ErrorResponseSchema } },
30
+ description: 'Not found',
31
+ },
32
+ },
33
+ }), (c) => c.json({ error: 'not_found' }, 404));
34
+ a.openapi(createRoute({
35
+ method: 'post',
36
+ path: '/v1/search',
37
+ request: {
38
+ body: { content: { 'application/json': { schema: SearchRequestSchema } } },
39
+ },
40
+ responses: {
41
+ 200: {
42
+ content: { 'application/json': { schema: SearchResponseSchema } },
43
+ description: 'Search results',
44
+ },
45
+ },
46
+ }), (c) => c.json({}, 200));
47
+ return a.getOpenAPI31Document({
48
+ openapi: '3.1.0',
49
+ info: { title: 'contracts-smoke', version: '0.0.0' },
50
+ });
51
+ })();
52
+ it('registers named components from .openapi("Name")', () => {
53
+ const names = Object.keys(doc.components?.schemas ?? {});
54
+ expect(names).toEqual(expect.arrayContaining(['SkillDetail', 'ErrorResponse', 'SearchResponse']));
55
+ });
56
+ it('emits the path param and query param with their examples', () => {
57
+ const op = doc.paths?.['/v1/skills/{id}']?.get;
58
+ const params = (op?.parameters ?? []);
59
+ const id = params.find((p) => p.name === 'id');
60
+ expect(id?.in).toBe('path');
61
+ expect(id?.schema?.format).toBe('uuid');
62
+ const limit = params.find((p) => p.name === 'limit');
63
+ expect(limit?.in).toBe('query');
64
+ });
65
+ it('accepts a plain-zod upstream schema as a request body', () => {
66
+ const body = doc.paths?.['/v1/search']?.post?.requestBody;
67
+ const props = body?.content['application/json']?.schema.properties ?? {};
68
+ expect(Object.keys(props)).toEqual(expect.arrayContaining(['query', 'minTrust', 'allowVulnerable', 'limit']));
69
+ });
70
+ });
71
+ //# sourceMappingURL=openapi.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi.test.js","sourceRoot":"","sources":["../src/openapi.test.ts"],"names":[],"mappings":"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"}