@thymian/core-testing 0.0.1

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.
Files changed (38) hide show
  1. package/README.md +285 -0
  2. package/dist/factories/http-request.factory.d.ts +40 -0
  3. package/dist/factories/http-request.factory.d.ts.map +1 -0
  4. package/dist/factories/http-request.factory.js +84 -0
  5. package/dist/factories/http-request.factory.js.map +1 -0
  6. package/dist/factories/http-response.factory.d.ts +51 -0
  7. package/dist/factories/http-response.factory.d.ts.map +1 -0
  8. package/dist/factories/http-response.factory.js +109 -0
  9. package/dist/factories/http-response.factory.js.map +1 -0
  10. package/dist/factories/parameter.factory.d.ts +28 -0
  11. package/dist/factories/parameter.factory.d.ts.map +1 -0
  12. package/dist/factories/parameter.factory.js +48 -0
  13. package/dist/factories/parameter.factory.js.map +1 -0
  14. package/dist/factories/schema.factory.d.ts +45 -0
  15. package/dist/factories/schema.factory.d.ts.map +1 -0
  16. package/dist/factories/schema.factory.js +81 -0
  17. package/dist/factories/schema.factory.js.map +1 -0
  18. package/dist/factories/thymian-format.factory.d.ts +46 -0
  19. package/dist/factories/thymian-format.factory.d.ts.map +1 -0
  20. package/dist/factories/thymian-format.factory.js +65 -0
  21. package/dist/factories/thymian-format.factory.js.map +1 -0
  22. package/dist/index.d.ts +40 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +46 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/mocks/emitter.mock.d.ts +71 -0
  27. package/dist/mocks/emitter.mock.d.ts.map +1 -0
  28. package/dist/mocks/emitter.mock.js +101 -0
  29. package/dist/mocks/emitter.mock.js.map +1 -0
  30. package/dist/mocks/logger.mock.d.ts +36 -0
  31. package/dist/mocks/logger.mock.d.ts.map +1 -0
  32. package/dist/mocks/logger.mock.js +74 -0
  33. package/dist/mocks/logger.mock.js.map +1 -0
  34. package/dist/mocks/plugin.mock.d.ts +85 -0
  35. package/dist/mocks/plugin.mock.d.ts.map +1 -0
  36. package/dist/mocks/plugin.mock.js +102 -0
  37. package/dist/mocks/plugin.mock.js.map +1 -0
  38. package/package.json +36 -0
@@ -0,0 +1,45 @@
1
+ import type { ThymianSchema } from '@thymian/core';
2
+ /**
3
+ * Creates a ThymianSchema with sensible defaults.
4
+ * All properties can be overridden.
5
+ *
6
+ * @param overrides - Partial schema to override defaults
7
+ * @returns A complete ThymianSchema object
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const stringSchema = createThymianSchema({ type: 'string', minLength: 5 });
12
+ * const objectSchema = createThymianSchema({
13
+ * type: 'object',
14
+ * properties: {
15
+ * name: createThymianSchema({ type: 'string' })
16
+ * }
17
+ * });
18
+ * ```
19
+ */
20
+ export declare function createThymianSchema(overrides?: Partial<ThymianSchema>): ThymianSchema;
21
+ /**
22
+ * Creates a string schema with sensible defaults
23
+ */
24
+ export declare function createStringSchema(overrides?: Partial<ThymianSchema>): ThymianSchema;
25
+ /**
26
+ * Creates a number schema with sensible defaults
27
+ */
28
+ export declare function createNumberSchema(overrides?: Partial<ThymianSchema>): ThymianSchema;
29
+ /**
30
+ * Creates an integer schema with sensible defaults
31
+ */
32
+ export declare function createIntegerSchema(overrides?: Partial<ThymianSchema>): ThymianSchema;
33
+ /**
34
+ * Creates a boolean schema with sensible defaults
35
+ */
36
+ export declare function createBooleanSchema(overrides?: Partial<ThymianSchema>): ThymianSchema;
37
+ /**
38
+ * Creates an object schema with sensible defaults
39
+ */
40
+ export declare function createObjectSchema(properties?: Record<string, ThymianSchema>, overrides?: Partial<ThymianSchema>): ThymianSchema;
41
+ /**
42
+ * Creates an array schema with sensible defaults
43
+ */
44
+ export declare function createArraySchema(items?: ThymianSchema, overrides?: Partial<ThymianSchema>): ThymianSchema;
45
+ //# sourceMappingURL=schema.factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.factory.d.ts","sourceRoot":"","sources":["../../src/factories/schema.factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,GAAE,OAAO,CAAC,aAAa,CAAM,GACrC,aAAa,CAKf;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,GAAE,OAAO,CAAC,aAAa,CAAM,GACrC,aAAa,CAKf;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,GAAE,OAAO,CAAC,aAAa,CAAM,GACrC,aAAa,CAKf;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,GAAE,OAAO,CAAC,aAAa,CAAM,GACrC,aAAa,CAKf;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,GAAE,OAAO,CAAC,aAAa,CAAM,GACrC,aAAa,CAKf;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAM,EAC9C,SAAS,GAAE,OAAO,CAAC,aAAa,CAAM,GACrC,aAAa,CAMf;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,GAAE,aAAoC,EAC3C,SAAS,GAAE,OAAO,CAAC,aAAa,CAAM,GACrC,aAAa,CAMf"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Creates a ThymianSchema with sensible defaults.
3
+ * All properties can be overridden.
4
+ *
5
+ * @param overrides - Partial schema to override defaults
6
+ * @returns A complete ThymianSchema object
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const stringSchema = createThymianSchema({ type: 'string', minLength: 5 });
11
+ * const objectSchema = createThymianSchema({
12
+ * type: 'object',
13
+ * properties: {
14
+ * name: createThymianSchema({ type: 'string' })
15
+ * }
16
+ * });
17
+ * ```
18
+ */
19
+ export function createThymianSchema(overrides = {}) {
20
+ return {
21
+ type: 'string',
22
+ ...overrides,
23
+ };
24
+ }
25
+ /**
26
+ * Creates a string schema with sensible defaults
27
+ */
28
+ export function createStringSchema(overrides = {}) {
29
+ return createThymianSchema({
30
+ type: 'string',
31
+ ...overrides,
32
+ });
33
+ }
34
+ /**
35
+ * Creates a number schema with sensible defaults
36
+ */
37
+ export function createNumberSchema(overrides = {}) {
38
+ return createThymianSchema({
39
+ type: 'number',
40
+ ...overrides,
41
+ });
42
+ }
43
+ /**
44
+ * Creates an integer schema with sensible defaults
45
+ */
46
+ export function createIntegerSchema(overrides = {}) {
47
+ return createThymianSchema({
48
+ type: 'integer',
49
+ ...overrides,
50
+ });
51
+ }
52
+ /**
53
+ * Creates a boolean schema with sensible defaults
54
+ */
55
+ export function createBooleanSchema(overrides = {}) {
56
+ return createThymianSchema({
57
+ type: 'boolean',
58
+ ...overrides,
59
+ });
60
+ }
61
+ /**
62
+ * Creates an object schema with sensible defaults
63
+ */
64
+ export function createObjectSchema(properties = {}, overrides = {}) {
65
+ return createThymianSchema({
66
+ type: 'object',
67
+ properties,
68
+ ...overrides,
69
+ });
70
+ }
71
+ /**
72
+ * Creates an array schema with sensible defaults
73
+ */
74
+ export function createArraySchema(items = createStringSchema(), overrides = {}) {
75
+ return createThymianSchema({
76
+ type: 'array',
77
+ items,
78
+ ...overrides,
79
+ });
80
+ }
81
+ //# sourceMappingURL=schema.factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.factory.js","sourceRoot":"","sources":["../../src/factories/schema.factory.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,mBAAmB,CACjC,YAAoC,EAAE;IAEtC,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,YAAoC,EAAE;IAEtC,OAAO,mBAAmB,CAAC;QACzB,IAAI,EAAE,QAAQ;QACd,GAAG,SAAS;KACb,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,YAAoC,EAAE;IAEtC,OAAO,mBAAmB,CAAC;QACzB,IAAI,EAAE,QAAQ;QACd,GAAG,SAAS;KACb,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,YAAoC,EAAE;IAEtC,OAAO,mBAAmB,CAAC;QACzB,IAAI,EAAE,SAAS;QACf,GAAG,SAAS;KACb,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,YAAoC,EAAE;IAEtC,OAAO,mBAAmB,CAAC;QACzB,IAAI,EAAE,SAAS;QACf,GAAG,SAAS;KACb,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,aAA4C,EAAE,EAC9C,YAAoC,EAAE;IAEtC,OAAO,mBAAmB,CAAC;QACzB,IAAI,EAAE,QAAQ;QACd,UAAU;QACV,GAAG,SAAS;KACb,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAAuB,kBAAkB,EAAE,EAC3C,YAAoC,EAAE;IAEtC,OAAO,mBAAmB,CAAC;QACzB,IAAI,EAAE,OAAO;QACb,KAAK;QACL,GAAG,SAAS;KACb,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,46 @@
1
+ import type { ThymianHttpRequest, ThymianHttpResponse } from '@thymian/core';
2
+ import { ThymianFormat } from '@thymian/core';
3
+ /**
4
+ * Creates an empty ThymianFormat instance.
5
+ *
6
+ * @returns A new ThymianFormat instance
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const format = createThymianFormat();
11
+ * format.addHttpTransaction(request, response);
12
+ * ```
13
+ */
14
+ export declare function createThymianFormat(): ThymianFormat;
15
+ /**
16
+ * Creates a ThymianFormat with a single HTTP transaction.
17
+ *
18
+ * @param request - Optional request override
19
+ * @param response - Optional response override
20
+ * @returns A ThymianFormat with one transaction
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * const format = createThymianFormatWithTransaction(
25
+ * createGetRequest({ path: '/users' }),
26
+ * createOkResponse()
27
+ * );
28
+ * ```
29
+ */
30
+ export declare function createThymianFormatWithTransaction(request?: ThymianHttpRequest, response?: ThymianHttpResponse): ThymianFormat;
31
+ /**
32
+ * Creates a ThymianFormat with multiple HTTP transactions.
33
+ *
34
+ * @param transactions - Array of [request, response] tuples
35
+ * @returns A ThymianFormat with multiple transactions
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * const format = createThymianFormatWithTransactions([
40
+ * [createGetRequest({ path: '/users' }), createOkResponse()],
41
+ * [createPostRequest({ path: '/users' }), createCreatedResponse()],
42
+ * ]);
43
+ * ```
44
+ */
45
+ export declare function createThymianFormatWithTransactions(transactions: Array<[ThymianHttpRequest, ThymianHttpResponse]> | number): ThymianFormat;
46
+ //# sourceMappingURL=thymian-format.factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thymian-format.factory.d.ts","sourceRoot":"","sources":["../../src/factories/thymian-format.factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAK9C;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,IAAI,aAAa,CAEnD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kCAAkC,CAChD,OAAO,GAAE,kBAAwC,EACjD,QAAQ,GAAE,mBAA0C,GACnD,aAAa,CAIf;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mCAAmC,CACjD,YAAY,EAAE,KAAK,CAAC,CAAC,kBAAkB,EAAE,mBAAmB,CAAC,CAAC,GAAG,MAAM,GACtE,aAAa,CAcf"}
@@ -0,0 +1,65 @@
1
+ import { ThymianFormat } from '@thymian/core';
2
+ import { createHttpRequest } from './http-request.factory.js';
3
+ import { createHttpResponse } from './http-response.factory.js';
4
+ /**
5
+ * Creates an empty ThymianFormat instance.
6
+ *
7
+ * @returns A new ThymianFormat instance
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const format = createThymianFormat();
12
+ * format.addHttpTransaction(request, response);
13
+ * ```
14
+ */
15
+ export function createThymianFormat() {
16
+ return new ThymianFormat();
17
+ }
18
+ /**
19
+ * Creates a ThymianFormat with a single HTTP transaction.
20
+ *
21
+ * @param request - Optional request override
22
+ * @param response - Optional response override
23
+ * @returns A ThymianFormat with one transaction
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * const format = createThymianFormatWithTransaction(
28
+ * createGetRequest({ path: '/users' }),
29
+ * createOkResponse()
30
+ * );
31
+ * ```
32
+ */
33
+ export function createThymianFormatWithTransaction(request = createHttpRequest(), response = createHttpResponse()) {
34
+ const format = new ThymianFormat();
35
+ format.addHttpTransaction(request, response);
36
+ return format;
37
+ }
38
+ /**
39
+ * Creates a ThymianFormat with multiple HTTP transactions.
40
+ *
41
+ * @param transactions - Array of [request, response] tuples
42
+ * @returns A ThymianFormat with multiple transactions
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * const format = createThymianFormatWithTransactions([
47
+ * [createGetRequest({ path: '/users' }), createOkResponse()],
48
+ * [createPostRequest({ path: '/users' }), createCreatedResponse()],
49
+ * ]);
50
+ * ```
51
+ */
52
+ export function createThymianFormatWithTransactions(transactions) {
53
+ const format = new ThymianFormat();
54
+ if (typeof transactions === 'number') {
55
+ transactions = Array.from({ length: transactions }, (_, i) => [
56
+ createHttpRequest({ path: `/transaction-${i}` }),
57
+ createHttpResponse(),
58
+ ]);
59
+ }
60
+ for (const [request, response] of transactions) {
61
+ format.addHttpTransaction(request, response);
62
+ }
63
+ return format;
64
+ }
65
+ //# sourceMappingURL=thymian-format.factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thymian-format.factory.js","sourceRoot":"","sources":["../../src/factories/thymian-format.factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,IAAI,aAAa,EAAE,CAAC;AAC7B,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,kCAAkC,CAChD,UAA8B,iBAAiB,EAAE,EACjD,WAAgC,kBAAkB,EAAE;IAEpD,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;IACnC,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,mCAAmC,CACjD,YAAuE;IAEvE,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;IAEnC,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;QACrC,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5D,iBAAiB,CAAC,EAAE,IAAI,EAAE,gBAAgB,CAAC,EAAE,EAAE,CAAC;YAChD,kBAAkB,EAAE;SACrB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,YAAY,EAAE,CAAC;QAC/C,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @thymian/core-testing
3
+ *
4
+ * Testing utilities, factories, and mocks for the Thymian plugin ecosystem.
5
+ *
6
+ * This package provides reusable testing utilities that make it easy to write
7
+ * tests for Thymian plugins and components.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import {
12
+ * createHttpRequest,
13
+ * createHttpResponse,
14
+ * createMockLogger,
15
+ * createMockEmitter,
16
+ * } from '@thymian/core-testing';
17
+ *
18
+ * // Create test data
19
+ * const request = createGetRequest({ path: '/users' });
20
+ * const response = createOkResponse();
21
+ *
22
+ * // Create test doubles
23
+ * const logger = createMockLogger();
24
+ * const emitter = createMockEmitter();
25
+ *
26
+ * // Test your plugin
27
+ * await myPlugin(emitter, logger, { cwd: '/test' });
28
+ *
29
+ * expect(logger.info).toHaveBeenCalled();
30
+ * ```
31
+ */
32
+ export { createDeleteRequest, createGetRequest, createHttpRequest, createPatchRequest, createPostRequest, createPutRequest, } from './factories/http-request.factory.js';
33
+ export { createBadRequestResponse, createCreatedResponse, createForbiddenResponse, createHttpResponse, createInternalServerErrorResponse, createNoContentResponse, createNotFoundResponse, createOkResponse, createUnauthorizedResponse, } from './factories/http-response.factory.js';
34
+ export { createOptionalParameter, createParameter, createRequiredParameter, } from './factories/parameter.factory.js';
35
+ export { createArraySchema, createBooleanSchema, createIntegerSchema, createNumberSchema, createObjectSchema, createStringSchema, createThymianSchema, } from './factories/schema.factory.js';
36
+ export { createThymianFormat, createThymianFormatWithTransaction, createThymianFormatWithTransactions, } from './factories/thymian-format.factory.js';
37
+ export { captureEmittedEvents, createEmitterWithActionHandlers, createEmitterWithHandlers, createMockEmitter, } from './mocks/emitter.mock.js';
38
+ export { createMockLogger, createSilentMockLogger, createVerboseMockLogger, } from './mocks/logger.mock.js';
39
+ export { createMockPlugin, createPluginThatEmits, createPluginWithMetadata, createSpyPluginFn, } from './mocks/plugin.mock.js';
40
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAMH,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,iCAAiC,EACjC,uBAAuB,EACvB,sBAAsB,EACtB,gBAAgB,EAChB,0BAA0B,GAC3B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,uBAAuB,EACvB,eAAe,EACf,uBAAuB,GACxB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,mBAAmB,EACnB,kCAAkC,EAClC,mCAAmC,GACpC,MAAM,uCAAuC,CAAC;AAM/C,OAAO,EACL,oBAAoB,EACpB,+BAA+B,EAC/B,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @thymian/core-testing
3
+ *
4
+ * Testing utilities, factories, and mocks for the Thymian plugin ecosystem.
5
+ *
6
+ * This package provides reusable testing utilities that make it easy to write
7
+ * tests for Thymian plugins and components.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import {
12
+ * createHttpRequest,
13
+ * createHttpResponse,
14
+ * createMockLogger,
15
+ * createMockEmitter,
16
+ * } from '@thymian/core-testing';
17
+ *
18
+ * // Create test data
19
+ * const request = createGetRequest({ path: '/users' });
20
+ * const response = createOkResponse();
21
+ *
22
+ * // Create test doubles
23
+ * const logger = createMockLogger();
24
+ * const emitter = createMockEmitter();
25
+ *
26
+ * // Test your plugin
27
+ * await myPlugin(emitter, logger, { cwd: '/test' });
28
+ *
29
+ * expect(logger.info).toHaveBeenCalled();
30
+ * ```
31
+ */
32
+ // ============================================================================
33
+ // Factories - Data Format
34
+ // ============================================================================
35
+ export { createDeleteRequest, createGetRequest, createHttpRequest, createPatchRequest, createPostRequest, createPutRequest, } from './factories/http-request.factory.js';
36
+ export { createBadRequestResponse, createCreatedResponse, createForbiddenResponse, createHttpResponse, createInternalServerErrorResponse, createNoContentResponse, createNotFoundResponse, createOkResponse, createUnauthorizedResponse, } from './factories/http-response.factory.js';
37
+ export { createOptionalParameter, createParameter, createRequiredParameter, } from './factories/parameter.factory.js';
38
+ export { createArraySchema, createBooleanSchema, createIntegerSchema, createNumberSchema, createObjectSchema, createStringSchema, createThymianSchema, } from './factories/schema.factory.js';
39
+ export { createThymianFormat, createThymianFormatWithTransaction, createThymianFormatWithTransactions, } from './factories/thymian-format.factory.js';
40
+ // ============================================================================
41
+ // Mocks - Test Doubles
42
+ // ============================================================================
43
+ export { captureEmittedEvents, createEmitterWithActionHandlers, createEmitterWithHandlers, createMockEmitter, } from './mocks/emitter.mock.js';
44
+ export { createMockLogger, createSilentMockLogger, createVerboseMockLogger, } from './mocks/logger.mock.js';
45
+ export { createMockPlugin, createPluginThatEmits, createPluginWithMetadata, createSpyPluginFn, } from './mocks/plugin.mock.js';
46
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,+EAA+E;AAC/E,0BAA0B;AAC1B,+EAA+E;AAE/E,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,iCAAiC,EACjC,uBAAuB,EACvB,sBAAsB,EACtB,gBAAgB,EAChB,0BAA0B,GAC3B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,uBAAuB,EACvB,eAAe,EACf,uBAAuB,GACxB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,mBAAmB,EACnB,kCAAkC,EAClC,mCAAmC,GACpC,MAAM,uCAAuC,CAAC;AAE/C,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E,OAAO,EACL,oBAAoB,EACpB,+BAA+B,EAC/B,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,71 @@
1
+ import type { ThymianActionName, ThymianActions, ThymianEventName, ThymianEvents } from '@thymian/core';
2
+ import { ThymianEmitter } from '@thymian/core';
3
+ /**
4
+ * Creates a mock ThymianEmitter with all methods stubbed using vi.fn().
5
+ * Useful for testing plugins and components that depend on an emitter.
6
+ *
7
+ * @returns A mock ThymianEmitter instance
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const emitter = createMockEmitter();
12
+ *
13
+ * // Use in tests
14
+ * await myPlugin(emitter, logger, options);
15
+ *
16
+ * // Assert on calls
17
+ * expect(emitter.emit).toHaveBeenCalledWith('core.register', expect.any(Object));
18
+ * ```
19
+ */
20
+ export declare function createMockEmitter(): ThymianEmitter;
21
+ /**
22
+ * Creates a ThymianEmitter with pre-configured event handlers.
23
+ * Useful for testing components that emit events.
24
+ *
25
+ * @param handlers - Map of event names to handler functions
26
+ * @returns A ThymianEmitter with handlers registered
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * const emitter = createEmitterWithHandlers({
31
+ * 'core.register': vi.fn(),
32
+ * 'core.error': vi.fn(),
33
+ * });
34
+ * ```
35
+ */
36
+ export declare function createEmitterWithHandlers<K extends ThymianEventName>(handlers: Partial<Record<K, (event: ThymianEvents[K]) => void | Promise<void>>>): ThymianEmitter;
37
+ /**
38
+ * Creates a ThymianEmitter with pre-configured action handlers.
39
+ * Useful for testing components that request actions.
40
+ *
41
+ * @param handlers - Map of action names to handler functions
42
+ * @returns A ThymianEmitter with action handlers registered
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * const emitter = createEmitterWithActionHandlers({
47
+ * 'core.load-format': async (event) => ({ format: createThymianFormat() }),
48
+ * });
49
+ * ```
50
+ */
51
+ export declare function createEmitterWithActionHandlers<K extends ThymianActionName>(handlers: Partial<Record<K, (event: ThymianActions[K]['event']) => Promise<ThymianActions[K]['response']>>>): ThymianEmitter;
52
+ /**
53
+ * Helper to capture all events emitted by an emitter.
54
+ * Returns an array that will be populated with emitted events.
55
+ *
56
+ * @param emitter - The emitter to capture events from
57
+ * @returns An array that captures [eventName, event] tuples
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * const emitter = createMockEmitter();
62
+ * const events = captureEmittedEvents(emitter);
63
+ *
64
+ * await emitter.emit('core.register', { plugin: myPlugin });
65
+ *
66
+ * expect(events).toHaveLength(1);
67
+ * expect(events[0][0]).toBe('core.register');
68
+ * ```
69
+ */
70
+ export declare function captureEmittedEvents(emitter: ThymianEmitter): Array<[ThymianEventName | ThymianActionName, any]>;
71
+ //# sourceMappingURL=emitter.mock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter.mock.d.ts","sourceRoot":"","sources":["../../src/mocks/emitter.mock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,aAAa,EACd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAK/C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,CAclD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,SAAS,gBAAgB,EAClE,QAAQ,EAAE,OAAO,CACf,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAC7D,GACA,cAAc,CAahB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,+BAA+B,CAAC,CAAC,SAAS,iBAAiB,EACzE,QAAQ,EAAE,OAAO,CACf,MAAM,CACJ,CAAC,EACD,CACE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAC9B,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAC5C,CACF,GACA,cAAc,CAkBhB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,cAAc,GACtB,KAAK,CAAC,CAAC,gBAAgB,GAAG,iBAAiB,EAAE,GAAG,CAAC,CAAC,CAUpD"}
@@ -0,0 +1,101 @@
1
+ import { ThymianEmitter } from '@thymian/core';
2
+ import { vi } from 'vitest';
3
+ import { createMockLogger } from './logger.mock.js';
4
+ /**
5
+ * Creates a mock ThymianEmitter with all methods stubbed using vi.fn().
6
+ * Useful for testing plugins and components that depend on an emitter.
7
+ *
8
+ * @returns A mock ThymianEmitter instance
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const emitter = createMockEmitter();
13
+ *
14
+ * // Use in tests
15
+ * await myPlugin(emitter, logger, options);
16
+ *
17
+ * // Assert on calls
18
+ * expect(emitter.emit).toHaveBeenCalledWith('core.register', expect.any(Object));
19
+ * ```
20
+ */
21
+ export function createMockEmitter() {
22
+ const emitter = new ThymianEmitter(createMockLogger(), ThymianEmitter.newEmitterState());
23
+ // Spy on all methods
24
+ vi.spyOn(emitter, 'emit');
25
+ vi.spyOn(emitter, 'emitAction');
26
+ vi.spyOn(emitter, 'on');
27
+ vi.spyOn(emitter, 'onAction');
28
+ vi.spyOn(emitter, 'onError');
29
+ return emitter;
30
+ }
31
+ /**
32
+ * Creates a ThymianEmitter with pre-configured event handlers.
33
+ * Useful for testing components that emit events.
34
+ *
35
+ * @param handlers - Map of event names to handler functions
36
+ * @returns A ThymianEmitter with handlers registered
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * const emitter = createEmitterWithHandlers({
41
+ * 'core.register': vi.fn(),
42
+ * 'core.error': vi.fn(),
43
+ * });
44
+ * ```
45
+ */
46
+ export function createEmitterWithHandlers(handlers) {
47
+ const emitter = new ThymianEmitter(createMockLogger(), ThymianEmitter.newEmitterState());
48
+ for (const [eventName, handler] of Object.entries(handlers)) {
49
+ emitter.on(eventName, handler);
50
+ }
51
+ return emitter;
52
+ }
53
+ /**
54
+ * Creates a ThymianEmitter with pre-configured action handlers.
55
+ * Useful for testing components that request actions.
56
+ *
57
+ * @param handlers - Map of action names to handler functions
58
+ * @returns A ThymianEmitter with action handlers registered
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * const emitter = createEmitterWithActionHandlers({
63
+ * 'core.load-format': async (event) => ({ format: createThymianFormat() }),
64
+ * });
65
+ * ```
66
+ */
67
+ export function createEmitterWithActionHandlers(handlers) {
68
+ const emitter = new ThymianEmitter(createMockLogger(), ThymianEmitter.newEmitterState());
69
+ for (const [actionName, handler] of Object.entries(handlers)) {
70
+ emitter.on(actionName, handler);
71
+ }
72
+ return emitter;
73
+ }
74
+ /**
75
+ * Helper to capture all events emitted by an emitter.
76
+ * Returns an array that will be populated with emitted events.
77
+ *
78
+ * @param emitter - The emitter to capture events from
79
+ * @returns An array that captures [eventName, event] tuples
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * const emitter = createMockEmitter();
84
+ * const events = captureEmittedEvents(emitter);
85
+ *
86
+ * await emitter.emit('core.register', { plugin: myPlugin });
87
+ *
88
+ * expect(events).toHaveLength(1);
89
+ * expect(events[0][0]).toBe('core.register');
90
+ * ```
91
+ */
92
+ export function captureEmittedEvents(emitter) {
93
+ const capturedEvents = [];
94
+ const originalEmit = emitter.emit.bind(emitter);
95
+ emitter.emit = vi.fn(async (eventName, event) => {
96
+ capturedEvents.push([eventName, event]);
97
+ return originalEmit(eventName, event);
98
+ });
99
+ return capturedEvents;
100
+ }
101
+ //# sourceMappingURL=emitter.mock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter.mock.js","sourceRoot":"","sources":["../../src/mocks/emitter.mock.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,OAAO,GAAG,IAAI,cAAc,CAChC,gBAAgB,EAAE,EAClB,cAAc,CAAC,eAAe,EAAE,CACjC,CAAC;IAEF,qBAAqB;IACrB,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1B,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAChC,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACxB,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAC9B,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAE7B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,yBAAyB,CACvC,QAEC;IAED,MAAM,OAAO,GAAG,IAAI,cAAc,CAChC,gBAAgB,EAAE,EAClB,cAAc,CAAC,eAAe,EAAE,CACjC,CAAC;IAEF,KAAK,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAEzD,EAAE,CAAC;QACF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,OAAc,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,+BAA+B,CAC7C,QAOC;IAED,MAAM,OAAO,GAAG,IAAI,cAAc,CAChC,gBAAgB,EAAE,EAClB,cAAc,CAAC,eAAe,EAAE,CACjC,CAAC;IAEF,KAAK,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAO1D,EAAE,CAAC;QACF,OAAO,CAAC,EAAE,CAAC,UAA8B,EAAE,OAAc,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAuB;IAEvB,MAAM,cAAc,GAAuD,EAAE,CAAC;IAE9E,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAChD,OAAO,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,SAAc,EAAE,KAAU,EAAE,EAAE;QACxD,cAAc,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;QACxC,OAAO,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACxC,CAAC,CAAQ,CAAC;IAEV,OAAO,cAAc,CAAC;AACxB,CAAC"}
@@ -0,0 +1,36 @@
1
+ import type { Logger } from '@thymian/core';
2
+ /**
3
+ * Creates a mock Logger with all methods stubbed using vi.fn().
4
+ * Useful for testing plugins and components that depend on a Logger.
5
+ *
6
+ * @param overrides - Partial logger to override defaults
7
+ * @returns A mock Logger instance
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const logger = createMockLogger({ namespace: 'test-plugin' });
12
+ *
13
+ * // Use in tests
14
+ * myPlugin(emitter, logger, options);
15
+ *
16
+ * // Assert on calls
17
+ * expect(logger.info).toHaveBeenCalledWith('Starting plugin');
18
+ * ```
19
+ */
20
+ export declare function createMockLogger(overrides?: Partial<Logger>): Logger;
21
+ /**
22
+ * Creates a verbose mock Logger (with verbose: true).
23
+ *
24
+ * @param overrides - Partial logger to override defaults
25
+ * @returns A mock Logger instance with verbose enabled
26
+ */
27
+ export declare function createVerboseMockLogger(overrides?: Partial<Logger>): Logger;
28
+ /**
29
+ * Creates a silent mock Logger that doesn't call any functions.
30
+ * Useful when you don't want to spy on logger calls.
31
+ *
32
+ * @param overrides - Partial logger to override defaults
33
+ * @returns A mock Logger instance with no-op functions
34
+ */
35
+ export declare function createSilentMockLogger(overrides?: Partial<Logger>): Logger;
36
+ //# sourceMappingURL=logger.mock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.mock.d.ts","sourceRoot":"","sources":["../../src/mocks/logger.mock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAG5C;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,GAAE,OAAO,CAAC,MAAM,CAAM,GAAG,MAAM,CAmBxE;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,GAAE,OAAO,CAAC,MAAM,CAAM,GAC9B,MAAM,CAKR;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,GAAE,OAAO,CAAC,MAAM,CAAM,GAC9B,MAAM,CAiBR"}
@@ -0,0 +1,74 @@
1
+ import { vi } from 'vitest';
2
+ /**
3
+ * Creates a mock Logger with all methods stubbed using vi.fn().
4
+ * Useful for testing plugins and components that depend on a Logger.
5
+ *
6
+ * @param overrides - Partial logger to override defaults
7
+ * @returns A mock Logger instance
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const logger = createMockLogger({ namespace: 'test-plugin' });
12
+ *
13
+ * // Use in tests
14
+ * myPlugin(emitter, logger, options);
15
+ *
16
+ * // Assert on calls
17
+ * expect(logger.info).toHaveBeenCalledWith('Starting plugin');
18
+ * ```
19
+ */
20
+ export function createMockLogger(overrides = {}) {
21
+ const logger = {
22
+ namespace: 'mock-logger',
23
+ verbose: false,
24
+ debug: vi.fn(),
25
+ info: vi.fn(),
26
+ error: vi.fn(),
27
+ trace: vi.fn(),
28
+ warn: vi.fn(),
29
+ out: vi.fn(),
30
+ child: vi.fn((name, verbose) => createMockLogger({
31
+ namespace: `${logger.namespace}:${name}`,
32
+ verbose: verbose ?? logger.verbose,
33
+ })),
34
+ ...overrides,
35
+ };
36
+ return logger;
37
+ }
38
+ /**
39
+ * Creates a verbose mock Logger (with verbose: true).
40
+ *
41
+ * @param overrides - Partial logger to override defaults
42
+ * @returns A mock Logger instance with verbose enabled
43
+ */
44
+ export function createVerboseMockLogger(overrides = {}) {
45
+ return createMockLogger({
46
+ verbose: true,
47
+ ...overrides,
48
+ });
49
+ }
50
+ /**
51
+ * Creates a silent mock Logger that doesn't call any functions.
52
+ * Useful when you don't want to spy on logger calls.
53
+ *
54
+ * @param overrides - Partial logger to override defaults
55
+ * @returns A mock Logger instance with no-op functions
56
+ */
57
+ export function createSilentMockLogger(overrides = {}) {
58
+ return {
59
+ namespace: 'silent-logger',
60
+ verbose: false,
61
+ debug: () => undefined,
62
+ info: () => undefined,
63
+ error: () => undefined,
64
+ trace: () => undefined,
65
+ warn: () => undefined,
66
+ out: () => undefined,
67
+ child: (name, verbose) => createSilentMockLogger({
68
+ namespace: `silent-logger:${name}`,
69
+ verbose: verbose ?? false,
70
+ }),
71
+ ...overrides,
72
+ };
73
+ }
74
+ //# sourceMappingURL=logger.mock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.mock.js","sourceRoot":"","sources":["../../src/mocks/logger.mock.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE5B;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,gBAAgB,CAAC,YAA6B,EAAE;IAC9D,MAAM,MAAM,GAAW;QACrB,SAAS,EAAE,aAAa;QACxB,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;QACd,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;QACb,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;QACd,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;QACd,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;QACb,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE;QACZ,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,OAAiB,EAAE,EAAE,CAC/C,gBAAgB,CAAC;YACf,SAAS,EAAE,GAAG,MAAM,CAAC,SAAS,IAAI,IAAI,EAAE;YACxC,OAAO,EAAE,OAAO,IAAI,MAAM,CAAC,OAAO;SACnC,CAAC,CACH;QACD,GAAG,SAAS;KACb,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CACrC,YAA6B,EAAE;IAE/B,OAAO,gBAAgB,CAAC;QACtB,OAAO,EAAE,IAAI;QACb,GAAG,SAAS;KACb,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CACpC,YAA6B,EAAE;IAE/B,OAAO;QACL,SAAS,EAAE,eAAe;QAC1B,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,GAAG,EAAE,CAAC,SAAS;QACtB,IAAI,EAAE,GAAG,EAAE,CAAC,SAAS;QACrB,KAAK,EAAE,GAAG,EAAE,CAAC,SAAS;QACtB,KAAK,EAAE,GAAG,EAAE,CAAC,SAAS;QACtB,IAAI,EAAE,GAAG,EAAE,CAAC,SAAS;QACrB,GAAG,EAAE,GAAG,EAAE,CAAC,SAAS;QACpB,KAAK,EAAE,CAAC,IAAY,EAAE,OAAiB,EAAE,EAAE,CACzC,sBAAsB,CAAC;YACrB,SAAS,EAAE,iBAAiB,IAAI,EAAE;YAClC,OAAO,EAAE,OAAO,IAAI,KAAK;SAC1B,CAAC;QACJ,GAAG,SAAS;KACb,CAAC;AACJ,CAAC"}