create-appraisejs 0.1.5 → 0.1.6

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
@@ -43,16 +43,3 @@ From the new project directory:
43
43
  - **If you ran setup:** you can go straight to the next step.
44
44
  - Sync entities: `npm run sync-all` (or `pnpm run sync-all`, etc.).
45
45
  - Start the dev server: `npm run dev` (or your package manager’s equivalent).
46
-
47
- See the project’s `README.md` for full details.
48
-
49
- ## Publishing to npm
50
-
51
- From the repo root or this package directory:
52
-
53
- 1. Ensure the package builds: `npm run build` (syncs templates and compiles TypeScript).
54
- 2. Bump version in `package.json` if needed.
55
- 3. Log in to npm: `npm login`.
56
- 4. Publish: `npm publish` (from `packages/create-appraisejs`).
57
-
58
- The `files` field in `package.json` includes only `dist` and `templates`, so source and dev dependencies are not published.
package/package.json CHANGED
@@ -1 +1,67 @@
1
- {"name":"create-appraisejs","version":"0.1.5","description":"Scaffold a new Appraise app in your directory","license":"Apache-2.0","author":"Hasnat Jamil","homepage":"https://github.com/jamil2018/appraise#readme","repository":{"type":"git","url":"git+https://github.com/jamil2018/appraise.git","directory":"packages/create-appraisejs"},"bugs":{"url":"https://github.com/jamil2018/appraise/issues"},"keywords":["appraisejs","appraise","testing","qa","cucumber","playwright","nextjs","scaffold"],"type":"module","main":"./dist/cli.js","bin":{"create-appraisejs":"./dist/cli.js"},"exports":{".":"./dist/cli.js"},"files":["dist","templates"],"scripts":{"prepublishOnly":"npm run build","build":"npm run sync-templates && tsc","sync-templates":"tsx scripts/sync-templates.ts","test":"vitest run","test:e2e":"vitest run --config vitest.e2e.config.ts"},"dependencies":{"@inquirer/prompts":"^7.2.0","cli-progress":"^3.12.0","cross-spawn":"^7.0.6","fs-extra":"^11.2.0","tar":"^7.0.0"},"devDependencies":{"@types/cli-progress":"^3.11.6","@types/cross-spawn":"^6.0.6","@types/fs-extra":"^11.0.4","@types/node":"^20.17.16","tsx":"^4.20.4","typescript":"^5.7.3","vitest":"^2.1.8"},"engines":{"node":">=18"},"overrides":{"esbuild":"^0.25.0"}}
1
+ {
2
+ "name": "create-appraisejs",
3
+ "version": "0.1.6",
4
+ "description": "Scaffold a new AppraiseJS app in your directory",
5
+ "license": "Apache-2.0",
6
+ "author": "Hasnat Jamil",
7
+ "homepage": "https://github.com/jamil2018/appraisejs-core#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/jamil2018/appraisejs-core.git",
11
+ "directory": "packages/create-appraisejs"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/jamil2018/appraisejs-core/issues"
15
+ },
16
+ "keywords": [
17
+ "appraisejs",
18
+ "appraisejs-core",
19
+ "testing",
20
+ "qa",
21
+ "cucumber",
22
+ "playwright",
23
+ "nextjs",
24
+ "scaffold"
25
+ ],
26
+ "type": "module",
27
+ "main": "./dist/cli.js",
28
+ "bin": {
29
+ "create-appraisejs": "./dist/cli.js"
30
+ },
31
+ "exports": {
32
+ ".": "./dist/cli.js"
33
+ },
34
+ "files": [
35
+ "dist",
36
+ "templates"
37
+ ],
38
+ "scripts": {
39
+ "prepublishOnly": "npm run build",
40
+ "build": "npm run sync-templates && tsc",
41
+ "sync-templates": "tsx scripts/sync-templates.ts",
42
+ "test": "vitest run",
43
+ "test:e2e": "vitest run --config vitest.e2e.config.ts"
44
+ },
45
+ "dependencies": {
46
+ "@inquirer/prompts": "^7.2.0",
47
+ "cli-progress": "^3.12.0",
48
+ "cross-spawn": "^7.0.6",
49
+ "fs-extra": "^11.2.0",
50
+ "tar": "^7.0.0"
51
+ },
52
+ "devDependencies": {
53
+ "@types/cli-progress": "^3.11.6",
54
+ "@types/cross-spawn": "^6.0.6",
55
+ "@types/fs-extra": "^11.0.4",
56
+ "@types/node": "^20.17.16",
57
+ "tsx": "^4.20.4",
58
+ "typescript": "^5.7.3",
59
+ "vitest": "^2.1.8"
60
+ },
61
+ "engines": {
62
+ "node": ">=18"
63
+ },
64
+ "overrides": {
65
+ "esbuild": "^0.25.0"
66
+ }
67
+ }
@@ -1,51 +1,51 @@
1
- # Appraise Starter Template
2
-
3
- This is a standalone Appraise starter project. Copy this folder into a new directory to start a new project.
4
-
5
- ## Prerequisites
6
-
7
- - Node.js 18+
8
- - npm, pnpm, or yarn
9
-
10
- ## Quick start
11
-
12
- ```bash
13
- # 1. Install dependencies
14
- npm install --legacy-peer-deps
15
-
16
- # 2. Setup: create .env, run migrations, install Playwright
17
- npm run setup
18
-
19
- # 3. Sync entities from filesystem to database
20
- npm run sync-all
21
-
22
- # 4. Start the dev server
23
- npm run dev
24
- ```
25
-
26
- ## What you get
27
-
28
- - **URL**: Open [http://localhost:3000](http://localhost:3000) in your browser.
29
- - **UI**: The full Appraise dashboard and UI — same as the main Appraise app. You can manage test suites, test cases, template steps, locators, environments, tags, and run tests.
30
-
31
- ## Scripts
32
-
33
- | Script | Description |
34
- | ------------------------ | --------------------------------------------------------------------------------------------------------------- |
35
- | `npm run dev` | Start Next.js dev server |
36
- | `npm run build` | Build for production |
37
- | `npm run start` | Start production server |
38
- | `npm run setup` | Install deps, create .env, migrate DB, install Playwright |
39
- | `npm run appraisejs:setup` | Alias for `setup` |
40
- | `npm run sync-all` | Sync all entities (modules, environments, tags, steps, locators, test suites, test cases) from filesystem to DB |
41
- | `npm run appraisejs:sync` | Alias for `sync-all` |
42
- | `npm run test` | Run Cucumber tests |
43
-
44
- ## Configuration
45
-
46
- - Copy `.env.example` to `.env` before running (or let `npm run setup` create it). Required: `DATABASE_URL="file:./prisma/dev.db"` for SQLite.
47
- - `appraisejs.config.json` — minimal starter config for future CLI/tooling.
48
-
49
- ## Note
50
-
51
- `npm run setup` runs `install-playwright`, which may require network access and a few minutes. The first `sync-all` run will sync entities from the included `src/tests` structure (locators, steps, environments) into the database.
1
+ # Appraise Starter Template
2
+
3
+ This is a standalone Appraise starter project. Copy this folder into a new directory to start a new project.
4
+
5
+ ## Prerequisites
6
+
7
+ - Node.js 18+
8
+ - npm, pnpm, or yarn
9
+
10
+ ## Quick start
11
+
12
+ ```bash
13
+ # 1. Install dependencies
14
+ npm install --legacy-peer-deps
15
+
16
+ # 2. Setup: create .env, run migrations, install Playwright
17
+ npm run setup
18
+
19
+ # 3. Sync entities from filesystem to database
20
+ npm run sync-all
21
+
22
+ # 4. Start the dev server
23
+ npm run dev
24
+ ```
25
+
26
+ ## What you get
27
+
28
+ - **URL**: Open [http://localhost:3000](http://localhost:3000) in your browser.
29
+ - **UI**: The full Appraise dashboard and UI — same as the main Appraise app. You can manage test suites, test cases, template steps, locators, environments, tags, and run tests.
30
+
31
+ ## Scripts
32
+
33
+ | Script | Description |
34
+ | ------------------------ | --------------------------------------------------------------------------------------------------------------- |
35
+ | `npm run dev` | Start Next.js dev server |
36
+ | `npm run build` | Build for production |
37
+ | `npm run start` | Start production server |
38
+ | `npm run setup` | Install deps, create .env, migrate DB, install Playwright |
39
+ | `npm run appraisejs:setup` | Alias for `setup` |
40
+ | `npm run sync-all` | Sync all entities (modules, environments, tags, steps, locators, test suites, test cases) from filesystem to DB |
41
+ | `npm run appraisejs:sync` | Alias for `sync-all` |
42
+ | `npm run test` | Run Cucumber tests |
43
+
44
+ ## Configuration
45
+
46
+ - Copy `.env.example` to `.env` before running (or let `npm run setup` create it). Required: `DATABASE_URL="file:./prisma/dev.db"` for SQLite.
47
+ - `appraisejs.config.json` — minimal starter config for future CLI/tooling.
48
+
49
+ ## Note
50
+
51
+ `npm run setup` runs `install-playwright`, which may require network access and a few minutes. The first `sync-all` run will sync entities from the included `src/tests` structure (locators, steps, environments) into the database.
@@ -1,124 +1,124 @@
1
- {
2
- "name": "appraisejs",
3
- "version": "0.1.0",
4
- "private": true,
5
- "type": "module",
6
- "scripts": {
7
- "dev": "next dev",
8
- "build": "next build",
9
- "start": "next start",
10
- "lint": "eslint .",
11
- "install-playwright": "npx playwright install && npx playwright install-deps",
12
- "install-dependencies": "npm install --legacy-peer-deps",
13
- "setup-env": "npx tsx scripts/setup-env.ts",
14
- "migrate-db": "npx prisma migrate dev",
15
- "setup": "npm run install-dependencies && npm run setup-env && npm run migrate-db && npm run install-playwright",
16
- "sync-features": "npx tsx scripts/regenerate-features.ts",
17
- "sync-features:dry-run": "npx tsx scripts/regenerate-features.ts --dry-run",
18
- "sync-locator-groups": "npx tsx scripts/sync-locator-groups.ts",
19
- "sync-environments": "npx tsx scripts/sync-environments.ts",
20
- "sync-locators": "npx tsx scripts/sync-locators.ts",
21
- "sync-modules": "npx tsx scripts/sync-modules.ts",
22
- "sync-tags": "npx tsx scripts/sync-tags.ts",
23
- "sync-test-suites": "npx tsx scripts/sync-test-suites.ts",
24
- "sync-test-cases": "npx tsx scripts/sync-test-cases.ts",
25
- "sync-template-step-groups": "npx tsx scripts/sync-template-step-groups.ts",
26
- "sync-template-steps": "npx tsx scripts/sync-template-steps.ts",
27
- "sync-all": "npx tsx scripts/sync-all.ts",
28
- "sync-template": "npx tsx scripts/sync-appraise-base-template.ts",
29
- "test": "cucumber-js",
30
- "appraisejs:setup": "npm run setup",
31
- "appraisejs:sync": "npm run sync-all"
32
- },
33
- "dependencies": {
34
- "@babel/parser": "^7.27.0",
35
- "@babel/types": "^7.27.0",
36
- "@faker-js/faker": "^10.2.0",
37
- "@prisma/client": "^6.2.1",
38
- "@radix-ui/react-alert-dialog": "^1.1.14",
39
- "@radix-ui/react-avatar": "^1.1.10",
40
- "@radix-ui/react-checkbox": "^1.3.2",
41
- "@radix-ui/react-dialog": "^1.1.14",
42
- "@radix-ui/react-dropdown-menu": "^2.1.15",
43
- "@radix-ui/react-label": "^2.1.7",
44
- "@radix-ui/react-navigation-menu": "^1.2.13",
45
- "@radix-ui/react-popover": "^1.1.14",
46
- "@radix-ui/react-progress": "^1.1.8",
47
- "@radix-ui/react-radio-group": "^1.3.8",
48
- "@radix-ui/react-scroll-area": "^1.2.9",
49
- "@radix-ui/react-select": "^2.2.5",
50
- "@radix-ui/react-separator": "^1.1.7",
51
- "@radix-ui/react-slot": "^1.2.3",
52
- "@radix-ui/react-tabs": "^1.1.12",
53
- "@radix-ui/react-toast": "^1.2.14",
54
- "@radix-ui/react-tooltip": "^1.2.8",
55
- "@tanstack/react-devtools": "^0.8.1",
56
- "@tanstack/react-form": "^1.25.0",
57
- "@tanstack/react-form-devtools": "^0.2.1",
58
- "@tanstack/react-table": "^8.20.6",
59
- "@types/archiver": "^7.0.0",
60
- "@uiw/codemirror-extensions-langs": "^4.23.10",
61
- "@uiw/codemirror-theme-github": "^4.23.10",
62
- "@uiw/react-codemirror": "^4.23.10",
63
- "@xyflow/react": "^12.4.4",
64
- "archiver": "^7.0.1",
65
- "better-sqlite3": "^12.4.1",
66
- "class-variance-authority": "^0.7.1",
67
- "clsx": "^2.1.1",
68
- "cmdk": "^1.1.1",
69
- "date-fns": "^4.1.0",
70
- "lucide-react": "^0.473.0",
71
- "motion": "^12.23.26",
72
- "next": "^16.0.7",
73
- "next-themes": "^0.4.4",
74
- "react": "^19.2.1",
75
- "react-day-picker": "^9.7.0",
76
- "react-dom": "^19.2.1",
77
- "recharts": "^2.15.4",
78
- "tailwind-merge": "^2.6.0",
79
- "tailwindcss-animate": "^1.0.7",
80
- "winston": "^3.19.0",
81
- "zod": "^3.24.1"
82
- },
83
- "devDependencies": {
84
- "@babel/traverse": "^7.28.5",
85
- "@cucumber/cucumber": "^12.6.0",
86
- "@cucumber/pretty-formatter": "^2.4.0",
87
- "@cucumber/tag-expressions": "^8.0.0",
88
- "@eslint/eslintrc": "^3",
89
- "@types/babel__traverse": "^7.28.0",
90
- "@types/better-sqlite3": "^7.6.13",
91
- "@types/chai": "^5.2.2",
92
- "@types/chai-as-promised": "^8.0.2",
93
- "@types/fs-extra": "^11.0.4",
94
- "@types/node": "^20.17.16",
95
- "@types/react": "^19.2.7",
96
- "@types/react-dom": "^19.2.3",
97
- "baseline-browser-mapping": "^2.9.3",
98
- "chai": "^5.2.1",
99
- "chai-as-promised": "^8.0.1",
100
- "commander": "^14.0.2",
101
- "dotenv": "^17.2.3",
102
- "eslint": "^9",
103
- "eslint-config-next": "^16.0.7",
104
- "execa": "^9.6.0",
105
- "glob": "^11.0.3",
106
- "globals": "^16.4.0",
107
- "jiti": "^2.6.1",
108
- "playwright": "^1.58.0",
109
- "postcss": "^8",
110
- "prettier": "^3.6.2",
111
- "prettier-plugin-tailwindcss": "^0.6.14",
112
- "prisma": "^6.2.1",
113
- "rimraf": "^6.1.2",
114
- "tailwindcss": "^3.4.1",
115
- "ts-node": "^10.9.2",
116
- "tsx": "^4.20.4",
117
- "typescript": "^5.7.3"
118
- },
119
- "overrides": {
120
- "react-is": "^19.2.1",
121
- "@types/react": "^19.2.7",
122
- "@types/react-dom": "^19.2.3"
123
- }
124
- }
1
+ {
2
+ "name": "appraisejs",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "next dev",
8
+ "build": "next build",
9
+ "start": "next start",
10
+ "lint": "eslint .",
11
+ "install-playwright": "npx playwright install && npx playwright install-deps",
12
+ "install-dependencies": "npm install --legacy-peer-deps",
13
+ "setup-env": "npx tsx scripts/setup-env.ts",
14
+ "migrate-db": "npx prisma migrate dev",
15
+ "setup": "npm run install-dependencies && npm run setup-env && npm run migrate-db && npm run install-playwright",
16
+ "sync-features": "npx tsx scripts/regenerate-features.ts",
17
+ "sync-features:dry-run": "npx tsx scripts/regenerate-features.ts --dry-run",
18
+ "sync-locator-groups": "npx tsx scripts/sync-locator-groups.ts",
19
+ "sync-environments": "npx tsx scripts/sync-environments.ts",
20
+ "sync-locators": "npx tsx scripts/sync-locators.ts",
21
+ "sync-modules": "npx tsx scripts/sync-modules.ts",
22
+ "sync-tags": "npx tsx scripts/sync-tags.ts",
23
+ "sync-test-suites": "npx tsx scripts/sync-test-suites.ts",
24
+ "sync-test-cases": "npx tsx scripts/sync-test-cases.ts",
25
+ "sync-template-step-groups": "npx tsx scripts/sync-template-step-groups.ts",
26
+ "sync-template-steps": "npx tsx scripts/sync-template-steps.ts",
27
+ "sync-all": "npx tsx scripts/sync-all.ts",
28
+ "sync-template": "npx tsx scripts/sync-appraise-base-template.ts",
29
+ "test": "cucumber-js",
30
+ "appraisejs:setup": "npm run setup",
31
+ "appraisejs:sync": "npm run sync-all"
32
+ },
33
+ "dependencies": {
34
+ "@babel/parser": "^7.27.0",
35
+ "@babel/types": "^7.27.0",
36
+ "@faker-js/faker": "^10.2.0",
37
+ "@prisma/client": "^6.2.1",
38
+ "@radix-ui/react-alert-dialog": "^1.1.14",
39
+ "@radix-ui/react-avatar": "^1.1.10",
40
+ "@radix-ui/react-checkbox": "^1.3.2",
41
+ "@radix-ui/react-dialog": "^1.1.14",
42
+ "@radix-ui/react-dropdown-menu": "^2.1.15",
43
+ "@radix-ui/react-label": "^2.1.7",
44
+ "@radix-ui/react-navigation-menu": "^1.2.13",
45
+ "@radix-ui/react-popover": "^1.1.14",
46
+ "@radix-ui/react-progress": "^1.1.8",
47
+ "@radix-ui/react-radio-group": "^1.3.8",
48
+ "@radix-ui/react-scroll-area": "^1.2.9",
49
+ "@radix-ui/react-select": "^2.2.5",
50
+ "@radix-ui/react-separator": "^1.1.7",
51
+ "@radix-ui/react-slot": "^1.2.3",
52
+ "@radix-ui/react-tabs": "^1.1.12",
53
+ "@radix-ui/react-toast": "^1.2.14",
54
+ "@radix-ui/react-tooltip": "^1.2.8",
55
+ "@tanstack/react-devtools": "^0.8.1",
56
+ "@tanstack/react-form": "^1.25.0",
57
+ "@tanstack/react-form-devtools": "^0.2.1",
58
+ "@tanstack/react-table": "^8.20.6",
59
+ "@types/archiver": "^7.0.0",
60
+ "@uiw/codemirror-extensions-langs": "^4.23.10",
61
+ "@uiw/codemirror-theme-github": "^4.23.10",
62
+ "@uiw/react-codemirror": "^4.23.10",
63
+ "@xyflow/react": "^12.4.4",
64
+ "archiver": "^7.0.1",
65
+ "better-sqlite3": "^12.4.1",
66
+ "class-variance-authority": "^0.7.1",
67
+ "clsx": "^2.1.1",
68
+ "cmdk": "^1.1.1",
69
+ "date-fns": "^4.1.0",
70
+ "lucide-react": "^0.473.0",
71
+ "motion": "^12.23.26",
72
+ "next": "^16.0.7",
73
+ "next-themes": "^0.4.4",
74
+ "react": "^19.2.1",
75
+ "react-day-picker": "^9.7.0",
76
+ "react-dom": "^19.2.1",
77
+ "recharts": "^2.15.4",
78
+ "tailwind-merge": "^2.6.0",
79
+ "tailwindcss-animate": "^1.0.7",
80
+ "winston": "^3.19.0",
81
+ "zod": "^3.24.1"
82
+ },
83
+ "devDependencies": {
84
+ "@babel/traverse": "^7.28.5",
85
+ "@cucumber/cucumber": "^12.6.0",
86
+ "@cucumber/pretty-formatter": "^2.4.0",
87
+ "@cucumber/tag-expressions": "^8.0.0",
88
+ "@eslint/eslintrc": "^3",
89
+ "@types/babel__traverse": "^7.28.0",
90
+ "@types/better-sqlite3": "^7.6.13",
91
+ "@types/chai": "^5.2.2",
92
+ "@types/chai-as-promised": "^8.0.2",
93
+ "@types/fs-extra": "^11.0.4",
94
+ "@types/node": "^20.17.16",
95
+ "@types/react": "^19.2.7",
96
+ "@types/react-dom": "^19.2.3",
97
+ "baseline-browser-mapping": "^2.9.3",
98
+ "chai": "^5.2.1",
99
+ "chai-as-promised": "^8.0.1",
100
+ "commander": "^14.0.2",
101
+ "dotenv": "^17.2.3",
102
+ "eslint": "^9",
103
+ "eslint-config-next": "^16.0.7",
104
+ "execa": "^9.6.0",
105
+ "glob": "^11.0.3",
106
+ "globals": "^16.4.0",
107
+ "jiti": "^2.6.1",
108
+ "playwright": "^1.58.0",
109
+ "postcss": "^8",
110
+ "prettier": "^3.6.2",
111
+ "prettier-plugin-tailwindcss": "^0.6.14",
112
+ "prisma": "^6.2.1",
113
+ "rimraf": "^6.1.2",
114
+ "tailwindcss": "^3.4.1",
115
+ "ts-node": "^10.9.2",
116
+ "tsx": "^4.20.4",
117
+ "typescript": "^5.7.3"
118
+ },
119
+ "overrides": {
120
+ "react-is": "^19.2.1",
121
+ "@types/react": "^19.2.7",
122
+ "@types/react-dom": "^19.2.3"
123
+ }
124
+ }
@@ -1,106 +1,106 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Sync the default template from the base app (repo root).
4
- * Copies src/, prisma/, public/, scripts/, and root config files into templates/default/,
5
- * preserves template-only README.md and appraisejs.config.json, and merges package.json scripts.
6
- *
7
- * Usage: npx tsx scripts/sync-appraise-base-template.ts
8
- * Or: npm run sync-template
9
- */
10
-
11
- import { cpSync, readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
12
- import { dirname, join } from 'path';
13
- import { fileURLToPath } from 'url';
14
-
15
- const __dirname = dirname(fileURLToPath(import.meta.url));
16
- const repoRoot = join(__dirname, '..');
17
- const target = join(repoRoot, 'templates', 'default');
18
-
19
- const EXCLUDED_DIRS = new Set(['node_modules', '.next', '.git']);
20
- const EXCLUDED_EXTENSIONS = new Set(['.db', '.sqlite', '.sqlite3']);
21
-
22
- function shouldExclude(relativePath: string): boolean {
23
- const parts = relativePath.split(/[/\\]/);
24
- if (parts.some((p) => EXCLUDED_DIRS.has(p))) return true;
25
- const ext = relativePath.endsWith('.sqlite3')
26
- ? '.sqlite3'
27
- : relativePath.endsWith('.sqlite')
28
- ? '.sqlite'
29
- : relativePath.slice(relativePath.lastIndexOf('.'));
30
- if (EXCLUDED_EXTENSIONS.has(ext)) return true;
31
- return false;
32
- }
33
-
34
- function copyDirWithFilter(src: string, dest: string): void {
35
- cpSync(src, dest, {
36
- recursive: true,
37
- force: true,
38
- filter: (source: string) => {
39
- const rel = source.slice(src.length).replace(/^[/\\]/, '') || '';
40
- return !shouldExclude(rel);
41
- },
42
- });
43
- }
44
-
45
- function copyFile(src: string, dest: string): void {
46
- mkdirSync(dirname(dest), { recursive: true });
47
- cpSync(src, dest, { force: true });
48
- }
49
-
50
- // 1. Preserve template-only files
51
- const readmePath = join(target, 'README.md');
52
- const appraisejsConfigPath = join(target, 'appraisejs.config.json');
53
- const savedReadme = existsSync(readmePath) ? readFileSync(readmePath, 'utf8') : null;
54
- const savedAppraisejsConfig = existsSync(appraisejsConfigPath)
55
- ? readFileSync(appraisejsConfigPath, 'utf8')
56
- : null;
57
-
58
- // 2. Copy directories
59
- console.log('Copying src/...');
60
- copyDirWithFilter(join(repoRoot, 'src'), join(target, 'src'));
61
- console.log('Copying prisma/...');
62
- copyDirWithFilter(join(repoRoot, 'prisma'), join(target, 'prisma'));
63
- console.log('Copying public/...');
64
- copyDirWithFilter(join(repoRoot, 'public'), join(target, 'public'));
65
- console.log('Copying scripts/...');
66
- copyDirWithFilter(join(repoRoot, 'scripts'), join(target, 'scripts'));
67
-
68
- // 3. Copy root config files
69
- const configFiles = [
70
- 'eslint.config.mjs',
71
- 'tailwind.config.ts',
72
- 'tsconfig.json',
73
- 'postcss.config.mjs',
74
- 'components.json',
75
- 'next.config.ts',
76
- '.env.example',
77
- ];
78
- console.log('Copying config files...');
79
- for (const name of configFiles) {
80
- const src = join(repoRoot, name);
81
- if (existsSync(src)) {
82
- copyFile(src, join(target, name));
83
- }
84
- }
85
-
86
- // 4. package.json: base + template-only scripts
87
- const rootPkg = JSON.parse(readFileSync(join(repoRoot, 'package.json'), 'utf8')) as {
88
- scripts: Record<string, string>;
89
- [key: string]: unknown;
90
- };
91
- rootPkg.scripts['appraisejs:setup'] = 'npm run setup';
92
- rootPkg.scripts['appraisejs:sync'] = 'npm run sync-all';
93
- writeFileSync(join(target, 'package.json'), JSON.stringify(rootPkg, null, 2) + '\n');
94
- console.log('Wrote package.json with appraisejs:setup and appraisejs:sync.');
95
-
96
- // 5. Restore template-only files
97
- if (savedReadme) {
98
- writeFileSync(readmePath, savedReadme);
99
- console.log('Restored README.md');
100
- }
101
- if (savedAppraisejsConfig) {
102
- writeFileSync(appraisejsConfigPath, savedAppraisejsConfig);
103
- console.log('Restored appraisejs.config.json');
104
- }
105
-
106
- console.log('Synced base app to templates/default.');
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Sync the default template from the base app (repo root).
4
+ * Copies src/, prisma/, public/, scripts/, and root config files into templates/default/,
5
+ * preserves template-only README.md and appraisejs.config.json, and merges package.json scripts.
6
+ *
7
+ * Usage: npx tsx scripts/sync-appraise-base-template.ts
8
+ * Or: npm run sync-template
9
+ */
10
+
11
+ import { cpSync, readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
12
+ import { dirname, join } from 'path';
13
+ import { fileURLToPath } from 'url';
14
+
15
+ const __dirname = dirname(fileURLToPath(import.meta.url));
16
+ const repoRoot = join(__dirname, '..');
17
+ const target = join(repoRoot, 'templates', 'default');
18
+
19
+ const EXCLUDED_DIRS = new Set(['node_modules', '.next', '.git']);
20
+ const EXCLUDED_EXTENSIONS = new Set(['.db', '.sqlite', '.sqlite3']);
21
+
22
+ function shouldExclude(relativePath: string): boolean {
23
+ const parts = relativePath.split(/[/\\]/);
24
+ if (parts.some((p) => EXCLUDED_DIRS.has(p))) return true;
25
+ const ext = relativePath.endsWith('.sqlite3')
26
+ ? '.sqlite3'
27
+ : relativePath.endsWith('.sqlite')
28
+ ? '.sqlite'
29
+ : relativePath.slice(relativePath.lastIndexOf('.'));
30
+ if (EXCLUDED_EXTENSIONS.has(ext)) return true;
31
+ return false;
32
+ }
33
+
34
+ function copyDirWithFilter(src: string, dest: string): void {
35
+ cpSync(src, dest, {
36
+ recursive: true,
37
+ force: true,
38
+ filter: (source: string) => {
39
+ const rel = source.slice(src.length).replace(/^[/\\]/, '') || '';
40
+ return !shouldExclude(rel);
41
+ },
42
+ });
43
+ }
44
+
45
+ function copyFile(src: string, dest: string): void {
46
+ mkdirSync(dirname(dest), { recursive: true });
47
+ cpSync(src, dest, { force: true });
48
+ }
49
+
50
+ // 1. Preserve template-only files
51
+ const readmePath = join(target, 'README.md');
52
+ const appraisejsConfigPath = join(target, 'appraisejs.config.json');
53
+ const savedReadme = existsSync(readmePath) ? readFileSync(readmePath, 'utf8') : null;
54
+ const savedAppraisejsConfig = existsSync(appraisejsConfigPath)
55
+ ? readFileSync(appraisejsConfigPath, 'utf8')
56
+ : null;
57
+
58
+ // 2. Copy directories
59
+ console.log('Copying src/...');
60
+ copyDirWithFilter(join(repoRoot, 'src'), join(target, 'src'));
61
+ console.log('Copying prisma/...');
62
+ copyDirWithFilter(join(repoRoot, 'prisma'), join(target, 'prisma'));
63
+ console.log('Copying public/...');
64
+ copyDirWithFilter(join(repoRoot, 'public'), join(target, 'public'));
65
+ console.log('Copying scripts/...');
66
+ copyDirWithFilter(join(repoRoot, 'scripts'), join(target, 'scripts'));
67
+
68
+ // 3. Copy root config files
69
+ const configFiles = [
70
+ 'eslint.config.mjs',
71
+ 'tailwind.config.ts',
72
+ 'tsconfig.json',
73
+ 'postcss.config.mjs',
74
+ 'components.json',
75
+ 'next.config.ts',
76
+ '.env.example',
77
+ ];
78
+ console.log('Copying config files...');
79
+ for (const name of configFiles) {
80
+ const src = join(repoRoot, name);
81
+ if (existsSync(src)) {
82
+ copyFile(src, join(target, name));
83
+ }
84
+ }
85
+
86
+ // 4. package.json: base + template-only scripts
87
+ const rootPkg = JSON.parse(readFileSync(join(repoRoot, 'package.json'), 'utf8')) as {
88
+ scripts: Record<string, string>;
89
+ [key: string]: unknown;
90
+ };
91
+ rootPkg.scripts['appraisejs:setup'] = 'npm run setup';
92
+ rootPkg.scripts['appraisejs:sync'] = 'npm run sync-all';
93
+ writeFileSync(join(target, 'package.json'), JSON.stringify(rootPkg, null, 2) + '\n');
94
+ console.log('Wrote package.json with appraisejs:setup and appraisejs:sync.');
95
+
96
+ // 5. Restore template-only files
97
+ if (savedReadme) {
98
+ writeFileSync(readmePath, savedReadme);
99
+ console.log('Restored README.md');
100
+ }
101
+ if (savedAppraisejsConfig) {
102
+ writeFileSync(appraisejsConfigPath, savedAppraisejsConfig);
103
+ console.log('Restored appraisejs.config.json');
104
+ }
105
+
106
+ console.log('Synced base app to templates/default.');
@@ -1,28 +1,28 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2017",
4
- "lib": ["dom", "dom.iterable", "esnext"],
5
- "allowJs": true,
6
- "skipLibCheck": true,
7
- "strict": true,
8
- "noEmit": true,
9
- "esModuleInterop": true,
10
- "module": "esnext",
11
- "moduleResolution": "bundler",
12
- "resolveJsonModule": true,
13
- "isolatedModules": true,
14
- "jsx": "react-jsx",
15
- "incremental": true,
16
- "forceConsistentCasingInFileNames": true,
17
- "plugins": [{ "name": "next" }],
18
- "paths": { "@/*": ["./src/*"] }
19
- },
20
- "include": [
21
- "next-env.d.ts",
22
- "**/*.ts",
23
- "**/*.tsx",
24
- ".next/types/**/*.ts",
25
- ".next/dev/types/**/*.ts"
26
- ],
27
- "exclude": ["node_modules", "packages/create-appraisejs"]
28
- }
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2017",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "react-jsx",
15
+ "incremental": true,
16
+ "forceConsistentCasingInFileNames": true,
17
+ "plugins": [{ "name": "next" }],
18
+ "paths": { "@/*": ["./src/*"] }
19
+ },
20
+ "include": [
21
+ "next-env.d.ts",
22
+ "**/*.ts",
23
+ "**/*.tsx",
24
+ ".next/types/**/*.ts",
25
+ ".next/dev/types/**/*.ts"
26
+ ],
27
+ "exclude": ["node_modules", "packages/create-appraisejs"]
28
+ }