create-appraisejs 0.2.0-alpha.2 → 0.2.0-alpha.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-appraisejs",
3
- "version": "0.2.0-alpha.2",
3
+ "version": "0.2.0-alpha.4",
4
4
  "description": "Scaffold a new AppraiseJS app in your directory",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Hasnat Jamil",
@@ -44,10 +44,14 @@
44
44
  "sync-templates": "tsx scripts/sync-templates.ts",
45
45
  "test": "vitest run",
46
46
  "test:e2e": "vitest run --config vitest.e2e.config.ts",
47
- "publish": "npm run build && npm publish",
48
- "publish:alpha": "npm run build && npm publish --tag alpha",
49
- "publish:beta": "npm run build && npm publish --tag beta",
50
- "bump:alpha": "npm version prerelease --preid alpha"
47
+ "publish:alpha": "npm publish --tag alpha",
48
+ "publish:beta": "npm publish --tag beta",
49
+ "bump:alpha": "npm version prerelease --preid alpha",
50
+ "bump:beta": "npm version prerelease --preid beta",
51
+ "bump:release": "npm version patch",
52
+ "bump:major": "npm version major",
53
+ "bump:minor": "npm version minor",
54
+ "bump:patch": "npm version patch"
51
55
  },
52
56
  "dependencies": {
53
57
  "@inquirer/prompts": "^7.2.0",
@@ -1,5 +1,5 @@
1
1
  {
2
- "preparedAt": "2026-03-23T19:35:53.852Z",
3
- "inputHash": "165288718820de7247b9067d6c4f1a78057520fb791c4b28fa781f2c30c95ea3",
2
+ "preparedAt": "2026-03-24T10:58:54.969Z",
3
+ "inputHash": "596a28d2c5dc408d39926068711127354f3752a92c086cd0df27e8cf85eb5990",
4
4
  "databasePath": "prisma/dev.db"
5
5
  }
Binary file
@@ -9,6 +9,7 @@
9
9
  */
10
10
 
11
11
  import { promises as fs } from 'fs'
12
+ import path from 'path'
12
13
  import prisma from '../src/config/db-config'
13
14
  import { ensureAutomationWorkspaceReady, getAutomationEnvironmentsDir } from '../src/lib/automation/paths'
14
15
 
@@ -40,16 +41,20 @@ interface SyncResult {
40
41
  skippedEnvironments: string[]
41
42
  }
42
43
 
44
+ const EMPTY_ENVIRONMENTS_FILE_CONTENT = '{}\n'
45
+
43
46
  /**
44
47
  * Reads and parses the environments.json file
45
48
  */
46
49
  async function readEnvironmentsFromFile(): Promise<Record<string, EnvironmentConfig>> {
47
- const filePath = `${getAutomationEnvironmentsDir()}/environments.json`
50
+ const filePath = path.join(getAutomationEnvironmentsDir(), 'environments.json')
48
51
 
49
52
  try {
50
53
  await fs.access(filePath)
51
54
  } catch {
52
- throw new Error(`Environments file not found at ${filePath}`)
55
+ await fs.mkdir(path.dirname(filePath), { recursive: true })
56
+ await fs.writeFile(filePath, EMPTY_ENVIRONMENTS_FILE_CONTENT, 'utf-8')
57
+ return {}
53
58
  }
54
59
 
55
60
  try {
@@ -342,4 +347,3 @@ async function main() {
342
347
  main()
343
348
 
344
349
 
345
-
@@ -1,9 +1,70 @@
1
- import { PrismaClient } from '@prisma/client'
2
-
3
- const globalForPrisma = global as unknown as {
4
- prisma: PrismaClient | undefined
5
- }
6
- const prisma = globalForPrisma.prisma ?? new PrismaClient()
1
+ import fs from 'fs'
2
+ import { createRequire } from 'module'
3
+ import path from 'path'
4
+
5
+ function readProjectDatabaseUrl(): string | null {
6
+ const envPath = path.join(process.cwd(), '.env')
7
+ if (!fs.existsSync(envPath)) {
8
+ return null
9
+ }
10
+
11
+ const envContent = fs.readFileSync(envPath, 'utf8')
12
+ const match = envContent.match(/^\s*DATABASE_URL\s*=\s*(?:"([^"]*)"|'([^']*)'|([^#\r\n]+))\s*$/m)
13
+ const rawValue = match?.[1] ?? match?.[2] ?? match?.[3]
14
+ const normalizedValue = rawValue?.trim()
15
+
16
+ return normalizedValue ? normalizedValue : null
17
+ }
18
+
19
+ function normalizeDatabaseUrl(databaseUrl: string): string {
20
+ if (!databaseUrl.startsWith('file:')) {
21
+ return databaseUrl
22
+ }
23
+
24
+ const sqlitePathWithQuery = databaseUrl.slice('file:'.length)
25
+ if (!sqlitePathWithQuery || sqlitePathWithQuery === ':memory:') {
26
+ return databaseUrl
27
+ }
28
+
29
+ const queryStartIndex = sqlitePathWithQuery.indexOf('?')
30
+ const sqlitePath = queryStartIndex >= 0 ? sqlitePathWithQuery.slice(0, queryStartIndex) : sqlitePathWithQuery
31
+ const query = queryStartIndex >= 0 ? sqlitePathWithQuery.slice(queryStartIndex) : ''
32
+
33
+ if (path.isAbsolute(sqlitePath)) {
34
+ return databaseUrl
35
+ }
36
+
37
+ // Prisma resolves relative SQLite paths from the schema directory. The app's schema
38
+ // lives in `<project>/prisma`, so normalize local file URLs to that location.
39
+ const absolutePath = path.resolve(process.cwd(), 'prisma', sqlitePath)
40
+ return `file:${absolutePath}${query}`
41
+ }
42
+
43
+ function ensureProjectDatabaseUrl(): void {
44
+ if (process.env.DATABASE_URL) {
45
+ return
46
+ }
47
+
48
+ const projectDatabaseUrl = readProjectDatabaseUrl()
49
+ if (!projectDatabaseUrl) {
50
+ return
51
+ }
52
+
53
+ process.env.DATABASE_URL = normalizeDatabaseUrl(projectDatabaseUrl)
54
+ }
55
+
56
+ ensureProjectDatabaseUrl()
57
+
58
+ type PrismaClientInstance = import('@prisma/client').PrismaClient
59
+ const require = createRequire(import.meta.url)
60
+ const { PrismaClient } = require('@prisma/client') as {
61
+ PrismaClient: new () => PrismaClientInstance
62
+ }
63
+
64
+ const globalForPrisma = global as unknown as {
65
+ prisma: PrismaClientInstance | undefined
66
+ }
67
+ const prisma = globalForPrisma.prisma ?? new PrismaClient()
7
68
 
8
69
  if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
9
70
 
@@ -1,14 +1,16 @@
1
- import { promises as fs } from 'fs'
2
- import * as path from 'path'
3
- import prisma from '@/config/db-config'
4
- import { ensureAutomationWorkspaceReady, getAutomationEnvironmentsDir } from '@/lib/automation/paths'
5
-
6
- interface EnvironmentConfig {
7
- baseUrl: string
8
- apiBaseUrl: string
9
- email: string
10
- password: string
11
- }
1
+ import { promises as fs } from 'fs'
2
+ import * as path from 'path'
3
+ import prisma from '@/config/db-config'
4
+ import { ensureAutomationWorkspaceReady, getAutomationEnvironmentsDir } from '@/lib/automation/paths'
5
+
6
+ interface EnvironmentConfig {
7
+ baseUrl: string
8
+ apiBaseUrl: string
9
+ email: string
10
+ password: string
11
+ }
12
+
13
+ const EMPTY_ENVIRONMENTS_FILE_CONTENT = '{}\n'
12
14
 
13
15
  export function getEnvironmentsFilePath(): string {
14
16
  return path.join(getAutomationEnvironmentsDir(), 'environments.json')
@@ -44,44 +46,38 @@ export async function generateEnvironmentsContent(): Promise<Record<string, Envi
44
46
  }
45
47
  }
46
48
 
47
- export async function createOrUpdateEnvironmentsFile(): Promise<boolean> {
48
- try {
49
- await ensureAutomationWorkspaceReady()
50
- const filePath = getEnvironmentsFilePath()
51
- await ensureConfigDirectoryExists()
52
-
53
- const content = await generateEnvironmentsContent()
54
-
55
- if (Object.keys(content).length === 0) {
56
- await deleteEnvironmentsFile()
57
- return true
58
- }
59
-
60
- await fs.writeFile(filePath, JSON.stringify(content, null, 2))
61
- return true
49
+ export async function createOrUpdateEnvironmentsFile(): Promise<boolean> {
50
+ try {
51
+ await ensureAutomationWorkspaceReady()
52
+ const filePath = getEnvironmentsFilePath()
53
+ await ensureConfigDirectoryExists()
54
+
55
+ const content = await generateEnvironmentsContent()
56
+
57
+ if (Object.keys(content).length === 0) {
58
+ await fs.writeFile(filePath, EMPTY_ENVIRONMENTS_FILE_CONTENT)
59
+ return true
60
+ }
61
+
62
+ await fs.writeFile(filePath, JSON.stringify(content, null, 2))
63
+ return true
62
64
  } catch (error) {
63
65
  console.error('Error creating/updating environments file:', error)
64
66
  return false
65
67
  }
66
68
  }
67
69
 
68
- export async function deleteEnvironmentsFile(): Promise<boolean> {
69
- try {
70
- await ensureAutomationWorkspaceReady()
71
- const filePath = getEnvironmentsFilePath()
72
-
73
- try {
74
- await fs.access(filePath)
75
- } catch {
76
- return true
77
- }
78
-
79
- await fs.unlink(filePath)
80
- return true
81
- } catch (error) {
82
- console.error('Error deleting environments file:', error)
83
- return false
84
- }
70
+ export async function deleteEnvironmentsFile(): Promise<boolean> {
71
+ try {
72
+ await ensureAutomationWorkspaceReady()
73
+ const filePath = getEnvironmentsFilePath()
74
+ await ensureConfigDirectoryExists()
75
+ await fs.writeFile(filePath, EMPTY_ENVIRONMENTS_FILE_CONTENT)
76
+ return true
77
+ } catch (error) {
78
+ console.error('Error deleting environments file:', error)
79
+ return false
80
+ }
85
81
  }
86
82
 
87
83
  export async function readEnvironmentsFile(): Promise<{