@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 +84 -0
- package/dist/decorators/index.d.ts +46 -0
- package/dist/decorators/index.js +14 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/package.json +55 -0
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"]}
|
package/dist/index.d.ts
ADDED
|
@@ -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
|
+
}
|