@lomray/create-ssr-app 1.0.0 → 1.1.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.
package/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
  <a href="https://nodejs.org/"><img src="https://img.shields.io/node/v/@lomray/create-ssr-app" alt="Node.js version" /></a>
11
11
  </p>
12
12
 
13
- Create a React application with Vite SSR Boost from the official Lomray templates.
13
+ Create a React Router (Data mode) app with SSR and Vite SSR Boost from the official Lomray templates.
14
14
  Start with minimal SSR, the full reference app, a Fastify production server, or localization.
15
15
 
16
16
  ## Usage
@@ -81,6 +81,10 @@ SSR behavior, and deployment.
81
81
  3. Removes `.github/`, `renovate.json`, `CHANGELOG.md`, `LICENSE`, and `SECURITY.md` from the template.
82
82
  When git initialization is skipped, it also removes `.husky/` and `scripts.prepare`.
83
83
  It keeps `vercel.json`, `amplify.yml`, `Dockerfile`, and the other project files.
84
+ It generates a fresh `.github/workflows/ci.yml` for pushes and pull requests, including with
85
+ `--no-git`. CI uses the template's `.nvmrc` or Node 22, installs with `npm ci --ignore-scripts`,
86
+ and runs the available `lint:check`, `ts:check`, `style:check`, `build -- --throw-warnings`,
87
+ `size:check`, and `smoke` scripts in that order. It has no deployment jobs or secrets.
84
88
  4. Sets `package.json`'s name to a valid npm name derived from the destination basename and its
85
89
  version to `0.1.0`. It deletes `description`, `repository`, `homepage`, `bugs`, `author`, and
86
90
  `keywords`, preserving `private` and other fields. The scaffolder does not edit lockfiles.
package/lib/ci.js ADDED
@@ -0,0 +1,37 @@
1
+ import { mkdir, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { statIfExists } from './files.js';
4
+ export const writeCiWorkflow = async (directory, manifest) => {
5
+ const { scripts } = manifest;
6
+ const commands = ['lint:check', 'ts:check', 'style:check', 'build', 'size:check', 'smoke']
7
+ .filter((script) => scripts &&
8
+ typeof scripts === 'object' &&
9
+ Object.hasOwn(scripts, script) &&
10
+ typeof scripts[script] === 'string')
11
+ .map((script) => ` - run: npm run ${script}${script === 'build' ? ' -- --throw-warnings' : ''}`);
12
+ const nodeVersion = (await statIfExists(join(directory, '.nvmrc')))?.isFile()
13
+ ? 'node-version-file: .nvmrc'
14
+ : "node-version: '22'";
15
+ const workflow = `name: CI
16
+
17
+ on: [push, pull_request]
18
+
19
+ permissions:
20
+ contents: read
21
+
22
+ jobs:
23
+ check:
24
+ runs-on: ubuntu-latest
25
+ steps:
26
+ - uses: actions/checkout@v4
27
+ - uses: actions/setup-node@v4
28
+ with:
29
+ ${nodeVersion}
30
+ cache: npm
31
+ - run: npm ci --ignore-scripts
32
+ ${commands.join('\n')}
33
+ `;
34
+ const workflows = join(directory, '.github', 'workflows');
35
+ await mkdir(workflows, { recursive: true });
36
+ await writeFile(join(workflows, 'ci.yml'), workflow);
37
+ };
package/lib/index.js CHANGED
@@ -61,6 +61,8 @@ export const scaffold = async (options, log = console.log, source = process.env.
61
61
  await checkDestination(directory, options.force);
62
62
  await copyDirectory(staging, directory);
63
63
  await removeTemplateMetadata(directory, shouldUseGit);
64
+ // Restore only the generated workflow after clearing any old destination metadata.
65
+ await copyDirectory(join(staging, '.github'), join(directory, '.github'));
64
66
  }
65
67
  finally {
66
68
  await rm(temporary, { recursive: true, force: true });
package/lib/project.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { readFile, rm, writeFile } from 'node:fs/promises';
2
2
  import { basename, join, resolve } from 'node:path';
3
+ import { writeCiWorkflow } from './ci.js';
3
4
  import { UserError, errorCause } from './errors.js';
4
5
  export const packageName = (directory) => {
5
6
  const name = basename(resolve(directory))
@@ -45,6 +46,7 @@ export const postProcess = async (directory, nameFrom, git) => {
45
46
  const rewritten = rewritePackage(manifest, nameFrom, git);
46
47
  await writeFile(manifestPath, `${JSON.stringify(rewritten, null, 2)}\n`);
47
48
  await removeTemplateMetadata(directory, git);
49
+ await writeCiWorkflow(directory, rewritten);
48
50
  };
49
51
  export const removeTemplateMetadata = async (directory, git) => {
50
52
  const removals = ['.github', 'renovate.json', 'CHANGELOG.md', 'LICENSE', 'SECURITY.md'];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lomray/create-ssr-app",
3
- "version": "1.0.0",
4
- "description": "Create a Lomray Vite SSR application from the official templates.",
3
+ "version": "1.1.0",
4
+ "description": "Create a Vite + React Router (Data mode) app with SSR from the official Lomray templates",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "create-ssr-app": "bin/create-ssr-app.mjs"
@@ -30,6 +30,10 @@
30
30
  "vite",
31
31
  "ssr",
32
32
  "react",
33
+ "react-router",
34
+ "server-side-rendering",
35
+ "template",
36
+ "vite-ssr-boost",
33
37
  "scaffold",
34
38
  "create",
35
39
  "lomray"
@@ -58,6 +62,7 @@
58
62
  "semantic-release": "^25.0.9",
59
63
  "typescript": "~6.0.3",
60
64
  "typescript-eslint": "^8.69.0",
61
- "vitest": "^5.0.0"
65
+ "vitest": "^5.0.0",
66
+ "yaml": "^2.9.0"
62
67
  }
63
68
  }