@nestjs-ssr/react 0.1.8 → 0.1.10

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.
package/src/cli/init.ts DELETED
@@ -1,260 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync } from 'fs';
4
- import { join, resolve, dirname } from 'path';
5
- import { fileURLToPath } from 'url';
6
- import { consola } from 'consola';
7
- import { defineCommand, runMain } from 'citty';
8
-
9
- const __filename = fileURLToPath(import.meta.url);
10
- const __dirname = dirname(__filename);
11
-
12
- const main = defineCommand({
13
- meta: {
14
- name: 'nestjs-ssr',
15
- description: 'Initialize @nestjs-ssr/react in your NestJS project',
16
- version: '0.1.6',
17
- },
18
- args: {
19
- force: {
20
- type: 'boolean',
21
- description: 'Overwrite existing files',
22
- alias: 'f',
23
- },
24
- views: {
25
- type: 'string',
26
- description: 'Views directory path',
27
- default: 'src/views',
28
- },
29
- },
30
- async run({ args }) {
31
- const cwd = process.cwd();
32
- const viewsDir = args.views;
33
-
34
- consola.box('@nestjs-ssr/react initialization');
35
- consola.start('Setting up your NestJS SSR React project...\n');
36
-
37
- // Find template files - check both src/ (dev) and dist/ (production) locations
38
- const templateLocations = [
39
- resolve(__dirname, '../../src/templates'), // Development (ts-node/tsx)
40
- resolve(__dirname, '../templates'), // Built package (dist/cli -> dist/templates)
41
- ];
42
- const templateDir = templateLocations.find(loc => existsSync(join(loc, 'entry-client.tsx')));
43
-
44
- if (!templateDir) {
45
- consola.error('Failed to locate template files');
46
- consola.info('Searched:', templateLocations);
47
- process.exit(1);
48
- }
49
-
50
- // Find global.d.ts - check both src/ (dev) and package root (production)
51
- const globalTypesLocations = [
52
- resolve(__dirname, '../../src/global.d.ts'), // Development
53
- resolve(__dirname, '../global.d.ts'), // Built (dist/cli -> dist/../src/global.d.ts)
54
- ];
55
- const globalTypesSrc = globalTypesLocations.find(loc => existsSync(loc));
56
-
57
- if (!globalTypesSrc) {
58
- consola.error('Failed to locate global.d.ts');
59
- consola.info('Searched:', globalTypesLocations);
60
- process.exit(1);
61
- }
62
-
63
- // Check that tsconfig.json exists - we don't create it
64
- const tsconfigPath = join(cwd, 'tsconfig.json');
65
- if (!existsSync(tsconfigPath)) {
66
- consola.error('No tsconfig.json found in project root');
67
- consola.info('Please create a tsconfig.json file first');
68
- process.exit(1);
69
- }
70
-
71
- // 1. Copy entry-client.tsx to views directory
72
- consola.start('Creating entry-client.tsx...');
73
- const entryClientSrc = join(templateDir, 'entry-client.tsx');
74
- const entryClientDest = join(cwd, viewsDir, 'entry-client.tsx');
75
-
76
- // Create views directory if it doesn't exist
77
- mkdirSync(join(cwd, viewsDir), { recursive: true });
78
-
79
- if (existsSync(entryClientDest) && !args.force) {
80
- consola.warn(`${viewsDir}/entry-client.tsx already exists (use --force to overwrite)`);
81
- } else {
82
- copyFileSync(entryClientSrc, entryClientDest);
83
- consola.success(`Created ${viewsDir}/entry-client.tsx`);
84
- }
85
-
86
- // 2. Copy entry-server.tsx to views directory
87
- consola.start('Creating entry-server.tsx...');
88
- const entryServerSrc = join(templateDir, 'entry-server.tsx');
89
- const entryServerDest = join(cwd, viewsDir, 'entry-server.tsx');
90
-
91
- if (existsSync(entryServerDest) && !args.force) {
92
- consola.warn(`${viewsDir}/entry-server.tsx already exists (use --force to overwrite)`);
93
- } else {
94
- copyFileSync(entryServerSrc, entryServerDest);
95
- consola.success(`Created ${viewsDir}/entry-server.tsx`);
96
- }
97
-
98
- // 2. Copy global.d.ts
99
- consola.start('Creating global.d.ts...');
100
- const globalTypesDest = join(cwd, 'src/global.d.ts');
101
-
102
- if (existsSync(globalTypesDest) && !args.force) {
103
- consola.warn('src/global.d.ts already exists (use --force to overwrite)');
104
- } else {
105
- copyFileSync(globalTypesSrc, globalTypesDest);
106
- consola.success('Created src/global.d.ts');
107
- }
108
-
109
- // 4. Update/create vite.config.js
110
- consola.start('Configuring vite.config.js...');
111
- const viteConfigPath = join(cwd, 'vite.config.js');
112
- const viteConfigTs = join(cwd, 'vite.config.ts');
113
- const useTypeScript = existsSync(viteConfigTs);
114
- const configPath = useTypeScript ? viteConfigTs : viteConfigPath;
115
-
116
- if (existsSync(configPath)) {
117
- consola.warn(`${useTypeScript ? 'vite.config.ts' : 'vite.config.js'} already exists`);
118
- consola.info('Please manually add to your Vite config:');
119
- consola.log(' import { resolve } from \'path\';');
120
- consola.log(' build: {');
121
- consola.log(' rollupOptions: {');
122
- consola.log(` input: { client: resolve(__dirname, '${viewsDir}/entry-client.tsx') }`);
123
- consola.log(' }');
124
- consola.log(' }');
125
- } else {
126
- const viteConfig = `import { defineConfig } from 'vite';
127
- import react from '@vitejs/plugin-react';
128
- import { resolve } from 'path';
129
-
130
- export default defineConfig({
131
- plugins: [react()],
132
- resolve: {
133
- alias: {
134
- '@': resolve(__dirname, 'src'),
135
- },
136
- },
137
- server: {
138
- port: 5173,
139
- strictPort: true,
140
- hmr: { port: 5173 },
141
- },
142
- build: {
143
- outDir: 'dist/client',
144
- manifest: true,
145
- rollupOptions: {
146
- input: {
147
- client: resolve(__dirname, '${viewsDir}/entry-client.tsx'),
148
- },
149
- },
150
- },
151
- });
152
- `;
153
- writeFileSync(viteConfigPath, viteConfig);
154
- consola.success('Created vite.config.js');
155
- }
156
-
157
- // 5. Update tsconfig.json
158
- consola.start('Configuring tsconfig.json...');
159
- try {
160
- const tsconfig = JSON.parse(readFileSync(tsconfigPath, 'utf-8'));
161
-
162
- let updated = false;
163
-
164
- if (!tsconfig.compilerOptions) {
165
- tsconfig.compilerOptions = {};
166
- }
167
-
168
- // Ensure jsx is set
169
- if (tsconfig.compilerOptions.jsx !== 'react-jsx') {
170
- tsconfig.compilerOptions.jsx = 'react-jsx';
171
- updated = true;
172
- }
173
-
174
- // Ensure paths includes @ alias
175
- if (!tsconfig.compilerOptions.paths) {
176
- tsconfig.compilerOptions.paths = {};
177
- }
178
- if (!tsconfig.compilerOptions.paths['@/*']) {
179
- tsconfig.compilerOptions.paths['@/*'] = ['./src/*'];
180
- updated = true;
181
- }
182
-
183
- // Ensure types includes vite/client
184
- if (!tsconfig.compilerOptions.types) {
185
- tsconfig.compilerOptions.types = [];
186
- }
187
- if (!tsconfig.compilerOptions.types.includes('vite/client')) {
188
- tsconfig.compilerOptions.types.push('vite/client');
189
- updated = true;
190
- }
191
-
192
- if (updated) {
193
- writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2));
194
- consola.success('Updated tsconfig.json');
195
- } else {
196
- consola.info('tsconfig.json already configured');
197
- }
198
- } catch (error) {
199
- consola.error('Failed to update tsconfig.json:', error);
200
- }
201
-
202
- // 6. Setup build scripts
203
- consola.start('Configuring build scripts...');
204
- const packageJsonPath = join(cwd, 'package.json');
205
-
206
- if (!existsSync(packageJsonPath)) {
207
- consola.warn('No package.json found, skipping build script setup');
208
- } else {
209
- try {
210
- const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
211
-
212
- if (!packageJson.scripts) {
213
- packageJson.scripts = {};
214
- }
215
-
216
- const existingBuild = packageJson.scripts.build;
217
- const defaultNestBuild = 'nest build';
218
- const ssrBuildPrefix = 'vite build && ';
219
-
220
- let shouldUpdate = false;
221
- let newBuildScript = '';
222
-
223
- if (!existingBuild) {
224
- // No build script exists, create one
225
- newBuildScript = `${ssrBuildPrefix}${defaultNestBuild}`;
226
- shouldUpdate = true;
227
- } else if (existingBuild.includes('vite build')) {
228
- // Already has vite build
229
- consola.info('Build script already includes vite build');
230
- } else if (existingBuild === defaultNestBuild) {
231
- // Default nest build, prepend vite build
232
- newBuildScript = `${ssrBuildPrefix}${existingBuild}`;
233
- shouldUpdate = true;
234
- } else {
235
- // Custom build script, ask user
236
- consola.warn(`Found custom build script: "${existingBuild}"`);
237
- consola.info('SSR requires running "vite build" before your build command');
238
- consola.info(`Recommended: ${ssrBuildPrefix}${existingBuild}`);
239
- consola.info('Please manually update your build script in package.json');
240
- }
241
-
242
- if (shouldUpdate) {
243
- packageJson.scripts.build = newBuildScript;
244
- writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
245
- consola.success(`Updated build script to: "${newBuildScript}"`);
246
- }
247
- } catch (error) {
248
- consola.error('Failed to update package.json:', error);
249
- }
250
- }
251
-
252
- consola.success('\nInitialization complete!');
253
- consola.box('Next steps');
254
- consola.info(`1. Create your first view component in ${viewsDir}/`);
255
- consola.info('2. Render it from a NestJS controller using render.render()');
256
- consola.info('3. Run your dev server with: pnpm start:dev');
257
- },
258
- });
259
-
260
- runMain(main);