@ahoo-wang/wow-generator 9.2.0-rc.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/LICENSE +201 -0
- package/README.md +177 -0
- package/README.zh-CN.md +149 -0
- package/dist/analysis/aggregates.d.cts +21 -0
- package/dist/analysis/aggregates.d.ts +21 -0
- package/dist/analysis/analyze.d.cts +18 -0
- package/dist/analysis/analyze.d.ts +18 -0
- package/dist/analysis/apiClients.d.cts +14 -0
- package/dist/analysis/apiClients.d.ts +14 -0
- package/dist/analysis/clientNames.d.cts +55 -0
- package/dist/analysis/clientNames.d.ts +55 -0
- package/dist/analysis/model.d.cts +212 -0
- package/dist/analysis/model.d.ts +212 -0
- package/dist/analysis/modelInfo.d.cts +23 -0
- package/dist/analysis/modelInfo.d.ts +23 -0
- package/dist/analysis/models.d.cts +17 -0
- package/dist/analysis/models.d.ts +17 -0
- package/dist/api/configuration.d.cts +30 -0
- package/dist/api/configuration.d.ts +30 -0
- package/dist/api/errors.d.cts +41 -0
- package/dist/api/errors.d.ts +41 -0
- package/dist/api/logger.d.cts +61 -0
- package/dist/api/logger.d.ts +61 -0
- package/dist/api/options.d.cts +47 -0
- package/dist/api/options.d.ts +47 -0
- package/dist/cli/program.d.cts +35 -0
- package/dist/cli/program.d.ts +35 -0
- package/dist/cli/runGenerate.d.cts +65 -0
- package/dist/cli/runGenerate.d.ts +65 -0
- package/dist/cli.cjs +3 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +6 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.js +98 -0
- package/dist/cli.js.map +1 -0
- package/dist/codeGenerator-DpDTDC4o.cjs +23 -0
- package/dist/codeGenerator-DpDTDC4o.cjs.map +1 -0
- package/dist/codeGenerator-kyY9eLML.js +2583 -0
- package/dist/codeGenerator-kyY9eLML.js.map +1 -0
- package/dist/emit/importRegistry.d.cts +50 -0
- package/dist/emit/importRegistry.d.ts +50 -0
- package/dist/emit/imports.d.cts +49 -0
- package/dist/emit/imports.d.ts +49 -0
- package/dist/emit/jsdoc.d.cts +38 -0
- package/dist/emit/jsdoc.d.ts +38 -0
- package/dist/emit/moduleBuilder.d.cts +80 -0
- package/dist/emit/moduleBuilder.d.ts +80 -0
- package/dist/emitters/apiClients.d.cts +10 -0
- package/dist/emitters/apiClients.d.ts +10 -0
- package/dist/emitters/commandClients.d.cts +14 -0
- package/dist/emitters/commandClients.d.ts +14 -0
- package/dist/emitters/decorators.d.cts +83 -0
- package/dist/emitters/decorators.d.ts +83 -0
- package/dist/emitters/emit.d.cts +15 -0
- package/dist/emitters/emit.d.ts +15 -0
- package/dist/emitters/indexFiles.d.cts +12 -0
- package/dist/emitters/indexFiles.d.ts +12 -0
- package/dist/emitters/models.d.cts +77 -0
- package/dist/emitters/models.d.ts +77 -0
- package/dist/emitters/queryClients.d.cts +11 -0
- package/dist/emitters/queryClients.d.ts +11 -0
- package/dist/emitters/target.d.cts +14 -0
- package/dist/emitters/target.d.ts +14 -0
- package/dist/finalize/finalize.d.cts +16 -0
- package/dist/finalize/finalize.d.ts +16 -0
- package/dist/finalize/typeOnlyImports.d.cts +13 -0
- package/dist/finalize/typeOnlyImports.d.ts +13 -0
- package/dist/finalize/verification.d.cts +14 -0
- package/dist/finalize/verification.d.ts +14 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +2 -0
- package/dist/input/configuration.d.cts +87 -0
- package/dist/input/configuration.d.ts +87 -0
- package/dist/input/parsers.d.cts +39 -0
- package/dist/input/parsers.d.ts +39 -0
- package/dist/input/resources.d.cts +36 -0
- package/dist/input/resources.d.ts +36 -0
- package/dist/naming/modelInfo.d.cts +10 -0
- package/dist/naming/modelInfo.d.ts +10 -0
- package/dist/naming/naming.d.cts +102 -0
- package/dist/naming/naming.d.ts +102 -0
- package/dist/naming/order.d.cts +2 -0
- package/dist/naming/order.d.ts +2 -0
- package/dist/naming/paths.d.cts +27 -0
- package/dist/naming/paths.d.ts +27 -0
- package/dist/openapi/components.d.cts +55 -0
- package/dist/openapi/components.d.ts +55 -0
- package/dist/openapi/document.d.cts +25 -0
- package/dist/openapi/document.d.ts +25 -0
- package/dist/openapi/operations.d.cts +78 -0
- package/dist/openapi/operations.d.ts +78 -0
- package/dist/openapi/references.d.cts +28 -0
- package/dist/openapi/references.d.ts +28 -0
- package/dist/openapi/responses.d.cts +44 -0
- package/dist/openapi/responses.d.ts +44 -0
- package/dist/openapi/schemas.d.cts +112 -0
- package/dist/openapi/schemas.d.ts +112 -0
- package/dist/output/outputStore.d.cts +92 -0
- package/dist/output/outputStore.d.ts +92 -0
- package/dist/pipeline/codeGenerator.d.cts +61 -0
- package/dist/pipeline/codeGenerator.d.ts +61 -0
- package/dist/pipeline/seams.d.cts +29 -0
- package/dist/pipeline/seams.d.ts +29 -0
- package/dist/types/typeResolver.d.cts +124 -0
- package/dist/types/typeResolver.d.ts +124 -0
- package/dist/version.d.cts +2 -0
- package/dist/version.d.ts +2 -0
- package/dist/wow/conventions.d.cts +154 -0
- package/dist/wow/conventions.d.ts +154 -0
- package/dist/wow/model.d.cts +116 -0
- package/dist/wow/model.d.ts +116 -0
- package/dist/wow/resolveWowModel.d.cts +21 -0
- package/dist/wow/resolveWowModel.d.ts +21 -0
- package/package.json +108 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { OpenAPI, Tag } from '@ahoo-wang/fetcher-openapi';
|
|
2
|
+
import { AggregateDefinition, TagAliasAggregate } from './model.js';
|
|
3
|
+
/** The oldest Wow server whose OpenAPI metadata the generator reads fully. */
|
|
4
|
+
export declare const MINIMUM_WOW_VERSION = "8.10";
|
|
5
|
+
/** The `info` extension naming the bounded context the document serves. */
|
|
6
|
+
export declare const CONTEXT_ALIAS_EXTENSION = "x-wow-context-alias";
|
|
7
|
+
/** The bounded context a document names, if it is a Wow service's. */
|
|
8
|
+
export declare function contextAliasOf(openAPI: OpenAPI): string | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Reads an aggregate off a tag named `<contextAlias>.<aggregateName>`.
|
|
11
|
+
*
|
|
12
|
+
* @param tagName - The tag name
|
|
13
|
+
* @returns `[contextAlias, aggregateName]`, or null when the tag names no aggregate
|
|
14
|
+
*/
|
|
15
|
+
export declare function isAliasAggregate(tagName: string): [string, string] | null;
|
|
16
|
+
/**
|
|
17
|
+
* The aggregate a tag names, or null when it names none.
|
|
18
|
+
*
|
|
19
|
+
* @param tag - The tag
|
|
20
|
+
*/
|
|
21
|
+
export declare function tagToAggregate(tag: Tag): TagAliasAggregate | null;
|
|
22
|
+
/**
|
|
23
|
+
* The command an operation sends, read off its id
|
|
24
|
+
* `<contextAlias>.<aggregateName>.<command>`.
|
|
25
|
+
*
|
|
26
|
+
* @param operationId - The operation id
|
|
27
|
+
* @returns The command name, or null when the id has another shape
|
|
28
|
+
*/
|
|
29
|
+
export declare function operationIdToCommandName(operationId?: string): string | null;
|
|
30
|
+
/** The operation that sends any command; it belongs to no aggregate. */
|
|
31
|
+
export declare const SEND_COMMAND_OPERATION_ID = "wow.command.send";
|
|
32
|
+
/** The response every command operation answers with. */
|
|
33
|
+
export declare const COMMAND_OK_RESPONSE_REF = "#/components/responses/wow.CommandOk";
|
|
34
|
+
/** The operation id suffix of the operation that loads an aggregate's state. */
|
|
35
|
+
export declare const STATE_OPERATION_SUFFIX = ".snapshot_state.single";
|
|
36
|
+
/** The operation id suffix of the operation that lists an aggregate's events. */
|
|
37
|
+
export declare const EVENTS_OPERATION_SUFFIX = ".event.list_query";
|
|
38
|
+
/** The operation id suffix of the operation that counts snapshots by a condition. */
|
|
39
|
+
export declare const FIELDS_OPERATION_SUFFIX = ".snapshot.count";
|
|
40
|
+
/** The request body extension naming an aggregate's query fields (Wow 8.11.1+). */
|
|
41
|
+
export declare const QUERY_FIELDS_EXTENSION = "x-wow-query-fields";
|
|
42
|
+
/**
|
|
43
|
+
* The route segment of an aggregate, read off one of its snapshot routes:
|
|
44
|
+
* `/tenant/{tenantId}/owner/{ownerId}/sales-order/snapshot/count` →
|
|
45
|
+
* `sales-order`. It differs from the aggregate name when the aggregate sets
|
|
46
|
+
* a resource name (`@AggregateRoute(resourceName = "sales-order")`).
|
|
47
|
+
*/
|
|
48
|
+
export declare const SNAPSHOT_ROUTE: RegExp;
|
|
49
|
+
/**
|
|
50
|
+
* The suffixes of the types Wow derives from an aggregate's state; the
|
|
51
|
+
* wow-client generics stand for them, so they generate no model.
|
|
52
|
+
*/
|
|
53
|
+
export declare const AGGREGATED_SCHEMA_SUFFIXES: readonly string[];
|
|
54
|
+
/**
|
|
55
|
+
* The names of the types Wow derives from an aggregate's state model.
|
|
56
|
+
*
|
|
57
|
+
* @param stateName - The name of the state model
|
|
58
|
+
*/
|
|
59
|
+
export declare function aggregatedTypeNames(stateName: string): string[];
|
|
60
|
+
/**
|
|
61
|
+
* Tells whether a schema is Wow's own, which wow-client already declares, so
|
|
62
|
+
* it generates no model: every `wow.` schema but the paged lists and operator
|
|
63
|
+
* maps of the query API, the aggregated query and event stream types, and
|
|
64
|
+
* the types derived from an aggregate's state.
|
|
65
|
+
*
|
|
66
|
+
* @param schemaKey - The schema's component key
|
|
67
|
+
* @param modelName - The name of the model the schema would generate, read
|
|
68
|
+
* only when the key alone does not decide
|
|
69
|
+
* @param aggregatedNames - The names of the types derived from the aggregates' states
|
|
70
|
+
*/
|
|
71
|
+
export declare function isWowSchema(schemaKey: string, modelName: () => string, aggregatedNames: ReadonlySet<string>): boolean;
|
|
72
|
+
/** Import path for the WOW framework types */
|
|
73
|
+
export declare const IMPORT_WOW_PATH = "@ahoo-wang/wow-client";
|
|
74
|
+
/**
|
|
75
|
+
* Import path for the deprecated Condition query model, which
|
|
76
|
+
* `@ahoo-wang/wow-client` keeps on its `/legacy` subpath for Wow 8.10 servers.
|
|
77
|
+
*/
|
|
78
|
+
export declare const IMPORT_WOW_LEGACY_PATH = "@ahoo-wang/wow-client/legacy";
|
|
79
|
+
/** The mapped type names that `IMPORT_WOW_LEGACY_PATH` exports. */
|
|
80
|
+
export declare const WOW_LEGACY_TYPES: ReadonlySet<string>;
|
|
81
|
+
/** Mapping of OpenAPI schema keys to WOW framework types */
|
|
82
|
+
export declare const WOW_TYPE_MAPPING: {
|
|
83
|
+
'wow.command.CommandResult': string;
|
|
84
|
+
'wow.command.CommandResultArray': string;
|
|
85
|
+
'wow.MessageHeaderSqlType': string;
|
|
86
|
+
'wow.api.BindingError': string;
|
|
87
|
+
'wow.api.DefaultErrorInfo': string;
|
|
88
|
+
'wow.api.RecoverableType': string;
|
|
89
|
+
'wow.api.command.DefaultDeleteAggregate': string;
|
|
90
|
+
'wow.api.command.DefaultRecoverAggregate': string;
|
|
91
|
+
'wow.api.abac.DefaultApplyResourceTags': string;
|
|
92
|
+
'wow.api.messaging.FunctionInfoData': string;
|
|
93
|
+
'wow.api.messaging.FunctionKind': string;
|
|
94
|
+
'wow.api.modeling.AggregateId': string;
|
|
95
|
+
'wow.api.query.Condition': string;
|
|
96
|
+
'wow.api.query.ConditionOptions': string;
|
|
97
|
+
'wow.api.query.ListQuery': string;
|
|
98
|
+
'wow.api.query.Operator': string;
|
|
99
|
+
'wow.api.query.PagedQuery': string;
|
|
100
|
+
'wow.api.query.Pagination': string;
|
|
101
|
+
'wow.api.query.Projection': string;
|
|
102
|
+
'wow.api.query.Sort': string;
|
|
103
|
+
'wow.api.query.Sort.Direction': string;
|
|
104
|
+
'wow.api.query.DynamicDocument': string;
|
|
105
|
+
'wow.api.query.DynamicDocumentArray': string;
|
|
106
|
+
'wow.command.CommandStage': string;
|
|
107
|
+
'wow.command.SimpleWaitSignal': string;
|
|
108
|
+
'wow.configuration.Aggregate': string;
|
|
109
|
+
'wow.configuration.BoundedContext': string;
|
|
110
|
+
'wow.configuration.WowMetadata': string;
|
|
111
|
+
'wow.modeling.DomainEvent': string;
|
|
112
|
+
'wow.openapi.BatchResult': string;
|
|
113
|
+
'wow.messaging.CompensationTarget': string;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* The wow-client type a schema maps to, and the module that exports it.
|
|
117
|
+
*
|
|
118
|
+
* @param schemaKey - The schema's component key
|
|
119
|
+
* @param properties - The schema's properties, if the caller has the schema:
|
|
120
|
+
* a ListQuery or PagedQuery that carries `filter` is the filter model's
|
|
121
|
+
* @returns The type, or undefined when the schema is not one of Wow's own
|
|
122
|
+
*/
|
|
123
|
+
export declare function wowTypeOf(schemaKey: string, properties?: Record<string, unknown>): {
|
|
124
|
+
name: string;
|
|
125
|
+
path: string;
|
|
126
|
+
} | undefined;
|
|
127
|
+
/**
|
|
128
|
+
* Tags whose operations generate no API client: Wow's own endpoints and
|
|
129
|
+
* Spring's actuator. The tags of aggregates are left out as well; their
|
|
130
|
+
* operations go to the command and query clients.
|
|
131
|
+
*/
|
|
132
|
+
export declare const IGNORED_API_CLIENT_TAGS: ReadonlySet<string>;
|
|
133
|
+
/**
|
|
134
|
+
* The resource-attribution path parameters Wow's CoSec interceptor fills,
|
|
135
|
+
* which generated clients therefore leave out.
|
|
136
|
+
*/
|
|
137
|
+
export declare const RESOURCE_ATTRIBUTION_PATH_PARAMETERS: readonly string[];
|
|
138
|
+
/** The route prefix of a tenant's resources (wow-client `ResourceAttributionPathSpec.TENANT`). */
|
|
139
|
+
export declare const TENANT_PATH_PREFIX = "/tenant/{tenantId}";
|
|
140
|
+
/** The route prefix of an owner's resources (wow-client `ResourceAttributionPathSpec.OWNER`). */
|
|
141
|
+
export declare const OWNER_PATH_PREFIX = "/owner/{ownerId}";
|
|
142
|
+
/**
|
|
143
|
+
* The resource attribution a query client of an aggregate uses, as the
|
|
144
|
+
* `ResourceAttributionPathSpec` member it generates: the prefix most of the
|
|
145
|
+
* aggregate's command routes start with, owner on a tie, none when no route
|
|
146
|
+
* starts with either.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* // commands at /tenant/{tenantId}/users, /tenant/{tenantId}/orders and /owner/{ownerId}/profile
|
|
151
|
+
* inferPathSpecType(aggregate); // 'ResourceAttributionPathSpec.TENANT'
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
export declare function inferPathSpecType(aggregateDefinition: Pick<AggregateDefinition, 'commands'>): string;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { HTTPMethod, Operation, Parameter, Tag } from '@ahoo-wang/fetcher-openapi';
|
|
2
|
+
import { AliasAggregate, Named } from '@ahoo-wang/wow-client';
|
|
3
|
+
import { KeySchema } from '../openapi/components.cjs';
|
|
4
|
+
export interface CommandDefinition extends Named {
|
|
5
|
+
/**
|
|
6
|
+
* The name of the command
|
|
7
|
+
*/
|
|
8
|
+
name: string;
|
|
9
|
+
/**
|
|
10
|
+
* The HTTP method for the command
|
|
11
|
+
*/
|
|
12
|
+
method: HTTPMethod;
|
|
13
|
+
/**
|
|
14
|
+
* The endpoint path for the command
|
|
15
|
+
*/
|
|
16
|
+
path: string;
|
|
17
|
+
/**
|
|
18
|
+
* The path parameters for the command
|
|
19
|
+
*/
|
|
20
|
+
pathParameters: Parameter[];
|
|
21
|
+
summary?: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
/**
|
|
24
|
+
* The schema for the command body
|
|
25
|
+
*/
|
|
26
|
+
schema: KeySchema;
|
|
27
|
+
operation: Operation;
|
|
28
|
+
}
|
|
29
|
+
export interface EventDefinition extends Named {
|
|
30
|
+
/**
|
|
31
|
+
* The name of the event
|
|
32
|
+
*/
|
|
33
|
+
name: string;
|
|
34
|
+
/**
|
|
35
|
+
* The title of the event
|
|
36
|
+
*/
|
|
37
|
+
title: string;
|
|
38
|
+
/**
|
|
39
|
+
* The schema for the event body
|
|
40
|
+
*/
|
|
41
|
+
schema: KeySchema;
|
|
42
|
+
}
|
|
43
|
+
export interface TagAliasAggregate extends AliasAggregate {
|
|
44
|
+
tag: Tag;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Complete definition of an aggregate including its commands, events, and state schemas.
|
|
48
|
+
*/
|
|
49
|
+
export interface AggregateDefinition {
|
|
50
|
+
/** The aggregate metadata with tag and alias information */
|
|
51
|
+
aggregate: TagAliasAggregate;
|
|
52
|
+
/**
|
|
53
|
+
* The aggregate's route segment, which is its name unless the aggregate
|
|
54
|
+
* sets a resource name: `sales-order` for the aggregate `order`.
|
|
55
|
+
*/
|
|
56
|
+
resourceName: string;
|
|
57
|
+
/**
|
|
58
|
+
* The schema for the aggregate root state
|
|
59
|
+
*/
|
|
60
|
+
state: KeySchema;
|
|
61
|
+
/**
|
|
62
|
+
* The fields schema for aggregate queries
|
|
63
|
+
*/
|
|
64
|
+
fields: KeySchema;
|
|
65
|
+
/**
|
|
66
|
+
* Map of command names to command definitions
|
|
67
|
+
*/
|
|
68
|
+
commands: Map<string, CommandDefinition>;
|
|
69
|
+
/**
|
|
70
|
+
* Map of event names to event definitions
|
|
71
|
+
*/
|
|
72
|
+
events: Map<string, EventDefinition>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Map of context aliases to sets of aggregate definitions
|
|
76
|
+
*/
|
|
77
|
+
export type BoundedContextAggregates = Map<string, Set<AggregateDefinition>>;
|
|
78
|
+
/**
|
|
79
|
+
* The doc comment the Wow metadata lends a schema: a command body takes its
|
|
80
|
+
* operation's summary and description where it has none of its own, an event
|
|
81
|
+
* body the title of its domain event. It holds every field the metadata
|
|
82
|
+
* sets, in the order it sets them, so a model's doc reads the schema with
|
|
83
|
+
* these over it the way it read the document the old resolver changed in
|
|
84
|
+
* place: a field the schema lacks comes last, and an `undefined` one is left
|
|
85
|
+
* out. The document itself is never changed.
|
|
86
|
+
*/
|
|
87
|
+
export type SchemaDocOverride = Readonly<Partial<Record<'title' | 'description', string | undefined>>>;
|
|
88
|
+
/** What the Wow metadata of a document says, read without changing it. */
|
|
89
|
+
export interface WowModel {
|
|
90
|
+
/** The bounded context the document names (`info.x-wow-context-alias`). */
|
|
91
|
+
readonly contextAlias?: string;
|
|
92
|
+
/** The aggregates that have state and query fields, by context alias. */
|
|
93
|
+
readonly contexts: BoundedContextAggregates;
|
|
94
|
+
/**
|
|
95
|
+
* The tags of every aggregate that exposes a Wow route, resolved or not.
|
|
96
|
+
* Their operations belong to command and query clients, not to API clients.
|
|
97
|
+
*/
|
|
98
|
+
readonly aggregateTags: ReadonlySet<string>;
|
|
99
|
+
/** The doc comments the metadata lends schemas, by component key. */
|
|
100
|
+
readonly schemaDocOverrides: ReadonlyMap<string, SchemaDocOverride>;
|
|
101
|
+
/** Aggregates and commands skipped for missing metadata, a warning each. */
|
|
102
|
+
readonly warnings: readonly string[];
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Tells whether the document comes from a Wow service: it names its bounded
|
|
106
|
+
* context, or it has aggregates.
|
|
107
|
+
*/
|
|
108
|
+
export declare function isWowDocument(wow: Pick<WowModel, 'contextAlias' | 'aggregateTags'>): boolean;
|
|
109
|
+
/**
|
|
110
|
+
* A schema as a model's doc reads it: the schema with the doc comment the
|
|
111
|
+
* Wow metadata lends it over it.
|
|
112
|
+
*
|
|
113
|
+
* @param schema - The schema, left unchanged
|
|
114
|
+
* @param override - What the metadata lends it, if anything
|
|
115
|
+
*/
|
|
116
|
+
export declare function withDocOverride<T extends object>(schema: T, override: SchemaDocOverride | undefined): T;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { HTTPMethod, Operation, Parameter, Tag } from '@ahoo-wang/fetcher-openapi';
|
|
2
|
+
import { AliasAggregate, Named } from '@ahoo-wang/wow-client';
|
|
3
|
+
import { KeySchema } from '../openapi/components.js';
|
|
4
|
+
export interface CommandDefinition extends Named {
|
|
5
|
+
/**
|
|
6
|
+
* The name of the command
|
|
7
|
+
*/
|
|
8
|
+
name: string;
|
|
9
|
+
/**
|
|
10
|
+
* The HTTP method for the command
|
|
11
|
+
*/
|
|
12
|
+
method: HTTPMethod;
|
|
13
|
+
/**
|
|
14
|
+
* The endpoint path for the command
|
|
15
|
+
*/
|
|
16
|
+
path: string;
|
|
17
|
+
/**
|
|
18
|
+
* The path parameters for the command
|
|
19
|
+
*/
|
|
20
|
+
pathParameters: Parameter[];
|
|
21
|
+
summary?: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
/**
|
|
24
|
+
* The schema for the command body
|
|
25
|
+
*/
|
|
26
|
+
schema: KeySchema;
|
|
27
|
+
operation: Operation;
|
|
28
|
+
}
|
|
29
|
+
export interface EventDefinition extends Named {
|
|
30
|
+
/**
|
|
31
|
+
* The name of the event
|
|
32
|
+
*/
|
|
33
|
+
name: string;
|
|
34
|
+
/**
|
|
35
|
+
* The title of the event
|
|
36
|
+
*/
|
|
37
|
+
title: string;
|
|
38
|
+
/**
|
|
39
|
+
* The schema for the event body
|
|
40
|
+
*/
|
|
41
|
+
schema: KeySchema;
|
|
42
|
+
}
|
|
43
|
+
export interface TagAliasAggregate extends AliasAggregate {
|
|
44
|
+
tag: Tag;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Complete definition of an aggregate including its commands, events, and state schemas.
|
|
48
|
+
*/
|
|
49
|
+
export interface AggregateDefinition {
|
|
50
|
+
/** The aggregate metadata with tag and alias information */
|
|
51
|
+
aggregate: TagAliasAggregate;
|
|
52
|
+
/**
|
|
53
|
+
* The aggregate's route segment, which is its name unless the aggregate
|
|
54
|
+
* sets a resource name: `sales-order` for the aggregate `order`.
|
|
55
|
+
*/
|
|
56
|
+
resourceName: string;
|
|
57
|
+
/**
|
|
58
|
+
* The schema for the aggregate root state
|
|
59
|
+
*/
|
|
60
|
+
state: KeySchema;
|
|
61
|
+
/**
|
|
62
|
+
* The fields schema for aggregate queries
|
|
63
|
+
*/
|
|
64
|
+
fields: KeySchema;
|
|
65
|
+
/**
|
|
66
|
+
* Map of command names to command definitions
|
|
67
|
+
*/
|
|
68
|
+
commands: Map<string, CommandDefinition>;
|
|
69
|
+
/**
|
|
70
|
+
* Map of event names to event definitions
|
|
71
|
+
*/
|
|
72
|
+
events: Map<string, EventDefinition>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Map of context aliases to sets of aggregate definitions
|
|
76
|
+
*/
|
|
77
|
+
export type BoundedContextAggregates = Map<string, Set<AggregateDefinition>>;
|
|
78
|
+
/**
|
|
79
|
+
* The doc comment the Wow metadata lends a schema: a command body takes its
|
|
80
|
+
* operation's summary and description where it has none of its own, an event
|
|
81
|
+
* body the title of its domain event. It holds every field the metadata
|
|
82
|
+
* sets, in the order it sets them, so a model's doc reads the schema with
|
|
83
|
+
* these over it the way it read the document the old resolver changed in
|
|
84
|
+
* place: a field the schema lacks comes last, and an `undefined` one is left
|
|
85
|
+
* out. The document itself is never changed.
|
|
86
|
+
*/
|
|
87
|
+
export type SchemaDocOverride = Readonly<Partial<Record<'title' | 'description', string | undefined>>>;
|
|
88
|
+
/** What the Wow metadata of a document says, read without changing it. */
|
|
89
|
+
export interface WowModel {
|
|
90
|
+
/** The bounded context the document names (`info.x-wow-context-alias`). */
|
|
91
|
+
readonly contextAlias?: string;
|
|
92
|
+
/** The aggregates that have state and query fields, by context alias. */
|
|
93
|
+
readonly contexts: BoundedContextAggregates;
|
|
94
|
+
/**
|
|
95
|
+
* The tags of every aggregate that exposes a Wow route, resolved or not.
|
|
96
|
+
* Their operations belong to command and query clients, not to API clients.
|
|
97
|
+
*/
|
|
98
|
+
readonly aggregateTags: ReadonlySet<string>;
|
|
99
|
+
/** The doc comments the metadata lends schemas, by component key. */
|
|
100
|
+
readonly schemaDocOverrides: ReadonlyMap<string, SchemaDocOverride>;
|
|
101
|
+
/** Aggregates and commands skipped for missing metadata, a warning each. */
|
|
102
|
+
readonly warnings: readonly string[];
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Tells whether the document comes from a Wow service: it names its bounded
|
|
106
|
+
* context, or it has aggregates.
|
|
107
|
+
*/
|
|
108
|
+
export declare function isWowDocument(wow: Pick<WowModel, 'contextAlias' | 'aggregateTags'>): boolean;
|
|
109
|
+
/**
|
|
110
|
+
* A schema as a model's doc reads it: the schema with the doc comment the
|
|
111
|
+
* Wow metadata lends it over it.
|
|
112
|
+
*
|
|
113
|
+
* @param schema - The schema, left unchanged
|
|
114
|
+
* @param override - What the metadata lends it, if anything
|
|
115
|
+
*/
|
|
116
|
+
export declare function withDocOverride<T extends object>(schema: T, override: SchemaDocOverride | undefined): T;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { OpenApiDocument } from '../openapi/document.cjs';
|
|
2
|
+
import { WowModel } from './model.cjs';
|
|
3
|
+
/**
|
|
4
|
+
* Reads the Wow metadata of a document: its bounded context, and each
|
|
5
|
+
* aggregate its tags name with the aggregate's commands, events, state,
|
|
6
|
+
* query fields and route segment.
|
|
7
|
+
*
|
|
8
|
+
* An aggregate needs its state (`snapshot_state.single`) and its query fields
|
|
9
|
+
* (`snapshot.count`) to generate clients; one that lacks either is left out
|
|
10
|
+
* with a warning, and so is a command whose body is not a component schema.
|
|
11
|
+
*
|
|
12
|
+
* It is a pure function: the document is left as it was. The doc comments the
|
|
13
|
+
* metadata lends command and event bodies are in
|
|
14
|
+
* {@link WowModel.schemaDocOverrides}.
|
|
15
|
+
*
|
|
16
|
+
* @param document - The document
|
|
17
|
+
* @returns The Wow model, and the warnings to log
|
|
18
|
+
* @throws GeneratorError (`specification`) when an aggregate's Wow metadata
|
|
19
|
+
* is malformed, or a command's response references form a cycle
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveWowModel(document: OpenApiDocument): WowModel;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { OpenApiDocument } from '../openapi/document.js';
|
|
2
|
+
import { WowModel } from './model.js';
|
|
3
|
+
/**
|
|
4
|
+
* Reads the Wow metadata of a document: its bounded context, and each
|
|
5
|
+
* aggregate its tags name with the aggregate's commands, events, state,
|
|
6
|
+
* query fields and route segment.
|
|
7
|
+
*
|
|
8
|
+
* An aggregate needs its state (`snapshot_state.single`) and its query fields
|
|
9
|
+
* (`snapshot.count`) to generate clients; one that lacks either is left out
|
|
10
|
+
* with a warning, and so is a command whose body is not a component schema.
|
|
11
|
+
*
|
|
12
|
+
* It is a pure function: the document is left as it was. The doc comments the
|
|
13
|
+
* metadata lends command and event bodies are in
|
|
14
|
+
* {@link WowModel.schemaDocOverrides}.
|
|
15
|
+
*
|
|
16
|
+
* @param document - The document
|
|
17
|
+
* @returns The Wow model, and the warnings to log
|
|
18
|
+
* @throws GeneratorError (`specification`) when an aggregate's Wow metadata
|
|
19
|
+
* is malformed, or a command's response references form a cycle
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveWowModel(document: OpenApiDocument): WowModel;
|
package/package.json
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ahoo-wang/wow-generator",
|
|
3
|
+
"version": "9.2.0-rc.0",
|
|
4
|
+
"description": "Generates TypeScript models, Fetcher decorator clients and Wow command and query clients from a local or remote OpenAPI 3 document. The Wow clients follow the CQRS model of the Wow DDD framework (https://github.com/Ahoo-Wang/Wow).",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"wow",
|
|
7
|
+
"wow-generator",
|
|
8
|
+
"cqrs",
|
|
9
|
+
"ddd",
|
|
10
|
+
"openapi",
|
|
11
|
+
"openapi3",
|
|
12
|
+
"swagger",
|
|
13
|
+
"generator",
|
|
14
|
+
"codegen",
|
|
15
|
+
"typescript",
|
|
16
|
+
"api",
|
|
17
|
+
"client",
|
|
18
|
+
"rest",
|
|
19
|
+
"fetch",
|
|
20
|
+
"http"
|
|
21
|
+
],
|
|
22
|
+
"author": "Ahoo-Wang",
|
|
23
|
+
"license": "Apache-2.0",
|
|
24
|
+
"homepage": "https://wow.ahoo.me/reference/typescript/wow-generator/",
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+https://github.com/Ahoo-Wang/Wow.git",
|
|
28
|
+
"directory": "typescript/wow-generator"
|
|
29
|
+
},
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/Ahoo-Wang/Wow/issues"
|
|
32
|
+
},
|
|
33
|
+
"type": "module",
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=22.12.0"
|
|
36
|
+
},
|
|
37
|
+
"main": "./dist/index.cjs",
|
|
38
|
+
"module": "./dist/index.js",
|
|
39
|
+
"types": "./dist/index.d.ts",
|
|
40
|
+
"bin": {
|
|
41
|
+
"wow-generator": "./dist/cli.js",
|
|
42
|
+
"fetcher-generator": "./dist/cli.js"
|
|
43
|
+
},
|
|
44
|
+
"exports": {
|
|
45
|
+
".": {
|
|
46
|
+
"import": {
|
|
47
|
+
"types": "./dist/index.d.ts",
|
|
48
|
+
"default": "./dist/index.js"
|
|
49
|
+
},
|
|
50
|
+
"require": {
|
|
51
|
+
"types": "./dist/index.d.cts",
|
|
52
|
+
"default": "./dist/index.cjs"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"./package.json": "./package.json"
|
|
56
|
+
},
|
|
57
|
+
"files": [
|
|
58
|
+
"dist",
|
|
59
|
+
"README.md",
|
|
60
|
+
"README.zh-CN.md"
|
|
61
|
+
],
|
|
62
|
+
"sideEffects": false,
|
|
63
|
+
"peerDependencies": {
|
|
64
|
+
"@ahoo-wang/fetcher": "^5.1.5",
|
|
65
|
+
"@ahoo-wang/fetcher-decorator": "^5.1.5",
|
|
66
|
+
"@ahoo-wang/fetcher-eventstream": "^5.1.5",
|
|
67
|
+
"@ahoo-wang/wow-client": "~9.2.0-rc.0"
|
|
68
|
+
},
|
|
69
|
+
"dependencies": {
|
|
70
|
+
"ts-morph": "^28.0.0",
|
|
71
|
+
"commander": "^14.0.3",
|
|
72
|
+
"yaml": "^2.9.1"
|
|
73
|
+
},
|
|
74
|
+
"devDependencies": {
|
|
75
|
+
"@ahoo-wang/fetcher": "^5.1.5",
|
|
76
|
+
"@ahoo-wang/fetcher-decorator": "^5.1.5",
|
|
77
|
+
"@ahoo-wang/fetcher-eventstream": "^5.1.5",
|
|
78
|
+
"@ahoo-wang/fetcher-openapi": "^5.1.5",
|
|
79
|
+
"@eslint/js": "^10.0.1",
|
|
80
|
+
"@types/node": "^26.6.3",
|
|
81
|
+
"@vitest/coverage-v8": "4.1.11",
|
|
82
|
+
"@vitest/ui": "^4.1.11",
|
|
83
|
+
"eslint": "^10.11.0",
|
|
84
|
+
"eslint-plugin-import-x": "^4.17.1",
|
|
85
|
+
"globals": "^17.12.0",
|
|
86
|
+
"prettier": "3.9.9",
|
|
87
|
+
"typescript": "~6.0.3",
|
|
88
|
+
"typescript-eslint": "^8.70.1",
|
|
89
|
+
"unplugin-dts": "1.1.1",
|
|
90
|
+
"vite": "8.3.1",
|
|
91
|
+
"vite-bundle-analyzer": "^1.3.9",
|
|
92
|
+
"vitest": "^4.1.11",
|
|
93
|
+
"@ahoo-wang/wow-client": "~9.2.0-rc.0"
|
|
94
|
+
},
|
|
95
|
+
"scripts": {
|
|
96
|
+
"build": "vite build && pnpm test:package",
|
|
97
|
+
"test:package": "node scripts/verify-package.mjs",
|
|
98
|
+
"test:ui": "vitest --ui",
|
|
99
|
+
"test": "vitest run --coverage --testTimeout=15000 && pnpm test:type",
|
|
100
|
+
"test:type": "tsc --noEmit -p test/tsconfig.types.json",
|
|
101
|
+
"lint": "eslint . --fix",
|
|
102
|
+
"clean": "rm -rf dist",
|
|
103
|
+
"analyze": "npx vite-bundle-analyzer -p auto",
|
|
104
|
+
"generate": "node dist/cli.js generate -i test/demo.spec.json -o test-output -t tsconfig.json",
|
|
105
|
+
"test:no-coverage": "vitest run --coverage.enabled=false --testTimeout=15000 && pnpm test:type",
|
|
106
|
+
"bench": "node scripts/bench.mjs"
|
|
107
|
+
}
|
|
108
|
+
}
|