nitrostack 1.0.74 → 1.0.75

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 (52) hide show
  1. package/dist/auth/__tests__/pkce.test.js +53 -4
  2. package/dist/auth/__tests__/pkce.test.js.map +1 -1
  3. package/dist/auth/__tests__/simple-jwt.test.js +153 -2
  4. package/dist/auth/__tests__/simple-jwt.test.js.map +1 -1
  5. package/dist/cli/commands/install.d.ts +10 -0
  6. package/dist/cli/commands/install.d.ts.map +1 -0
  7. package/dist/cli/commands/install.js +79 -0
  8. package/dist/cli/commands/install.js.map +1 -0
  9. package/dist/cli/index.d.ts.map +1 -1
  10. package/dist/cli/index.js +8 -0
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/core/__tests__/errors.test.d.ts +2 -0
  13. package/dist/core/__tests__/errors.test.d.ts.map +1 -0
  14. package/dist/core/__tests__/errors.test.js +109 -0
  15. package/dist/core/__tests__/errors.test.js.map +1 -0
  16. package/dist/core/__tests__/logger.test.d.ts +2 -0
  17. package/dist/core/__tests__/logger.test.d.ts.map +1 -0
  18. package/dist/core/__tests__/logger.test.js +83 -0
  19. package/dist/core/__tests__/logger.test.js.map +1 -0
  20. package/dist/core/__tests__/prompt.test.d.ts +2 -0
  21. package/dist/core/__tests__/prompt.test.d.ts.map +1 -0
  22. package/dist/core/__tests__/prompt.test.js +126 -0
  23. package/dist/core/__tests__/prompt.test.js.map +1 -0
  24. package/dist/core/__tests__/resource.test.d.ts +2 -0
  25. package/dist/core/__tests__/resource.test.d.ts.map +1 -0
  26. package/dist/core/__tests__/resource.test.js +173 -0
  27. package/dist/core/__tests__/resource.test.js.map +1 -0
  28. package/dist/core/pipes/__tests__/pipes.test.js +113 -1
  29. package/dist/core/pipes/__tests__/pipes.test.js.map +1 -1
  30. package/dist/widgets/hooks/__tests__/hooks.test.d.ts +2 -0
  31. package/dist/widgets/hooks/__tests__/hooks.test.d.ts.map +1 -0
  32. package/dist/widgets/hooks/__tests__/hooks.test.js +129 -0
  33. package/dist/widgets/hooks/__tests__/hooks.test.js.map +1 -0
  34. package/dist/widgets/hooks/__tests__/use-widget-state.test.d.ts +2 -0
  35. package/dist/widgets/hooks/__tests__/use-widget-state.test.d.ts.map +1 -0
  36. package/dist/widgets/hooks/__tests__/use-widget-state.test.js +66 -0
  37. package/dist/widgets/hooks/__tests__/use-widget-state.test.js.map +1 -0
  38. package/dist/widgets/runtime/__tests__/widget-polyfill.test.d.ts +2 -0
  39. package/dist/widgets/runtime/__tests__/widget-polyfill.test.d.ts.map +1 -0
  40. package/dist/widgets/runtime/__tests__/widget-polyfill.test.js +66 -0
  41. package/dist/widgets/runtime/__tests__/widget-polyfill.test.js.map +1 -0
  42. package/package.json +6 -2
  43. package/src/studio/app/chat/page.tsx +21 -0
  44. package/src/studio/lib/llm-service.ts +77 -10
  45. package/templates/typescript-oauth/OAUTH_SETUP.md +592 -0
  46. package/templates/typescript-oauth/README.md +186 -235
  47. package/templates/typescript-oauth/package.json +5 -3
  48. package/templates/typescript-pizzaz/README.md +78 -57
  49. package/templates/typescript-pizzaz/package.json +32 -30
  50. package/templates/typescript-starter/README.md +22 -14
  51. package/templates/typescript-starter/package.json +4 -1
  52. package/templates/typescript-starter/package-lock.json +0 -4112
@@ -0,0 +1,83 @@
1
+ import { jest, describe, it, expect, beforeEach } from '@jest/globals';
2
+ // Mock winston
3
+ const mockTransports = {
4
+ Console: jest.fn().mockImplementation(() => ({})),
5
+ File: jest.fn().mockImplementation(() => ({})),
6
+ };
7
+ const mockCreateLogger = jest.fn().mockReturnValue({
8
+ debug: jest.fn(),
9
+ info: jest.fn(),
10
+ warn: jest.fn(),
11
+ error: jest.fn(),
12
+ });
13
+ const mockFormat = {
14
+ combine: jest.fn().mockReturnValue({}),
15
+ timestamp: jest.fn().mockReturnValue({}),
16
+ json: jest.fn().mockReturnValue({}),
17
+ colorize: jest.fn().mockReturnValue({}),
18
+ printf: jest.fn().mockReturnValue({}),
19
+ };
20
+ jest.unstable_mockModule('winston', () => ({
21
+ default: {
22
+ createLogger: mockCreateLogger,
23
+ transports: mockTransports,
24
+ format: mockFormat,
25
+ },
26
+ }));
27
+ // Mock EventEmitterTransport
28
+ jest.unstable_mockModule('../events/log-emitter.js', () => ({
29
+ EventEmitterTransport: jest.fn().mockImplementation(() => ({})),
30
+ }));
31
+ const { createLogger, defaultLogger } = await import('../logger.js');
32
+ describe('Logger', () => {
33
+ beforeEach(() => {
34
+ jest.clearAllMocks();
35
+ });
36
+ describe('createLogger', () => {
37
+ it('should create a logger with default options', () => {
38
+ const logger = createLogger({});
39
+ expect(logger).toBeDefined();
40
+ expect(logger.debug).toBeDefined();
41
+ expect(logger.info).toBeDefined();
42
+ expect(logger.warn).toBeDefined();
43
+ expect(logger.error).toBeDefined();
44
+ expect(mockCreateLogger).toHaveBeenCalled();
45
+ });
46
+ it('should create logger with custom level', () => {
47
+ const logger = createLogger({ level: 'debug' });
48
+ expect(logger).toBeDefined();
49
+ expect(mockCreateLogger).toHaveBeenCalledWith(expect.objectContaining({ level: 'debug' }));
50
+ });
51
+ it('should add file transport when file is specified', () => {
52
+ createLogger({ file: '/tmp/test.log' });
53
+ expect(mockTransports.File).toHaveBeenCalled();
54
+ });
55
+ it('should add console transport when enableConsole is true', () => {
56
+ createLogger({ enableConsole: true });
57
+ expect(mockTransports.Console).toHaveBeenCalled();
58
+ });
59
+ it('should not add console transport by default', () => {
60
+ mockTransports.Console.mockClear();
61
+ createLogger({});
62
+ expect(mockTransports.Console).not.toHaveBeenCalled();
63
+ });
64
+ it('should log messages through winston', () => {
65
+ const logger = createLogger({ level: 'info' });
66
+ logger.debug('debug message', { key: 'value' });
67
+ logger.info('info message');
68
+ logger.warn('warn message');
69
+ logger.error('error message');
70
+ const mockLogger = mockCreateLogger.mock.results[0]?.value;
71
+ expect(mockLogger.debug).toHaveBeenCalledWith('debug message', { key: 'value' });
72
+ expect(mockLogger.info).toHaveBeenCalled();
73
+ expect(mockLogger.warn).toHaveBeenCalled();
74
+ expect(mockLogger.error).toHaveBeenCalled();
75
+ });
76
+ });
77
+ describe('defaultLogger', () => {
78
+ it('should be defined', () => {
79
+ expect(defaultLogger).toBeDefined();
80
+ });
81
+ });
82
+ });
83
+ //# sourceMappingURL=logger.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.test.js","sourceRoot":"","sources":["../../../src/core/__tests__/logger.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=prompt.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.test.d.ts","sourceRoot":"","sources":["../../../src/core/__tests__/prompt.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,126 @@
1
+ import { jest, describe, it, expect, beforeEach } from '@jest/globals';
2
+ import { Prompt, createPrompt } from '../prompt.js';
3
+ import { ValidationError } from '../errors.js';
4
+ describe('Prompt', () => {
5
+ const mockContext = {
6
+ requestId: 'test-request',
7
+ logger: {
8
+ debug: jest.fn(),
9
+ info: jest.fn(),
10
+ warn: jest.fn(),
11
+ error: jest.fn(),
12
+ },
13
+ metadata: {},
14
+ };
15
+ beforeEach(() => {
16
+ jest.clearAllMocks();
17
+ });
18
+ describe('Prompt class', () => {
19
+ it('should create a prompt with name and description', () => {
20
+ const prompt = new Prompt({
21
+ name: 'greeting',
22
+ description: 'A greeting prompt',
23
+ handler: async () => [{ role: 'assistant', content: 'Hello' }]
24
+ });
25
+ expect(prompt.name).toBe('greeting');
26
+ expect(prompt.description).toBe('A greeting prompt');
27
+ });
28
+ it('should return empty array for arguments if not defined', () => {
29
+ const prompt = new Prompt({
30
+ name: 'simple',
31
+ description: 'Simple prompt',
32
+ handler: async () => []
33
+ });
34
+ expect(prompt.arguments).toEqual([]);
35
+ });
36
+ it('should return arguments if defined', () => {
37
+ const prompt = new Prompt({
38
+ name: 'parameterized',
39
+ description: 'Prompt with args',
40
+ arguments: [
41
+ { name: 'name', description: 'User name', required: true },
42
+ { name: 'age', description: 'User age', required: false }
43
+ ],
44
+ handler: async () => []
45
+ });
46
+ expect(prompt.arguments).toHaveLength(2);
47
+ expect(prompt.arguments[0].name).toBe('name');
48
+ });
49
+ it('should execute handler and return messages', async () => {
50
+ const messages = [
51
+ { role: 'assistant', content: 'Hello, World!' }
52
+ ];
53
+ const prompt = new Prompt({
54
+ name: 'test',
55
+ description: 'Test prompt',
56
+ handler: async () => messages
57
+ });
58
+ const result = await prompt.execute({}, mockContext);
59
+ expect(result).toEqual(messages);
60
+ expect(mockContext.logger.info).toHaveBeenCalledWith('Executing prompt: test', expect.any(Object));
61
+ });
62
+ it('should throw ValidationError for missing required argument', async () => {
63
+ const prompt = new Prompt({
64
+ name: 'test',
65
+ description: 'Test prompt',
66
+ arguments: [
67
+ { name: 'required_arg', description: 'Required', required: true }
68
+ ],
69
+ handler: async () => []
70
+ });
71
+ await expect(prompt.execute({}, mockContext))
72
+ .rejects.toThrow(ValidationError);
73
+ });
74
+ it('should pass with all required arguments', async () => {
75
+ const prompt = new Prompt({
76
+ name: 'test',
77
+ description: 'Test prompt',
78
+ arguments: [
79
+ { name: 'required_arg', description: 'Required', required: true }
80
+ ],
81
+ handler: async (args) => [
82
+ { role: 'assistant', content: `Got: ${args.required_arg}` }
83
+ ]
84
+ });
85
+ const result = await prompt.execute({ required_arg: 'value' }, mockContext);
86
+ expect(result).toHaveLength(1);
87
+ });
88
+ it('should log error when handler throws', async () => {
89
+ const prompt = new Prompt({
90
+ name: 'failing',
91
+ description: 'Failing prompt',
92
+ handler: async () => { throw new Error('Handler failed'); }
93
+ });
94
+ await expect(prompt.execute({}, mockContext)).rejects.toThrow('Handler failed');
95
+ expect(mockContext.logger.error).toHaveBeenCalledWith('Error executing prompt: failing', expect.any(Object));
96
+ });
97
+ it('should convert to MCP prompt format', () => {
98
+ const prompt = new Prompt({
99
+ name: 'example',
100
+ description: 'Example prompt',
101
+ arguments: [
102
+ { name: 'arg1', description: 'Arg 1', required: true }
103
+ ],
104
+ handler: async () => []
105
+ });
106
+ const mcpPrompt = prompt.toMcpPrompt();
107
+ expect(mcpPrompt).toEqual({
108
+ name: 'example',
109
+ description: 'Example prompt',
110
+ arguments: [{ name: 'arg1', description: 'Arg 1', required: true }]
111
+ });
112
+ });
113
+ });
114
+ describe('createPrompt helper', () => {
115
+ it('should create a Prompt instance', () => {
116
+ const prompt = createPrompt({
117
+ name: 'helper-test',
118
+ description: 'Created via helper',
119
+ handler: async () => []
120
+ });
121
+ expect(prompt).toBeInstanceOf(Prompt);
122
+ expect(prompt.name).toBe('helper-test');
123
+ });
124
+ });
125
+ });
126
+ //# sourceMappingURL=prompt.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.test.js","sourceRoot":"","sources":["../../../src/core/__tests__/prompt.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=resource.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource.test.d.ts","sourceRoot":"","sources":["../../../src/core/__tests__/resource.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,173 @@
1
+ import { jest, describe, it, expect, beforeEach } from '@jest/globals';
2
+ import { Resource, createResource } from '../resource.js';
3
+ describe('Resource', () => {
4
+ const mockContext = {
5
+ requestId: 'test-request',
6
+ logger: {
7
+ debug: jest.fn(),
8
+ info: jest.fn(),
9
+ warn: jest.fn(),
10
+ error: jest.fn(),
11
+ },
12
+ metadata: {},
13
+ };
14
+ beforeEach(() => {
15
+ jest.clearAllMocks();
16
+ });
17
+ describe('Resource class', () => {
18
+ it('should create a resource with uri, name, and description', () => {
19
+ const resource = new Resource({
20
+ uri: 'file://test.txt',
21
+ name: 'Test File',
22
+ description: 'A test file resource',
23
+ handler: async () => ({ type: 'text', data: 'content' })
24
+ });
25
+ expect(resource.uri).toBe('file://test.txt');
26
+ expect(resource.name).toBe('Test File');
27
+ expect(resource.description).toBe('A test file resource');
28
+ });
29
+ it('should return mimeType if defined', () => {
30
+ const resource = new Resource({
31
+ uri: 'file://test.json',
32
+ name: 'JSON File',
33
+ description: 'A JSON resource',
34
+ mimeType: 'application/json',
35
+ handler: async () => ({ type: 'json', data: {} })
36
+ });
37
+ expect(resource.mimeType).toBe('application/json');
38
+ });
39
+ it('should return undefined mimeType if not defined', () => {
40
+ const resource = new Resource({
41
+ uri: 'file://test.txt',
42
+ name: 'Text File',
43
+ description: 'A text resource',
44
+ handler: async () => ({ type: 'text', data: 'content' })
45
+ });
46
+ expect(resource.mimeType).toBeUndefined();
47
+ });
48
+ it('should fetch resource content', async () => {
49
+ const content = { type: 'text', data: 'Hello, World!' };
50
+ let called = false;
51
+ const resource = new Resource({
52
+ uri: 'file://test.txt',
53
+ name: 'Test',
54
+ description: 'Test resource',
55
+ handler: async (uri) => {
56
+ called = true;
57
+ expect(uri).toBe('file://test.txt');
58
+ return content;
59
+ }
60
+ });
61
+ const result = await resource.fetch(mockContext);
62
+ expect(result).toEqual(content);
63
+ expect(called).toBe(true);
64
+ expect(mockContext.logger.info).toHaveBeenCalledWith('Fetching resource: file://test.txt');
65
+ });
66
+ it('should cache resource if cacheable', async () => {
67
+ const content = { type: 'text', data: 'Cached content' };
68
+ let callCount = 0;
69
+ const resource = new Resource({
70
+ uri: 'file://cached.txt',
71
+ name: 'Cached',
72
+ description: 'Cacheable resource',
73
+ metadata: { cacheable: true, cacheMaxAge: 60000 },
74
+ handler: async () => {
75
+ callCount++;
76
+ return content;
77
+ }
78
+ });
79
+ // First fetch
80
+ await resource.fetch(mockContext);
81
+ expect(callCount).toBe(1);
82
+ // Second fetch should use cache
83
+ await resource.fetch(mockContext);
84
+ expect(callCount).toBe(1); // Still 1
85
+ expect(mockContext.logger.debug).toHaveBeenCalledWith('Serving cached resource: file://cached.txt');
86
+ });
87
+ it('should clear cache', async () => {
88
+ const content = { type: 'text', data: 'content' };
89
+ let callCount = 0;
90
+ const resource = new Resource({
91
+ uri: 'file://cached.txt',
92
+ name: 'Cached',
93
+ description: 'Cacheable resource',
94
+ metadata: { cacheable: true },
95
+ handler: async () => {
96
+ callCount++;
97
+ return content;
98
+ }
99
+ });
100
+ // Fetch and cache
101
+ await resource.fetch(mockContext);
102
+ expect(callCount).toBe(1);
103
+ // Clear cache
104
+ resource.clearCache();
105
+ // Should fetch again
106
+ await resource.fetch(mockContext);
107
+ expect(callCount).toBe(2);
108
+ });
109
+ it('should log error and throw when handler fails', async () => {
110
+ const resource = new Resource({
111
+ uri: 'file://failing.txt',
112
+ name: 'Failing',
113
+ description: 'Failing resource',
114
+ handler: async () => {
115
+ throw new Error('Fetch failed');
116
+ }
117
+ });
118
+ await expect(resource.fetch(mockContext)).rejects.toThrow('Fetch failed');
119
+ expect(mockContext.logger.error).toHaveBeenCalledWith('Error fetching resource: file://failing.txt', expect.any(Object));
120
+ });
121
+ it('should convert to MCP resource format', () => {
122
+ const resource = new Resource({
123
+ uri: 'file://example.txt',
124
+ name: 'Example',
125
+ description: 'Example resource',
126
+ mimeType: 'text/plain',
127
+ handler: async () => ({ type: 'text', data: '' })
128
+ });
129
+ const mcpResource = resource.toMcpResource();
130
+ expect(mcpResource).toEqual({
131
+ uri: 'file://example.txt',
132
+ name: 'Example',
133
+ description: 'Example resource',
134
+ mimeType: 'text/plain'
135
+ });
136
+ });
137
+ it('should handle binary resource content', async () => {
138
+ const content = { type: 'binary', data: Buffer.from('binary data') };
139
+ const resource = new Resource({
140
+ uri: 'file://binary.bin',
141
+ name: 'Binary',
142
+ description: 'Binary resource',
143
+ handler: async () => content
144
+ });
145
+ const result = await resource.fetch(mockContext);
146
+ expect(result.type).toBe('binary');
147
+ });
148
+ it('should handle json resource content', async () => {
149
+ const content = { type: 'json', data: { key: 'value' } };
150
+ const resource = new Resource({
151
+ uri: 'file://data.json',
152
+ name: 'JSON',
153
+ description: 'JSON resource',
154
+ handler: async () => content
155
+ });
156
+ const result = await resource.fetch(mockContext);
157
+ expect(result.type).toBe('json');
158
+ });
159
+ });
160
+ describe('createResource helper', () => {
161
+ it('should create a Resource instance', () => {
162
+ const resource = createResource({
163
+ uri: 'file://helper-test.txt',
164
+ name: 'Helper Test',
165
+ description: 'Created via helper',
166
+ handler: async () => ({ type: 'text', data: '' })
167
+ });
168
+ expect(resource).toBeInstanceOf(Resource);
169
+ expect(resource.uri).toBe('file://helper-test.txt');
170
+ });
171
+ });
172
+ });
173
+ //# sourceMappingURL=resource.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource.test.js","sourceRoot":"","sources":["../../../src/core/__tests__/resource.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAG1D,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;IACtB,MAAM,WAAW,GAAqB;QAClC,SAAS,EAAE,cAAc;QACzB,MAAM,EAAE;YACJ,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;YAChB,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;YACf,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;YACf,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACnB;QACD,QAAQ,EAAE,EAAE;KACf,CAAC;IAEF,UAAU,CAAC,GAAG,EAAE;QACZ,IAAI,CAAC,aAAa,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC5B,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;YAChE,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC;gBAC1B,GAAG,EAAE,iBAAiB;gBACtB,IAAI,EAAE,WAAW;gBACjB,WAAW,EAAE,sBAAsB;gBACnC,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;aAC3D,CAAC,CAAC;YAEH,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAC7C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACxC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YACzC,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC;gBAC1B,GAAG,EAAE,kBAAkB;gBACvB,IAAI,EAAE,WAAW;gBACjB,WAAW,EAAE,iBAAiB;gBAC9B,QAAQ,EAAE,kBAAkB;gBAC5B,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;aACpD,CAAC,CAAC;YAEH,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACvD,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC;gBAC1B,GAAG,EAAE,iBAAiB;gBACtB,IAAI,EAAE,WAAW;gBACjB,WAAW,EAAE,iBAAiB;gBAC9B,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;aAC3D,CAAC,CAAC;YAEH,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,aAAa,EAAE,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;YAC3C,MAAM,OAAO,GAAoB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;YACzE,IAAI,MAAM,GAAG,KAAK,CAAC;YAEnB,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC;gBAC1B,GAAG,EAAE,iBAAiB;gBACtB,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,eAAe;gBAC5B,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;oBACnB,MAAM,GAAG,IAAI,CAAC;oBACd,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;oBACpC,OAAO,OAAO,CAAC;gBACnB,CAAC;aACJ,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAEjD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAChC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAChD,oCAAoC,CACvC,CAAC;QACN,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;YAChD,MAAM,OAAO,GAAoB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC;YAC1E,IAAI,SAAS,GAAG,CAAC,CAAC;YAElB,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC;gBAC1B,GAAG,EAAE,mBAAmB;gBACxB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,oBAAoB;gBACjC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE;gBACjD,OAAO,EAAE,KAAK,IAAI,EAAE;oBAChB,SAAS,EAAE,CAAC;oBACZ,OAAO,OAAO,CAAC;gBACnB,CAAC;aACJ,CAAC,CAAC;YAEH,cAAc;YACd,MAAM,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAClC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAE1B,gCAAgC;YAChC,MAAM,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAClC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU;YACrC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,oBAAoB,CACjD,4CAA4C,CAC/C,CAAC;QACN,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oBAAoB,EAAE,KAAK,IAAI,EAAE;YAChC,MAAM,OAAO,GAAoB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;YACnE,IAAI,SAAS,GAAG,CAAC,CAAC;YAElB,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC;gBAC1B,GAAG,EAAE,mBAAmB;gBACxB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,oBAAoB;gBACjC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE;gBAC7B,OAAO,EAAE,KAAK,IAAI,EAAE;oBAChB,SAAS,EAAE,CAAC;oBACZ,OAAO,OAAO,CAAC;gBACnB,CAAC;aACJ,CAAC,CAAC;YAEH,kBAAkB;YAClB,MAAM,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAClC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAE1B,cAAc;YACd,QAAQ,CAAC,UAAU,EAAE,CAAC;YAEtB,qBAAqB;YACrB,MAAM,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAClC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;YAC3D,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC;gBAC1B,GAAG,EAAE,oBAAoB;gBACzB,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,kBAAkB;gBAC/B,OAAO,EAAE,KAAK,IAAI,EAAE;oBAChB,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;gBACpC,CAAC;aACJ,CAAC,CAAC;YAEH,MAAM,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YAC1E,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,oBAAoB,CACjD,6CAA6C,EAC7C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CACrB,CAAC;QACN,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC7C,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC;gBAC1B,GAAG,EAAE,oBAAoB;gBACzB,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,kBAAkB;gBAC/B,QAAQ,EAAE,YAAY;gBACtB,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;aACpD,CAAC,CAAC;YAEH,MAAM,WAAW,GAAG,QAAQ,CAAC,aAAa,EAAE,CAAC;YAE7C,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC;gBACxB,GAAG,EAAE,oBAAoB;gBACzB,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,kBAAkB;gBAC/B,QAAQ,EAAE,YAAY;aACzB,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;YACnD,MAAM,OAAO,GAAoB,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;YAEtF,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC;gBAC1B,GAAG,EAAE,mBAAmB;gBACxB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,iBAAiB;gBAC9B,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO;aAC/B,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YACjD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;YACjD,MAAM,OAAO,GAAoB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC;YAE1E,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC;gBAC1B,GAAG,EAAE,kBAAkB;gBACvB,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,eAAe;gBAC5B,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO;aAC/B,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YACjD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACnC,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YACzC,MAAM,QAAQ,GAAG,cAAc,CAAC;gBAC5B,GAAG,EAAE,wBAAwB;gBAC7B,IAAI,EAAE,aAAa;gBACnB,WAAW,EAAE,oBAAoB;gBACjC,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;aACpD,CAAC,CAAC;YAEH,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;YAC1C,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -7,10 +7,29 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
10
13
  import { describe, it, expect } from '@jest/globals';
11
14
  import 'reflect-metadata';
12
- import { UsePipes, getPipeMetadata } from '../pipe.decorator';
15
+ import { UsePipes, getPipeMetadata, Pipe, Body, Validated, getParamPipesMetadata, isPipe } from '../pipe.decorator.js';
13
16
  describe('Pipes Module', () => {
17
+ describe('@Pipe Decorator', () => {
18
+ it('should mark a class as a pipe', () => {
19
+ let TestPipe = class TestPipe {
20
+ transform(value) { return value; }
21
+ };
22
+ TestPipe = __decorate([
23
+ Pipe()
24
+ ], TestPipe);
25
+ expect(isPipe(TestPipe)).toBe(true);
26
+ });
27
+ it('should return false for non-pipe classes', () => {
28
+ class RegularClass {
29
+ }
30
+ expect(isPipe(RegularClass)).toBe(false);
31
+ });
32
+ });
14
33
  describe('@UsePipes Decorator', () => {
15
34
  it('should register pipes metadata', () => {
16
35
  class MockPipe {
@@ -47,6 +66,99 @@ describe('Pipes Module', () => {
47
66
  const metadata = getPipeMetadata(TestController.prototype, 'method');
48
67
  expect(metadata).toEqual([Pipe1, Pipe2]);
49
68
  });
69
+ it('should return empty array for methods without pipes', () => {
70
+ class TestController {
71
+ method() { }
72
+ }
73
+ const metadata = getPipeMetadata(TestController.prototype, 'method');
74
+ expect(metadata).toEqual([]);
75
+ });
76
+ it('should accumulate pipes from multiple @UsePipes', () => {
77
+ class Pipe1 {
78
+ transform(v) { return v; }
79
+ }
80
+ class Pipe2 {
81
+ transform(v) { return v; }
82
+ }
83
+ class TestController {
84
+ method() { }
85
+ }
86
+ __decorate([
87
+ UsePipes(Pipe1),
88
+ UsePipes(Pipe2),
89
+ __metadata("design:type", Function),
90
+ __metadata("design:paramtypes", []),
91
+ __metadata("design:returntype", void 0)
92
+ ], TestController.prototype, "method", null);
93
+ const metadata = getPipeMetadata(TestController.prototype, 'method');
94
+ expect(metadata).toContain(Pipe1);
95
+ expect(metadata).toContain(Pipe2);
96
+ });
97
+ });
98
+ describe('@Body Decorator', () => {
99
+ it('should register parameter pipe metadata', () => {
100
+ class ValidationPipe {
101
+ transform(v) { return v; }
102
+ }
103
+ class TestController {
104
+ method(input) { }
105
+ }
106
+ __decorate([
107
+ __param(0, Body(ValidationPipe)),
108
+ __metadata("design:type", Function),
109
+ __metadata("design:paramtypes", [Object]),
110
+ __metadata("design:returntype", void 0)
111
+ ], TestController.prototype, "method", null);
112
+ const metadata = getParamPipesMetadata(TestController.prototype, 'method');
113
+ expect(metadata[0]).toEqual({
114
+ type: 'body',
115
+ pipes: [ValidationPipe]
116
+ });
117
+ });
118
+ it('should register multiple pipes for parameter', () => {
119
+ class Pipe1 {
120
+ transform(v) { return v; }
121
+ }
122
+ class Pipe2 {
123
+ transform(v) { return v; }
124
+ }
125
+ class TestController {
126
+ method(input) { }
127
+ }
128
+ __decorate([
129
+ __param(0, Body(Pipe1, Pipe2)),
130
+ __metadata("design:type", Function),
131
+ __metadata("design:paramtypes", [Object]),
132
+ __metadata("design:returntype", void 0)
133
+ ], TestController.prototype, "method", null);
134
+ const metadata = getParamPipesMetadata(TestController.prototype, 'method');
135
+ expect(metadata[0].pipes).toEqual([Pipe1, Pipe2]);
136
+ });
137
+ it('should return empty object for methods without param pipes', () => {
138
+ class TestController {
139
+ method(input) { }
140
+ }
141
+ const metadata = getParamPipesMetadata(TestController.prototype, 'method');
142
+ expect(metadata).toEqual({});
143
+ });
144
+ });
145
+ describe('@Validated Decorator', () => {
146
+ it('should register body type with empty pipes', () => {
147
+ class TestController {
148
+ method(input) { }
149
+ }
150
+ __decorate([
151
+ __param(0, Validated()),
152
+ __metadata("design:type", Function),
153
+ __metadata("design:paramtypes", [Object]),
154
+ __metadata("design:returntype", void 0)
155
+ ], TestController.prototype, "method", null);
156
+ const metadata = getParamPipesMetadata(TestController.prototype, 'method');
157
+ expect(metadata[0]).toEqual({
158
+ type: 'body',
159
+ pipes: []
160
+ });
161
+ });
50
162
  });
51
163
  });
52
164
  //# sourceMappingURL=pipes.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pipes.test.js","sourceRoot":"","sources":["../../../../src/core/pipes/__tests__/pipes.test.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAQ,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAG9D,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC1B,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;YACtC,MAAM,QAAQ;gBACV,SAAS,CAAC,KAAU,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC;aAC1C;YAED,MAAM,cAAc;gBAEhB,MAAM,KAAK,CAAC;aACf;YADG;gBADC,QAAQ,CAAC,QAAQ,CAAC;;;;wDACP;YAGhB,MAAM,QAAQ,GAAG,eAAe,CAAC,cAAc,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YACrE,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;YACtC,MAAM,KAAK;gBAA4B,SAAS,CAAC,CAAM,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;aAAE;YACxE,MAAM,KAAK;gBAA4B,SAAS,CAAC,CAAM,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;aAAE;YAExE,MAAM,cAAc;gBAEhB,MAAM,KAAK,CAAC;aACf;YADG;gBADC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;;;;wDACX;YAGhB,MAAM,QAAQ,GAAG,eAAe,CAAC,cAAc,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YACrE,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"pipes.test.js","sourceRoot":"","sources":["../../../../src/core/pipes/__tests__/pipes.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=hooks.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.test.d.ts","sourceRoot":"","sources":["../../../../src/widgets/hooks/__tests__/hooks.test.ts"],"names":[],"mappings":""}