@ir-kit/asyncapi-typescript 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/LICENSE.md +21 -0
- package/README.md +124 -0
- package/dist/ast/raw-text-node.d.ts +21 -0
- package/dist/ast/raw-text-node.d.ts.map +1 -0
- package/dist/ast/raw-text-node.js +37 -0
- package/dist/ast/raw-text-node.js.map +1 -0
- package/dist/ast/ts-build.d.ts +42 -0
- package/dist/ast/ts-build.d.ts.map +1 -0
- package/dist/ast/ts-build.js +93 -0
- package/dist/ast/ts-build.js.map +1 -0
- package/dist/ast/ts-node.d.ts +25 -0
- package/dist/ast/ts-node.d.ts.map +1 -0
- package/dist/ast/ts-node.js +41 -0
- package/dist/ast/ts-node.js.map +1 -0
- package/dist/ast/ts-renderer.d.ts +21 -0
- package/dist/ast/ts-renderer.d.ts.map +1 -0
- package/dist/ast/ts-renderer.js +79 -0
- package/dist/ast/ts-renderer.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator.d.ts +13 -0
- package/dist/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator.js +63 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/plugin.d.ts +149 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +51 -0
- package/dist/plugin.js.map +1 -0
- package/dist/plugins/amqplib/bundle/amqp.gen.ts +99 -0
- package/dist/plugins/amqplib/config.d.ts +3 -0
- package/dist/plugins/amqplib/config.d.ts.map +1 -0
- package/dist/plugins/amqplib/config.js +2 -0
- package/dist/plugins/amqplib/config.js.map +1 -0
- package/dist/plugins/amqplib/index.d.ts +3 -0
- package/dist/plugins/amqplib/index.d.ts.map +1 -0
- package/dist/plugins/amqplib/index.js +2 -0
- package/dist/plugins/amqplib/index.js.map +1 -0
- package/dist/plugins/amqplib/plugin.d.ts +4 -0
- package/dist/plugins/amqplib/plugin.d.ts.map +1 -0
- package/dist/plugins/amqplib/plugin.js +18 -0
- package/dist/plugins/amqplib/plugin.js.map +1 -0
- package/dist/plugins/amqplib/types.d.ts +5 -0
- package/dist/plugins/amqplib/types.d.ts.map +1 -0
- package/dist/plugins/amqplib/types.js +2 -0
- package/dist/plugins/amqplib/types.js.map +1 -0
- package/dist/plugins/dispatch/bundle/dispatch.gen.ts +188 -0
- package/dist/plugins/dispatch/config.d.ts +3 -0
- package/dist/plugins/dispatch/config.d.ts.map +1 -0
- package/dist/plugins/dispatch/config.js +2 -0
- package/dist/plugins/dispatch/config.js.map +1 -0
- package/dist/plugins/dispatch/index.d.ts +3 -0
- package/dist/plugins/dispatch/index.d.ts.map +1 -0
- package/dist/plugins/dispatch/index.js +2 -0
- package/dist/plugins/dispatch/index.js.map +1 -0
- package/dist/plugins/dispatch/plugin.d.ts +12 -0
- package/dist/plugins/dispatch/plugin.d.ts.map +1 -0
- package/dist/plugins/dispatch/plugin.js +54 -0
- package/dist/plugins/dispatch/plugin.js.map +1 -0
- package/dist/plugins/dispatch/types.d.ts +6 -0
- package/dist/plugins/dispatch/types.d.ts.map +1 -0
- package/dist/plugins/dispatch/types.js +2 -0
- package/dist/plugins/dispatch/types.js.map +1 -0
- package/dist/plugins/event-map/config.d.ts +3 -0
- package/dist/plugins/event-map/config.d.ts.map +1 -0
- package/dist/plugins/event-map/config.js +4 -0
- package/dist/plugins/event-map/config.js.map +1 -0
- package/dist/plugins/event-map/index.d.ts +3 -0
- package/dist/plugins/event-map/index.d.ts.map +1 -0
- package/dist/plugins/event-map/index.js +2 -0
- package/dist/plugins/event-map/index.js.map +1 -0
- package/dist/plugins/event-map/plugin.d.ts +3 -0
- package/dist/plugins/event-map/plugin.d.ts.map +1 -0
- package/dist/plugins/event-map/plugin.js +62 -0
- package/dist/plugins/event-map/plugin.js.map +1 -0
- package/dist/plugins/event-map/types.d.ts +8 -0
- package/dist/plugins/event-map/types.d.ts.map +1 -0
- package/dist/plugins/event-map/types.js +2 -0
- package/dist/plugins/event-map/types.js.map +1 -0
- package/dist/plugins/events/config.d.ts +3 -0
- package/dist/plugins/events/config.d.ts.map +1 -0
- package/dist/plugins/events/config.js +4 -0
- package/dist/plugins/events/config.js.map +1 -0
- package/dist/plugins/events/index.d.ts +3 -0
- package/dist/plugins/events/index.d.ts.map +1 -0
- package/dist/plugins/events/index.js +2 -0
- package/dist/plugins/events/index.js.map +1 -0
- package/dist/plugins/events/plugin.d.ts +3 -0
- package/dist/plugins/events/plugin.d.ts.map +1 -0
- package/dist/plugins/events/plugin.js +48 -0
- package/dist/plugins/events/plugin.js.map +1 -0
- package/dist/plugins/events/types.d.ts +8 -0
- package/dist/plugins/events/types.d.ts.map +1 -0
- package/dist/plugins/events/types.js +2 -0
- package/dist/plugins/events/types.js.map +1 -0
- package/dist/plugins/index-barrel/config.d.ts +3 -0
- package/dist/plugins/index-barrel/config.d.ts.map +1 -0
- package/dist/plugins/index-barrel/config.js +2 -0
- package/dist/plugins/index-barrel/config.js.map +1 -0
- package/dist/plugins/index-barrel/index.d.ts +3 -0
- package/dist/plugins/index-barrel/index.d.ts.map +1 -0
- package/dist/plugins/index-barrel/index.js +2 -0
- package/dist/plugins/index-barrel/index.js.map +1 -0
- package/dist/plugins/index-barrel/plugin.d.ts +9 -0
- package/dist/plugins/index-barrel/plugin.d.ts.map +1 -0
- package/dist/plugins/index-barrel/plugin.js +47 -0
- package/dist/plugins/index-barrel/plugin.js.map +1 -0
- package/dist/plugins/index-barrel/types.d.ts +5 -0
- package/dist/plugins/index-barrel/types.d.ts.map +1 -0
- package/dist/plugins/index-barrel/types.js +2 -0
- package/dist/plugins/index-barrel/types.js.map +1 -0
- package/dist/plugins/typescript/config.d.ts +3 -0
- package/dist/plugins/typescript/config.d.ts.map +1 -0
- package/dist/plugins/typescript/config.js +4 -0
- package/dist/plugins/typescript/config.js.map +1 -0
- package/dist/plugins/typescript/index.d.ts +3 -0
- package/dist/plugins/typescript/index.d.ts.map +1 -0
- package/dist/plugins/typescript/index.js +2 -0
- package/dist/plugins/typescript/index.js.map +1 -0
- package/dist/plugins/typescript/plugin.d.ts +13 -0
- package/dist/plugins/typescript/plugin.d.ts.map +1 -0
- package/dist/plugins/typescript/plugin.js +67 -0
- package/dist/plugins/typescript/plugin.js.map +1 -0
- package/dist/plugins/typescript/types.d.ts +8 -0
- package/dist/plugins/typescript/types.d.ts.map +1 -0
- package/dist/plugins/typescript/types.js +2 -0
- package/dist/plugins/typescript/types.js.map +1 -0
- package/dist/runtime/copy-bundle.d.ts +16 -0
- package/dist/runtime/copy-bundle.d.ts.map +1 -0
- package/dist/runtime/copy-bundle.js +38 -0
- package/dist/runtime/copy-bundle.js.map +1 -0
- package/dist/runtime/load-document.d.ts +8 -0
- package/dist/runtime/load-document.d.ts.map +1 -0
- package/dist/runtime/load-document.js +21 -0
- package/dist/runtime/load-document.js.map +1 -0
- package/dist/runtime/order-plugins.d.ts +8 -0
- package/dist/runtime/order-plugins.d.ts.map +1 -0
- package/dist/runtime/order-plugins.js +31 -0
- package/dist/runtime/order-plugins.js.map +1 -0
- package/dist/runtime/plugin-instance.d.ts +18 -0
- package/dist/runtime/plugin-instance.d.ts.map +1 -0
- package/dist/runtime/plugin-instance.js +72 -0
- package/dist/runtime/plugin-instance.js.map +1 -0
- package/package.json +84 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
3
|
+
import { defaultExtensions, defaultModuleEntryNames, defaultNameConflictResolvers, Project, simpleNameConflictResolver, } from "@hey-api/codegen-core";
|
|
4
|
+
import { assertSafeOutputDir } from "@ir-kit/codegen-core";
|
|
5
|
+
import { RawTextRenderer, TsStatementRenderer } from "./ast/ts-renderer.js";
|
|
6
|
+
import {} from "./plugin.js";
|
|
7
|
+
import { loadDocument } from "./runtime/load-document.js";
|
|
8
|
+
import { orderPlugins } from "./runtime/order-plugins.js";
|
|
9
|
+
import { createPluginInstance } from "./runtime/plugin-instance.js";
|
|
10
|
+
export async function generate(opts) {
|
|
11
|
+
const document = await loadDocument(opts.input);
|
|
12
|
+
const outputDir = resolve(opts.output);
|
|
13
|
+
assertSafeOutputDir(outputDir);
|
|
14
|
+
// Plugin → renderer side channel; codegen-core File has no metadata slot.
|
|
15
|
+
const headers = new Map();
|
|
16
|
+
const project = new Project({
|
|
17
|
+
root: outputDir,
|
|
18
|
+
defaultFileName: "index",
|
|
19
|
+
defaultNameConflictResolver: simpleNameConflictResolver,
|
|
20
|
+
extensions: defaultExtensions,
|
|
21
|
+
moduleEntryNames: defaultModuleEntryNames,
|
|
22
|
+
nameConflictResolvers: defaultNameConflictResolvers,
|
|
23
|
+
renderers: [new TsStatementRenderer(headers), new RawTextRenderer()],
|
|
24
|
+
});
|
|
25
|
+
const apiRegistry = new Map();
|
|
26
|
+
const filesEmitted = [];
|
|
27
|
+
for (const reg of orderPlugins(opts.plugins)) {
|
|
28
|
+
const def = reg.__definition;
|
|
29
|
+
if (def.api !== undefined)
|
|
30
|
+
apiRegistry.set(def.name, def.api);
|
|
31
|
+
const config = def.resolveConfig
|
|
32
|
+
? def.resolveConfig(reg.__userConfig, { document })
|
|
33
|
+
: { ...def.defaultConfig, ...(reg.__userConfig ?? {}) };
|
|
34
|
+
const instance = createPluginInstance(def.name, config, def.api, {
|
|
35
|
+
document,
|
|
36
|
+
project,
|
|
37
|
+
files: filesEmitted,
|
|
38
|
+
apiRegistry,
|
|
39
|
+
headers,
|
|
40
|
+
});
|
|
41
|
+
if (def.hooks?.before)
|
|
42
|
+
await def.hooks.before(instance);
|
|
43
|
+
await def.handler(instance);
|
|
44
|
+
if (def.hooks?.after)
|
|
45
|
+
await def.hooks.after(instance);
|
|
46
|
+
}
|
|
47
|
+
project.plan();
|
|
48
|
+
return writeRenderedFiles(project.render(), outputDir);
|
|
49
|
+
}
|
|
50
|
+
async function writeRenderedFiles(rendered, outputDir) {
|
|
51
|
+
await mkdir(outputDir, { recursive: true });
|
|
52
|
+
const written = [];
|
|
53
|
+
for (const out of rendered) {
|
|
54
|
+
if (!out.path)
|
|
55
|
+
continue;
|
|
56
|
+
const abs = isAbsolute(out.path) ? out.path : join(outputDir, out.path);
|
|
57
|
+
await mkdir(dirname(abs), { recursive: true });
|
|
58
|
+
await writeFile(abs, out.content, "utf8");
|
|
59
|
+
written.push({ path: relative(outputDir, abs), content: out.content });
|
|
60
|
+
}
|
|
61
|
+
return { output: outputDir, files: written };
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin contract for `@ir-kit/asyncapi-typescript`.
|
|
3
|
+
*
|
|
4
|
+
* Shape mirrors `@hey-api/openapi-ts`'s `definePluginConfig` / plugin
|
|
5
|
+
* instance pattern, adapted to AsyncAPI primitives. Plugins are
|
|
6
|
+
* authored as definitions and registered via factory call:
|
|
7
|
+
*
|
|
8
|
+
* export const myPlugin = definePluginConfig({
|
|
9
|
+
* name: "my-plugin",
|
|
10
|
+
* defaultConfig: { ... },
|
|
11
|
+
* dependsOn: ["typescript"],
|
|
12
|
+
* handler: async (plugin) => {
|
|
13
|
+
* for (const ev of plugin.forEach("message")) { ... }
|
|
14
|
+
* plugin.emit({ path: "out.gen.ts", content: "..." });
|
|
15
|
+
* },
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* // caller:
|
|
19
|
+
* generate({ plugins: [myPlugin({ ... }), ...], ... });
|
|
20
|
+
*/
|
|
21
|
+
import type { AsyncAPIDocumentInterface, ChannelInterface, MessageInterface, OperationInterface } from "@asyncapi/parser";
|
|
22
|
+
import type ts from "typescript";
|
|
23
|
+
export interface GeneratedFile {
|
|
24
|
+
/** Path relative to the configured output directory. */
|
|
25
|
+
path: string;
|
|
26
|
+
content: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* One named-import group. The `from` path is the logical (extension-free)
|
|
30
|
+
* file path of another plugin's file in the same project — e.g. the
|
|
31
|
+
* `events` plugin emits `events.gen.ts`, so reference it as `"events.gen"`.
|
|
32
|
+
* The renderer resolves that to a relative path between source and importer
|
|
33
|
+
* at print time.
|
|
34
|
+
*/
|
|
35
|
+
export interface EmitTsImportGroup {
|
|
36
|
+
/** Logical path of the source file (no extension). */
|
|
37
|
+
from: string;
|
|
38
|
+
/** Names being imported. `isType` adds a per-specifier `type` modifier. */
|
|
39
|
+
names: ReadonlyArray<{
|
|
40
|
+
name: string;
|
|
41
|
+
isType?: boolean;
|
|
42
|
+
}>;
|
|
43
|
+
/** Top-level `import type { ... }` (vs `import { ..., type X }`). */
|
|
44
|
+
isType?: boolean;
|
|
45
|
+
}
|
|
46
|
+
export interface EmitTsOptions {
|
|
47
|
+
header?: string;
|
|
48
|
+
imports?: ReadonlyArray<EmitTsImportGroup>;
|
|
49
|
+
}
|
|
50
|
+
export type ForEachKind = "message" | "channel" | "operation";
|
|
51
|
+
export type ForEachEvent = {
|
|
52
|
+
type: "message";
|
|
53
|
+
message: MessageInterface;
|
|
54
|
+
} | {
|
|
55
|
+
type: "channel";
|
|
56
|
+
channel: ChannelInterface;
|
|
57
|
+
} | {
|
|
58
|
+
type: "operation";
|
|
59
|
+
operation: OperationInterface;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* What a plugin's handler receives. Strongly typed against the plugin's
|
|
63
|
+
* own `Config` and `Api` so config / api access doesn't degrade to `any`.
|
|
64
|
+
*/
|
|
65
|
+
export interface PluginInstance<Config = unknown, Api = unknown> {
|
|
66
|
+
/** Plugin's stable identifier. */
|
|
67
|
+
readonly name: string;
|
|
68
|
+
/** Resolved config — defaults merged with user overrides (and `resolveConfig`). */
|
|
69
|
+
readonly config: Config;
|
|
70
|
+
/** Plugin's own api object — typed straight through from the definition. */
|
|
71
|
+
readonly api: Api;
|
|
72
|
+
/** The parsed AsyncAPI document. */
|
|
73
|
+
readonly document: AsyncAPIDocumentInterface;
|
|
74
|
+
/** Files emitted so far (by this and prior plugins). */
|
|
75
|
+
readonly files: ReadonlyArray<GeneratedFile>;
|
|
76
|
+
/** Add a file to the output as raw text. Use for Modelina output, copied bundles, etc. */
|
|
77
|
+
emit(file: GeneratedFile): void;
|
|
78
|
+
/**
|
|
79
|
+
* Add a file to the output as a list of `ts.Statement` AST nodes; the
|
|
80
|
+
* `TsStatementRenderer` prints them at render time. Optional `header`
|
|
81
|
+
* is attached as a leading comment on the first statement. Use this
|
|
82
|
+
* over `emit` for plugin output you construct via `ts.factory`.
|
|
83
|
+
*
|
|
84
|
+
* Cross-file imports go through `options.imports` (graph-driven), not
|
|
85
|
+
* inline `ts.factory.createImportDeclaration` calls — the underlying
|
|
86
|
+
* codegen-core `File.addImport` resolves source files into relative
|
|
87
|
+
* paths at print time, so imports survive file moves and rename
|
|
88
|
+
* collision resolution.
|
|
89
|
+
*/
|
|
90
|
+
emitTs(path: string, statements: ReadonlyArray<ts.Statement>, options?: EmitTsOptions): void;
|
|
91
|
+
/** Look up another plugin's api by name. Returns `undefined` if absent. */
|
|
92
|
+
getApi<T = unknown>(name: string): T | undefined;
|
|
93
|
+
/** Iterate spec entities of the given kinds, in document order. */
|
|
94
|
+
forEach(...kinds: ForEachKind[]): IterableIterator<ForEachEvent>;
|
|
95
|
+
}
|
|
96
|
+
export interface PluginHooks<Config = unknown, Api = unknown> {
|
|
97
|
+
before?: (plugin: PluginInstance<Config, Api>) => Promise<void> | void;
|
|
98
|
+
after?: (plugin: PluginInstance<Config, Api>) => Promise<void> | void;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Plugin author's contract. Pass to `definePluginConfig` to get a
|
|
102
|
+
* factory that callers invoke when building their plugin list.
|
|
103
|
+
*/
|
|
104
|
+
export interface PluginDefinition<Name extends string = string, UserConfig = unknown, ResolvedConfig = UserConfig, Api = unknown> {
|
|
105
|
+
/** Stable identifier — used in `dependsOn`, `getApi`, log messages. */
|
|
106
|
+
name: Name;
|
|
107
|
+
/** Baseline config; user overrides are layered on top. */
|
|
108
|
+
defaultConfig: ResolvedConfig;
|
|
109
|
+
/**
|
|
110
|
+
* Optional. Compute the final config from user input + document
|
|
111
|
+
* context (e.g. inspect installed package versions, infer features
|
|
112
|
+
* from the spec). Default behavior is shallow-merge of user over
|
|
113
|
+
* defaults.
|
|
114
|
+
*/
|
|
115
|
+
resolveConfig?: (user: Partial<UserConfig> | undefined, context: {
|
|
116
|
+
document: AsyncAPIDocumentInterface;
|
|
117
|
+
}) => ResolvedConfig;
|
|
118
|
+
/** API surface other plugins can fetch via `plugin.getApi(name)`. */
|
|
119
|
+
api?: Api;
|
|
120
|
+
hooks?: PluginHooks<ResolvedConfig, Api>;
|
|
121
|
+
/** Names of plugins this one depends on. The orchestrator topologically sorts. */
|
|
122
|
+
dependsOn?: ReadonlyArray<string>;
|
|
123
|
+
/** The actual codegen work. */
|
|
124
|
+
handler: (plugin: PluginInstance<ResolvedConfig, Api>) => Promise<void> | void;
|
|
125
|
+
}
|
|
126
|
+
/** What the orchestrator receives — a sealed instance ready to run. */
|
|
127
|
+
export interface RegisteredPlugin<Name extends string = string, UserConfig = unknown, ResolvedConfig = UserConfig, Api = unknown> {
|
|
128
|
+
readonly __definition: PluginDefinition<Name, UserConfig, ResolvedConfig, Api>;
|
|
129
|
+
readonly __userConfig: Partial<UserConfig> | undefined;
|
|
130
|
+
readonly name: Name;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Generic-erased view used at orchestration boundaries.
|
|
134
|
+
*
|
|
135
|
+
* `RegisteredPlugin<X>` types can't be uniformly stored in an array
|
|
136
|
+
* because hooks are contravariant in `Config`. This widening alias
|
|
137
|
+
* uses `any` deliberately — internal to the orchestrator, not exposed
|
|
138
|
+
* to plugin authors (who keep full type safety).
|
|
139
|
+
*/
|
|
140
|
+
export type AnyRegisteredPlugin = RegisteredPlugin<string, any, any, any>;
|
|
141
|
+
/**
|
|
142
|
+
* Wrap a plugin definition into a factory. Author exports the returned
|
|
143
|
+
* factory; caller invokes it (with optional config overrides) when
|
|
144
|
+
* building the `plugins` array.
|
|
145
|
+
*/
|
|
146
|
+
export declare function definePluginConfig<Name extends string, UserConfig, ResolvedConfig, Api>(def: PluginDefinition<Name, UserConfig, ResolvedConfig, Api>): (config?: Partial<UserConfig>) => RegisteredPlugin<Name, UserConfig, ResolvedConfig, Api>;
|
|
147
|
+
/** Convenience: orchestrator-internal `forEach` implementation. */
|
|
148
|
+
export declare function iterateDocument(document: AsyncAPIDocumentInterface, kinds: ReadonlyArray<ForEachKind>): IterableIterator<ForEachEvent>;
|
|
149
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin contract for `@ir-kit/asyncapi-typescript`.
|
|
3
|
+
*
|
|
4
|
+
* Shape mirrors `@hey-api/openapi-ts`'s `definePluginConfig` / plugin
|
|
5
|
+
* instance pattern, adapted to AsyncAPI primitives. Plugins are
|
|
6
|
+
* authored as definitions and registered via factory call:
|
|
7
|
+
*
|
|
8
|
+
* export const myPlugin = definePluginConfig({
|
|
9
|
+
* name: "my-plugin",
|
|
10
|
+
* defaultConfig: { ... },
|
|
11
|
+
* dependsOn: ["typescript"],
|
|
12
|
+
* handler: async (plugin) => {
|
|
13
|
+
* for (const ev of plugin.forEach("message")) { ... }
|
|
14
|
+
* plugin.emit({ path: "out.gen.ts", content: "..." });
|
|
15
|
+
* },
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* // caller:
|
|
19
|
+
* generate({ plugins: [myPlugin({ ... }), ...], ... });
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Wrap a plugin definition into a factory. Author exports the returned
|
|
23
|
+
* factory; caller invokes it (with optional config overrides) when
|
|
24
|
+
* building the `plugins` array.
|
|
25
|
+
*/
|
|
26
|
+
export function definePluginConfig(def) {
|
|
27
|
+
return (config) => ({
|
|
28
|
+
__definition: def,
|
|
29
|
+
__userConfig: config,
|
|
30
|
+
name: def.name,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/** Convenience: orchestrator-internal `forEach` implementation. */
|
|
34
|
+
export function* iterateDocument(document, kinds) {
|
|
35
|
+
if (kinds.includes("channel")) {
|
|
36
|
+
for (const channel of document.channels().all()) {
|
|
37
|
+
yield { type: "channel", channel };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (kinds.includes("operation")) {
|
|
41
|
+
for (const operation of document.operations().all()) {
|
|
42
|
+
yield { type: "operation", operation };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (kinds.includes("message")) {
|
|
46
|
+
for (const message of document.allMessages().all()) {
|
|
47
|
+
yield { type: "message", message };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAwJH;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAMhC,GAA4D;IAI5D,OAAO,CAAC,MAA4B,EAAE,EAAE,CAAC,CAAC;QACxC,YAAY,EAAE,GAAG;QACjB,YAAY,EAAE,MAAM;QACpB,IAAI,EAAE,GAAG,CAAC,IAAI;KACf,CAAC,CAAC;AACL,CAAC;AAED,mEAAmE;AACnE,MAAM,SAAS,CAAC,CAAC,eAAe,CAC9B,QAAmC,EACnC,KAAiC;IAEjC,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC;YAChD,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;QACrC,CAAC;IACH,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,KAAK,MAAM,SAAS,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC;YACpD,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;QACzC,CAAC;IACH,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC;YACnD,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;QACrC,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// AUTO-GENERATED by @ir-kit/asyncapi-typescript — do not hand-edit.
|
|
2
|
+
|
|
3
|
+
import type { Channel, ConsumeMessage } from "amqplib";
|
|
4
|
+
|
|
5
|
+
export interface EventDescriptor {
|
|
6
|
+
exchange: string;
|
|
7
|
+
exchangeType: string;
|
|
8
|
+
type: string;
|
|
9
|
+
contentType?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ConsumerLike {
|
|
13
|
+
bindings: ReadonlyArray<{ exchange: string; routingKey: string }>;
|
|
14
|
+
dispatch: (raw: ConsumeMessage | null) => Promise<void> | void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface AssertExchangesOptions {
|
|
18
|
+
durable?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export async function assertExchanges(
|
|
22
|
+
channel: Channel,
|
|
23
|
+
events: Readonly<Record<string, EventDescriptor>>,
|
|
24
|
+
opts: AssertExchangesOptions = {},
|
|
25
|
+
) {
|
|
26
|
+
const seen = new Set<string>();
|
|
27
|
+
for (const ev of Object.values(events)) {
|
|
28
|
+
if (seen.has(ev.exchange)) continue;
|
|
29
|
+
seen.add(ev.exchange);
|
|
30
|
+
await channel.assertExchange(ev.exchange, ev.exchangeType, {
|
|
31
|
+
durable: opts.durable,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface BindAndConsumeOptions {
|
|
37
|
+
durable?: boolean;
|
|
38
|
+
exclusive?: boolean;
|
|
39
|
+
autoDelete?: boolean;
|
|
40
|
+
noAck?: boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export async function bindAndConsume(
|
|
44
|
+
channel: Channel,
|
|
45
|
+
queue: string,
|
|
46
|
+
registry: ConsumerLike,
|
|
47
|
+
opts: BindAndConsumeOptions = {},
|
|
48
|
+
) {
|
|
49
|
+
await channel.assertQueue(queue, {
|
|
50
|
+
durable: opts.durable,
|
|
51
|
+
exclusive: opts.exclusive,
|
|
52
|
+
autoDelete: opts.autoDelete,
|
|
53
|
+
});
|
|
54
|
+
for (const { exchange, routingKey } of registry.bindings) {
|
|
55
|
+
await channel.bindQueue(queue, exchange, routingKey);
|
|
56
|
+
}
|
|
57
|
+
return channel.consume(queue, registry.dispatch, {
|
|
58
|
+
noAck: opts.noAck,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Encode a typed payload to bytes. Default is JSON.stringify + utf8.
|
|
64
|
+
* Override to swap in protobuf / msgpack / cbor / etc.
|
|
65
|
+
*/
|
|
66
|
+
export type SerializeFn = <T>(payload: T) => Buffer;
|
|
67
|
+
|
|
68
|
+
const defaultSerialize: SerializeFn = (payload) =>
|
|
69
|
+
Buffer.from(JSON.stringify(payload));
|
|
70
|
+
|
|
71
|
+
export interface PublishOptions {
|
|
72
|
+
serialize?: SerializeFn;
|
|
73
|
+
persistent?: boolean;
|
|
74
|
+
expiration?: number;
|
|
75
|
+
priority?: number;
|
|
76
|
+
correlationId?: string;
|
|
77
|
+
replyTo?: string;
|
|
78
|
+
headers?: Record<string, unknown>;
|
|
79
|
+
mandatory?: boolean;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function publish<T>(
|
|
83
|
+
channel: Channel,
|
|
84
|
+
ev: EventDescriptor,
|
|
85
|
+
payload: T,
|
|
86
|
+
opts: PublishOptions = {},
|
|
87
|
+
): boolean {
|
|
88
|
+
const serialize = opts.serialize ?? defaultSerialize;
|
|
89
|
+
return channel.publish(ev.exchange, ev.type, serialize(payload), {
|
|
90
|
+
contentType: ev.contentType,
|
|
91
|
+
persistent: opts.persistent,
|
|
92
|
+
expiration: opts.expiration?.toString(),
|
|
93
|
+
priority: opts.priority,
|
|
94
|
+
correlationId: opts.correlationId,
|
|
95
|
+
replyTo: opts.replyTo,
|
|
96
|
+
headers: opts.headers,
|
|
97
|
+
mandatory: opts.mandatory,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/plugins/amqplib/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD,eAAO,MAAM,aAAa,EAAE,qBAAmD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/plugins/amqplib/config.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,aAAa,GAA0B,EAA2B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/amqplib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,YAAY,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/amqplib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AmqplibPluginConfig } from "./types.js";
|
|
2
|
+
/** Emit `assertExchanges` / `bindAndConsume` / `publish` by copying `bundle/`. */
|
|
3
|
+
export declare const amqplib: (config?: Partial<AmqplibPluginConfig> | undefined) => import("../../plugin.js").RegisteredPlugin<"amqplib", AmqplibPluginConfig, Required<AmqplibPluginConfig>, unknown>;
|
|
4
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/amqplib/plugin.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,mBAAmB,EAAyB,MAAM,YAAY,CAAC;AAI7E,kFAAkF;AAClF,eAAO,MAAM,OAAO,2KAclB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { dirname, resolve } from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { definePluginConfig } from "../../plugin.js";
|
|
4
|
+
import { readBundle } from "../../runtime/copy-bundle.js";
|
|
5
|
+
import { defaultConfig } from "./config.js";
|
|
6
|
+
const bundleDir = resolve(dirname(fileURLToPath(import.meta.url)), "bundle");
|
|
7
|
+
/** Emit `assertExchanges` / `bindAndConsume` / `publish` by copying `bundle/`. */
|
|
8
|
+
export const amqplib = definePluginConfig({
|
|
9
|
+
name: "amqplib",
|
|
10
|
+
defaultConfig,
|
|
11
|
+
dependsOn: ["events"],
|
|
12
|
+
async handler(plugin) {
|
|
13
|
+
for (const file of await readBundle(bundleDir)) {
|
|
14
|
+
plugin.emit(file);
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../src/plugins/amqplib/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;AAE7E,kFAAkF;AAClF,MAAM,CAAC,MAAM,OAAO,GAAG,kBAAkB,CAKvC;IACA,IAAI,EAAE,SAAS;IACf,aAAa;IACb,SAAS,EAAE,CAAC,QAAQ,CAAC;IACrB,KAAK,CAAC,OAAO,CAAC,MAAM;QAClB,KAAK,MAAM,IAAI,IAAI,MAAM,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC/C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/plugins/amqplib/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,KAAK,CAAC;CAClB;AAED,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC,mBAAmB,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/plugins/amqplib/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
// AUTO-GENERATED by @ir-kit/asyncapi-typescript — do not hand-edit.
|
|
2
|
+
|
|
3
|
+
import type { ConsumeMessage } from "amqplib";
|
|
4
|
+
|
|
5
|
+
export type Handler<T> = (msg: T, raw: ConsumeMessage) => Promise<void> | void;
|
|
6
|
+
|
|
7
|
+
export interface EventMeta {
|
|
8
|
+
type: string;
|
|
9
|
+
exchange: string;
|
|
10
|
+
routingKey: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Decodes a raw message body into the typed shape. Default is
|
|
15
|
+
* JSON.parse + utf8. Override to plug in a validator (zod/typia/ajv) —
|
|
16
|
+
* runtime is otherwise unverified and the cast is taken on trust.
|
|
17
|
+
*/
|
|
18
|
+
export type ParseFn = (buf: Buffer) => unknown;
|
|
19
|
+
|
|
20
|
+
const defaultParse: ParseFn = (buf) => JSON.parse(buf.toString("utf8"));
|
|
21
|
+
|
|
22
|
+
export interface RegistryOptions {
|
|
23
|
+
parse?: ParseFn;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class Registry<
|
|
27
|
+
// biome-ignore lint/suspicious/noExplicitAny: caller's spec defines its shape
|
|
28
|
+
EM extends Record<string, any>,
|
|
29
|
+
Registered extends keyof EM = never,
|
|
30
|
+
> {
|
|
31
|
+
private handlers = new Map<keyof EM, Handler<unknown>>();
|
|
32
|
+
private metaByType = new Map<keyof EM, EventMeta>();
|
|
33
|
+
private parse: ParseFn;
|
|
34
|
+
|
|
35
|
+
constructor(
|
|
36
|
+
events: Readonly<Record<string, EventMeta>>,
|
|
37
|
+
opts: RegistryOptions = {},
|
|
38
|
+
) {
|
|
39
|
+
for (const meta of Object.values(events)) {
|
|
40
|
+
this.metaByType.set(meta.type as keyof EM, meta);
|
|
41
|
+
}
|
|
42
|
+
this.parse = opts.parse ?? defaultParse;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
on<K extends keyof EM>(
|
|
46
|
+
type: K,
|
|
47
|
+
handler: Handler<EM[K]>,
|
|
48
|
+
): Registry<EM, Registered | K> {
|
|
49
|
+
if (this.handlers.has(type)) {
|
|
50
|
+
console.warn(
|
|
51
|
+
`Registry.on: handler for "${String(type)}" was already registered, overwriting`,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
this.handlers.set(type, handler as Handler<unknown>);
|
|
55
|
+
return this as Registry<EM, Registered | K>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
dispatch = (raw: ConsumeMessage | null): void => {
|
|
59
|
+
if (!raw) return;
|
|
60
|
+
|
|
61
|
+
let msg: EM[keyof EM];
|
|
62
|
+
try {
|
|
63
|
+
msg = this.parse(raw.content) as EM[keyof EM];
|
|
64
|
+
} catch (err) {
|
|
65
|
+
console.error("Registry.dispatch: failed to parse message body", err);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const incoming = raw.fields.routingKey;
|
|
70
|
+
|
|
71
|
+
// Fast path: producer publishes with the concrete event type as the
|
|
72
|
+
// routing key, so most messages match an exact key in `handlers`.
|
|
73
|
+
const direct = this.handlers.get(incoming as keyof EM);
|
|
74
|
+
if (direct) {
|
|
75
|
+
this.runHandler(direct, msg, raw, incoming);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Slow path: incoming key didn't match a registered type literally,
|
|
80
|
+
// so walk patterns for a wildcard match (`*`, `#`).
|
|
81
|
+
for (const [type, handler] of this.handlers) {
|
|
82
|
+
const meta = this.metaByType.get(type);
|
|
83
|
+
if (!meta) continue;
|
|
84
|
+
if (matchRoutingKey(meta.routingKey, incoming)) {
|
|
85
|
+
this.runHandler(handler, msg, raw, String(type));
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
private runHandler(
|
|
92
|
+
handler: Handler<unknown>,
|
|
93
|
+
msg: unknown,
|
|
94
|
+
raw: ConsumeMessage,
|
|
95
|
+
label: string,
|
|
96
|
+
): void {
|
|
97
|
+
try {
|
|
98
|
+
const result = handler(msg, raw);
|
|
99
|
+
if (result instanceof Promise) {
|
|
100
|
+
result.catch((err: unknown) => {
|
|
101
|
+
console.error(`Registry.dispatch: handler for "${label}" threw`, err);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
} catch (err) {
|
|
105
|
+
console.error(`Registry.dispatch: handler for "${label}" threw`, err);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
toCallback<K extends Registered>(
|
|
110
|
+
type: K,
|
|
111
|
+
): (raw: ConsumeMessage | null) => void {
|
|
112
|
+
const handler = this.handlers.get(type);
|
|
113
|
+
if (!handler) {
|
|
114
|
+
throw new Error(
|
|
115
|
+
`Registry.toCallback: no handler registered for "${String(type)}"`,
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
return (raw) => {
|
|
119
|
+
if (!raw) return;
|
|
120
|
+
let msg: EM[K];
|
|
121
|
+
try {
|
|
122
|
+
msg = this.parse(raw.content) as EM[K];
|
|
123
|
+
} catch (err) {
|
|
124
|
+
console.error(
|
|
125
|
+
`Registry.toCallback("${String(type)}"): failed to parse message body`,
|
|
126
|
+
err,
|
|
127
|
+
);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
this.runHandler(handler, msg as unknown, raw, String(type));
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
get bindings(): ReadonlyArray<{
|
|
135
|
+
type: Registered;
|
|
136
|
+
exchange: string;
|
|
137
|
+
routingKey: string;
|
|
138
|
+
}> {
|
|
139
|
+
const out: Array<{
|
|
140
|
+
type: Registered;
|
|
141
|
+
exchange: string;
|
|
142
|
+
routingKey: string;
|
|
143
|
+
}> = [];
|
|
144
|
+
for (const type of this.handlers.keys()) {
|
|
145
|
+
const meta = this.metaByType.get(type);
|
|
146
|
+
if (!meta) continue;
|
|
147
|
+
out.push({
|
|
148
|
+
type: type as Registered,
|
|
149
|
+
exchange: meta.exchange,
|
|
150
|
+
routingKey: meta.routingKey,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
return out;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export function createRegistry<
|
|
158
|
+
// biome-ignore lint/suspicious/noExplicitAny: caller's spec defines its shape
|
|
159
|
+
EM extends Record<string, any>,
|
|
160
|
+
>(
|
|
161
|
+
events: Readonly<Record<string, EventMeta>>,
|
|
162
|
+
opts: RegistryOptions = {},
|
|
163
|
+
): Registry<EM> {
|
|
164
|
+
return new Registry<EM>(events, opts);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** RabbitMQ topic-exchange routing-key matcher: `*` = one word, `#` = zero or more. */
|
|
168
|
+
function matchRoutingKey(pattern: string, key: string): boolean {
|
|
169
|
+
return matchSegments(pattern.split("."), key.split("."));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function matchSegments(
|
|
173
|
+
p: ReadonlyArray<string>,
|
|
174
|
+
k: ReadonlyArray<string>,
|
|
175
|
+
): boolean {
|
|
176
|
+
if (p.length === 0) return k.length === 0;
|
|
177
|
+
const head = p[0];
|
|
178
|
+
const tail = p.slice(1);
|
|
179
|
+
if (head === "#") {
|
|
180
|
+
for (let i = 0; i <= k.length; i++) {
|
|
181
|
+
if (matchSegments(tail, k.slice(i))) return true;
|
|
182
|
+
}
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
if (k.length === 0) return false;
|
|
186
|
+
if (head === "*" || head === k[0]) return matchSegments(tail, k.slice(1));
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/plugins/dispatch/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEzD,eAAO,MAAM,aAAa,EAAE,sBACE,CAAC"}
|