@ludena-studio/nx-astro 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +21 -0
  3. package/README.md +287 -0
  4. package/docs/configuration.md +528 -0
  5. package/docs/testing.md +322 -0
  6. package/executors/add/executor.d.ts +9 -0
  7. package/executors/add/executor.d.ts.map +1 -0
  8. package/executors/add/executor.js +51 -0
  9. package/executors/add/schema.json +20 -0
  10. package/executors/build/executor.d.ts +8 -0
  11. package/executors/build/executor.d.ts.map +1 -0
  12. package/executors/build/executor.js +43 -0
  13. package/executors/build/schema.json +15 -0
  14. package/executors/dev/executor.d.ts +10 -0
  15. package/executors/dev/executor.d.ts.map +1 -0
  16. package/executors/dev/executor.js +61 -0
  17. package/executors/dev/schema.json +25 -0
  18. package/executors/preview/executor.d.ts +9 -0
  19. package/executors/preview/executor.d.ts.map +1 -0
  20. package/executors/preview/executor.js +50 -0
  21. package/executors/preview/schema.json +20 -0
  22. package/executors/utils.d.ts +18 -0
  23. package/executors/utils.d.ts.map +1 -0
  24. package/executors/utils.js +80 -0
  25. package/executors.json +25 -0
  26. package/generators/app/files/.gitignore__template__ +9 -0
  27. package/generators/app/files/README.md__template__ +27 -0
  28. package/generators/app/files/astro.config.mjs__template__ +12 -0
  29. package/generators/app/files/src/env.d.ts__template__ +1 -0
  30. package/generators/app/files/src/pages/index.astro__template__ +20 -0
  31. package/generators/app/files/tsconfig.json__template__ +11 -0
  32. package/generators/app/files-tailwind/src/styles/global.css__template__ +1 -0
  33. package/generators/app/generator.d.ts +11 -0
  34. package/generators/app/generator.d.ts.map +1 -0
  35. package/generators/app/generator.js +123 -0
  36. package/generators/app/schema.json +49 -0
  37. package/generators.json +10 -0
  38. package/index.d.ts +6 -0
  39. package/index.d.ts.map +1 -0
  40. package/index.js +8 -0
  41. package/package.json +32 -0
  42. package/tsconfig.spec.json +13 -0
@@ -0,0 +1,322 @@
1
+ # Testing Guide
2
+
3
+ ## Overview
4
+
5
+ The `@ludena-studio/nx-astro` plugin features a comprehensive suite of unit and integration tests ensuring correct functionality of all components.
6
+
7
+ ### Current Coverage
8
+
9
+ - **Total Tests**: 122
10
+ - **Passing Tests**: 122 (100%)
11
+ - **Test Suites**: 5 (executors + generator + utils)
12
+
13
+ ### Test Suites
14
+
15
+ #### 1. Executors (✅ 100% passing)
16
+ - **`dev/executor.spec.ts`** - 48 tests
17
+ - **`build/executor.spec.ts`** - 28 tests
18
+ - **`preview/executor.spec.ts`** - Covered within dev tests
19
+ - **`add/executor.spec.ts`** - 39 tests
20
+
21
+ #### 2. Generators
22
+ - **`generators/app/generator.spec.ts`** - 41 tests
23
+
24
+ #### 3. Utilities
25
+ - **`executors/utils.spec.ts`** - 26 tests
26
+
27
+ ## Running Tests
28
+
29
+ ### Run all tests
30
+ ```bash
31
+ nx test nx-astro
32
+ ```
33
+
34
+ ### Run tests with coverage
35
+ ```bash
36
+ nx test nx-astro --coverage
37
+ ```
38
+
39
+ ### Run specific tests
40
+ ```bash
41
+ # Run only executor tests
42
+ nx test nx-astro --testPathPattern="executor"
43
+
44
+ # Run a specific test
45
+ nx test nx-astro --testNamePattern="should start dev server"
46
+ ```
47
+
48
+ ### Watch mode for development
49
+ ```bash
50
+ nx test nx-astro --watch
51
+ ```
52
+
53
+ ## Test Structure
54
+
55
+ ### Executor Tests
56
+
57
+ Each executor has comprehensive coverage including:
58
+
59
+ **Basic Functionality**:
60
+ - Successful execution with default options
61
+ - Passing options to Astro CLI
62
+ - Correct argument handling
63
+
64
+ **Error Handling**:
65
+ - Astro installation validation
66
+ - Non-zero exit code handling
67
+ - Spawn process error handling
68
+ - Project resolution errors
69
+
70
+ **Edge Cases**:
71
+ - Invalid or edge ports (0, 65535)
72
+ - IPv6 addresses
73
+ - URLs with query parameters
74
+ - Project names with special characters
75
+ - Deep nested paths
76
+
77
+ **Security**:
78
+ - Verification of `shell: false` to prevent injection
79
+ - Arguments passed as array, not strings
80
+ - Input sanitization
81
+
82
+ **Logging**:
83
+ - Informative startup messages
84
+ - Appropriate success/error messages
85
+ - Useful debug information
86
+
87
+ ### Utility Tests
88
+
89
+ **`getProjectRoot()`**:
90
+ - Correct project path extraction
91
+ - Missing projectName handling
92
+ - Project not found in graph handling
93
+ - Projects with dashes and special characters
94
+ - Nested directory structures
95
+
96
+ **`findAstroBinary()`**:
97
+ - Search in project node_modules
98
+ - Fallback to global command
99
+ - Windows path handling
100
+ - Paths with trailing slashes
101
+
102
+ **`validateAstroInstalled()`**:
103
+ - Verification in dependencies
104
+ - Verification in devDependencies
105
+ - Missing package.json handling
106
+ - Corrupted package.json handling
107
+ - Package name case-sensitivity
108
+
109
+ **`setupSignalHandlers()`**:
110
+ - Correct SIGTERM, SIGINT, exit handlers setup
111
+ - No kill of already terminated processes
112
+ - Appropriate cleanup
113
+
114
+ ### Generator Tests
115
+
116
+ **Basic Functionality**:
117
+ - App generation with default options
118
+ - Correct project.json structure
119
+ - Correct executor usage
120
+
121
+ **Directories**:
122
+ - Apps in custom directories
123
+ - Nested directories
124
+ - Name normalization
125
+
126
+ **Tags**:
127
+ - Comma-separated tag parsing
128
+ - Whitespace trimming
129
+ - Empty/undefined tag handling
130
+
131
+ **Generated Files**:
132
+ - index.astro creation
133
+ - astro.config.mjs creation
134
+ - tsconfig.json creation
135
+ - README.md creation
136
+ - env.d.ts creation
137
+
138
+ **Naming Conventions**:
139
+ - camelCase to kebab-case conversion
140
+ - Names with numbers
141
+ - Single-word names
142
+ - Path normalization
143
+
144
+ ## Best Practices Implemented
145
+
146
+ ### 1. Appropriate Mocking
147
+ ```typescript
148
+ jest.mock('child_process');
149
+ jest.mock('../utils');
150
+ jest.mock('@nx/devkit', () => ({
151
+ logger: {
152
+ error: jest.fn(),
153
+ info: jest.fn(),
154
+ },
155
+ }));
156
+ ```
157
+
158
+ ### 2. Clean Setup/Teardown
159
+ ```typescript
160
+ beforeEach(() => {
161
+ jest.clearAllMocks();
162
+ // Reset state...
163
+ });
164
+
165
+ afterEach(() => {
166
+ // Cleanup...
167
+ });
168
+ ```
169
+
170
+ ### 3. Security Tests
171
+ ```typescript
172
+ it('should use shell: false to prevent command injection', async () => {
173
+ await executor({}, context);
174
+
175
+ expect(mockSpawn).toHaveBeenCalledWith(
176
+ expect.any(String),
177
+ expect.any(Array),
178
+ expect.objectContaining({ shell: false })
179
+ );
180
+ });
181
+ ```
182
+
183
+ ### 4. Performance Tests
184
+ ```typescript
185
+ it('should complete quickly for successful builds', async () => {
186
+ const start = Date.now();
187
+ await buildExecutor({}, mockContext);
188
+ const duration = Date.now() - start;
189
+
190
+ expect(duration).toBeLessThan(100);
191
+ });
192
+ ```
193
+
194
+ ### 5. Exhaustive Edge Cases
195
+ Each function has test cases for:
196
+ - Most common valid inputs
197
+ - Edge inputs (empty, null, undefined)
198
+ - Malformed or unexpected inputs
199
+ - Error conditions
200
+ - System limits
201
+
202
+ ## Useful Commands
203
+
204
+ ### Clear Jest cache
205
+ ```bash
206
+ nx test nx-astro --clearCache
207
+ ```
208
+
209
+ ### View tests in verbose mode
210
+ ```bash
211
+ nx test nx-astro --verbose
212
+ ```
213
+
214
+ ### Generate HTML coverage report
215
+ ```bash
216
+ nx test nx-astro --coverage
217
+ open coverage/packages/nx-astro/index.html
218
+ ```
219
+
220
+ ### Debug tests
221
+ ```bash
222
+ node --inspect-brk node_modules/.bin/jest --config packages/nx-astro/jest.config.ts --runInBand
223
+ ```
224
+
225
+ ## Configuration
226
+
227
+ ### jest.config.ts
228
+ ```typescript
229
+ export default {
230
+ displayName: 'nx-astro',
231
+ preset: '../../jest.preset.js',
232
+ testEnvironment: 'node',
233
+ transform: {
234
+ '^.+\\.[tj]s$': ['ts-jest', {
235
+ tsconfig: '<rootDir>/tsconfig.spec.json',
236
+ }],
237
+ },
238
+ coverageThreshold: {
239
+ global: {
240
+ branches: 80,
241
+ functions: 80,
242
+ lines: 80,
243
+ statements: 80,
244
+ },
245
+ },
246
+ };
247
+ ```
248
+
249
+ ### tsconfig.spec.json
250
+ Dedicated configuration for Jest types:
251
+ ```json
252
+ {
253
+ "extends": "./tsconfig.json",
254
+ "compilerOptions": {
255
+ "types": ["jest", "node"]
256
+ },
257
+ "include": ["**/*.spec.ts", "**/*.test.ts"]
258
+ }
259
+ ```
260
+
261
+ ## CI/CD Integration
262
+
263
+ ### GitHub Actions Integration
264
+ ```yaml
265
+ - name: Run tests
266
+ run: nx test nx-astro --coverage
267
+
268
+ - name: Upload coverage
269
+ uses: codecov/codecov-action@v3
270
+ with:
271
+ files: ./coverage/packages/nx-astro/coverage-final.json
272
+ ```
273
+
274
+ ## Quality Metrics
275
+
276
+ ✅ **100% of tests passing**
277
+ ✅ **100% of executors tested**
278
+ ✅ **Edge cases covered**
279
+ ✅ **Security tests implemented**
280
+ ✅ **Performance tests included**
281
+
282
+ ## Next Steps
283
+
284
+ 1. **Continuous Integration**: Set up CI/CD to run tests automatically
285
+ 2. **E2E Tests**: Add end-to-end tests with real Nx workspace
286
+ 3. **100% Coverage**: Refine generator tests
287
+ 4. **Mutation Testing**: Implement Stryker to validate test quality
288
+
289
+ ## Troubleshooting
290
+
291
+ ### Tests timing out
292
+
293
+ If tests are timing out, increase the timeout:
294
+
295
+ ```typescript
296
+ it('should handle long-running operations', async () => {
297
+ // Test code...
298
+ }, 10000); // 10 second timeout
299
+ ```
300
+
301
+ ### Mock not working
302
+
303
+ Ensure mocks are defined before importing the module:
304
+
305
+ ```typescript
306
+ jest.mock('./module');
307
+ import { function } from './module'; // Import after mock
308
+ ```
309
+
310
+ ### Coverage not accurate
311
+
312
+ Clear Jest cache and run coverage again:
313
+
314
+ ```bash
315
+ nx test nx-astro --clearCache --coverage
316
+ ```
317
+
318
+ ## Resources
319
+
320
+ - [Jest Documentation](https://jestjs.io/docs/getting-started)
321
+ - [Testing Nx Plugins](https://nx.dev/extending-nx/recipes/local-generators#unit-testing-generators)
322
+ - [Testing Best Practices](https://testingjavascript.com/)
@@ -0,0 +1,9 @@
1
+ import { ExecutorContext } from '@nx/devkit';
2
+ export interface AddExecutorSchema {
3
+ integration: string;
4
+ yes?: boolean;
5
+ }
6
+ export default function runExecutor(options: AddExecutorSchema, context: ExecutorContext): Promise<{
7
+ success: boolean;
8
+ }>;
9
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../../../packages/nx-astro/executors/add/executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAU,MAAM,YAAY,CAAC;AAQrD,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,wBAA8B,WAAW,CACvC,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CA4D/B"}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = runExecutor;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const child_process_1 = require("child_process");
6
+ const utils_1 = require("../utils");
7
+ async function runExecutor(options, context) {
8
+ try {
9
+ if (!options.integration) {
10
+ devkit_1.logger.error('❌ Integration name is required');
11
+ devkit_1.logger.info('💡 Usage: nx add <project> --integration=<name>');
12
+ return { success: false };
13
+ }
14
+ const projectRoot = (0, utils_1.getProjectRoot)(context);
15
+ // Validate Astro is installed
16
+ if (!(0, utils_1.validateAstroInstalled)(projectRoot)) {
17
+ return { success: false };
18
+ }
19
+ const astroBinary = (0, utils_1.findAstroBinary)(projectRoot);
20
+ const args = ['add', options.integration];
21
+ if (options.yes) {
22
+ args.push('--yes');
23
+ }
24
+ devkit_1.logger.info(`🔌 Adding ${options.integration} integration to ${context.projectName}`);
25
+ devkit_1.logger.info(`📂 Project root: ${projectRoot}`);
26
+ return new Promise((resolve) => {
27
+ const child = (0, child_process_1.spawn)(astroBinary, args, {
28
+ cwd: projectRoot,
29
+ stdio: 'inherit',
30
+ shell: false,
31
+ });
32
+ child.on('error', (error) => {
33
+ devkit_1.logger.error(`❌ Failed to add integration: ${error.message}`);
34
+ resolve({ success: false });
35
+ });
36
+ child.on('exit', (code) => {
37
+ if (code === 0) {
38
+ devkit_1.logger.info(`✅ Successfully added ${options.integration} integration!`);
39
+ }
40
+ else if (code !== null) {
41
+ devkit_1.logger.error(`❌ Failed to add ${options.integration} integration (code ${code})`);
42
+ }
43
+ resolve({ success: code === 0 });
44
+ });
45
+ });
46
+ }
47
+ catch (error) {
48
+ devkit_1.logger.error(`❌ Error: ${error instanceof Error ? error.message : String(error)}`);
49
+ return { success: false };
50
+ }
51
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "version": 2,
4
+ "title": "Add Astro Integration",
5
+ "description": "Add an integration to an Astro application",
6
+ "type": "object",
7
+ "properties": {
8
+ "integration": {
9
+ "type": "string",
10
+ "description": "Name of the integration to add (e.g., 'tailwind', 'partytown', 'react', 'vue')",
11
+ "x-prompt": "Which integration would you like to add?"
12
+ },
13
+ "yes": {
14
+ "type": "boolean",
15
+ "description": "Skip confirmation prompts",
16
+ "default": false
17
+ }
18
+ },
19
+ "required": ["integration"]
20
+ }
@@ -0,0 +1,8 @@
1
+ import { ExecutorContext } from '@nx/devkit';
2
+ export interface BuildExecutorSchema {
3
+ outputPath?: string;
4
+ }
5
+ export default function runExecutor(options: BuildExecutorSchema, context: ExecutorContext): Promise<{
6
+ success: boolean;
7
+ }>;
8
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../../../packages/nx-astro/executors/build/executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAU,MAAM,YAAY,CAAC;AAQrD,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAA8B,WAAW,CACvC,OAAO,EAAE,mBAAmB,EAC5B,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CA2C/B"}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = runExecutor;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const child_process_1 = require("child_process");
6
+ const utils_1 = require("../utils");
7
+ async function runExecutor(options, context) {
8
+ try {
9
+ const projectRoot = (0, utils_1.getProjectRoot)(context);
10
+ // Validate Astro is installed
11
+ if (!(0, utils_1.validateAstroInstalled)(projectRoot)) {
12
+ return { success: false };
13
+ }
14
+ const astroBinary = (0, utils_1.findAstroBinary)(projectRoot);
15
+ const args = ['build'];
16
+ devkit_1.logger.info(`🏗️ Building Astro project: ${context.projectName}`);
17
+ devkit_1.logger.info(`📂 Project root: ${projectRoot}`);
18
+ return new Promise((resolve) => {
19
+ const child = (0, child_process_1.spawn)(astroBinary, args, {
20
+ cwd: projectRoot,
21
+ stdio: 'inherit',
22
+ shell: false,
23
+ });
24
+ child.on('error', (error) => {
25
+ devkit_1.logger.error(`❌ Build failed: ${error.message}`);
26
+ resolve({ success: false });
27
+ });
28
+ child.on('exit', (code) => {
29
+ if (code === 0) {
30
+ devkit_1.logger.info('✅ Build completed successfully');
31
+ }
32
+ else if (code !== null) {
33
+ devkit_1.logger.error(`❌ Build failed with exit code ${code}`);
34
+ }
35
+ resolve({ success: code === 0 });
36
+ });
37
+ });
38
+ }
39
+ catch (error) {
40
+ devkit_1.logger.error(`❌ Error: ${error instanceof Error ? error.message : String(error)}`);
41
+ return { success: false };
42
+ }
43
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "version": 2,
4
+ "title": "Astro Build",
5
+ "description": "Build Astro application for production",
6
+ "type": "object",
7
+ "properties": {
8
+ "outputPath": {
9
+ "type": "string",
10
+ "description": "Custom output directory",
11
+ "default": "dist"
12
+ }
13
+ },
14
+ "required": []
15
+ }
@@ -0,0 +1,10 @@
1
+ import { ExecutorContext } from '@nx/devkit';
2
+ export interface DevExecutorSchema {
3
+ port?: number;
4
+ host?: string | boolean;
5
+ open?: boolean | string;
6
+ }
7
+ export default function runExecutor(options: DevExecutorSchema, context: ExecutorContext): Promise<{
8
+ success: boolean;
9
+ }>;
10
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../../../packages/nx-astro/executors/dev/executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAU,MAAM,YAAY,CAAC;AASrD,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CACzB;AAED,wBAA8B,WAAW,CACvC,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAmE/B"}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = runExecutor;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const child_process_1 = require("child_process");
6
+ const utils_1 = require("../utils");
7
+ async function runExecutor(options, context) {
8
+ try {
9
+ const projectRoot = (0, utils_1.getProjectRoot)(context);
10
+ // Validate Astro is installed
11
+ if (!(0, utils_1.validateAstroInstalled)(projectRoot)) {
12
+ return { success: false };
13
+ }
14
+ const astroBinary = (0, utils_1.findAstroBinary)(projectRoot);
15
+ const args = ['dev'];
16
+ // Build command arguments
17
+ if (options.port !== undefined) {
18
+ args.push('--port', String(options.port));
19
+ }
20
+ if (options.host !== undefined) {
21
+ args.push('--host', typeof options.host === 'boolean' ? String(options.host) : options.host);
22
+ }
23
+ if (options.open !== undefined) {
24
+ if (typeof options.open === 'boolean') {
25
+ if (options.open) {
26
+ args.push('--open');
27
+ }
28
+ }
29
+ else {
30
+ args.push('--open', options.open);
31
+ }
32
+ }
33
+ devkit_1.logger.info(`🚀 Starting Astro dev server for ${context.projectName}`);
34
+ devkit_1.logger.info(`📂 Project root: ${projectRoot}`);
35
+ return new Promise((resolve) => {
36
+ const child = (0, child_process_1.spawn)(astroBinary, args, {
37
+ cwd: projectRoot,
38
+ stdio: 'inherit',
39
+ shell: false, // More secure
40
+ });
41
+ (0, utils_1.setupSignalHandlers)(child);
42
+ child.on('error', (error) => {
43
+ devkit_1.logger.error(`❌ Failed to start Astro dev server: ${error.message}`);
44
+ resolve({ success: false });
45
+ });
46
+ child.on('exit', (code) => {
47
+ if (code === 0) {
48
+ devkit_1.logger.info('✅ Astro dev server stopped');
49
+ }
50
+ else if (code !== null) {
51
+ devkit_1.logger.error(`❌ Astro dev server exited with code ${code}`);
52
+ }
53
+ resolve({ success: code === 0 });
54
+ });
55
+ });
56
+ }
57
+ catch (error) {
58
+ devkit_1.logger.error(`❌ Error: ${error instanceof Error ? error.message : String(error)}`);
59
+ return { success: false };
60
+ }
61
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "version": 2,
4
+ "title": "Astro Dev Server",
5
+ "description": "Run Astro development server",
6
+ "type": "object",
7
+ "properties": {
8
+ "port": {
9
+ "type": "number",
10
+ "description": "Port to run the dev server on",
11
+ "default": 4321
12
+ },
13
+ "host": {
14
+ "type": ["string", "boolean"],
15
+ "description": "Hostname to listen on (true for 0.0.0.0)",
16
+ "default": "localhost"
17
+ },
18
+ "open": {
19
+ "type": ["boolean", "string"],
20
+ "description": "Open the browser on server start",
21
+ "default": false
22
+ }
23
+ },
24
+ "required": []
25
+ }
@@ -0,0 +1,9 @@
1
+ import { ExecutorContext } from '@nx/devkit';
2
+ export interface PreviewExecutorSchema {
3
+ port?: number;
4
+ host?: string | boolean;
5
+ }
6
+ export default function runExecutor(options: PreviewExecutorSchema, context: ExecutorContext): Promise<{
7
+ success: boolean;
8
+ }>;
9
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../../../packages/nx-astro/executors/preview/executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAU,MAAM,YAAY,CAAC;AASrD,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACzB;AAED,wBAA8B,WAAW,CACvC,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAwD/B"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = runExecutor;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const child_process_1 = require("child_process");
6
+ const utils_1 = require("../utils");
7
+ async function runExecutor(options, context) {
8
+ try {
9
+ const projectRoot = (0, utils_1.getProjectRoot)(context);
10
+ // Validate Astro is installed
11
+ if (!(0, utils_1.validateAstroInstalled)(projectRoot)) {
12
+ return { success: false };
13
+ }
14
+ const astroBinary = (0, utils_1.findAstroBinary)(projectRoot);
15
+ const args = ['preview'];
16
+ if (options.port !== undefined) {
17
+ args.push('--port', String(options.port));
18
+ }
19
+ if (options.host !== undefined) {
20
+ args.push('--host', typeof options.host === 'boolean' ? String(options.host) : options.host);
21
+ }
22
+ devkit_1.logger.info(`👀 Starting Astro preview server for ${context.projectName}`);
23
+ devkit_1.logger.info(`📂 Project root: ${projectRoot}`);
24
+ return new Promise((resolve) => {
25
+ const child = (0, child_process_1.spawn)(astroBinary, args, {
26
+ cwd: projectRoot,
27
+ stdio: 'inherit',
28
+ shell: false,
29
+ });
30
+ (0, utils_1.setupSignalHandlers)(child);
31
+ child.on('error', (error) => {
32
+ devkit_1.logger.error(`❌ Failed to start preview server: ${error.message}`);
33
+ resolve({ success: false });
34
+ });
35
+ child.on('exit', (code) => {
36
+ if (code === 0) {
37
+ devkit_1.logger.info('✅ Preview server stopped');
38
+ }
39
+ else if (code !== null) {
40
+ devkit_1.logger.error(`❌ Preview server exited with code ${code}`);
41
+ }
42
+ resolve({ success: code === 0 });
43
+ });
44
+ });
45
+ }
46
+ catch (error) {
47
+ devkit_1.logger.error(`❌ Error: ${error instanceof Error ? error.message : String(error)}`);
48
+ return { success: false };
49
+ }
50
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "version": 2,
4
+ "title": "Astro Preview",
5
+ "description": "Preview production build locally",
6
+ "type": "object",
7
+ "properties": {
8
+ "port": {
9
+ "type": "number",
10
+ "description": "Port to run the preview server on",
11
+ "default": 4321
12
+ },
13
+ "host": {
14
+ "type": ["string", "boolean"],
15
+ "description": "Hostname to listen on (true for 0.0.0.0)",
16
+ "default": "localhost"
17
+ }
18
+ },
19
+ "required": []
20
+ }
@@ -0,0 +1,18 @@
1
+ import { ExecutorContext } from '@nx/devkit';
2
+ /**
3
+ * Get the project root directory from executor context
4
+ */
5
+ export declare function getProjectRoot(context: ExecutorContext): string;
6
+ /**
7
+ * Find Astro CLI binary in the project
8
+ */
9
+ export declare function findAstroBinary(workspaceRoot: string): string;
10
+ /**
11
+ * Validate that Astro is installed
12
+ */
13
+ export declare function validateAstroInstalled(projectRoot: string): boolean;
14
+ /**
15
+ * Setup signal handlers for graceful process termination
16
+ */
17
+ export declare function setupSignalHandlers(childProcess: any): void;
18
+ //# sourceMappingURL=utils.d.ts.map