svger-cli 3.0.0 → 3.1.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.
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Test Fixtures
3
+ * Reusable test data for unit tests
4
+ */
5
+ export const sampleSVGs = {
6
+ simple: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
7
+ <circle cx="12" cy="12" r="10"/>
8
+ </svg>`,
9
+ withFill: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
10
+ <path d="M12 2L2 7l10 5 10-5-10-5z"/>
11
+ </svg>`,
12
+ complex: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
13
+ <path stroke-linecap="round" stroke-linejoin="round" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
14
+ </svg>`,
15
+ nested: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
16
+ <g>
17
+ <circle cx="12" cy="12" r="10"/>
18
+ <path d="M12 2v20"/>
19
+ <path d="M2 12h20"/>
20
+ </g>
21
+ </svg>`,
22
+ multiPath: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
23
+ <path d="M12 2L2 7l10 5 10-5-10-5z"/>
24
+ <path d="M2 17l10 5 10-5M2 12l10 5 10-5"/>
25
+ </svg>`,
26
+ withGradient: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
27
+ <defs>
28
+ <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
29
+ <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
30
+ <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
31
+ </linearGradient>
32
+ </defs>
33
+ <circle cx="12" cy="12" r="10" fill="url(#grad1)"/>
34
+ </svg>`,
35
+ withText: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
36
+ <text x="12" y="12" text-anchor="middle">SVG</text>
37
+ </svg>`,
38
+ accessibility: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img" aria-labelledby="iconTitle">
39
+ <title id="iconTitle">Home Icon</title>
40
+ <desc>An icon representing a house</desc>
41
+ <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
42
+ </svg>`,
43
+ animated: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
44
+ <circle cx="12" cy="12" r="10">
45
+ <animate attributeName="r" from="10" to="5" dur="1s" repeatCount="indefinite"/>
46
+ </circle>
47
+ </svg>`,
48
+ invalid: `<svg><unclosed`,
49
+ empty: ``,
50
+ malformed: `<invalid>not an svg</invalid>`
51
+ };
52
+ export const sampleConfigs = {
53
+ react: {
54
+ framework: 'react',
55
+ typescript: true,
56
+ naming: 'pascal',
57
+ generateIndex: true
58
+ },
59
+ vue: {
60
+ framework: 'vue',
61
+ typescript: true,
62
+ naming: 'kebab',
63
+ generateIndex: true
64
+ },
65
+ angular: {
66
+ framework: 'angular',
67
+ typescript: true,
68
+ naming: 'kebab',
69
+ generateIndex: true
70
+ },
71
+ minimal: {
72
+ framework: 'react'
73
+ },
74
+ full: {
75
+ source: './icons',
76
+ output: './components',
77
+ framework: 'react',
78
+ typescript: true,
79
+ naming: 'pascal',
80
+ generateIndex: true,
81
+ watch: false,
82
+ clean: true,
83
+ parallel: true,
84
+ verbose: true,
85
+ responsive: {
86
+ mobile: 16,
87
+ tablet: 20,
88
+ desktop: 24
89
+ },
90
+ theme: {
91
+ primary: '#007bff',
92
+ secondary: '#6c757d'
93
+ }
94
+ }
95
+ };
96
+ export const expectedOutputs = {
97
+ react: {
98
+ js: `import React from 'react';
99
+
100
+ export const TestIcon = (props) => (
101
+ <svg {...props}>
102
+ <circle cx="12" cy="12" r="10"/>
103
+ </svg>
104
+ );
105
+
106
+ export default TestIcon;`,
107
+ ts: `import React from 'react';
108
+
109
+ interface TestIconProps extends React.SVGProps<SVGSVGElement> {}
110
+
111
+ export const TestIcon: React.FC<TestIconProps> = (props) => (
112
+ <svg {...props}>
113
+ <circle cx="12" cy="12" r="10"/>
114
+ </svg>
115
+ );
116
+
117
+ export default TestIcon;`,
118
+ withForwardRef: `import React, { forwardRef } from 'react';
119
+
120
+ interface TestIconProps extends React.SVGProps<SVGSVGElement> {}
121
+
122
+ export const TestIcon = forwardRef<SVGSVGElement, TestIconProps>(
123
+ (props, ref) => (
124
+ <svg ref={ref} {...props}>
125
+ <circle cx="12" cy="12" r="10"/>
126
+ </svg>
127
+ )
128
+ );
129
+
130
+ TestIcon.displayName = 'TestIcon';
131
+
132
+ export default TestIcon;`
133
+ },
134
+ vue: {
135
+ composition: `<template>
136
+ <svg v-bind="$attrs">
137
+ <circle cx="12" cy="12" r="10"/>
138
+ </svg>
139
+ </template>
140
+
141
+ <script setup lang="ts">
142
+ </script>`,
143
+ options: `<template>
144
+ <svg v-bind="$attrs">
145
+ <circle cx="12" cy="12" r="10"/>
146
+ </svg>
147
+ </template>
148
+
149
+ <script lang="ts">
150
+ export default {
151
+ name: 'TestIcon'
152
+ };
153
+ </script>`
154
+ },
155
+ angular: {
156
+ standalone: `import { Component } from '@angular/core';
157
+
158
+ @Component({
159
+ selector: 'app-test-icon',
160
+ standalone: true,
161
+ template: \`
162
+ <svg>
163
+ <circle cx="12" cy="12" r="10"/>
164
+ </svg>
165
+ \`
166
+ })
167
+ export class TestIconComponent {}`
168
+ },
169
+ svelte: `<script lang="ts">
170
+ export let width: number = 24;
171
+ export let height: number = 24;
172
+ </script>
173
+
174
+ <svg {width} {height}>
175
+ <circle cx="12" cy="12" r="10"/>
176
+ </svg>`,
177
+ indexFile: `export { default as HomeIcon } from './HomeIcon';
178
+ export { default as UserIcon } from './UserIcon';
179
+ export { default as SettingsIcon } from './SettingsIcon';
180
+
181
+ /**
182
+ * SVG Components Index
183
+ * Generated by svger-cli
184
+ *
185
+ * Import individual components:
186
+ * import { HomeIcon } from './components';
187
+ *
188
+ * Import all components:
189
+ * import * as Icons from './components';
190
+ */`
191
+ };
192
+ export const mockFileStructure = {
193
+ input: {
194
+ 'home.svg': sampleSVGs.simple,
195
+ 'user.svg': sampleSVGs.withFill,
196
+ 'settings.svg': sampleSVGs.complex,
197
+ 'nested/folder/icon.svg': sampleSVGs.nested
198
+ },
199
+ expected: {
200
+ 'HomeIcon.tsx': expectedOutputs.react.ts,
201
+ 'UserIcon.tsx': expectedOutputs.react.ts,
202
+ 'SettingsIcon.tsx': expectedOutputs.react.ts,
203
+ 'index.ts': expectedOutputs.indexFile
204
+ }
205
+ };
206
+ export const frameworks = [
207
+ 'react',
208
+ 'react-native',
209
+ 'vue',
210
+ 'angular',
211
+ 'svelte',
212
+ 'solid',
213
+ 'lit',
214
+ 'preact',
215
+ 'vanilla'
216
+ ];
217
+ export const namingConventions = ['pascal', 'camel', 'kebab'];
218
+ export const fileExtensions = {
219
+ react: { js: '.jsx', ts: '.tsx' },
220
+ 'react-native': { js: '.jsx', ts: '.tsx' },
221
+ vue: { js: '.vue', ts: '.vue' },
222
+ angular: { js: '.component.ts', ts: '.component.ts' },
223
+ svelte: { js: '.svelte', ts: '.svelte' },
224
+ solid: { js: '.tsx', ts: '.tsx' },
225
+ lit: { js: '.ts', ts: '.ts' },
226
+ preact: { js: '.tsx', ts: '.tsx' },
227
+ vanilla: { js: '.ts', ts: '.ts' }
228
+ };
package/dist/cli.js CHANGED
@@ -11,7 +11,7 @@ const program = new CLI();
11
11
  program
12
12
  .name('svger-cli')
13
13
  .description('Custom SVG to Angular, React, Vue, Svelte, Solid, and other component converter')
14
- .version('2.0.0');
14
+ .version('3.0.0');
15
15
  // -------- Build Command --------
16
16
  /**
17
17
  * Build all SVGs from a source folder to an output folder.
@@ -85,9 +85,9 @@ async function processAllSVGs(options, processedFiles) {
85
85
  }
86
86
  }
87
87
  // Generate index file if enabled
88
- if (options.generateIndex && results.length > 0) {
88
+ if (options.generateIndex) {
89
89
  try {
90
- await generateIndexFile(outputPath, results, options);
90
+ await generateIndexFile(outputPath, options);
91
91
  }
92
92
  catch (error) {
93
93
  logger.error('Failed to generate index file:', error);
@@ -97,16 +97,35 @@ async function processAllSVGs(options, processedFiles) {
97
97
  }
98
98
  /**
99
99
  * Generate index file with all exports
100
+ * Scans the output directory for all existing component files
100
101
  */
101
- async function generateIndexFile(outputDir, results, options) {
102
- const extension = options.typescript ? 'ts' : 'js';
103
- const exports = results
104
- .filter(r => r.componentName)
105
- .map(r => `export { default as ${r.componentName} } from './${r.componentName}';`)
106
- .join('\n');
107
- const indexPath = path.join(outputDir, `index.${extension}`);
108
- await FileSystem.writeFile(indexPath, exports, 'utf-8');
109
- logger.debug(`Generated index file: ${indexPath}`);
102
+ async function generateIndexFile(outputDir, options) {
103
+ try {
104
+ // Scan output directory for all component files
105
+ const files = await FileSystem.readDir(outputDir);
106
+ const extension = options.typescript ? 'tsx' : 'jsx';
107
+ // Filter component files (exclude index files)
108
+ const componentFiles = files.filter(file => (file.endsWith(`.${extension}`) ||
109
+ file.endsWith('.ts') ||
110
+ file.endsWith('.js')) &&
111
+ !file.startsWith('index.'));
112
+ if (componentFiles.length === 0) {
113
+ logger.warn('No component files found for index generation');
114
+ return;
115
+ }
116
+ // Extract component names
117
+ const componentNames = componentFiles.map(file => path.basename(file, path.extname(file)));
118
+ const indexExtension = options.typescript ? 'ts' : 'js';
119
+ const exports = componentNames
120
+ .map(name => `export { default as ${name} } from './${name}';`)
121
+ .join('\n');
122
+ const indexPath = path.join(outputDir, `index.${indexExtension}`);
123
+ await FileSystem.writeFile(indexPath, exports, 'utf-8');
124
+ logger.debug(`Generated index file: ${indexPath}`);
125
+ }
126
+ catch (error) {
127
+ logger.error('Failed to generate index file:', error);
128
+ }
110
129
  }
111
130
  /**
112
131
  * Transform SVG import path to component path
@@ -140,7 +140,7 @@ async function processAllSVGs(options, processedFiles) {
140
140
  }
141
141
  // Generate index file
142
142
  if (options.generateIndex) {
143
- await generateIndexFile(outputDir, results, options);
143
+ await generateIndexFile(outputDir, options);
144
144
  }
145
145
  const successful = results.filter(r => r.success).length;
146
146
  logger.info(`SVGER: Processed ${successful}/${svgFiles.length} SVG files`);
@@ -182,16 +182,35 @@ async function processSVGFile(svgPath, outputDir, options) {
182
182
  }
183
183
  /**
184
184
  * Generate index file with all exports
185
+ * Scans the output directory for all existing component files
185
186
  */
186
- async function generateIndexFile(outputDir, results, options) {
187
- const extension = options.typescript ? 'ts' : 'js';
188
- const exports = results
189
- .filter(r => r.componentName)
190
- .map(r => `export { default as ${r.componentName} } from './${r.componentName}';`)
191
- .join('\n');
192
- const indexPath = path.join(outputDir, `index.${extension}`);
193
- await FileSystem.writeFile(indexPath, exports, 'utf-8');
194
- logger.debug(`Generated index file: ${indexPath}`);
187
+ async function generateIndexFile(outputDir, options) {
188
+ try {
189
+ // Scan output directory for all component files
190
+ const files = await FileSystem.readDir(outputDir);
191
+ const extension = options.typescript ? 'tsx' : 'jsx';
192
+ // Filter component files (exclude index files)
193
+ const componentFiles = files.filter(file => (file.endsWith(`.${extension}`) ||
194
+ file.endsWith('.ts') ||
195
+ file.endsWith('.js')) &&
196
+ !file.startsWith('index.'));
197
+ if (componentFiles.length === 0) {
198
+ logger.warn('No component files found for index generation');
199
+ return;
200
+ }
201
+ // Extract component names
202
+ const componentNames = componentFiles.map(file => path.basename(file, path.extname(file)));
203
+ const indexExtension = options.typescript ? 'ts' : 'js';
204
+ const exports = componentNames
205
+ .map(name => `export { default as ${name} } from './${name}';`)
206
+ .join('\n');
207
+ const indexPath = path.join(outputDir, `index.${indexExtension}`);
208
+ await FileSystem.writeFile(indexPath, exports, 'utf-8');
209
+ logger.debug(`Generated index file: ${indexPath}`);
210
+ }
211
+ catch (error) {
212
+ logger.error('Failed to generate index file:', error);
213
+ }
195
214
  }
196
215
  // Default export
197
216
  export default svgerRollupPlugin;
@@ -47,13 +47,9 @@ export function svgerVitePlugin(options = {}) {
47
47
  svgo: options.svgo !== undefined ? options.svgo : false,
48
48
  generateIndex: options.generateIndex !== undefined ? options.generateIndex : true,
49
49
  };
50
- let viteConfig;
51
50
  const processedFiles = new Set();
52
51
  return {
53
52
  name: PLUGIN_NAME,
54
- configResolved(resolvedConfig) {
55
- viteConfig = resolvedConfig;
56
- },
57
53
  async buildStart() {
58
54
  logger.info('SVGER Vite Plugin: Processing SVG files...');
59
55
  await processAllSVGs(pluginOptions, processedFiles);
@@ -164,7 +160,7 @@ async function processAllSVGs(options, processedFiles) {
164
160
  }
165
161
  // Generate index file
166
162
  if (options.generateIndex) {
167
- await generateIndexFile(outputDir, results, options);
163
+ await generateIndexFile(outputDir, options);
168
164
  }
169
165
  const successful = results.filter(r => r.success).length;
170
166
  logger.info(`SVGER: Processed ${successful}/${svgFiles.length} SVG files`);
@@ -206,16 +202,35 @@ async function processSVGFile(svgPath, outputDir, options) {
206
202
  }
207
203
  /**
208
204
  * Generate index file with all exports
205
+ * Scans the output directory for all existing component files
209
206
  */
210
- async function generateIndexFile(outputDir, results, options) {
211
- const extension = options.typescript ? 'ts' : 'js';
212
- const exports = results
213
- .filter(r => r.componentName)
214
- .map(r => `export { default as ${r.componentName} } from './${r.componentName}';`)
215
- .join('\n');
216
- const indexPath = path.join(outputDir, `index.${extension}`);
217
- await FileSystem.writeFile(indexPath, exports, 'utf-8');
218
- logger.debug(`Generated index file: ${indexPath}`);
207
+ async function generateIndexFile(outputDir, options) {
208
+ try {
209
+ // Scan output directory for all component files
210
+ const files = await FileSystem.readDir(outputDir);
211
+ const extension = options.typescript ? 'tsx' : 'jsx';
212
+ // Filter component files (exclude index files)
213
+ const componentFiles = files.filter(file => (file.endsWith(`.${extension}`) ||
214
+ file.endsWith('.ts') ||
215
+ file.endsWith('.js')) &&
216
+ !file.startsWith('index.'));
217
+ if (componentFiles.length === 0) {
218
+ logger.warn('No component files found for index generation');
219
+ return;
220
+ }
221
+ // Extract component names
222
+ const componentNames = componentFiles.map(file => path.basename(file, path.extname(file)));
223
+ const indexExtension = options.typescript ? 'ts' : 'js';
224
+ const exports = componentNames
225
+ .map(name => `export { default as ${name} } from './${name}';`)
226
+ .join('\n');
227
+ const indexPath = path.join(outputDir, `index.${indexExtension}`);
228
+ await FileSystem.writeFile(indexPath, exports, 'utf-8');
229
+ logger.debug(`Generated index file: ${indexPath}`);
230
+ }
231
+ catch (error) {
232
+ logger.error('Failed to generate index file:', error);
233
+ }
219
234
  }
220
235
  // Default export
221
236
  export default svgerVitePlugin;
@@ -45,6 +45,7 @@ export declare class SvgerWebpackPlugin {
45
45
  private processSVGFile;
46
46
  /**
47
47
  * Generate index file with all exports
48
+ * Scans the output directory for all existing component files
48
49
  */
49
50
  private generateIndexFile;
50
51
  /**
@@ -111,7 +111,7 @@ export class SvgerWebpackPlugin {
111
111
  }
112
112
  // Generate index file
113
113
  if (this.options.generateIndex) {
114
- await this.generateIndexFile(outputDir, results.filter(r => r.success));
114
+ await this.generateIndexFile(outputDir);
115
115
  }
116
116
  const successful = results.filter(r => r.success).length;
117
117
  logger.info(`SVGER: Processed ${successful}/${svgFiles.length} SVG files`);
@@ -176,16 +176,35 @@ export class SvgerWebpackPlugin {
176
176
  }
177
177
  /**
178
178
  * Generate index file with all exports
179
+ * Scans the output directory for all existing component files
179
180
  */
180
- async generateIndexFile(outputDir, results) {
181
- const extension = this.options.typescript ? 'ts' : 'js';
182
- const exports = results
183
- .filter(r => r.componentName)
184
- .map(r => `export { default as ${r.componentName} } from './${r.componentName}';`)
185
- .join('\n');
186
- const indexPath = path.join(outputDir, `index.${extension}`);
187
- await FileSystem.writeFile(indexPath, exports, 'utf-8');
188
- logger.debug(`Generated index file: ${indexPath}`);
181
+ async generateIndexFile(outputDir) {
182
+ try {
183
+ // Scan output directory for all component files
184
+ const files = await FileSystem.readDir(outputDir);
185
+ const extension = this.options.typescript ? 'tsx' : 'jsx';
186
+ // Filter component files (exclude index files)
187
+ const componentFiles = files.filter(file => (file.endsWith(`.${extension}`) ||
188
+ file.endsWith('.ts') ||
189
+ file.endsWith('.js')) &&
190
+ !file.startsWith('index.'));
191
+ if (componentFiles.length === 0) {
192
+ logger.warn('No component files found for index generation');
193
+ return;
194
+ }
195
+ // Extract component names
196
+ const componentNames = componentFiles.map(file => path.basename(file, path.extname(file)));
197
+ const indexExtension = this.options.typescript ? 'ts' : 'js';
198
+ const exports = componentNames
199
+ .map(name => `export { default as ${name} } from './${name}';`)
200
+ .join('\n');
201
+ const indexPath = path.join(outputDir, `index.${indexExtension}`);
202
+ await FileSystem.writeFile(indexPath, exports, 'utf-8');
203
+ logger.debug(`Generated index file: ${indexPath}`);
204
+ }
205
+ catch (error) {
206
+ logger.error('Failed to generate index file:', error);
207
+ }
189
208
  }
190
209
  /**
191
210
  * Get changed files from webpack
@@ -42,6 +42,8 @@ export declare class SVGService {
42
42
  clean(outDir: string): Promise<void>;
43
43
  /**
44
44
  * Generate index.ts file with all component exports
45
+ * Scans the output directory for all existing component files,
46
+ * including those from locked SVGs that weren't regenerated
45
47
  */
46
48
  private generateIndexFile;
47
49
  /**
@@ -76,7 +76,7 @@ export class SVGService {
76
76
  defaultWidth: mergedConfig.defaultWidth,
77
77
  defaultHeight: mergedConfig.defaultHeight,
78
78
  defaultFill: mergedConfig.defaultFill,
79
- namingConvention: mergedConfig.output?.naming || 'pascal',
79
+ namingConvention: mergedConfig.outputConfig?.naming || 'pascal',
80
80
  styleRules: Object.fromEntries(Object.entries(mergedConfig.styleRules || {}).filter(([, v]) => v !== undefined)),
81
81
  });
82
82
  results.push({
@@ -107,9 +107,8 @@ export class SVGService {
107
107
  });
108
108
  }
109
109
  // Generate index.ts file with all component exports
110
- if (successful > 0) {
111
- await this.generateIndexFile(outDir, results.filter(r => r.success).map(r => r.file), mergedConfig);
112
- }
110
+ // This includes both newly generated components and existing locked components
111
+ await this.generateIndexFile(outDir, mergedConfig);
113
112
  }
114
113
  /**
115
114
  * Generate a React component from a single SVG file
@@ -257,13 +256,30 @@ export class SVGService {
257
256
  }
258
257
  /**
259
258
  * Generate index.ts file with all component exports
259
+ * Scans the output directory for all existing component files,
260
+ * including those from locked SVGs that weren't regenerated
260
261
  */
261
- async generateIndexFile(outDir, svgFiles, config) {
262
+ async generateIndexFile(outDir, config) {
262
263
  try {
263
- const namingConvention = config?.output?.naming || 'pascal';
264
- const componentNames = svgFiles.map(file => {
265
- const baseName = path.basename(file, '.svg');
266
- return svgProcessor.generateComponentName(baseName, namingConvention);
264
+ // Scan output directory for all component files
265
+ const files = await FileSystem.readDir(outDir);
266
+ // Get the file extension based on typescript setting
267
+ const typescript = config?.typescript !== false;
268
+ const ext = typescript ? '.tsx' : '.jsx';
269
+ // Filter component files (exclude index.ts/index.js)
270
+ const componentFiles = files.filter(file => (file.endsWith(ext) ||
271
+ file.endsWith('.ts') ||
272
+ file.endsWith('.js')) &&
273
+ !file.startsWith('index.'));
274
+ if (componentFiles.length === 0) {
275
+ logger.warn('No component files found in output directory for index generation');
276
+ return;
277
+ }
278
+ // Extract component names from filenames
279
+ const componentNames = componentFiles.map(file => {
280
+ // Remove extension to get component name
281
+ const baseName = path.basename(file, path.extname(file));
282
+ return baseName;
267
283
  });
268
284
  const indexContent = this.generateIndexContent(componentNames);
269
285
  const indexPath = path.join(outDir, 'index.ts');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svger-cli",
3
- "version": "3.0.0",
3
+ "version": "3.1.1",
4
4
  "description": "Enterprise-grade, zero-dependency SVG to component converter with official Webpack, Vite, Rollup, Babel, Next.js & Jest integrations. Supporting React, React Native, Vue, Angular, Svelte, Solid, Lit, Preact & Vanilla. Features auto-generated TypeScript exports, HMR, responsive design, themes & 85% faster processing than SVGR.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -86,6 +86,8 @@
86
86
  "clean": "node -e \"require('fs').rmSync('dist', {recursive: true, force: true})\"",
87
87
  "dev": "ts-node --esm src/cli.ts",
88
88
  "test": "npm run test:frameworks && npm run test:config && npm run test:e2e && npm run test:integrations",
89
+ "test:jest": "jest --passWithNoTests",
90
+ "test:unit": "jest --testPathPattern='src/__tests__' --passWithNoTests",
89
91
  "test:frameworks": "node frameworks.test.js",
90
92
  "test:config": "tsc tests/config-options.test.ts --outDir dist-tests --module es2022 --target es2022 --moduleResolution bundler && node dist-tests/config-options.test.js",
91
93
  "test:e2e": "tsc tests/e2e-complete.test.ts --outDir dist-tests --module es2022 --target es2022 --moduleResolution bundler && node dist-tests/e2e-complete.test.js",
@@ -93,7 +95,8 @@
93
95
  "test:watch": "jest --watch",
94
96
  "test:coverage": "jest --coverage",
95
97
  "test:integration": "jest --testPathPattern=integration",
96
- "test:all": "npm run test:frameworks && npm run test:config && npm run test:e2e",
98
+ "test:all": "npm run test:jest && npm run test:frameworks && npm run test:config && npm run test:e2e",
99
+ "prepublishOnly": "npm run build",
97
100
  "lint": "eslint src --ext .ts,.tsx",
98
101
  "lint:fix": "eslint src --ext .ts,.tsx --fix",
99
102
  "typecheck": "tsc --noEmit",