@ahoo-wang/fetcher-generator 2.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/LICENSE +201 -0
- package/README.md +289 -0
- package/dist/aggregate/aggregate.d.ts +73 -0
- package/dist/aggregate/aggregate.d.ts.map +1 -0
- package/dist/aggregate/aggregateResolver.d.ts +48 -0
- package/dist/aggregate/aggregateResolver.d.ts.map +1 -0
- package/dist/aggregate/index.d.ts +5 -0
- package/dist/aggregate/index.d.ts.map +1 -0
- package/dist/aggregate/types.d.ts +33 -0
- package/dist/aggregate/types.d.ts.map +1 -0
- package/dist/aggregate/utils.d.ts +45 -0
- package/dist/aggregate/utils.d.ts.map +1 -0
- package/dist/baseCodeGenerator.d.ts +22 -0
- package/dist/baseCodeGenerator.d.ts.map +1 -0
- package/dist/cli.cjs +2 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +56 -0
- package/dist/client/clientGenerator.d.ts +25 -0
- package/dist/client/clientGenerator.d.ts.map +1 -0
- package/dist/client/commandClientGenerator.d.ts +38 -0
- package/dist/client/commandClientGenerator.d.ts.map +1 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/queryClientGenerator.d.ts +32 -0
- package/dist/client/queryClientGenerator.d.ts.map +1 -0
- package/dist/client/utils.d.ts +12 -0
- package/dist/client/utils.d.ts.map +1 -0
- package/dist/index.cjs +11 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +968 -0
- package/dist/model/index.d.ts +4 -0
- package/dist/model/index.d.ts.map +1 -0
- package/dist/model/modelGenerator.d.ts +130 -0
- package/dist/model/modelGenerator.d.ts.map +1 -0
- package/dist/model/modelInfo.d.ts +27 -0
- package/dist/model/modelInfo.d.ts.map +1 -0
- package/dist/model/wowTypeMapping.d.ts +33 -0
- package/dist/model/wowTypeMapping.d.ts.map +1 -0
- package/dist/types.d.ts +44 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/clis.d.ts +18 -0
- package/dist/utils/clis.d.ts.map +1 -0
- package/dist/utils/components.d.ts +64 -0
- package/dist/utils/components.d.ts.map +1 -0
- package/dist/utils/index.d.ts +11 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/logger.d.ts +21 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/naming.d.ts +21 -0
- package/dist/utils/naming.d.ts.map +1 -0
- package/dist/utils/openAPIParser.d.ts +14 -0
- package/dist/utils/openAPIParser.d.ts.map +1 -0
- package/dist/utils/operations.d.ts +29 -0
- package/dist/utils/operations.d.ts.map +1 -0
- package/dist/utils/references.d.ts +3 -0
- package/dist/utils/references.d.ts.map +1 -0
- package/dist/utils/resources.d.ts +4 -0
- package/dist/utils/resources.d.ts.map +1 -0
- package/dist/utils/responses.d.ts +8 -0
- package/dist/utils/responses.d.ts.map +1 -0
- package/dist/utils/schemas.d.ts +22 -0
- package/dist/utils/schemas.d.ts.map +1 -0
- package/dist/utils/sourceFiles.d.ts +54 -0
- package/dist/utils/sourceFiles.d.ts.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Tag } from '@ahoo-wang/fetcher-openapi';
|
|
2
|
+
import { PartialBy } from '@ahoo-wang/fetcher';
|
|
3
|
+
import { AggregateDefinition, TagAliasAggregate } from './aggregate';
|
|
4
|
+
/**
|
|
5
|
+
* Checks if a tag name follows the alias aggregate pattern and extracts its components.
|
|
6
|
+
*
|
|
7
|
+
* This function determines if a tag name follows the format "contextAlias.aggregateName"
|
|
8
|
+
* and returns the components if it matches.
|
|
9
|
+
*
|
|
10
|
+
* @param tagName - The tag name to check
|
|
11
|
+
* @returns A tuple with [contextAlias, aggregateName] if the pattern matches, null otherwise
|
|
12
|
+
*/
|
|
13
|
+
export declare function isAliasAggregate(tagName: string): [string, string] | null;
|
|
14
|
+
/**
|
|
15
|
+
* Converts a Tag to a TagAliasAggregate if it follows the alias pattern.
|
|
16
|
+
*
|
|
17
|
+
* This function checks if a tag name follows the alias aggregate pattern and
|
|
18
|
+
* creates a TagAliasAggregate object with the tag and its parsed components.
|
|
19
|
+
*
|
|
20
|
+
* @param tag - The Tag to convert
|
|
21
|
+
* @returns A TagAliasAggregate if the tag name matches the pattern, null otherwise
|
|
22
|
+
*/
|
|
23
|
+
export declare function tagToAggregate(tag: Tag): TagAliasAggregate | null;
|
|
24
|
+
/**
|
|
25
|
+
* Converts an array of Tags to a map of aggregates.
|
|
26
|
+
*
|
|
27
|
+
* This function processes an array of tags, converts those that follow the alias pattern
|
|
28
|
+
* to aggregates, and returns a map where keys are tag names and values are partial
|
|
29
|
+
* aggregate definitions.
|
|
30
|
+
*
|
|
31
|
+
* @param tags - Optional array of Tags to process
|
|
32
|
+
* @returns A map of aggregate definitions keyed by tag name
|
|
33
|
+
*/
|
|
34
|
+
export declare function tagsToAggregates(tags?: Tag[]): Map<string, PartialBy<AggregateDefinition, 'state' | 'fields'>>;
|
|
35
|
+
/**
|
|
36
|
+
* Extracts the command name from an operation ID.
|
|
37
|
+
*
|
|
38
|
+
* This function parses an operation ID expected to follow the format
|
|
39
|
+
* "context.aggregate.command" and returns the command part.
|
|
40
|
+
*
|
|
41
|
+
* @param operationId - Optional operation ID to parse
|
|
42
|
+
* @returns The command name if the operation ID follows the expected format, null otherwise
|
|
43
|
+
*/
|
|
44
|
+
export declare function operationIdToCommandName(operationId?: string): string | null;
|
|
45
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/aggregate/utils.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,GAAG,EAAE,MAAM,4BAA4B,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErE;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAMzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG,iBAAiB,GAAG,IAAI,CAWjE;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,CAAC,EAAE,GAAG,EAAE,GACX,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,mBAAmB,EAAE,OAAO,GAAG,QAAQ,CAAC,CAAC,CAmBjE;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS5E"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Project } from 'ts-morph';
|
|
2
|
+
import { OpenAPI } from '@ahoo-wang/fetcher-openapi';
|
|
3
|
+
import { GenerateContext, Logger } from './types';
|
|
4
|
+
import { BoundedContextAggregates } from './aggregate';
|
|
5
|
+
export declare abstract class BaseCodeGenerator implements GenerateContext {
|
|
6
|
+
readonly project: Project;
|
|
7
|
+
readonly openAPI: OpenAPI;
|
|
8
|
+
readonly outputDir: string;
|
|
9
|
+
readonly contextAggregates: BoundedContextAggregates;
|
|
10
|
+
readonly logger?: Logger;
|
|
11
|
+
/**
|
|
12
|
+
* Creates a new ClientGenerator instance.
|
|
13
|
+
* @param context - The generation context containing OpenAPI spec and project details
|
|
14
|
+
*/
|
|
15
|
+
protected constructor(context: GenerateContext);
|
|
16
|
+
/**
|
|
17
|
+
* Generates code based on the provided context.
|
|
18
|
+
* Subclasses must implement this method to define their specific generation logic.
|
|
19
|
+
*/
|
|
20
|
+
abstract generate(): void;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=baseCodeGenerator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseCodeGenerator.d.ts","sourceRoot":"","sources":["../src/baseCodeGenerator.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAEvD,8BAAsB,iBAAkB,YAAW,eAAe;IAChE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,iBAAiB,EAAE,wBAAwB,CAAC;IACrD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,SAAS,aAAa,OAAO,EAAE,eAAe;IAQ9C;;;OAGG;IACH,QAAQ,CAAC,QAAQ,IAAI,IAAI;CAC1B"}
|
package/dist/cli.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";const t=require("commander"),i=require("./index.cjs"),c=require("ts-morph");require("yaml");require("fs");require("@ahoo-wang/fetcher");class s{info(e){console.log(`ℹ️ ${e}`)}success(e){console.log(`✅ ${e}`)}error(e){console.error(`❌ ${e}`)}progress(e){console.log(`🔄 ${e}`)}}function a(r){if(!r)return!1;try{const e=new URL(r);return e.protocol==="http:"||e.protocol==="https:"}catch{return r.length>0}}async function p(r){const e=new s;process.on("SIGINT",()=>{e.error("Generation interrupted by user"),process.exit(130)}),a(r.input)||(e.error("Invalid input: must be a valid file path or HTTP/HTTPS URL"),process.exit(2));try{e.info("Starting code generation...");const o=new c.Project,n={inputPath:r.input,outputDir:r.output,project:o,logger:e};await new i.CodeGenerator(n).generate(),e.success(`Code generation completed successfully! Files generated in: ${r.output}`)}catch(o){e.error(`Error during code generation: ${o}`),process.exit(1)}}t.program.name("fetcher-generator").description("OpenAPI Specification TypeScript code generator for Wow").version("1.0.0");t.program.command("generate").description("Generate TypeScript code from OpenAPI specification").requiredOption("-i, --input <path>","Input OpenAPI specification file path or URL (http/https)").option("-o, --output <path>","Output directory path","src/generated").option("-c, --config <file>","Configuration file path").option("-v, --verbose","Enable verbose logging").option("--dry-run","Show what would be generated without writing files").action(p);t.program.parse();
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;GAGG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { program as t } from "commander";
|
|
3
|
+
import { CodeGenerator as i } from "./index.js";
|
|
4
|
+
import { Project as c } from "ts-morph";
|
|
5
|
+
import "yaml";
|
|
6
|
+
import "fs";
|
|
7
|
+
import "@ahoo-wang/fetcher";
|
|
8
|
+
class p {
|
|
9
|
+
info(e) {
|
|
10
|
+
console.log(`ℹ️ ${e}`);
|
|
11
|
+
}
|
|
12
|
+
success(e) {
|
|
13
|
+
console.log(`✅ ${e}`);
|
|
14
|
+
}
|
|
15
|
+
error(e) {
|
|
16
|
+
console.error(`❌ ${e}`);
|
|
17
|
+
}
|
|
18
|
+
progress(e) {
|
|
19
|
+
console.log(`🔄 ${e}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function a(o) {
|
|
23
|
+
if (!o) return !1;
|
|
24
|
+
try {
|
|
25
|
+
const e = new URL(o);
|
|
26
|
+
return e.protocol === "http:" || e.protocol === "https:";
|
|
27
|
+
} catch {
|
|
28
|
+
return o.length > 0;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async function s(o) {
|
|
32
|
+
const e = new p();
|
|
33
|
+
process.on("SIGINT", () => {
|
|
34
|
+
e.error("Generation interrupted by user"), process.exit(130);
|
|
35
|
+
}), a(o.input) || (e.error("Invalid input: must be a valid file path or HTTP/HTTPS URL"), process.exit(2));
|
|
36
|
+
try {
|
|
37
|
+
e.info("Starting code generation...");
|
|
38
|
+
const r = new c(), n = {
|
|
39
|
+
inputPath: o.input,
|
|
40
|
+
outputDir: o.output,
|
|
41
|
+
project: r,
|
|
42
|
+
logger: e
|
|
43
|
+
};
|
|
44
|
+
await new i(n).generate(), e.success(
|
|
45
|
+
`Code generation completed successfully! Files generated in: ${o.output}`
|
|
46
|
+
);
|
|
47
|
+
} catch (r) {
|
|
48
|
+
e.error(`Error during code generation: ${r}`), process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
t.name("fetcher-generator").description("OpenAPI Specification TypeScript code generator for Wow").version("1.0.0");
|
|
52
|
+
t.command("generate").description("Generate TypeScript code from OpenAPI specification").requiredOption(
|
|
53
|
+
"-i, --input <path>",
|
|
54
|
+
"Input OpenAPI specification file path or URL (http/https)"
|
|
55
|
+
).option("-o, --output <path>", "Output directory path", "src/generated").option("-c, --config <file>", "Configuration file path").option("-v, --verbose", "Enable verbose logging").option("--dry-run", "Show what would be generated without writing files").action(s);
|
|
56
|
+
t.parse();
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { BaseCodeGenerator } from '../baseCodeGenerator';
|
|
2
|
+
import { GenerateContext } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Generates TypeScript client classes for aggregates.
|
|
5
|
+
* Creates query clients and command clients based on aggregate definitions.
|
|
6
|
+
*/
|
|
7
|
+
export declare class ClientGenerator extends BaseCodeGenerator {
|
|
8
|
+
private readonly queryClientGenerator;
|
|
9
|
+
private readonly commandClientGenerator;
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new ClientGenerator instance.
|
|
12
|
+
* @param context - The generation context containing OpenAPI spec and project details
|
|
13
|
+
*/
|
|
14
|
+
constructor(context: GenerateContext);
|
|
15
|
+
/**
|
|
16
|
+
* Generates client classes for all aggregates.
|
|
17
|
+
*/
|
|
18
|
+
generate(): void;
|
|
19
|
+
/**
|
|
20
|
+
* Processes a bounded context by creating a file with the context alias constant.
|
|
21
|
+
* @param contextAlias - The alias of the bounded context to process
|
|
22
|
+
*/
|
|
23
|
+
processBoundedContext(contextAlias: string): void;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=clientGenerator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientGenerator.d.ts","sourceRoot":"","sources":["../../src/client/clientGenerator.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAG3C;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,iBAAiB;IACpD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAuB;IAC5D,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAyB;IAEhE;;;OAGG;gBACS,OAAO,EAAE,eAAe;IAMpC;;OAEG;IACH,QAAQ,IAAI,IAAI;IAahB;;;OAGG;IACH,qBAAqB,CAAC,YAAY,EAAE,MAAM;CAO3C"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { BaseCodeGenerator } from '../baseCodeGenerator';
|
|
2
|
+
import { GenerateContext } from '../types';
|
|
3
|
+
import { ClassDeclaration, SourceFile } from 'ts-morph';
|
|
4
|
+
import { AggregateDefinition, CommandDefinition } from '../aggregate';
|
|
5
|
+
/**
|
|
6
|
+
* Generates TypeScript command client classes for aggregates.
|
|
7
|
+
* Creates command clients that can send commands to aggregates.
|
|
8
|
+
*/
|
|
9
|
+
export declare class CommandClientGenerator extends BaseCodeGenerator {
|
|
10
|
+
private readonly commandEndpointPathsName;
|
|
11
|
+
private readonly defaultCommandClientOptionsName;
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new CommandClientGenerator instance.
|
|
14
|
+
* @param context - The generation context containing OpenAPI spec and project details
|
|
15
|
+
*/
|
|
16
|
+
constructor(context: GenerateContext);
|
|
17
|
+
/**
|
|
18
|
+
* Generates command client classes for all aggregates.
|
|
19
|
+
*/
|
|
20
|
+
generate(): void;
|
|
21
|
+
/**
|
|
22
|
+
* Processes and generates command client for an aggregate.
|
|
23
|
+
* @param aggregate - The aggregate definition
|
|
24
|
+
*/
|
|
25
|
+
processAggregate(aggregate: AggregateDefinition): void;
|
|
26
|
+
processCommandEndpointPaths(clientFile: SourceFile, aggregateDefinition: AggregateDefinition): void;
|
|
27
|
+
getEndpointPath(command: CommandDefinition): string;
|
|
28
|
+
processCommandClient(clientFile: SourceFile, aggregateDefinition: AggregateDefinition, isStream?: boolean): void;
|
|
29
|
+
private methodToDecorator;
|
|
30
|
+
/**
|
|
31
|
+
* Processes and generates a command method for the command client.
|
|
32
|
+
* @param sourceFile - The source file containing the client
|
|
33
|
+
* @param client - The client class declaration
|
|
34
|
+
* @param definition - The command definition
|
|
35
|
+
*/
|
|
36
|
+
processCommandMethod(sourceFile: SourceFile, client: ClassDeclaration, definition: CommandDefinition, returnType: string): void;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=commandClientGenerator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commandClientGenerator.d.ts","sourceRoot":"","sources":["../../src/client/commandClientGenerator.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EACL,gBAAgB,EAIhB,UAAU,EAEX,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAKtE;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,iBAAiB;IAC3D,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAA4B;IACrE,OAAO,CAAC,QAAQ,CAAC,+BAA+B,CACb;IAEnC;;;OAGG;gBACS,OAAO,EAAE,eAAe;IAIpC;;OAEG;IACH,QAAQ,IAAI,IAAI;IAiBhB;;;OAGG;IACH,gBAAgB,CAAC,SAAS,EAAE,mBAAmB;IAsD/C,2BAA2B,CACzB,UAAU,EAAE,UAAU,EACtB,mBAAmB,EAAE,mBAAmB;IAa1C,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM;IAInD,oBAAoB,CAClB,UAAU,EAAE,UAAU,EACtB,mBAAmB,EAAE,mBAAmB,EACxC,QAAQ,GAAE,OAAe;IAiD3B,OAAO,CAAC,iBAAiB;IAOzB;;;;;OAKG;IACH,oBAAoB,CAClB,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,gBAAgB,EACxB,UAAU,EAAE,iBAAiB,EAC7B,UAAU,EAAE,MAAM;CAoDrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAaA,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { SourceFile } from 'ts-morph';
|
|
2
|
+
import { GenerateContext } from '../types';
|
|
3
|
+
import { BaseCodeGenerator } from '../baseCodeGenerator';
|
|
4
|
+
import { AggregateDefinition, TagAliasAggregate } from '../aggregate';
|
|
5
|
+
/**
|
|
6
|
+
* Generates TypeScript query client classes for aggregates.
|
|
7
|
+
* Creates query clients that can perform state queries and event streaming.
|
|
8
|
+
*/
|
|
9
|
+
export declare class QueryClientGenerator extends BaseCodeGenerator {
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new QueryClientGenerator instance.
|
|
12
|
+
* @param context - The generation context containing OpenAPI spec and project details
|
|
13
|
+
*/
|
|
14
|
+
constructor(context: GenerateContext);
|
|
15
|
+
/**
|
|
16
|
+
* Generates query client classes for all aggregates.
|
|
17
|
+
*/
|
|
18
|
+
generate(): void;
|
|
19
|
+
/**
|
|
20
|
+
* Creates or retrieves a source file for client generation.
|
|
21
|
+
* @param aggregate - The aggregate metadata
|
|
22
|
+
* @param fileName - The name of the client file
|
|
23
|
+
* @returns The source file for the client
|
|
24
|
+
*/
|
|
25
|
+
createClientFilePath(aggregate: TagAliasAggregate, fileName: string): SourceFile;
|
|
26
|
+
/**
|
|
27
|
+
* Processes and generates query client classes for an aggregate.
|
|
28
|
+
* @param aggregate - The aggregate definition
|
|
29
|
+
*/
|
|
30
|
+
processQueryClient(aggregate: AggregateDefinition): void;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=queryClientGenerator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryClientGenerator.d.ts","sourceRoot":"","sources":["../../src/client/queryClientGenerator.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,UAAU,EAA2B,MAAM,UAAU,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAKtE;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,iBAAiB;IACzD;;;OAGG;gBACS,OAAO,EAAE,eAAe;IAIpC;;OAEG;IACH,QAAQ,IAAI,IAAI;IAiBhB;;;;;OAKG;IACH,oBAAoB,CAClB,SAAS,EAAE,iBAAiB,EAC5B,QAAQ,EAAE,MAAM,GACf,UAAU;IASb;;;OAGG;IACH,kBAAkB,CAAC,SAAS,EAAE,mBAAmB;CAwDlD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Project, SourceFile } from 'ts-morph';
|
|
2
|
+
import { AggregateDefinition, TagAliasAggregate } from '../aggregate';
|
|
3
|
+
export declare function inferPathSpecType(aggregateDefinition: AggregateDefinition): string;
|
|
4
|
+
export declare function createClientFilePath(project: Project, outputDir: string, aggregate: TagAliasAggregate, fileName: string): SourceFile;
|
|
5
|
+
/**
|
|
6
|
+
* Generates the client class name for an aggregate.
|
|
7
|
+
* @param aggregate - The aggregate metadata
|
|
8
|
+
* @param suffix - The suffix to append to the aggregate name
|
|
9
|
+
* @returns The generated client class name
|
|
10
|
+
*/
|
|
11
|
+
export declare function getClientName(aggregate: TagAliasAggregate, suffix: string): string;
|
|
12
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/client/utils.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGtE,wBAAgB,iBAAiB,CAC/B,mBAAmB,EAAE,mBAAmB,GACvC,MAAM,CAiBR;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,iBAAiB,EAC5B,QAAQ,EAAE,MAAM,GACf,UAAU,CAGZ;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,MAAM,GACb,MAAM,CAER"}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const A=require("ts-morph"),B=require("yaml"),L=require("fs"),g=require("@ahoo-wang/fetcher"),v=require("@ahoo-wang/fetcher-wow");function y(r){return r.$ref.split("/").pop()}function P(r,e){const n=y(r);return e.schemas?.[n]}function F(r,e){const n=y(r);return e.requestBodies?.[n]}function K(r,e){const n=y(r);return e.parameters?.[n]}function C(r,e){return{key:y(r),schema:P(r,e)}}const I=/[-_\s.]+|(?=[A-Z])/;function T(r){if(r===""||r.length===0)return"";let e;return Array.isArray(r)?e=r.flatMap(n=>n.split(I)):e=r.split(I),e.filter(n=>n.length>0).map(n=>{if(n.length===0)return"";const t=n.charAt(0),o=n.slice(1);return(/[a-zA-Z]/.test(t)?t.toUpperCase():t)+o.toLowerCase()}).join("")}function D(r){const e=T(r);return e.charAt(0).toLowerCase()+e.slice(1)}function U(r){return r.startsWith("http://")||r.startsWith("https://")?Q(r):V(r)}async function Q(r){return await(await fetch(r)).text()}function V(r){return new Promise((e,n)=>{L.readFile(r,"utf-8",(t,o)=>{t?n(t):e(o)})})}async function k(r){const e=await U(r);switch(J(e)){case"json":return JSON.parse(e);case"yaml":return B.parse(e);default:throw new Error(`Unsupported file format: ${r}`)}}function J(r){const e=r.trimStart();if(e.startsWith("{")||e.startsWith("["))return"json";if(e.startsWith("-")||e.startsWith("%YAML"))return"yaml";try{return JSON.parse(e),"json"}catch{if(e.length>0)return"yaml"}throw new Error("Unable to infer file format")}function l(r){return!!(r&&typeof r=="object"&&"$ref"in r)}function z(r){return!r||l(r)||!r.content?void 0:r.content[g.ContentTypeValues.APPLICATION_JSON]?.schema}function H(r){return[{method:"get",operation:r.get},{method:"put",operation:r.put},{method:"post",operation:r.post},{method:"delete",operation:r.delete},{method:"options",operation:r.options},{method:"head",operation:r.head},{method:"patch",operation:r.patch},{method:"trace",operation:r.trace}].filter(({operation:e})=>e!==void 0)}function M(r){return r.responses[200]}function b(r){const e=M(r);return z(e)}function Y(r){return Array.isArray(r.enum)&&r.enum.length>0}function j(r){if(Array.isArray(r))return r.map(e=>j(e)).join(" | ");switch(r){case"string":return"string";case"number":case"integer":return"number";case"boolean":return"boolean";case"null":return"null";default:return"any"}}const Z="types.ts",S="@";function $(r){return g.combineURLs(r.path,Z)}function O(r,e,n){const t=g.combineURLs(e,n),o=r.getSourceFile(t);return o||r.createSourceFile(t,"",{overwrite:!0})}function E(r,e,n){let t=r.getImportDeclaration(o=>o.getModuleSpecifierValue()===e);t||(t=r.addImportDeclaration({moduleSpecifier:e})),n.forEach(o=>{t.getNamedImports().some(s=>s.getName()===o)||t.addNamedImport(o)})}function h(r,e,n){let t=$(n);n.path.startsWith(S)||(t=g.combineURLs(e,t));let o=t;t.startsWith(S)||(o=g.combineURLs(S,t)),E(r,o,[n.name])}function X(r,e,n,t){r.path!==t.path&&h(e,n,t)}function q(r,e){const n=[r,e].filter(t=>t!==void 0&&t.length>0);return n.length>0?n.join(`
|
|
2
|
+
`):void 0}function x(r,e){const n=q(r,e);return n?[n]:[]}function _(r,e,n){const t=q(e,n);t&&r.addJsDoc({description:t})}function ee(r){const e=r.split(".");return e.length!=2||e[0].length===0||e[1].length===0?null:e}function te(r){const e=ee(r.name);return e?{tag:r,contextAlias:e[0],aggregateName:e[1]}:null}function ne(r){const e=r?.map(t=>te(t)).filter(t=>t!==null);if(!e)return new Map;const n=new Map;return e.forEach(t=>{n.set(t.tag.name,{aggregate:t,commands:new Map,events:new Map})}),n}function re(r){if(!r)return null;const e=r.split(".");return e.length!=3?null:e[2]}const oe="#/components/responses/wow.CommandOk",ae="#/components/parameters/wow.id";class se{constructor(e){this.openAPI=e,this.aggregates=ne(e.tags),this.build()}aggregates;build(){for(const[e,n]of Object.entries(this.openAPI.paths)){const t=H(n);for(const o of t)this.commands(e,o),this.state(o.operation),this.events(o.operation),this.fields(o.operation)}}resolve(){const e=new Map;for(const n of this.aggregates.values()){if(!n.state||!n.fields)continue;const t=n.aggregate.contextAlias;let o=e.get(t);o||(o=new Set,e.set(t,o)),o.add(n)}return e}commands(e,n){const t=n.operation;if(t.operationId==="wow.command.send")return;const o=re(t.operationId);if(!o)return;const a=M(t);if(!a||!l(a)||a.$ref!==oe||!t.requestBody)return;const s=t.parameters??[],c=s.filter(u=>l(u)&&u.$ref===ae).at(0),i=s.filter(u=>!l(u)&&u.in==="path");if(c){const u=K(c,this.openAPI.components);i.push(u)}const m=t.requestBody.content[g.ContentTypeValues.APPLICATION_JSON].schema,f=C(m,this.openAPI.components);f.schema.title=f.schema.title||t.summary,f.schema.description=f.schema.description||t.description;const W={name:o,method:n.method,path:e,pathParameters:i,summary:t.summary,description:t.description,schema:f,operation:t};t.tags?.forEach(u=>{const R=this.aggregates.get(u);R&&R.commands.set(o,W)})}state(e){if(!e.operationId?.endsWith(".snapshot_state.single"))return;const n=b(e);if(!l(n))return;const t=C(n,this.openAPI.components);e.tags?.forEach(o=>{const a=this.aggregates.get(o);a&&(a.state=t)})}events(e){if(!this.openAPI.components||!e.operationId?.endsWith(".event.list_query"))return;const n=b(e);if(l(n))return;const t=n?.items;if(!l(t))return;const a=P(t,this.openAPI.components).properties.body.items.anyOf.map(s=>{const c=s.title,i=s.properties.name.const,p=s.properties.body,m=C(p,this.openAPI.components);return m.schema.title=m.schema.title||s.title,{title:c,name:i,schema:m}});e.tags?.forEach(s=>{const c=this.aggregates.get(s);c&&a.forEach(i=>{c.events.set(i.name,i)})})}fields(e){if(!this.openAPI.components||!e.operationId?.endsWith(".snapshot.count"))return;const t=F(e.requestBody,this.openAPI.components).content[g.ContentTypeValues.APPLICATION_JSON].schema,a=P(t,this.openAPI.components).properties?.field,s=C(a,this.openAPI.components);e.tags?.forEach(c=>{const i=this.aggregates.get(c);i&&(i.fields=s)})}}const N="@ahoo-wang/fetcher-wow",ie={"wow.command.CommandResult":"CommandResult","wow.MessageHeaderSqlType":"MessageHeaderSqlType","wow.api.BindingError":"BindingError","wow.api.DefaultErrorInfo":"ErrorInfo","wow.api.RecoverableType":"RecoverableType","wow.api.command.DefaultDeleteAggregate":"DeleteAggregate","wow.api.command.DefaultRecoverAggregate":"RecoverAggregate","wow.api.messaging.FunctionInfoData":"FunctionInfo","wow.api.messaging.FunctionKind":"FunctionKind","wow.api.modeling.AggregateId":"AggregateId","wow.api.query.Condition":"Condition","wow.api.query.ConditionOptions":"ConditionOptions","wow.api.query.ListQuery":"ListQuery","wow.api.query.Operator":"Operator","wow.api.query.PagedQuery":"PagedQuery","wow.api.query.Pagination":"Pagination","wow.api.query.Projection":"Projection","wow.api.query.Sort":"FieldSort","wow.api.query.Sort.Direction":"SortDirection","wow.command.CommandStage":"CommandStage","wow.command.SimpleWaitSignal":"WaitSignal","wow.configuration.Aggregate":"Aggregate","wow.configuration.BoundedContext":"BoundedContext","wow.configuration.WowMetadata":"WowMetadata","wow.modeling.DomainEvent":"DomainEvent","wow.openapi.BatchResult":"BatchResult","wow.messaging.CompensationTarget":"CompensationTarget"};function d(r){if(!r)return{name:"",path:"/"};const e=ie[r];if(e)return{name:e,path:N};const n=r.split(".");let t=-1;for(let i=0;i<n.length;i++)if(n[i]&&/^[A-Z]/.test(n[i])){t=i;break}if(t===-1)return{name:r,path:"/"};const o=n.slice(0,t),a=o.length>0?`/${o.join("/")}`:"/",s=n.slice(t);return{name:T(s),path:a}}class w{project;openAPI;outputDir;contextAggregates;logger;constructor(e){this.project=e.project,this.openAPI=e.openAPI,this.outputDir=e.outputDir,this.contextAggregates=e.contextAggregates,this.logger=e.logger}}class ce extends w{constructor(e){super(e)}getOrCreateSourceFile(e){const n=$(e);return O(this.project,this.outputDir,n)}generate(){const e=this.openAPI.components?.schemas;if(!e){this.logger?.info("No schemas found in OpenAPI specification");return}this.logger?.progress(`Generating models for ${Object.keys(e).length} schemas`),Object.entries(e).forEach(([n,t])=>{n.startsWith("wow.")||(this.logger?.progress(`Processing schema: ${n}`),this.generateKeyedSchema(n,t))}),this.logger?.success("Model generation completed")}generateKeyedSchema(e,n){const t=d(e),o=this.getOrCreateSourceFile(t),a=this.process(t,o,n);return _(a,n.title,n.description),o}process(e,n,t){let o=this.processEnum(e,n,t);return o||(o=this.processObject(e,n,t),o)||(o=this.processUnion(e,n,t),o)?o:this.processTypeAlias(e,n,t)}processEnum(e,n,t){if(Y(t))return n.addEnum({name:e.name,isExported:!0,members:t.enum.filter(o=>typeof o=="string"&&o.length>0).map(o=>({name:o,initializer:`'${o}'`}))})}processObject(e,n,t){if(t.type!=="object"||!t.properties)return;const o={},a=t.required||[];for(const[s,c]of Object.entries(t.properties)){const i=this.resolveType(e,n,c),p=!a.includes(s);o[s]=p?`${i} | undefined`:i}return n.addInterface({name:e.name,isExported:!0,properties:Object.entries(o).map(([s,c])=>({name:s,type:c}))})}processUnion(e,n,t){let o=null;if(t.allOf?o=t.allOf.map(a=>this.resolveType(e,n,a)).join(" & "):t.anyOf?o=t.anyOf.map(a=>this.resolveType(e,n,a)).join(" | "):t.oneOf&&(o=t.oneOf.map(a=>this.resolveType(e,n,a)).join(" | ")),!!o)return n.addTypeAlias({name:e.name,type:o,isExported:!0,docs:x(t.title,t.description)})}processTypeAlias(e,n,t){const o=this.resolveType(e,n,t);return n.addTypeAlias({name:e.name,type:o,isExported:!0,docs:x(t.title,t.description)})}resolveType(e,n,t){if(l(t))return this.resolveReference(e,n,t);if(t.type==="array")return`${t.items?this.resolveType(e,n,t.items):"any"}[]`;if(t.type==="object"&&!t.properties)return"Record<string, any>";let o;return t.type?o=j(t.type):o="any",t.nullable&&(o=`${o} | null`),o}resolveReference(e,n,t){const o=y(t),a=d(o);return X(e,n,this.outputDir,a),a.name}}function pe(r){let e=0,n=0;return r.commands.forEach(t=>{t.path.startsWith(v.ResourceAttributionPathSpec.TENANT)&&(e+=1),t.path.startsWith(v.ResourceAttributionPathSpec.OWNER)&&(n+=1)}),e===0&&n===0?"ResourceAttributionPathSpec.NONE":e>n?"ResourceAttributionPathSpec.TENANT":"ResourceAttributionPathSpec.OWNER"}function G(r,e,n,t){const o=`${n.contextAlias}/${n.aggregateName}/${t}.ts`;return O(r,e,o)}function ue(r,e){return`${T(r.aggregateName)}${e}`}class me extends w{constructor(e){super(e)}generate(){const e=Array.from(this.contextAggregates.values()).flat().length;this.logger?.progress(`Generating query clients for ${e} aggregates`);for(const[,n]of this.contextAggregates)n.forEach(t=>{this.logger?.progress(`Processing query client for aggregate: ${t.aggregate.aggregateName}`),this.processQueryClient(t)});this.logger?.success("Query client generation completed")}createClientFilePath(e,n){return G(this.project,this.outputDir,e,n)}processQueryClient(e){const n=this.createClientFilePath(e.aggregate,"queryClient");n.addImportDeclaration({moduleSpecifier:N,namedImports:["QueryClientFactory","QueryClientOptions","ResourceAttributionPathSpec"]});const t="DEFAULT_QUERY_CLIENT_OPTIONS";n.addVariableStatement({declarationKind:A.VariableDeclarationKind.Const,declarations:[{name:t,type:"QueryClientOptions",initializer:`{
|
|
3
|
+
contextAlias: '${e.aggregate.contextAlias}',
|
|
4
|
+
aggregateName: '${e.aggregate.aggregateName}',
|
|
5
|
+
resourceAttribution: ${pe(e)},
|
|
6
|
+
}`}],isExported:!1});const o=[];for(const p of e.events.values()){const m=d(p.schema.key);h(n,this.outputDir,m),o.push(m)}const a="DOMAIN_EVENT_TYPES";n.addTypeAlias({name:a,type:o.map(p=>p.name).join(" | ")});const s=`${D(e.aggregate.aggregateName)}QueryClientFactory`,c=d(e.state.key),i=d(e.fields.key);h(n,this.outputDir,c),h(n,this.outputDir,i),n.addVariableStatement({declarationKind:A.VariableDeclarationKind.Const,declarations:[{name:s,initializer:`new QueryClientFactory<${c.name}, ${i.name} | string, ${a}>(${t})`}],isExported:!0})}}class le extends w{commandEndpointPathsName="COMMAND_ENDPOINT_PATHS";defaultCommandClientOptionsName="DEFAULT_COMMAND_CLIENT_OPTIONS";constructor(e){super(e)}generate(){const e=Array.from(this.contextAggregates.values()).flat().length;this.logger?.progress(`Generating command clients for ${e} aggregates`);for(const[,n]of this.contextAggregates)n.forEach(t=>{this.logger?.progress(`Processing command client for aggregate: ${t.aggregate.aggregateName}`),this.processAggregate(t)});this.logger?.success("Command client generation completed")}processAggregate(e){const n=G(this.project,this.outputDir,e.aggregate,"commandClient");this.processCommandEndpointPaths(n,e),n.addVariableStatement({declarationKind:A.VariableDeclarationKind.Const,declarations:[{name:this.defaultCommandClientOptionsName,type:"ApiMetadata",initializer:`{
|
|
7
|
+
basePath: '${e.aggregate.contextAlias}'
|
|
8
|
+
}`}],isExported:!1}),n.addImportDeclaration({moduleSpecifier:N,namedImports:["CommandRequest","CommandResult","CommandResultEventStream","DeleteAggregate","RecoverAggregate"],isTypeOnly:!0}),n.addImportDeclaration({moduleSpecifier:"@ahoo-wang/fetcher-eventstream",namedImports:["JsonEventStreamResultExtractor"]}),E(n,"@ahoo-wang/fetcher",["ContentTypeValues"]),E(n,"@ahoo-wang/fetcher-decorator",["type ApiMetadata","type ApiMetadataCapable","api","post","put","del","request","attribute","path","autoGeneratedError"]),this.processCommandClient(n,e),this.processCommandClient(n,e,!0)}processCommandEndpointPaths(e,n){const t=e.addEnum({name:this.commandEndpointPathsName});n.commands.forEach(o=>{t.addMember({name:o.name.toUpperCase(),initializer:`'${o.path}'`})})}getEndpointPath(e){return`${this.commandEndpointPathsName}.${e.name.toUpperCase()}`}processCommandClient(e,n,t=!1){let o="CommandClient",a={name:"api",arguments:[]},s="Promise<CommandResult>";t&&(o="Stream"+o,a={name:"api",arguments:["''",`{
|
|
9
|
+
headers: { Accept: ContentTypeValues.TEXT_EVENT_STREAM },
|
|
10
|
+
resultExtractor: JsonEventStreamResultExtractor,
|
|
11
|
+
}`]},s="Promise<CommandResultEventStream>");const c=ue(n.aggregate,o),i=e.addClass({name:c,isExported:!0,decorators:[a],implements:["ApiMetadataCapable"]});i.addConstructor({parameters:[{name:"apiMetadata",type:"ApiMetadata",scope:A.Scope.Public,isReadonly:!0,initializer:`${this.defaultCommandClientOptionsName}`}]}),n.commands.forEach(p=>{this.processCommandMethod(e,i,p,s)})}methodToDecorator(e){return e==="delete"?"del":e}processCommandMethod(e,n,t,o){const a=d(t.schema.key);h(e,this.outputDir,a);const s=t.pathParameters.map(i=>({name:i.name,type:"string",decorators:[{name:"path",arguments:[`'${i.name}'`]}]}));s.push({name:"commandRequest",type:`CommandRequest<${a.name}>`,decorators:[{name:"request",arguments:[]}]}),s.push({name:"attributes",type:"Record<string, any>",decorators:[{name:"attribute",arguments:[]}]});const c=n.addMethod({name:D(t.name),decorators:[{name:this.methodToDecorator(t.method),arguments:[`${this.getEndpointPath(t)}`]}],parameters:s,returnType:o,statements:[`throw autoGeneratedError(${s.map(i=>i.name).join(",")});`]});_(c,t.summary,t.description)}}class ge extends w{queryClientGenerator;commandClientGenerator;constructor(e){super(e),this.queryClientGenerator=new me(e),this.commandClientGenerator=new le(e)}generate(){this.logger?.progress(`Generating clients for ${this.contextAggregates.size} bounded contexts`);for(const[e]of this.contextAggregates)this.logger?.progress(`Processing bounded context: ${e}`),this.processBoundedContext(e);this.queryClientGenerator.generate(),this.commandClientGenerator.generate(),this.logger?.success("Client generation completed")}processBoundedContext(e){const n=`${e}/boundedContext.ts`;O(this.project,this.outputDir,n).addStatements(`export const BOUNDED_CONTEXT_ALIAS = '${e}';`)}}class de{constructor(e){this.options=e,this.project=e.project}project;async generate(){const e=await k(this.options.inputPath),t=new se(e).resolve(),o={openAPI:e,project:this.project,outputDir:this.options.outputDir,contextAggregates:t,logger:this.options.logger};new ce(o).generate(),new ge(o).generate(),this.project.getSourceFiles().forEach(c=>{c.formatText(),c.organizeImports(),c.fixMissingImports()}),await this.project.save()}}exports.CodeGenerator=de;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { GeneratorOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Main code generator class that orchestrates the generation of TypeScript code from OpenAPI specifications.
|
|
4
|
+
* Handles model generation, client generation, and project formatting.
|
|
5
|
+
*/
|
|
6
|
+
export declare class CodeGenerator {
|
|
7
|
+
private readonly options;
|
|
8
|
+
private readonly project;
|
|
9
|
+
/**
|
|
10
|
+
* Creates a new CodeGenerator instance.
|
|
11
|
+
* @param options - Configuration options for code generation
|
|
12
|
+
*/
|
|
13
|
+
constructor(options: GeneratorOptions);
|
|
14
|
+
/**
|
|
15
|
+
* Generates TypeScript code from the OpenAPI specification.
|
|
16
|
+
* Parses the OpenAPI spec, resolves aggregates, generates models and clients,
|
|
17
|
+
* and formats the output files.
|
|
18
|
+
*/
|
|
19
|
+
generate(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAmB,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAM5D;;;GAGG;AACH,qBAAa,aAAa;IAOZ,OAAO,CAAC,QAAQ,CAAC,OAAO;IANpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAElC;;;OAGG;gBAC0B,OAAO,EAAE,gBAAgB;IAItD;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAsBhC"}
|