@hexaijs/contracts 0.1.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 ADDED
@@ -0,0 +1,84 @@
1
+ # @hexaijs/contracts
2
+
3
+ > Zero-dependency marker decorators and base message classes for hexai contract definitions
4
+
5
+ ## Overview
6
+
7
+ `@hexaijs/contracts` provides the foundational contract types used across hexai:
8
+
9
+ - **Command** and **Query** base classes with typed payload and result
10
+ - **Decorator markers** (`@PublicEvent`, `@PublicCommand`, `@PublicQuery`) for static analysis by the contracts generator
11
+
12
+ This package has no runtime dependencies beyond `@hexaijs/core` as a peer dependency.
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @hexaijs/contracts
18
+ ```
19
+
20
+ ## Core Exports
21
+
22
+ ### Command and Query
23
+
24
+ Base classes for CQRS messages. Both accept two type parameters:
25
+
26
+ ```typescript
27
+ import { Command, Query } from "@hexaijs/contracts";
28
+
29
+ class CreateOrderCommand extends Command<
30
+ { customerId: string; items: Item[] }, // Payload
31
+ { orderId: string } // ResultType
32
+ > {
33
+ static readonly type = "order.create-order";
34
+ }
35
+
36
+ class GetOrderQuery extends Query<
37
+ { orderId: string }, // Payload
38
+ OrderDto // ResultType
39
+ > {
40
+ static readonly type = "order.get-order";
41
+ }
42
+ ```
43
+
44
+ `Command` and `Query` extend `Message<Payload>` from `@hexaijs/core`, adding a phantom `ResultType` property for TypeScript type inference.
45
+
46
+ ### Decorators (`@hexaijs/contracts/decorators`)
47
+
48
+ Pure no-op markers used by `@hexaijs/plugin-contracts-generator` for static analysis. They have no runtime effect.
49
+
50
+ ```typescript
51
+ import { PublicCommand, PublicEvent, PublicQuery } from "@hexaijs/contracts/decorators";
52
+
53
+ @PublicCommand()
54
+ class CreateOrderCommand extends Command<CreateOrderPayload, CreateOrderResult> { ... }
55
+
56
+ @PublicEvent({ version: 2 })
57
+ class OrderPlaced extends DomainEvent<OrderPlacedPayload> { ... }
58
+
59
+ @PublicQuery({ response: "UserProfile" })
60
+ class GetUserQuery extends Query<{ userId: string }, UserProfile> { ... }
61
+ ```
62
+
63
+ #### Decorator Options
64
+
65
+ | Decorator | Options |
66
+ |-----------|---------|
67
+ | `@PublicEvent(options?)` | `version?: number` — event version; `context?: string` — business context (inferred from package) |
68
+ | `@PublicCommand(options?)` | `context?: string` — business context; `response?: string` — explicit response type name |
69
+ | `@PublicQuery(options?)` | `context?: string` — business context; `response?: string` — explicit response type name |
70
+
71
+ ## API Highlights
72
+
73
+ | Export | Subpath | Description |
74
+ |--------|---------|-------------|
75
+ | `Command<P, O>` | `.` | Base class for commands with payload and output type |
76
+ | `Query<P, O>` | `.` | Base class for queries with payload and output type |
77
+ | `PublicEvent` | `./decorators` | No-op marker for domain events |
78
+ | `PublicCommand` | `./decorators` | No-op marker for commands |
79
+ | `PublicQuery` | `./decorators` | No-op marker for queries |
80
+
81
+ ## See Also
82
+
83
+ - [@hexaijs/application](../application/README.md) — Application layer that consumes these contracts
84
+ - [@hexaijs/plugin-contracts-generator](../plugin-contracts-generator/README.md) — Generates frontend-compatible types from decorated classes
@@ -0,0 +1,46 @@
1
+ interface PublicEventOptions {
2
+ /**
3
+ * Event version for versioned events
4
+ * @example @PublicEvent({ version: 2 })
5
+ */
6
+ version?: number;
7
+ /**
8
+ * Business context this event belongs to.
9
+ * If not specified, inferred from package name.
10
+ * @example @PublicEvent({ context: 'lecture' })
11
+ */
12
+ context?: string;
13
+ }
14
+ interface PublicCommandOptions {
15
+ /**
16
+ * Business context this command belongs to.
17
+ * If not specified, inferred from package name.
18
+ * @example @PublicCommand({ context: 'auth' })
19
+ */
20
+ context?: string;
21
+ /**
22
+ * Explicit response type name for this command.
23
+ * If specified, the parser will look for this type in the same file.
24
+ * @example @PublicCommand({ response: 'CreateUserResult' })
25
+ */
26
+ response?: string;
27
+ }
28
+ interface PublicQueryOptions {
29
+ /**
30
+ * Business context this query belongs to.
31
+ * If not specified, inferred from package name.
32
+ * @example @PublicQuery({ context: 'catalog' })
33
+ */
34
+ context?: string;
35
+ /**
36
+ * Explicit response type name for this query.
37
+ * If specified, the parser will look for this type in the same file.
38
+ * @example @PublicQuery({ response: 'UserProfile' })
39
+ */
40
+ response?: string;
41
+ }
42
+ declare function PublicEvent(_options?: PublicEventOptions): ClassDecorator;
43
+ declare function PublicCommand(_options?: PublicCommandOptions): ClassDecorator;
44
+ declare function PublicQuery(_options?: PublicQueryOptions): ClassDecorator;
45
+
46
+ export { PublicCommand, type PublicCommandOptions, PublicEvent, type PublicEventOptions, PublicQuery, type PublicQueryOptions };
@@ -0,0 +1,14 @@
1
+ // src/decorators/index.ts
2
+ function PublicEvent(_options = {}) {
3
+ return (target) => target;
4
+ }
5
+ function PublicCommand(_options = {}) {
6
+ return (target) => target;
7
+ }
8
+ function PublicQuery(_options = {}) {
9
+ return (target) => target;
10
+ }
11
+
12
+ export { PublicCommand, PublicEvent, PublicQuery };
13
+ //# sourceMappingURL=index.js.map
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/decorators/index.ts"],"names":[],"mappings":";AA+CO,SAAS,WAAA,CAAY,QAAA,GAA+B,EAAC,EAAmB;AAC7E,EAAA,OAAO,CAAC,MAAA,KAAW,MAAA;AACrB;AAEO,SAAS,aAAA,CACd,QAAA,GAAiC,EAAC,EAClB;AAChB,EAAA,OAAO,CAAC,MAAA,KAAW,MAAA;AACrB;AAEO,SAAS,WAAA,CAAY,QAAA,GAA+B,EAAC,EAAmB;AAC7E,EAAA,OAAO,CAAC,MAAA,KAAW,MAAA;AACrB","file":"index.js","sourcesContent":["export interface PublicEventOptions {\n /**\n * Event version for versioned events\n * @example @PublicEvent({ version: 2 })\n */\n version?: number;\n\n /**\n * Business context this event belongs to.\n * If not specified, inferred from package name.\n * @example @PublicEvent({ context: 'lecture' })\n */\n context?: string;\n}\n\nexport interface PublicCommandOptions {\n /**\n * Business context this command belongs to.\n * If not specified, inferred from package name.\n * @example @PublicCommand({ context: 'auth' })\n */\n context?: string;\n\n /**\n * Explicit response type name for this command.\n * If specified, the parser will look for this type in the same file.\n * @example @PublicCommand({ response: 'CreateUserResult' })\n */\n response?: string;\n}\n\nexport interface PublicQueryOptions {\n /**\n * Business context this query belongs to.\n * If not specified, inferred from package name.\n * @example @PublicQuery({ context: 'catalog' })\n */\n context?: string;\n\n /**\n * Explicit response type name for this query.\n * If specified, the parser will look for this type in the same file.\n * @example @PublicQuery({ response: 'UserProfile' })\n */\n response?: string;\n}\n\nexport function PublicEvent(_options: PublicEventOptions = {}): ClassDecorator {\n return (target) => target;\n}\n\nexport function PublicCommand(\n _options: PublicCommandOptions = {}\n): ClassDecorator {\n return (target) => target;\n}\n\nexport function PublicQuery(_options: PublicQueryOptions = {}): ClassDecorator {\n return (target) => target;\n}\n"]}
@@ -0,0 +1,14 @@
1
+ export { PublicCommand, PublicCommandOptions, PublicEvent, PublicEventOptions, PublicQuery, PublicQueryOptions } from './decorators/index.js';
2
+ import { Message } from '@hexaijs/core';
3
+
4
+ declare class Command<Payload = unknown, ResultType = unknown> extends Message<Payload> {
5
+ readonly ResultType: ResultType;
6
+ static getIntent(): string;
7
+ }
8
+
9
+ declare class Query<Payload = unknown, ResultType = unknown> extends Message<Payload> {
10
+ readonly ResultType: ResultType;
11
+ static getIntent(): string;
12
+ }
13
+
14
+ export { Command, Query };
package/dist/index.js ADDED
@@ -0,0 +1,26 @@
1
+ import { Message } from '@hexaijs/core';
2
+
3
+ // src/decorators/index.ts
4
+ function PublicEvent(_options = {}) {
5
+ return (target) => target;
6
+ }
7
+ function PublicCommand(_options = {}) {
8
+ return (target) => target;
9
+ }
10
+ function PublicQuery(_options = {}) {
11
+ return (target) => target;
12
+ }
13
+ var Command = class extends Message {
14
+ static getIntent() {
15
+ return "command";
16
+ }
17
+ };
18
+ var Query = class extends Message {
19
+ static getIntent() {
20
+ return "query";
21
+ }
22
+ };
23
+
24
+ export { Command, PublicCommand, PublicEvent, PublicQuery, Query };
25
+ //# sourceMappingURL=index.js.map
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/decorators/index.ts","../src/command.ts","../src/query.ts"],"names":["Message"],"mappings":";;;AA+CO,SAAS,WAAA,CAAY,QAAA,GAA+B,EAAC,EAAmB;AAC7E,EAAA,OAAO,CAAC,MAAA,KAAW,MAAA;AACrB;AAEO,SAAS,aAAA,CACd,QAAA,GAAiC,EAAC,EAClB;AAChB,EAAA,OAAO,CAAC,MAAA,KAAW,MAAA;AACrB;AAEO,SAAS,WAAA,CAAY,QAAA,GAA+B,EAAC,EAAmB;AAC7E,EAAA,OAAO,CAAC,MAAA,KAAW,MAAA;AACrB;ACzDO,IAAM,OAAA,GAAN,cAA+D,OAAA,CAAiB;AAAA,EAGnF,OAAgB,SAAA,GAAoB;AAChC,IAAA,OAAO,SAAA;AAAA,EACX;AACJ;ACNO,IAAM,KAAA,GAAN,cAA6DA,OAAAA,CAAiB;AAAA,EAGjF,OAAgB,SAAA,GAAoB;AAChC,IAAA,OAAO,OAAA;AAAA,EACX;AACJ","file":"index.js","sourcesContent":["export interface PublicEventOptions {\n /**\n * Event version for versioned events\n * @example @PublicEvent({ version: 2 })\n */\n version?: number;\n\n /**\n * Business context this event belongs to.\n * If not specified, inferred from package name.\n * @example @PublicEvent({ context: 'lecture' })\n */\n context?: string;\n}\n\nexport interface PublicCommandOptions {\n /**\n * Business context this command belongs to.\n * If not specified, inferred from package name.\n * @example @PublicCommand({ context: 'auth' })\n */\n context?: string;\n\n /**\n * Explicit response type name for this command.\n * If specified, the parser will look for this type in the same file.\n * @example @PublicCommand({ response: 'CreateUserResult' })\n */\n response?: string;\n}\n\nexport interface PublicQueryOptions {\n /**\n * Business context this query belongs to.\n * If not specified, inferred from package name.\n * @example @PublicQuery({ context: 'catalog' })\n */\n context?: string;\n\n /**\n * Explicit response type name for this query.\n * If specified, the parser will look for this type in the same file.\n * @example @PublicQuery({ response: 'UserProfile' })\n */\n response?: string;\n}\n\nexport function PublicEvent(_options: PublicEventOptions = {}): ClassDecorator {\n return (target) => target;\n}\n\nexport function PublicCommand(\n _options: PublicCommandOptions = {}\n): ClassDecorator {\n return (target) => target;\n}\n\nexport function PublicQuery(_options: PublicQueryOptions = {}): ClassDecorator {\n return (target) => target;\n}\n","import { Message } from \"@hexaijs/core\";\n\nexport class Command<Payload = unknown, ResultType = unknown> extends Message<Payload> {\n declare readonly ResultType: ResultType;\n\n static override getIntent(): string {\n return \"command\";\n }\n}\n","import { Message } from \"@hexaijs/core\";\n\nexport class Query<Payload = unknown, ResultType = unknown> extends Message<Payload> {\n declare readonly ResultType: ResultType;\n\n static override getIntent(): string {\n return \"query\";\n }\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@hexaijs/contracts",
3
+ "publishConfig": {
4
+ "access": "public"
5
+ },
6
+ "version": "0.1.0",
7
+ "type": "module",
8
+ "description": "Zero-dependency marker decorators for hexai contract definitions",
9
+ "license": "MIT",
10
+ "author": "Sangwoo Hyun <wkdny.hyun@gmail.com>",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/workingdanny911/hexai.git",
14
+ "directory": "packages/contracts"
15
+ },
16
+ "homepage": "https://github.com/workingdanny911/hexai#readme",
17
+ "bugs": {
18
+ "url": "https://github.com/workingdanny911/hexai/issues"
19
+ },
20
+ "keywords": [
21
+ "hexai",
22
+ "hexagonal",
23
+ "clean-architecture",
24
+ "ddd",
25
+ "contracts",
26
+ "decorators",
27
+ "typescript"
28
+ ],
29
+ "files": [
30
+ "dist",
31
+ "LICENSE"
32
+ ],
33
+ "exports": {
34
+ ".": {
35
+ "types": "./dist/index.d.ts",
36
+ "import": "./dist/index.js"
37
+ },
38
+ "./decorators": {
39
+ "types": "./dist/decorators/index.d.ts",
40
+ "import": "./dist/decorators/index.js"
41
+ },
42
+ "./package.json": "./package.json"
43
+ },
44
+ "scripts": {
45
+ "test": "vitest run",
46
+ "build": "tsup"
47
+ },
48
+ "peerDependencies": {
49
+ "@hexaijs/core": "^0.6.0"
50
+ },
51
+ "devDependencies": {
52
+ "@hexaijs/core": "workspace:^",
53
+ "@hexaijs/tooling": "workspace:*"
54
+ }
55
+ }