@useavalon/avalon 0.1.5 → 0.1.7

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 (39) hide show
  1. package/package.json +31 -58
  2. package/src/build/prop-extractors/index.ts +11 -11
  3. package/src/build/prop-extractors/lit.ts +1 -1
  4. package/src/build/prop-extractors/qwik.ts +2 -2
  5. package/src/build/prop-extractors/solid.ts +1 -1
  6. package/src/build/prop-extractors/svelte.ts +1 -1
  7. package/src/schemas/routing.ts +2 -2
  8. package/src/vite-plugin/nitro-integration.ts +1 -1
  9. package/src/vite-plugin/plugin.ts +20 -16
  10. package/src/build/README.md +0 -310
  11. package/src/client/tests/css-hmr-handler.test.ts +0 -360
  12. package/src/client/tests/framework-adapter.test.ts +0 -519
  13. package/src/client/tests/hmr-coordinator.test.ts +0 -176
  14. package/src/client/tests/hydration-option-parsing.test.ts +0 -107
  15. package/src/client/tests/lit-adapter.test.ts +0 -427
  16. package/src/client/tests/preact-adapter.test.ts +0 -353
  17. package/src/client/tests/qwik-adapter.test.ts +0 -343
  18. package/src/client/tests/react-adapter.test.ts +0 -317
  19. package/src/client/tests/solid-adapter.test.ts +0 -396
  20. package/src/client/tests/svelte-adapter.test.ts +0 -387
  21. package/src/client/tests/vue-adapter.test.ts +0 -407
  22. package/src/components/tests/component-analyzer.test.ts +0 -96
  23. package/src/components/tests/component-detection.test.ts +0 -347
  24. package/src/components/tests/persistent-islands.test.ts +0 -398
  25. package/src/core/components/tests/enhanced-framework-detector.test.ts +0 -577
  26. package/src/core/components/tests/framework-registry.test.ts +0 -465
  27. package/src/core/integrations/README.md +0 -282
  28. package/src/core/layout/tests/enhanced-layout-resolver.test.ts +0 -477
  29. package/src/core/layout/tests/layout-cache-optimization.test.ts +0 -149
  30. package/src/core/layout/tests/layout-composer.test.ts +0 -486
  31. package/src/core/layout/tests/layout-data-loader.test.ts +0 -443
  32. package/src/core/layout/tests/layout-discovery.test.ts +0 -253
  33. package/src/core/layout/tests/layout-matcher.test.ts +0 -480
  34. package/src/core/modules/tests/framework-module-resolver.test.ts +0 -263
  35. package/src/core/modules/tests/module-resolution-integration.test.ts +0 -117
  36. package/src/islands/discovery/tests/island-discovery.test.ts +0 -881
  37. package/src/middleware/__tests__/discovery.test.ts +0 -107
  38. package/src/types/tests/layout-types.test.ts +0 -197
  39. package/src/vite-plugin/tests/image-optimization.test.ts +0 -54
@@ -1,107 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { join } from 'node:path';
3
- import { mkdtemp, mkdir, writeFile, rm } from 'node:fs/promises';
4
- import { tmpdir } from 'node:os';
5
- import { discoverScopedMiddleware, getMatchingMiddleware } from '../discovery.ts';
6
-
7
- describe('discoverScopedMiddleware', () => {
8
- let tempDir: string;
9
-
10
- beforeEach(async () => {
11
- tempDir = await mkdtemp(join(tmpdir(), 'middleware-test-'));
12
- });
13
-
14
- afterEach(async () => {
15
- await rm(tempDir, { recursive: true, force: true });
16
- });
17
-
18
- it('discovers _middleware.ts files in pages subdirectories', async () => {
19
- // Create pages directory structure with middleware files
20
- await mkdir(join(tempDir, 'pages', 'admin'), { recursive: true });
21
- await mkdir(join(tempDir, 'pages', 'blog'), { recursive: true });
22
- await writeFile(join(tempDir, 'pages', 'admin', '_middleware.ts'), 'export default () => {};');
23
- await writeFile(join(tempDir, 'pages', 'blog', '_middleware.ts'), 'export default () => {};');
24
-
25
- const routes = await discoverScopedMiddleware({ baseDir: tempDir });
26
-
27
- expect(routes).toHaveLength(2);
28
- expect(routes.every(r => r.type === 'pages')).toBe(true);
29
- expect(routes.map(r => r.filePath)).toEqual(
30
- expect.arrayContaining([
31
- join(tempDir, 'pages', 'admin', '_middleware.ts'),
32
- join(tempDir, 'pages', 'blog', '_middleware.ts'),
33
- ])
34
- );
35
- });
36
-
37
- it('discovers nested _middleware.ts files with correct priority ordering', async () => {
38
- await mkdir(join(tempDir, 'pages', 'admin', 'users'), { recursive: true });
39
- await writeFile(join(tempDir, 'pages', 'admin', '_middleware.ts'), 'export default () => {};');
40
- await writeFile(join(tempDir, 'pages', 'admin', 'users', '_middleware.ts'), 'export default () => {};');
41
-
42
- const routes = await discoverScopedMiddleware({ baseDir: tempDir });
43
-
44
- expect(routes).toHaveLength(2);
45
- // Parent middleware (depth 1) should come before child (depth 2)
46
- expect(routes[0].priority).toBeLessThan(routes[1].priority);
47
- expect(routes[0].filePath).toContain(join('admin', '_middleware.ts'));
48
- expect(routes[1].filePath).toContain(join('admin', 'users', '_middleware.ts'));
49
- });
50
-
51
- it('does NOT scan api directory for middleware', async () => {
52
- await mkdir(join(tempDir, 'pages', 'admin'), { recursive: true });
53
- await mkdir(join(tempDir, 'api', 'admin'), { recursive: true });
54
- await writeFile(join(tempDir, 'pages', 'admin', '_middleware.ts'), 'export default () => {};');
55
- await writeFile(join(tempDir, 'api', 'admin', '_middleware.ts'), 'export default () => {};');
56
-
57
- const routes = await discoverScopedMiddleware({ baseDir: tempDir });
58
-
59
- expect(routes).toHaveLength(1);
60
- expect(routes[0].type).toBe('pages');
61
- expect(routes[0].filePath).toContain(join('pages', 'admin', '_middleware.ts'));
62
- });
63
-
64
- it('returns empty array when no middleware files exist', async () => {
65
- await mkdir(join(tempDir, 'pages'), { recursive: true });
66
-
67
- const routes = await discoverScopedMiddleware({ baseDir: tempDir });
68
-
69
- expect(routes).toHaveLength(0);
70
- });
71
-
72
- it('returns empty array when pages directory does not exist', async () => {
73
- const routes = await discoverScopedMiddleware({ baseDir: tempDir });
74
-
75
- expect(routes).toHaveLength(0);
76
- });
77
- });
78
-
79
- describe('getMatchingMiddleware', () => {
80
- it('matches page middleware for page routes', () => {
81
- const routes = [
82
- {
83
- pattern: new URLPattern({ pathname: '/admin{/*}?' }),
84
- filePath: '/src/pages/admin/_middleware.ts',
85
- priority: 51,
86
- type: 'pages' as const,
87
- },
88
- ];
89
-
90
- const matches = getMatchingMiddleware(routes, new URL('http://localhost/admin/dashboard'));
91
- expect(matches).toHaveLength(1);
92
- });
93
-
94
- it('does not match page middleware for API routes', () => {
95
- const routes = [
96
- {
97
- pattern: new URLPattern({ pathname: '/*' }),
98
- filePath: '/src/pages/_middleware.ts',
99
- priority: 50,
100
- type: 'pages' as const,
101
- },
102
- ];
103
-
104
- const matches = getMatchingMiddleware(routes, new URL('http://localhost/api/users'));
105
- expect(matches).toHaveLength(0);
106
- });
107
- });
@@ -1,197 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import {
3
- LayoutContextSchema,
4
- LayoutDataSchema,
5
- LayoutRouteSchema,
6
- LayoutHandlerSchema,
7
- LayoutPropsSchema,
8
- LayoutDiscoveryOptionsSchema,
9
- LayoutConfigSchema,
10
- ResolvedLayoutSchema,
11
- } from '../../schemas/layout.ts';
12
- import { validators, safeValidators } from '../../schemas/index.ts';
13
- import type {
14
- LayoutContext,
15
- LayoutData,
16
- LayoutRoute,
17
- LayoutHandler,
18
- LayoutProps,
19
- LayoutDiscoveryOptions,
20
- LayoutConfig,
21
- ResolvedLayout,
22
- } from '../layout.ts';
23
-
24
- describe('Layout System Types and Schemas', () => {
25
- it('LayoutContext - should validate valid layout context', () => {
26
- const mockRequest = new Request('https://example.com/test');
27
- const mockParams = { id: '123' };
28
- const mockQuery = new URLSearchParams('?page=1');
29
- const mockState = new Map();
30
-
31
- const validContext: LayoutContext = {
32
- request: mockRequest,
33
- params: mockParams,
34
- query: mockQuery,
35
- state: mockState,
36
- };
37
-
38
- const result = safeValidators.layoutContext(validContext);
39
- expect(result.success).toEqual(true);
40
- });
41
-
42
- it('LayoutContext - should reject invalid layout context', () => {
43
- const invalidContext = {
44
- request: 'not-a-request',
45
- params: 'not-an-object',
46
- query: 'not-urlsearchparams',
47
- state: 'not-a-map',
48
- };
49
-
50
- const result = safeValidators.layoutContext(invalidContext);
51
- expect(result.success).toEqual(false);
52
- });
53
-
54
- it('LayoutData - should validate layout data as record', () => {
55
- const validData: LayoutData = {
56
- user: { name: 'John', id: 123 },
57
- settings: { theme: 'dark' },
58
- items: [1, 2, 3],
59
- };
60
-
61
- const result = safeValidators.layoutData(validData);
62
- expect(result.success).toEqual(true);
63
- });
64
-
65
- it('LayoutData - should accept empty layout data', () => {
66
- const emptyData: LayoutData = {};
67
-
68
- const result = safeValidators.layoutData(emptyData);
69
- expect(result.success).toEqual(true);
70
- });
71
-
72
- it('LayoutHandler - should validate valid layout handler', () => {
73
- const validHandler = {
74
- component: () => null,
75
- path: '/src/pages/blog/_layout.tsx',
76
- priority: 10,
77
- };
78
-
79
- const result = safeValidators.layoutHandler(validHandler);
80
- expect(result.success).toEqual(true);
81
- });
82
-
83
- it('LayoutDiscoveryOptions - should validate with defaults', () => {
84
- const options = {
85
- baseDirectory: '/src/pages',
86
- };
87
-
88
- const result = safeValidators.layoutDiscoveryOptions(options);
89
- expect(result.success).toEqual(true);
90
- if (result.success) {
91
- expect(result.data.filePattern).toEqual('_layout.tsx');
92
- expect(result.data.excludeDirectories).toEqual([]);
93
- expect(result.data.enableWatching).toEqual(false);
94
- expect(result.data.developmentMode).toEqual(false);
95
- }
96
- });
97
-
98
- it('LayoutDiscoveryOptions - should validate with custom options', () => {
99
- const options: LayoutDiscoveryOptions = {
100
- baseDirectory: '/src/pages',
101
- filePattern: 'layout.tsx',
102
- excludeDirectories: ['node_modules', '.git'],
103
- enableWatching: true,
104
- developmentMode: true,
105
- };
106
-
107
- const result = safeValidators.layoutDiscoveryOptions(options);
108
- expect(result.success).toEqual(true);
109
- if (result.success) {
110
- expect(result.data.filePattern).toEqual('layout.tsx');
111
- expect(result.data.excludeDirectories).toEqual(['node_modules', '.git']);
112
- expect(result.data.enableWatching).toEqual(true);
113
- expect(result.data.developmentMode).toEqual(true);
114
- }
115
- });
116
-
117
- it('LayoutConfig - should validate layout config with all options', () => {
118
- const config: LayoutConfig = {
119
- skipLayouts: ['root', 'admin'],
120
- replaceLayout: true,
121
- onlyLayouts: ['custom'],
122
- customLayout: '/custom/layout.tsx',
123
- };
124
-
125
- const result = safeValidators.layoutConfig(config);
126
- expect(result.success).toEqual(true);
127
- });
128
-
129
- it('LayoutConfig - should validate empty layout config', () => {
130
- const config: LayoutConfig = {};
131
-
132
- const result = safeValidators.layoutConfig(config);
133
- expect(result.success).toEqual(true);
134
- });
135
-
136
- it('ResolvedLayout - should validate complete resolved layout', () => {
137
- const resolvedLayout: ResolvedLayout = {
138
- handlers: [],
139
- dataLoaders: [],
140
- errorBoundaries: [],
141
- streamingComponents: [],
142
- metadata: {
143
- totalLayouts: 2,
144
- resolutionTime: 15.5,
145
- cacheHit: false,
146
- },
147
- };
148
-
149
- const result = safeValidators.resolvedLayout(resolvedLayout);
150
- expect(result.success).toEqual(true);
151
- });
152
-
153
- it('ResolvedLayout - should require all metadata fields', () => {
154
- const incompleteLayout = {
155
- handlers: [],
156
- dataLoaders: [],
157
- errorBoundaries: [],
158
- streamingComponents: [],
159
- metadata: {
160
- totalLayouts: 2,
161
- },
162
- };
163
-
164
- const result = safeValidators.resolvedLayout(incompleteLayout);
165
- expect(result.success).toEqual(false);
166
- });
167
-
168
- it('Type compatibility - should ensure TypeScript types match Zod schemas', () => {
169
- const mockRequest = new Request('https://example.com');
170
- const layoutContext: LayoutContext = {
171
- request: mockRequest,
172
- params: { id: '123' },
173
- query: new URLSearchParams(),
174
- state: new Map(),
175
- };
176
-
177
- const validatedContext = validators.layoutContext(layoutContext);
178
- expect(validatedContext).toBeDefined();
179
- expect(validatedContext.request).toEqual(mockRequest);
180
- });
181
-
182
- it('Error handling - should provide meaningful error messages', () => {
183
- const invalidData = {
184
- request: null,
185
- params: null,
186
- query: null,
187
- state: null,
188
- };
189
-
190
- const result = safeValidators.layoutContext(invalidData);
191
- expect(result.success).toEqual(false);
192
- if (!result.success) {
193
- expect(result.error.message).toContain('Invalid layout context');
194
- expect(result.error.getFormattedErrors().length > 0).toEqual(true);
195
- }
196
- });
197
- });
@@ -1,54 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from "vitest";
2
- import { createImagePlugin } from "../image-optimization.ts";
3
- import type { ResolvedImageConfig } from "../types.ts";
4
-
5
- describe("createImagePlugin", () => {
6
- const defaultConfig: ResolvedImageConfig = {
7
- enabled: true,
8
- defaultFormat: "webp",
9
- quality: 80,
10
- widths: [200, 400, 600, 800, 1200],
11
- removeMetadata: true,
12
- include: /^[^?]+\.(heif|avif|jpeg|jpg|png|tiff|webp|gif)(\?.*)?$/,
13
- exclude: "public/**/*",
14
- };
15
-
16
- beforeEach(() => {
17
- vi.clearAllMocks();
18
- });
19
-
20
- it("returns empty array when disabled", async () => {
21
- const plugins = await createImagePlugin({ ...defaultConfig, enabled: false }, false);
22
- expect(plugins).toEqual([]);
23
- });
24
-
25
- it("returns imagetools plugin when enabled", async () => {
26
- const plugins = await createImagePlugin(defaultConfig, false);
27
- expect(plugins.length).toBe(1);
28
- expect(plugins[0].name).toBe("imagetools");
29
- });
30
-
31
- it("logs info when verbose is true", async () => {
32
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => {});
33
-
34
- await createImagePlugin(defaultConfig, true);
35
-
36
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Image optimization enabled"));
37
- consoleSpy.mockRestore();
38
- });
39
-
40
- it("respects custom format setting", async () => {
41
- const plugins = await createImagePlugin({ ...defaultConfig, defaultFormat: "avif" }, true);
42
- expect(plugins.length).toBe(1);
43
- });
44
-
45
- it("respects custom quality setting", async () => {
46
- const plugins = await createImagePlugin({ ...defaultConfig, quality: 90 }, false);
47
- expect(plugins.length).toBe(1);
48
- });
49
-
50
- it("respects custom widths setting", async () => {
51
- const plugins = await createImagePlugin({ ...defaultConfig, widths: [320, 640, 1280] }, false);
52
- expect(plugins.length).toBe(1);
53
- });
54
- });