spine-framework 0.3.65 → 0.3.67
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.
|
@@ -56,6 +56,8 @@ export function registerInstallAppCommands(program: Command) {
|
|
|
56
56
|
throw new Error(`Package not found at ${pkgPath}`)
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
console.log(` Package path: ${pkgPath}`)
|
|
60
|
+
|
|
59
61
|
// 3. Determine app slug from package manifest or name
|
|
60
62
|
const appSlug = resolveAppSlug(pkgPath, pkgSlug)
|
|
61
63
|
console.log(` App slug: ${appSlug}`)
|
|
@@ -66,11 +68,18 @@ export function registerInstallAppCommands(program: Command) {
|
|
|
66
68
|
mkdirSync(appDest, { recursive: true })
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
// Copy
|
|
70
|
-
const
|
|
71
|
-
|
|
71
|
+
// Copy all allowed directories and files
|
|
72
|
+
const allowedEntries = [
|
|
73
|
+
'index.tsx', 'manifest.json', 'package.json',
|
|
74
|
+
'pages', 'components', 'hooks', 'utils', 'functions', 'seed', 'public'
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
console.log(` Copying files from ${pkgPath} to ${appDest}`)
|
|
78
|
+
|
|
79
|
+
for (const entry of allowedEntries) {
|
|
72
80
|
const src = join(pkgPath, entry)
|
|
73
81
|
if (existsSync(src)) {
|
|
82
|
+
console.log(` Copying ${entry}`)
|
|
74
83
|
cpSync(src, join(appDest, entry), { recursive: true })
|
|
75
84
|
}
|
|
76
85
|
}
|
|
@@ -109,7 +118,8 @@ export function registerInstallAppCommands(program: Command) {
|
|
|
109
118
|
loadEnv()
|
|
110
119
|
|
|
111
120
|
const pkgSlug = packageName.split('@')[0]
|
|
112
|
-
const
|
|
121
|
+
const pkgPath = join(PROJECT_ROOT, 'node_modules', pkgSlug)
|
|
122
|
+
const appSlug = resolveAppSlug(pkgPath, pkgSlug)
|
|
113
123
|
const appDir = join(PROJECT_ROOT, 'custom/apps', appSlug)
|
|
114
124
|
|
|
115
125
|
try {
|
|
@@ -185,7 +195,8 @@ function resolveAppSlug(pkgPath: string, pkgName: string): string {
|
|
|
185
195
|
if (manifest.slug) return manifest.slug
|
|
186
196
|
} catch {}
|
|
187
197
|
// Derive from package name: spine-framework-portal → portal
|
|
188
|
-
|
|
198
|
+
const slug = pkgName.replace(/^spine-framework-/, '')
|
|
199
|
+
return slug || pkgName // fallback to full name if replacement results in empty
|
|
189
200
|
}
|
|
190
201
|
|
|
191
202
|
function loadEnv() {
|
|
@@ -124,17 +124,18 @@ function validateRequiredFiles(appPath: string, manifest: Manifest): void {
|
|
|
124
124
|
function validateAllowedDirectories(appPath: string): void {
|
|
125
125
|
const allowedDirs = [
|
|
126
126
|
'pages', 'components', 'hooks', 'utils', 'functions',
|
|
127
|
-
'seed', 'public'
|
|
127
|
+
'seed', 'public'
|
|
128
128
|
]
|
|
129
129
|
|
|
130
130
|
const entries = readdirSync(appPath, { withFileTypes: true })
|
|
131
131
|
.filter(dirent => dirent.isDirectory())
|
|
132
132
|
.map(dirent => dirent.name)
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
// Filter out .devin/ since it's optional and handled separately
|
|
135
|
+
const unknownDirs = entries.filter(dir => !allowedDirs.includes(dir) && dir !== '.devin')
|
|
135
136
|
|
|
136
137
|
if (unknownDirs.length > 0) {
|
|
137
|
-
throw new ValidationError(`❌ Unknown directories found: ${unknownDirs.join(', ')}. Allowed directories: ${allowedDirs.join(', ')}`)
|
|
138
|
+
throw new ValidationError(`❌ Unknown directories found: ${unknownDirs.join(', ')}. Allowed directories: ${allowedDirs.join(', ')} (plus optional .devin/)`)
|
|
138
139
|
}
|
|
139
140
|
}
|
|
140
141
|
|
|
@@ -162,6 +163,10 @@ function validateDevinDirectory(appPath: string): void {
|
|
|
162
163
|
}
|
|
163
164
|
}
|
|
164
165
|
}
|
|
166
|
+
|
|
167
|
+
console.log(`✅ .devin/ directory valid (if present)`)
|
|
168
|
+
} else {
|
|
169
|
+
console.log(`✅ .devin/ directory not present (optional)`)
|
|
165
170
|
}
|
|
166
171
|
}
|
|
167
172
|
|