@opalesce/core 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,424 @@
1
+ # @opalesce/core
2
+
3
+ `@opalesce/core` is the in-memory AsyncAPI generation engine for Opalesce. It parses input once, resolves plugin dependencies, runs plugin lifecycle hooks, shares typed services, and collects generated text artifacts without writing files.
4
+
5
+ The package is released as a focused building block for advanced integrations. Normal consumers use the `opalesce` facade, while `@opalesce/config` and `@opalesce/cli` remain the focused config, filesystem, and command layers.
6
+
7
+ ## Project Workflow
8
+
9
+ Most projects describe generation without calling the pipeline directly:
10
+
11
+ ```ts
12
+ // opalesce.config.ts
13
+ import { defineConfig, definePlugin } from "opalesce";
14
+
15
+ const versionFile = definePlugin(() => ({
16
+ name: "version-file",
17
+ build(context) {
18
+ context.emit({
19
+ path: "metadata/version.txt",
20
+ contents: `AsyncAPI ${context.document.version()}\n`,
21
+ });
22
+ },
23
+ }));
24
+
25
+ export default defineConfig({
26
+ input: "./asyncapi.yaml",
27
+ output: {
28
+ path: "./generated",
29
+ },
30
+ plugins: [versionFile()],
31
+ });
32
+ ```
33
+
34
+ ```sh
35
+ opalesce generate
36
+ ```
37
+
38
+ The CLI discovers the config, reads the input, calls `run` once, and writes successful artifacts. The config remains side-effect free.
39
+
40
+ ## Programmatic Usage
41
+
42
+ Call `run` explicitly when another program already owns input loading and artifact persistence:
43
+
44
+ ```ts
45
+ import { definePipelineConfig, definePlugin, run, type Input } from "opalesce";
46
+
47
+ const input = {
48
+ asyncapi: "3.1.0",
49
+ info: {
50
+ title: "Events",
51
+ version: "1.0.0",
52
+ },
53
+ } satisfies Input;
54
+
55
+ const versionFile = definePlugin((options: { readonly path: string }) => ({
56
+ name: "version-file",
57
+ build(context) {
58
+ context.emit({
59
+ path: options.path,
60
+ contents: `AsyncAPI ${context.document.version()}\n`,
61
+ });
62
+ },
63
+ }));
64
+
65
+ const config = definePipelineConfig({
66
+ input,
67
+ plugins: [versionFile({ path: "metadata/version.txt" })],
68
+ });
69
+
70
+ const result = await run(config);
71
+
72
+ console.log(result.artifacts);
73
+ ```
74
+
75
+ The result contains the official parsed AsyncAPI document, parser diagnostics, artifacts in emission order, and the resolved plugin order:
76
+
77
+ ```ts
78
+ interface PipelineResult {
79
+ readonly document: AsyncAPIDocumentInterface;
80
+ readonly diagnostics: readonly Diagnostic[];
81
+ readonly artifacts: readonly GeneratedArtifact[];
82
+ readonly pluginNames: readonly string[];
83
+ }
84
+ ```
85
+
86
+ ## Internal Workspace Usage
87
+
88
+ Internal packages can depend on Core directly:
89
+
90
+ ```json
91
+ {
92
+ "dependencies": {
93
+ "@opalesce/core": "workspace:*"
94
+ }
95
+ }
96
+ ```
97
+
98
+ Then refresh workspace links:
99
+
100
+ ```sh
101
+ pnpm install
102
+ ```
103
+
104
+ The scoped package is not a normal consumer dependency; prefer the `opalesce` facade unless direct access to the engine is required.
105
+
106
+ ## Pipeline Lifecycle
107
+
108
+ `run` executes one deterministic pipeline:
109
+
110
+ 1. Validate plugin names and dependency relationships.
111
+ 2. Resolve a stable topological plugin order.
112
+ 3. Parse `config.input` once.
113
+ 4. Run every plugin `setup` hook in resolved order.
114
+ 5. Run every plugin `build` hook in the same order.
115
+ 6. Return a frozen result with all in-memory artifacts.
116
+
117
+ Plugin configuration failures happen before parsing. Core parse failures pass through unchanged. A setup or build failure stops the pipeline immediately.
118
+
119
+ ## Pipeline Configuration
120
+
121
+ ```ts
122
+ interface PipelineConfig {
123
+ readonly input: Input;
124
+ readonly parser?: ParseAsyncAPIOptions;
125
+ readonly plugins?: readonly OrchestrationPlugin[];
126
+ }
127
+ ```
128
+
129
+ | Field | Required | Purpose |
130
+ | --------- | -------- | ------------------------------------------------------------------------------------------------------------ |
131
+ | `input` | Yes | YAML or JSON text, a JavaScript AsyncAPI object, or an existing official AsyncAPI document accepted by Core. |
132
+ | `parser` | No | Core parser-constructor and parse options forwarded unchanged to `parseAsyncAPI`. |
133
+ | `plugins` | No | Plugins to validate, order, and execute. Defaults to an empty pipeline. |
134
+
135
+ `defineConfig` is an identity helper. It preserves the concrete config type and improves TypeScript inference:
136
+
137
+ ```ts
138
+ const config = defineConfig({
139
+ input,
140
+ parser: {
141
+ parse: {
142
+ source: "memory://events/asyncapi.yaml",
143
+ },
144
+ },
145
+ plugins: [],
146
+ });
147
+ ```
148
+
149
+ An input string is treated as AsyncAPI document content, not as a filesystem path.
150
+
151
+ ## Defining Plugins
152
+
153
+ `definePlugin` preserves the arguments and concrete return type of a plugin factory:
154
+
155
+ ```ts
156
+ import { definePlugin } from "opalesce";
157
+
158
+ interface ManifestPluginOptions {
159
+ readonly path: string;
160
+ }
161
+
162
+ export const manifestPlugin = definePlugin((options: ManifestPluginOptions) => ({
163
+ name: "manifest",
164
+ build(context) {
165
+ context.emit({
166
+ path: options.path,
167
+ contents: JSON.stringify(
168
+ {
169
+ asyncapi: context.document.version(),
170
+ },
171
+ null,
172
+ 2,
173
+ ),
174
+ });
175
+ },
176
+ }));
177
+ ```
178
+
179
+ A plugin can implement either or both lifecycle hooks:
180
+
181
+ ```ts
182
+ interface OrchestrationPlugin {
183
+ readonly name: string;
184
+ readonly dependsOn?: readonly string[];
185
+ setup?(context: PluginSetupContext): void | Promise<void>;
186
+ build?(context: PluginBuildContext): void | Promise<void>;
187
+ }
188
+ ```
189
+
190
+ - `setup` registers or consumes shared in-memory services.
191
+ - `build` consumes services, inspects previously emitted artifacts, and emits new artifacts.
192
+ - All setup hooks finish before the first build hook starts.
193
+ - Hooks run sequentially. A hook can be synchronous or asynchronous.
194
+
195
+ Plugin names must be non-empty and unique in one pipeline.
196
+
197
+ ## Plugin Dependencies
198
+
199
+ Use `dependsOn` when a plugin requires another configured plugin:
200
+
201
+ ```ts
202
+ const provider = definePlugin(() => ({
203
+ name: "provider",
204
+ setup() {},
205
+ }));
206
+
207
+ const consumer = definePlugin(() => ({
208
+ name: "consumer",
209
+ dependsOn: ["provider"],
210
+ build() {},
211
+ }));
212
+
213
+ const config = defineConfig({
214
+ input,
215
+ plugins: [consumer(), provider()],
216
+ });
217
+ ```
218
+
219
+ The resolved order is `provider`, then `consumer`, even though the consumer appears first in the config. Config order breaks ties between plugins that are currently eligible to run.
220
+
221
+ The runner rejects:
222
+
223
+ - Empty plugin names.
224
+ - Duplicate plugin names.
225
+ - Missing dependencies.
226
+ - Self dependencies.
227
+ - Dependency cycles.
228
+
229
+ These failures use `PluginConfigurationError` and occur before Core parses the input.
230
+
231
+ ## Sharing Typed Services
232
+
233
+ Service tokens allow one plugin to provide a typed in-memory capability to another plugin without adding untyped fields to a global context.
234
+
235
+ ```ts
236
+ import { createServiceToken, definePipelineConfig, definePlugin, run } from "opalesce";
237
+
238
+ interface DocumentInfo {
239
+ readonly asyncapiVersion: string;
240
+ }
241
+
242
+ const documentInfoService = createServiceToken<DocumentInfo>("document-info");
243
+
244
+ const documentInfoProvider = definePlugin(() => ({
245
+ name: "document-info-provider",
246
+ setup(context) {
247
+ context.provide(documentInfoService, {
248
+ asyncapiVersion: context.document.version(),
249
+ });
250
+ },
251
+ }));
252
+
253
+ const documentInfoFile = definePlugin(() => ({
254
+ name: "document-info-file",
255
+ dependsOn: ["document-info-provider"],
256
+ build(context) {
257
+ const documentInfo = context.get(documentInfoService);
258
+
259
+ context.emit({
260
+ path: "metadata/document.txt",
261
+ contents: `${documentInfo.asyncapiVersion}\n`,
262
+ });
263
+ },
264
+ }));
265
+
266
+ const result = await run(
267
+ definePipelineConfig({
268
+ input,
269
+ plugins: [documentInfoFile(), documentInfoProvider()],
270
+ }),
271
+ );
272
+ ```
273
+
274
+ The generic token type controls both `provide` and `get`. Token identity, not the diagnostic name, selects the value, so two tokens with the same name remain independent.
275
+
276
+ A token can be provided only once per pipeline. Retrieving an unavailable token or providing the same token twice raises `ServiceRegistryError` inside the active plugin hook.
277
+
278
+ A future `@opalesce/schema` package can use this boundary to export a shared `ServiceToken<SchemaGraph>`.
279
+
280
+ ## Emitting Artifacts
281
+
282
+ Only build contexts expose `emit`:
283
+
284
+ ```ts
285
+ context.emit({
286
+ path: "types/UserCreated.ts",
287
+ contents: "export interface UserCreated {}\n",
288
+ });
289
+ ```
290
+
291
+ Artifact paths must:
292
+
293
+ - Be non-empty and relative.
294
+ - Use forward slashes.
295
+ - Contain no empty, `.` or `..` segments.
296
+ - Not be POSIX or Windows absolute paths.
297
+ - Be unique across the complete pipeline.
298
+
299
+ Artifacts are stored as defensive frozen copies. `context.artifacts` is a frozen snapshot of artifacts emitted so far, allowing a later plugin such as a barrel generator to inspect earlier output:
300
+
301
+ ```ts
302
+ const barrelPlugin = definePlugin(() => ({
303
+ name: "barrel",
304
+ build(context) {
305
+ const modules = context.artifacts
306
+ .filter((artifact) => artifact.path.endsWith(".ts"))
307
+ .map((artifact) => `export * from "./${artifact.path}";`)
308
+ .join("\n");
309
+
310
+ context.emit({
311
+ path: "index.ts",
312
+ contents: `${modules}\n`,
313
+ });
314
+ },
315
+ }));
316
+ ```
317
+
318
+ Core returns artifacts but does not write them. A facade or storage layer owns output-directory resolution, atomic writes, cleanup, and rollback.
319
+
320
+ ## Error Handling
321
+
322
+ ```ts
323
+ import { PluginConfigurationError, PluginExecutionError, run } from "opalesce";
324
+ import { AsyncAPIParseError } from "@opalesce/core";
325
+
326
+ try {
327
+ await run(config);
328
+ } catch (error) {
329
+ if (error instanceof PluginConfigurationError) {
330
+ console.error(error.code, error.pluginNames);
331
+ } else if (error instanceof AsyncAPIParseError) {
332
+ console.error(error.diagnostics);
333
+ } else if (error instanceof PluginExecutionError) {
334
+ console.error(error.pluginName, error.phase, error.cause);
335
+ } else {
336
+ throw error;
337
+ }
338
+ }
339
+ ```
340
+
341
+ | Error | When it is raised |
342
+ | -------------------------- | -------------------------------------------------------------------------------------------------------------- |
343
+ | `PluginConfigurationError` | Plugin names or dependency relationships are invalid. This error is not wrapped. |
344
+ | `AsyncAPIParseError` | Core cannot produce a valid AsyncAPI document. This error passes through unchanged. |
345
+ | `PluginExecutionError` | A setup or build hook fails. It contains `pluginName`, `phase`, and the original `cause`. |
346
+ | `ServiceRegistryError` | A hook retrieves a missing service or provides a token twice. It is available as `PluginExecutionError.cause`. |
347
+ | `ArtifactError` | A hook emits an invalid or colliding artifact path. It is available as `PluginExecutionError.cause`. |
348
+
349
+ The pipeline is fail-fast and returns no partial result after an error.
350
+
351
+ ## Public API
352
+
353
+ Runtime exports:
354
+
355
+ - `parseAsyncAPI`
356
+ - `AsyncAPIParseError`
357
+ - `defineConfig`
358
+ - `definePlugin`
359
+ - `run`
360
+ - `createServiceToken`
361
+ - `PluginConfigurationError`
362
+ - `PluginExecutionError`
363
+ - `ServiceRegistryError`
364
+ - `ArtifactError`
365
+
366
+ The root entry point also exports the parser, pipeline, plugin, context, service, artifact, and error-code types:
367
+
368
+ - `Input`
369
+ - `ParseAsyncAPIOptions`
370
+ - `AsyncAPIDocumentInterface`
371
+ - `Diagnostic`
372
+
373
+ ## Current Boundaries
374
+
375
+ `@opalesce/core` intentionally does not:
376
+
377
+ - Discover or execute `opalesce.config.*`.
378
+ - Provide an `opalesce` bin or CLI arguments.
379
+ - Read an AsyncAPI source file.
380
+ - Write or clean output directories.
381
+ - Generate schemas, TypeScript, Zod, JSON Schema, or barrel files by itself.
382
+ - Support binary artifacts.
383
+
384
+ Those behaviors belong to config-loader, CLI, storage, schema, and output-plugin packages built on top of this API.
385
+
386
+ ## Prerequisites
387
+
388
+ Workspace development uses Node.js 24 as declared by the repository Nix environment. The package does not yet declare a public runtime support range.
389
+
390
+ Recommended:
391
+
392
+ ```sh
393
+ nix develop
394
+ pnpm install
395
+ ```
396
+
397
+ The workspace pins pnpm through the root `packageManager` field. For manual setup, install Node.js 24, enable the pinned pnpm version, and run `pnpm install` from the repository root.
398
+
399
+ ## Stack
400
+
401
+ | Area | Version source files |
402
+ | ----------------------------------------- | ------------------------------------------ |
403
+ | Runtime dependencies and package metadata | [`package.json`](./package.json) |
404
+ | Development environment | [`../../flake.nix`](../../flake.nix) |
405
+ | Workspace command aliases | [`../../justfile`](../../justfile) |
406
+
407
+ ## Development Commands
408
+
409
+ Run commands from the repository root:
410
+
411
+ | Command | Purpose |
412
+ | ---------------------------------------- | ----------------------------------------------------------- |
413
+ | `just nx build @opalesce/core` | Build ESM JavaScript and TypeScript declarations. |
414
+ | `pnpm --dir packages/core run typecheck` | Type-check package source and tests without emitting files. |
415
+ | `pnpm --dir packages/core run test` | Run focused parser and orchestration runtime tests. |
416
+ | `just nx run @opalesce/core:check` | Run package type-checking and tests. |
417
+ | `just nx run-many -t build` | Build every Nx package project. |
418
+ | `just nx run-many -t check --parallel=1` | Run package checks across the Nx workspace. |
419
+
420
+ The package tests cover parser option forwarding, lifecycle ordering, dependency validation, typed services, artifact validation, immutable results, package exports, and error propagation.
421
+
422
+ ## License
423
+
424
+ No license has been declared yet.
@@ -0,0 +1,10 @@
1
+ export { ArtifactError, PluginConfigurationError, PluginExecutionError, ServiceRegistryError, } from "./orchestrator/errors.js";
2
+ export type { ArtifactErrorCode, PluginConfigurationErrorCode, ServiceRegistryErrorCode, } from "./orchestrator/errors.js";
3
+ export { defineConfig, definePlugin } from "./orchestrator/helpers.js";
4
+ export { run } from "./orchestrator/run.js";
5
+ export { createServiceToken } from "./orchestrator/services.js";
6
+ export type { ServiceToken } from "./orchestrator/services.js";
7
+ export type { GeneratedArtifact, OrchestrationPlugin, PipelineConfig, PipelineResult, PluginBuildContext, PluginContext, PluginExecutionPhase, PluginSetupContext, } from "./orchestrator/types.js";
8
+ export { AsyncAPIParseError, parseAsyncAPI } from "./parseAsyncAPI.js";
9
+ export type { AsyncAPIDocumentInterface, AsyncAPIParserOptions, Diagnostic, Input, ParseAsyncAPIOptions, ParseOptions, ParsedAsyncAPI, } from "./parseAsyncAPI.js";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,iBAAiB,EACjB,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,YAAY,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,YAAY,EACV,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACvE,YAAY,EACV,yBAAyB,EACzB,qBAAqB,EACrB,UAAU,EACV,KAAK,EACL,oBAAoB,EACpB,YAAY,EACZ,cAAc,GACf,MAAM,oBAAoB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { ArtifactError, PluginConfigurationError, PluginExecutionError, ServiceRegistryError, } from "./orchestrator/errors.js";
2
+ export { defineConfig, definePlugin } from "./orchestrator/helpers.js";
3
+ export { run } from "./orchestrator/run.js";
4
+ export { createServiceToken } from "./orchestrator/services.js";
5
+ export { AsyncAPIParseError, parseAsyncAPI } from "./parseAsyncAPI.js";
@@ -0,0 +1,8 @@
1
+ import type { GeneratedArtifact } from "./types.js";
2
+ export declare class ArtifactStore {
3
+ private readonly artifacts;
4
+ private readonly paths;
5
+ emit(artifact: GeneratedArtifact): void;
6
+ snapshot(): readonly GeneratedArtifact[];
7
+ }
8
+ //# sourceMappingURL=artifacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../../src/orchestrator/artifacts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAkBpD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2B;IACrD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAE3C,IAAI,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI;IAkBvC,QAAQ,IAAI,SAAS,iBAAiB,EAAE;CAGzC"}
@@ -0,0 +1,34 @@
1
+ import { ArtifactError } from "./errors.js";
2
+ function isCanonicalArtifactPath(path) {
3
+ if (path.length === 0 ||
4
+ path.includes("\\") ||
5
+ path.includes("\0") ||
6
+ path.startsWith("/") ||
7
+ /^[A-Za-z]:\//u.test(path)) {
8
+ return false;
9
+ }
10
+ return path
11
+ .split("/")
12
+ .every((segment) => segment.length > 0 && segment !== "." && segment !== "..");
13
+ }
14
+ export class ArtifactStore {
15
+ artifacts = [];
16
+ paths = new Set();
17
+ emit(artifact) {
18
+ if (!isCanonicalArtifactPath(artifact.path)) {
19
+ throw new ArtifactError("invalid-path", artifact.path);
20
+ }
21
+ if (this.paths.has(artifact.path)) {
22
+ throw new ArtifactError("path-collision", artifact.path);
23
+ }
24
+ const storedArtifact = Object.freeze({
25
+ path: artifact.path,
26
+ contents: artifact.contents,
27
+ });
28
+ this.paths.add(storedArtifact.path);
29
+ this.artifacts.push(storedArtifact);
30
+ }
31
+ snapshot() {
32
+ return Object.freeze([...this.artifacts]);
33
+ }
34
+ }
@@ -0,0 +1,29 @@
1
+ import type { PluginExecutionPhase } from "./types.js";
2
+ export type PluginConfigurationErrorCode = "empty-name" | "duplicate-name" | "missing-dependency" | "dependency-cycle";
3
+ export declare class PluginConfigurationError extends Error {
4
+ readonly name = "PluginConfigurationError";
5
+ readonly code: PluginConfigurationErrorCode;
6
+ readonly pluginNames: readonly string[];
7
+ constructor(code: PluginConfigurationErrorCode, message: string, pluginNames?: readonly string[]);
8
+ }
9
+ export type ServiceRegistryErrorCode = "duplicate-service" | "missing-service";
10
+ export declare class ServiceRegistryError extends Error {
11
+ readonly name = "ServiceRegistryError";
12
+ readonly code: ServiceRegistryErrorCode;
13
+ readonly serviceName: string;
14
+ constructor(code: ServiceRegistryErrorCode, serviceName: string);
15
+ }
16
+ export type ArtifactErrorCode = "invalid-path" | "path-collision";
17
+ export declare class ArtifactError extends Error {
18
+ readonly name = "ArtifactError";
19
+ readonly code: ArtifactErrorCode;
20
+ readonly path: string;
21
+ constructor(code: ArtifactErrorCode, path: string);
22
+ }
23
+ export declare class PluginExecutionError extends Error {
24
+ readonly name = "PluginExecutionError";
25
+ readonly pluginName: string;
26
+ readonly phase: PluginExecutionPhase;
27
+ constructor(pluginName: string, phase: PluginExecutionPhase, cause: unknown);
28
+ }
29
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/orchestrator/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,MAAM,MAAM,4BAA4B,GACpC,YAAY,GACZ,gBAAgB,GAChB,oBAAoB,GACpB,kBAAkB,CAAC;AAEvB,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,SAAkB,IAAI,8BAA8B;IACpD,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC;IAC5C,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;gBAGtC,IAAI,EAAE,4BAA4B,EAClC,OAAO,EAAE,MAAM,EACf,WAAW,GAAE,SAAS,MAAM,EAAO;CAMtC;AAED,MAAM,MAAM,wBAAwB,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AAE/E,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,SAAkB,IAAI,0BAA0B;IAChD,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;IACxC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAEjB,IAAI,EAAE,wBAAwB,EAAE,WAAW,EAAE,MAAM;CAShE;AAED,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,gBAAgB,CAAC;AAElE,qBAAa,aAAc,SAAQ,KAAK;IACtC,SAAkB,IAAI,mBAAmB;IACzC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM;CASlD;AAED,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,SAAkB,IAAI,0BAA0B;IAChD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,oBAAoB,CAAC;gBAEzB,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,oBAAoB,EAAE,KAAK,EAAE,OAAO;CAK5E"}
@@ -0,0 +1,44 @@
1
+ export class PluginConfigurationError extends Error {
2
+ name = "PluginConfigurationError";
3
+ code;
4
+ pluginNames;
5
+ constructor(code, message, pluginNames = []) {
6
+ super(message);
7
+ this.code = code;
8
+ this.pluginNames = Object.freeze([...pluginNames]);
9
+ }
10
+ }
11
+ export class ServiceRegistryError extends Error {
12
+ name = "ServiceRegistryError";
13
+ code;
14
+ serviceName;
15
+ constructor(code, serviceName) {
16
+ super(code === "duplicate-service"
17
+ ? `Service "${serviceName}" has already been provided.`
18
+ : `Service "${serviceName}" has not been provided.`);
19
+ this.code = code;
20
+ this.serviceName = serviceName;
21
+ }
22
+ }
23
+ export class ArtifactError extends Error {
24
+ name = "ArtifactError";
25
+ code;
26
+ path;
27
+ constructor(code, path) {
28
+ super(code === "invalid-path"
29
+ ? `Artifact path "${path}" must be a canonical relative path using forward slashes.`
30
+ : `Artifact path "${path}" has already been emitted.`);
31
+ this.code = code;
32
+ this.path = path;
33
+ }
34
+ }
35
+ export class PluginExecutionError extends Error {
36
+ name = "PluginExecutionError";
37
+ pluginName;
38
+ phase;
39
+ constructor(pluginName, phase, cause) {
40
+ super(`Plugin "${pluginName}" failed during ${phase}.`, { cause });
41
+ this.pluginName = pluginName;
42
+ this.phase = phase;
43
+ }
44
+ }
@@ -0,0 +1,4 @@
1
+ import type { OrchestrationPlugin, PipelineConfig } from "./types.js";
2
+ export declare function defineConfig<const TConfig extends PipelineConfig>(config: TConfig): TConfig;
3
+ export declare function definePlugin<TFactory extends (...arguments_: never[]) => OrchestrationPlugin>(factory: TFactory): TFactory;
4
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/orchestrator/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEtE,wBAAgB,YAAY,CAAC,KAAK,CAAC,OAAO,SAAS,cAAc,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAE3F;AAED,wBAAgB,YAAY,CAAC,QAAQ,SAAS,CAAC,GAAG,UAAU,EAAE,KAAK,EAAE,KAAK,mBAAmB,EAC3F,OAAO,EAAE,QAAQ,GAChB,QAAQ,CAEV"}
@@ -0,0 +1,6 @@
1
+ export function defineConfig(config) {
2
+ return config;
3
+ }
4
+ export function definePlugin(factory) {
5
+ return factory;
6
+ }
@@ -0,0 +1,3 @@
1
+ import type { OrchestrationPlugin } from "./types.js";
2
+ export declare function orderPlugins(configuredPlugins: readonly OrchestrationPlugin[]): readonly OrchestrationPlugin[];
3
+ //# sourceMappingURL=orderPlugins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orderPlugins.d.ts","sourceRoot":"","sources":["../../src/orchestrator/orderPlugins.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAOtD,wBAAgB,YAAY,CAC1B,iBAAiB,EAAE,SAAS,mBAAmB,EAAE,GAChD,SAAS,mBAAmB,EAAE,CAwEhC"}
@@ -0,0 +1,41 @@
1
+ import { PluginConfigurationError } from "./errors.js";
2
+ export function orderPlugins(configuredPlugins) {
3
+ const records = [];
4
+ const pluginsByName = new Map();
5
+ for (const plugin of configuredPlugins) {
6
+ if (typeof plugin.name !== "string" || plugin.name.trim().length === 0) {
7
+ throw new PluginConfigurationError("empty-name", "Plugin names must contain at least one non-whitespace character.");
8
+ }
9
+ if (pluginsByName.has(plugin.name)) {
10
+ throw new PluginConfigurationError("duplicate-name", `Plugin name "${plugin.name}" is configured more than once.`, [plugin.name]);
11
+ }
12
+ pluginsByName.set(plugin.name, plugin);
13
+ records.push({
14
+ plugin,
15
+ dependencies: Object.freeze([...new Set(plugin.dependsOn ?? [])]),
16
+ });
17
+ }
18
+ for (const record of records) {
19
+ if (record.dependencies.includes(record.plugin.name)) {
20
+ throw new PluginConfigurationError("dependency-cycle", `Plugin "${record.plugin.name}" cannot depend on itself.`, [record.plugin.name]);
21
+ }
22
+ const missing = record.dependencies.filter((name) => !pluginsByName.has(name));
23
+ if (missing.length > 0) {
24
+ throw new PluginConfigurationError("missing-dependency", `Plugin "${record.plugin.name}" requires missing dependencies: ${missing.join(", ")}.`, [record.plugin.name, ...missing]);
25
+ }
26
+ }
27
+ const pending = [...records];
28
+ const resolvedNames = new Set();
29
+ const ordered = [];
30
+ while (pending.length > 0) {
31
+ const ready = pending.find((record) => record.dependencies.every((name) => resolvedNames.has(name)));
32
+ if (ready === undefined) {
33
+ const cyclicNames = pending.map((record) => record.plugin.name);
34
+ throw new PluginConfigurationError("dependency-cycle", `Plugin dependency cycle detected: ${cyclicNames.join(", ")}.`, cyclicNames);
35
+ }
36
+ pending.splice(pending.indexOf(ready), 1);
37
+ ordered.push(ready.plugin);
38
+ resolvedNames.add(ready.plugin.name);
39
+ }
40
+ return Object.freeze(ordered);
41
+ }
@@ -0,0 +1,3 @@
1
+ import type { PipelineConfig, PipelineResult } from "./types.js";
2
+ export declare function run(config: PipelineConfig): Promise<PipelineResult>;
3
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/orchestrator/run.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAEV,cAAc,EACd,cAAc,EAIf,MAAM,YAAY,CAAC;AAcpB,wBAAsB,GAAG,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAiDzE"}
@@ -0,0 +1,57 @@
1
+ import { parseAsyncAPI } from "../parseAsyncAPI.js";
2
+ import { ArtifactStore } from "./artifacts.js";
3
+ import { PluginExecutionError } from "./errors.js";
4
+ import { orderPlugins } from "./orderPlugins.js";
5
+ import { ServiceRegistry } from "./services.js";
6
+ async function runHook(pluginName, phase, hook) {
7
+ try {
8
+ await hook();
9
+ }
10
+ catch (cause) {
11
+ throw new PluginExecutionError(pluginName, phase, cause);
12
+ }
13
+ }
14
+ export async function run(config) {
15
+ const plugins = orderPlugins(config.plugins ?? []);
16
+ const parsed = await parseAsyncAPI(config.input, config.parser);
17
+ const services = new ServiceRegistry();
18
+ const artifacts = new ArtifactStore();
19
+ function get(token) {
20
+ return services.get(token);
21
+ }
22
+ const setupContext = Object.freeze({
23
+ document: parsed.document,
24
+ diagnostics: parsed.diagnostics,
25
+ get,
26
+ provide(token, value) {
27
+ services.provide(token, value);
28
+ },
29
+ });
30
+ const buildContext = Object.freeze({
31
+ document: parsed.document,
32
+ diagnostics: parsed.diagnostics,
33
+ get,
34
+ get artifacts() {
35
+ return artifacts.snapshot();
36
+ },
37
+ emit(artifact) {
38
+ artifacts.emit(artifact);
39
+ },
40
+ });
41
+ for (const plugin of plugins) {
42
+ if (plugin.setup !== undefined) {
43
+ await runHook(plugin.name, "setup", () => plugin.setup?.(setupContext));
44
+ }
45
+ }
46
+ for (const plugin of plugins) {
47
+ if (plugin.build !== undefined) {
48
+ await runHook(plugin.name, "build", () => plugin.build?.(buildContext));
49
+ }
50
+ }
51
+ return Object.freeze({
52
+ document: parsed.document,
53
+ diagnostics: parsed.diagnostics,
54
+ artifacts: artifacts.snapshot(),
55
+ pluginNames: Object.freeze(plugins.map((plugin) => plugin.name)),
56
+ });
57
+ }
@@ -0,0 +1,26 @@
1
+ declare const serviceAccess: unique symbol;
2
+ interface MissingService {
3
+ readonly found: false;
4
+ }
5
+ interface AvailableService<T> {
6
+ readonly found: true;
7
+ readonly value: T;
8
+ }
9
+ type ServiceLookup<T> = MissingService | AvailableService<T>;
10
+ interface ServiceAccess<T> {
11
+ read(scope: object): ServiceLookup<T>;
12
+ write(scope: object, value: T): boolean;
13
+ }
14
+ export interface ServiceToken<T> {
15
+ readonly name: string;
16
+ readonly key: symbol;
17
+ readonly [serviceAccess]: ServiceAccess<T>;
18
+ }
19
+ export declare function createServiceToken<T>(name: string): ServiceToken<T>;
20
+ export declare class ServiceRegistry {
21
+ private readonly scope;
22
+ provide<T>(token: ServiceToken<T>, value: T): void;
23
+ get<T>(token: ServiceToken<T>): T;
24
+ }
25
+ export {};
26
+ //# sourceMappingURL=services.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/orchestrator/services.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,aAAa,eAAoC,CAAC;AAExD,UAAU,cAAc;IACtB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACvB;AAED,UAAU,gBAAgB,CAAC,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;CACnB;AAED,KAAK,aAAa,CAAC,CAAC,IAAI,cAAc,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;AAE7D,UAAU,aAAa,CAAC,CAAC;IACvB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;IACtC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC;CACzC;AAED,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;CAC5C;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,CA2BnE;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAM;IAE5B,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAMlD,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC;CASlC"}
@@ -0,0 +1,42 @@
1
+ import { ServiceRegistryError } from "./errors.js";
2
+ const serviceAccess = Symbol("opalesce.service-access");
3
+ export function createServiceToken(name) {
4
+ const values = new WeakMap();
5
+ return Object.freeze({
6
+ name,
7
+ key: Symbol(name),
8
+ [serviceAccess]: {
9
+ read(scope) {
10
+ const entry = values.get(scope);
11
+ return entry === undefined
12
+ ? { found: false }
13
+ : {
14
+ found: true,
15
+ value: entry.value,
16
+ };
17
+ },
18
+ write(scope, value) {
19
+ if (values.has(scope)) {
20
+ return false;
21
+ }
22
+ values.set(scope, { value });
23
+ return true;
24
+ },
25
+ },
26
+ });
27
+ }
28
+ export class ServiceRegistry {
29
+ scope = {};
30
+ provide(token, value) {
31
+ if (!token[serviceAccess].write(this.scope, value)) {
32
+ throw new ServiceRegistryError("duplicate-service", token.name);
33
+ }
34
+ }
35
+ get(token) {
36
+ const lookup = token[serviceAccess].read(this.scope);
37
+ if (!lookup.found) {
38
+ throw new ServiceRegistryError("missing-service", token.name);
39
+ }
40
+ return lookup.value;
41
+ }
42
+ }
@@ -0,0 +1,37 @@
1
+ import type { AsyncAPIDocumentInterface, Diagnostic, Input, ParseAsyncAPIOptions } from "../parseAsyncAPI.js";
2
+ import type { ServiceToken } from "./services.js";
3
+ export interface GeneratedArtifact {
4
+ readonly path: string;
5
+ readonly contents: string;
6
+ }
7
+ export interface PluginContext {
8
+ readonly document: AsyncAPIDocumentInterface;
9
+ readonly diagnostics: readonly Diagnostic[];
10
+ get<T>(token: ServiceToken<T>): T;
11
+ }
12
+ export interface PluginSetupContext extends PluginContext {
13
+ provide<T>(token: ServiceToken<T>, value: T): void;
14
+ }
15
+ export interface PluginBuildContext extends PluginContext {
16
+ readonly artifacts: readonly GeneratedArtifact[];
17
+ emit(artifact: GeneratedArtifact): void;
18
+ }
19
+ export interface OrchestrationPlugin<TName extends string = string> {
20
+ readonly name: TName;
21
+ readonly dependsOn?: readonly string[];
22
+ setup?(context: PluginSetupContext): void | Promise<void>;
23
+ build?(context: PluginBuildContext): void | Promise<void>;
24
+ }
25
+ export interface PipelineConfig {
26
+ readonly input: Input;
27
+ readonly parser?: ParseAsyncAPIOptions;
28
+ readonly plugins?: readonly OrchestrationPlugin[];
29
+ }
30
+ export interface PipelineResult {
31
+ readonly document: AsyncAPIDocumentInterface;
32
+ readonly diagnostics: readonly Diagnostic[];
33
+ readonly artifacts: readonly GeneratedArtifact[];
34
+ readonly pluginNames: readonly string[];
35
+ }
36
+ export type PluginExecutionPhase = "setup" | "build";
37
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/orchestrator/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,UAAU,EACV,KAAK,EACL,oBAAoB,EACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,CAAC;IAC7C,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;IAC5C,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,kBAAmB,SAAQ,aAAa;IACvD,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;CACpD;AAED,MAAM,WAAW,kBAAmB,SAAQ,aAAa;IACvD,QAAQ,CAAC,SAAS,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACjD,IAAI,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,mBAAmB,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM;IAChE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,KAAK,CAAC,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,KAAK,CAAC,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,oBAAoB,CAAC;IACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACnD;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,CAAC;IAC7C,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;IAC5C,QAAQ,CAAC,SAAS,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACjD,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG,OAAO,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ import { Parser, type AsyncAPIDocumentInterface, type Diagnostic, type Input, type ParseOptions } from "@asyncapi/parser";
2
+ export type { AsyncAPIDocumentInterface, Diagnostic, Input, ParseOptions } from "@asyncapi/parser";
3
+ export interface ParsedAsyncAPI {
4
+ readonly document: AsyncAPIDocumentInterface;
5
+ readonly diagnostics: readonly Diagnostic[];
6
+ }
7
+ export type AsyncAPIParserOptions = NonNullable<ConstructorParameters<typeof Parser>[0]>;
8
+ export interface ParseAsyncAPIOptions {
9
+ readonly parser?: AsyncAPIParserOptions;
10
+ readonly parse?: ParseOptions;
11
+ }
12
+ export declare class AsyncAPIParseError extends Error {
13
+ readonly diagnostics: readonly Diagnostic[];
14
+ constructor(diagnostics: readonly Diagnostic[]);
15
+ }
16
+ export declare function parseAsyncAPI(input: Input, options?: ParseAsyncAPIOptions): Promise<ParsedAsyncAPI>;
17
+ //# sourceMappingURL=parseAsyncAPI.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseAsyncAPI.d.ts","sourceRoot":"","sources":["../src/parseAsyncAPI.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,MAAM,EACN,KAAK,yBAAyB,EAC9B,KAAK,UAAU,EACf,KAAK,KAAK,EACV,KAAK,YAAY,EAClB,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EAAE,yBAAyB,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEnG,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,CAAC;IAC7C,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;CAC7C;AAED,MAAM,MAAM,qBAAqB,GAAG,WAAW,CAAC,qBAAqB,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzF,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,qBAAqB,CAAC;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC;CAC/B;AAMD,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;gBAEhC,WAAW,EAAE,SAAS,UAAU,EAAE;CAK/C;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,KAAK,EACZ,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,cAAc,CAAC,CAezB"}
@@ -0,0 +1,24 @@
1
+ import { DiagnosticSeverity, Parser, } from "@asyncapi/parser";
2
+ function freezeDiagnostics(diagnostics) {
3
+ return Object.freeze([...diagnostics]);
4
+ }
5
+ export class AsyncAPIParseError extends Error {
6
+ diagnostics;
7
+ constructor(diagnostics) {
8
+ super("Failed to parse the AsyncAPI document.");
9
+ this.name = "AsyncAPIParseError";
10
+ this.diagnostics = freezeDiagnostics(diagnostics);
11
+ }
12
+ }
13
+ export async function parseAsyncAPI(input, options) {
14
+ const parser = new Parser(options?.parser);
15
+ const output = await parser.parse(input, options?.parse);
16
+ if (!output.document ||
17
+ output.diagnostics.some((diagnostic) => diagnostic.severity === DiagnosticSeverity.Error)) {
18
+ throw new AsyncAPIParseError(output.diagnostics);
19
+ }
20
+ return {
21
+ document: output.document,
22
+ diagnostics: freezeDiagnostics(output.diagnostics),
23
+ };
24
+ }
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@opalesce/core",
3
+ "version": "0.0.0",
4
+ "description": "AsyncAPI parsing and plugin orchestration engine for Opalesce",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/ravecat/opalesce.git",
8
+ "directory": "packages/core"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "!dist/*.tsbuildinfo"
13
+ ],
14
+ "type": "module",
15
+ "main": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.js"
21
+ }
22
+ },
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "dependencies": {
27
+ "@asyncapi/parser": "^3.6.0"
28
+ },
29
+ "scripts": {
30
+ "typecheck": "tsc -p tsconfig.check.json",
31
+ "test": "vitest run --config vitest.config.ts",
32
+ "check": "pnpm run typecheck && pnpm run test"
33
+ }
34
+ }