reset-framework-cli 1.1.5 → 1.2.1
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/LICENSE +20 -20
- package/README.md +57 -47
- package/package.json +8 -4
- package/src/commands/build.js +125 -113
- package/src/commands/dev.js +156 -144
- package/src/commands/doctor.js +137 -89
- package/src/commands/init.js +822 -822
- package/src/commands/package.js +41 -41
- package/src/index.js +215 -213
- package/src/lib/context.js +66 -66
- package/src/lib/framework.js +126 -39
- package/src/lib/logger.js +11 -11
- package/src/lib/output.js +147 -147
- package/src/lib/process.js +148 -148
- package/src/lib/project.js +759 -468
- package/src/lib/toolchain.js +62 -62
- package/src/lib/ui.js +244 -244
- package/templates/basic/README.md +15 -15
- package/templates/basic/frontend/README.md +73 -73
- package/templates/basic/frontend/eslint.config.js +23 -23
- package/templates/basic/frontend/index.html +13 -13
- package/templates/basic/frontend/package.json +31 -31
- package/templates/basic/frontend/public/icons.svg +24 -24
- package/templates/basic/frontend/src/App.css +216 -216
- package/templates/basic/frontend/src/App.tsx +77 -77
- package/templates/basic/frontend/src/assets/vite.svg +1 -1
- package/templates/basic/frontend/src/index.css +111 -111
- package/templates/basic/frontend/src/lib/reset.ts +1 -1
- package/templates/basic/frontend/src/main.tsx +10 -10
- package/templates/basic/frontend/tsconfig.app.json +28 -28
- package/templates/basic/frontend/tsconfig.json +7 -7
- package/templates/basic/frontend/tsconfig.node.json +26 -26
- package/templates/basic/frontend/vite.config.ts +16 -16
- package/templates/basic/reset.config.json +58 -58
package/src/lib/project.js
CHANGED
|
@@ -1,112 +1,139 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs"
|
|
2
|
-
import { createRequire } from "node:module"
|
|
3
|
-
import path from "node:path"
|
|
4
|
-
import { fileURLToPath } from "node:url"
|
|
5
|
-
|
|
6
|
-
const require = createRequire(import.meta.url)
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs"
|
|
2
|
+
import { createRequire } from "node:module"
|
|
3
|
+
import path from "node:path"
|
|
4
|
+
import { fileURLToPath } from "node:url"
|
|
5
|
+
|
|
6
|
+
const require = createRequire(import.meta.url)
|
|
7
|
+
|
|
8
|
+
const runtimePackageDescriptors = [
|
|
9
|
+
{
|
|
10
|
+
packageName: "@reset-framework/runtime-darwin-arm64",
|
|
11
|
+
workspaceDirName: "runtime-darwin-arm64",
|
|
12
|
+
platform: "darwin",
|
|
13
|
+
arch: "arm64",
|
|
14
|
+
artifactRootSegments: ["dist", "darwin-arm64", "reset-framework.app"],
|
|
15
|
+
binarySegments: ["dist", "darwin-arm64", "reset-framework.app", "Contents", "MacOS", "reset-framework"]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
packageName: "@reset-framework/runtime-darwin-x64",
|
|
19
|
+
workspaceDirName: "runtime-darwin-x64",
|
|
20
|
+
platform: "darwin",
|
|
21
|
+
arch: "x64",
|
|
22
|
+
artifactRootSegments: ["dist", "darwin-x64", "reset-framework.app"],
|
|
23
|
+
binarySegments: ["dist", "darwin-x64", "reset-framework.app", "Contents", "MacOS", "reset-framework"]
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
packageName: "@reset-framework/runtime-win32-x64",
|
|
27
|
+
workspaceDirName: "runtime-win32-x64",
|
|
28
|
+
platform: "win32",
|
|
29
|
+
arch: "x64",
|
|
30
|
+
artifactRootSegments: ["dist", "win32-x64"],
|
|
31
|
+
binarySegments: ["dist", "win32-x64", "reset-framework.exe"]
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
function requireString(object, key, scope) {
|
|
36
|
+
if (typeof object?.[key] !== "string" || object[key].trim() === "") {
|
|
37
|
+
throw new Error(`Missing or invalid string field '${scope}.${key}'`)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return object[key]
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function optionalString(object, key, fallback) {
|
|
44
|
+
if (object == null || !(key in object)) {
|
|
45
|
+
return fallback
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (typeof object[key] !== "string" || object[key].trim() === "") {
|
|
49
|
+
throw new Error(`Missing or invalid string field '${key}'`)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return object[key]
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function optionalObject(object, key) {
|
|
56
|
+
if (object == null || !(key in object)) {
|
|
57
|
+
return {}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (typeof object[key] !== "object" || object[key] === null || Array.isArray(object[key])) {
|
|
61
|
+
throw new Error(`Missing or invalid object field '${key}'`)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return object[key]
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function sanitizeName(value) {
|
|
68
|
+
return value
|
|
69
|
+
.toLowerCase()
|
|
70
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
71
|
+
.replace(/^-+|-+$/g, "") || "reset-app"
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function normalizeFrontendDir(value) {
|
|
75
|
+
const trimmed = value.trim()
|
|
76
|
+
|
|
77
|
+
if (trimmed === "." || trimmed === "./") {
|
|
78
|
+
return "."
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (path.isAbsolute(trimmed)) {
|
|
82
|
+
throw new Error("project.frontendDir must be a relative path")
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const normalized = path.normalize(trimmed).replace(/\\/g, "/").replace(/\/+$/g, "")
|
|
86
|
+
|
|
87
|
+
if (normalized === "" || normalized === ".") {
|
|
88
|
+
return "."
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (normalized.startsWith("../")) {
|
|
92
|
+
throw new Error("project.frontendDir cannot point outside the app root")
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return normalized
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function normalizeStyling(value) {
|
|
99
|
+
if (value === "css" || value === "tailwindcss") {
|
|
100
|
+
return value
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
throw new Error("project.styling must be either 'css' or 'tailwindcss'")
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function normalizeProtocolScheme(value) {
|
|
107
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
108
|
+
throw new Error("protocols.schemes[].scheme must be a non-empty string")
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const normalized = value.trim().toLowerCase()
|
|
112
|
+
if (!/^[a-z][a-z0-9+.-]*$/.test(normalized)) {
|
|
113
|
+
throw new Error(
|
|
114
|
+
"protocols.schemes[].scheme must start with a letter and only contain letters, numbers, '+', '-', and '.'"
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return normalized
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function normalizeProtocolRole(value) {
|
|
122
|
+
if (value === "Editor" || value === "Viewer" || value === "Shell" || value === "None") {
|
|
123
|
+
return value
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
throw new Error("protocols.schemes[].role must be one of Editor, Viewer, Shell, None")
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function toTitleCase(value) {
|
|
130
|
+
return value
|
|
131
|
+
.split(/[^a-zA-Z0-9]+/)
|
|
132
|
+
.filter(Boolean)
|
|
133
|
+
.map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
|
|
134
|
+
.join(" ") || "Reset App"
|
|
135
|
+
}
|
|
136
|
+
|
|
110
137
|
function readJsonFile(filePath) {
|
|
111
138
|
return JSON.parse(readFileSync(filePath, "utf8"))
|
|
112
139
|
}
|
|
@@ -122,105 +149,219 @@ function getFrameworkBuildType(mode) {
|
|
|
122
149
|
function resolveExistingCandidate(candidates) {
|
|
123
150
|
return candidates.find((candidate) => existsSync(candidate)) ?? null
|
|
124
151
|
}
|
|
125
|
-
|
|
126
|
-
function isPathInside(parentDir, candidatePath) {
|
|
127
|
-
const relative = path.relative(parentDir, candidatePath)
|
|
128
|
-
return relative !== "" && !relative.startsWith("..") && !path.isAbsolute(relative)
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function resolvePackageInfo(packageName, fallbackRoot) {
|
|
132
|
-
try {
|
|
133
|
-
const packageJsonPath = require.resolve(`${packageName}/package.json`)
|
|
134
|
-
const packageRoot = path.dirname(packageJsonPath)
|
|
135
|
-
const manifest = readJsonFile(packageJsonPath)
|
|
136
|
-
|
|
137
|
-
return {
|
|
138
|
-
packageName: manifest.name ?? packageName,
|
|
139
|
-
packageRoot,
|
|
140
|
-
packageJsonPath,
|
|
141
|
-
version: manifest.version ?? "0.0.0",
|
|
142
|
-
localFallback: false
|
|
143
|
-
}
|
|
144
|
-
} catch {
|
|
145
|
-
const packageJsonPath = path.join(fallbackRoot, "package.json")
|
|
146
|
-
const manifest = readJsonFile(packageJsonPath)
|
|
147
|
-
|
|
148
|
-
return {
|
|
149
|
-
packageName: manifest.name ?? packageName,
|
|
150
|
-
packageRoot: fallbackRoot,
|
|
151
|
-
packageJsonPath,
|
|
152
|
-
version: manifest.version ?? "0.0.0",
|
|
153
|
-
localFallback: true
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function resolveWorkspacePackageInfo(packageName, workspaceRoot, fallbackInfo) {
|
|
159
|
-
const packageJsonPath = path.join(workspaceRoot, "package.json")
|
|
160
|
-
|
|
161
|
-
if (!existsSync(packageJsonPath)) {
|
|
162
|
-
return fallbackInfo
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const manifest = readJsonFile(packageJsonPath)
|
|
166
|
-
|
|
167
|
-
return {
|
|
168
|
-
packageName: manifest.name ?? packageName,
|
|
169
|
-
packageRoot: workspaceRoot,
|
|
170
|
-
packageJsonPath,
|
|
171
|
-
version: manifest.version ?? fallbackInfo.version,
|
|
172
|
-
localFallback: true
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
152
|
+
|
|
153
|
+
function isPathInside(parentDir, candidatePath) {
|
|
154
|
+
const relative = path.relative(parentDir, candidatePath)
|
|
155
|
+
return relative !== "" && !relative.startsWith("..") && !path.isAbsolute(relative)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function resolvePackageInfo(packageName, fallbackRoot) {
|
|
159
|
+
try {
|
|
160
|
+
const packageJsonPath = require.resolve(`${packageName}/package.json`)
|
|
161
|
+
const packageRoot = path.dirname(packageJsonPath)
|
|
162
|
+
const manifest = readJsonFile(packageJsonPath)
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
packageName: manifest.name ?? packageName,
|
|
166
|
+
packageRoot,
|
|
167
|
+
packageJsonPath,
|
|
168
|
+
version: manifest.version ?? "0.0.0",
|
|
169
|
+
localFallback: false
|
|
170
|
+
}
|
|
171
|
+
} catch {
|
|
172
|
+
const packageJsonPath = path.join(fallbackRoot, "package.json")
|
|
173
|
+
const manifest = readJsonFile(packageJsonPath)
|
|
174
|
+
|
|
175
|
+
return {
|
|
176
|
+
packageName: manifest.name ?? packageName,
|
|
177
|
+
packageRoot: fallbackRoot,
|
|
178
|
+
packageJsonPath,
|
|
179
|
+
version: manifest.version ?? "0.0.0",
|
|
180
|
+
localFallback: true
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function resolveWorkspacePackageInfo(packageName, workspaceRoot, fallbackInfo) {
|
|
186
|
+
const packageJsonPath = path.join(workspaceRoot, "package.json")
|
|
187
|
+
|
|
188
|
+
if (!existsSync(packageJsonPath)) {
|
|
189
|
+
return fallbackInfo
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const manifest = readJsonFile(packageJsonPath)
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
packageName: manifest.name ?? packageName,
|
|
196
|
+
packageRoot: workspaceRoot,
|
|
197
|
+
packageJsonPath,
|
|
198
|
+
version: manifest.version ?? fallbackInfo.version,
|
|
199
|
+
localFallback: true
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function resolveOptionalPackageInfo(packageName, fallbackRoot) {
|
|
204
|
+
try {
|
|
205
|
+
const packageJsonPath = require.resolve(`${packageName}/package.json`)
|
|
206
|
+
const packageRoot = path.dirname(packageJsonPath)
|
|
207
|
+
const manifest = readJsonFile(packageJsonPath)
|
|
208
|
+
|
|
209
|
+
return {
|
|
210
|
+
packageName: manifest.name ?? packageName,
|
|
211
|
+
packageRoot,
|
|
212
|
+
packageJsonPath,
|
|
213
|
+
version: manifest.version ?? "0.0.0",
|
|
214
|
+
localFallback: false
|
|
215
|
+
}
|
|
216
|
+
} catch {
|
|
217
|
+
const packageJsonPath = path.join(fallbackRoot, "package.json")
|
|
218
|
+
|
|
219
|
+
if (!existsSync(packageJsonPath)) {
|
|
220
|
+
return null
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const manifest = readJsonFile(packageJsonPath)
|
|
224
|
+
|
|
225
|
+
return {
|
|
226
|
+
packageName: manifest.name ?? packageName,
|
|
227
|
+
packageRoot: fallbackRoot,
|
|
228
|
+
packageJsonPath,
|
|
229
|
+
version: manifest.version ?? "0.0.0",
|
|
230
|
+
localFallback: true
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function resolveOptionalWorkspacePackageInfo(packageName, workspaceRoot, fallbackInfo) {
|
|
236
|
+
const packageJsonPath = path.join(workspaceRoot, "package.json")
|
|
237
|
+
|
|
238
|
+
if (!existsSync(packageJsonPath)) {
|
|
239
|
+
return fallbackInfo
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const manifest = readJsonFile(packageJsonPath)
|
|
243
|
+
const version = fallbackInfo?.version ?? manifest.version ?? "0.0.0"
|
|
244
|
+
|
|
245
|
+
return {
|
|
246
|
+
packageName: manifest.name ?? packageName,
|
|
247
|
+
packageRoot: workspaceRoot,
|
|
248
|
+
packageJsonPath,
|
|
249
|
+
version,
|
|
250
|
+
localFallback: true
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function resolveCurrentRuntimeDescriptor() {
|
|
255
|
+
return runtimePackageDescriptors.find(
|
|
256
|
+
(descriptor) =>
|
|
257
|
+
descriptor.platform === process.platform &&
|
|
258
|
+
descriptor.arch === process.arch
|
|
259
|
+
) ?? null
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function resolveRuntimePackage(packagesDir) {
|
|
263
|
+
const descriptor = resolveCurrentRuntimeDescriptor()
|
|
264
|
+
|
|
265
|
+
if (!descriptor) {
|
|
266
|
+
return null
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const workspaceRoot = path.join(packagesDir, descriptor.workspaceDirName)
|
|
270
|
+
const packageInfo = resolveOptionalWorkspacePackageInfo(
|
|
271
|
+
descriptor.packageName,
|
|
272
|
+
workspaceRoot,
|
|
273
|
+
resolveOptionalPackageInfo(descriptor.packageName, workspaceRoot)
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
return {
|
|
277
|
+
descriptor,
|
|
278
|
+
packageInfo,
|
|
279
|
+
artifactRoot: packageInfo ? path.join(packageInfo.packageRoot, ...descriptor.artifactRootSegments) : null,
|
|
280
|
+
binaryPath: packageInfo ? path.join(packageInfo.packageRoot, ...descriptor.binarySegments) : null
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function hasSourceRuntimeLayout(frameworkPaths) {
|
|
285
|
+
return Boolean(
|
|
286
|
+
frameworkPaths.frameworkPackage &&
|
|
287
|
+
frameworkPaths.frameworkRoot &&
|
|
288
|
+
frameworkPaths.runtimeDir &&
|
|
289
|
+
frameworkPaths.rootCMakePath &&
|
|
290
|
+
frameworkPaths.vcpkgManifestPath &&
|
|
291
|
+
existsSync(frameworkPaths.frameworkPackage.packageJsonPath) &&
|
|
292
|
+
existsSync(frameworkPaths.frameworkRoot) &&
|
|
293
|
+
existsSync(frameworkPaths.runtimeDir) &&
|
|
294
|
+
existsSync(frameworkPaths.rootCMakePath) &&
|
|
295
|
+
existsSync(frameworkPaths.vcpkgManifestPath)
|
|
296
|
+
)
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function isSourceRuntimeRequested(options = {}) {
|
|
300
|
+
if (options.preferSource === true) {
|
|
301
|
+
return true
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const raw = process.env.RESET_FRAMEWORK_RUNTIME_SOURCE
|
|
305
|
+
if (typeof raw !== "string") {
|
|
306
|
+
return false
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return ["1", "true", "yes", "on", "source"].includes(raw.trim().toLowerCase())
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export function resolveFrameworkPaths() {
|
|
313
|
+
const moduleDir = path.dirname(fileURLToPath(import.meta.url))
|
|
314
|
+
const cliDir = path.resolve(moduleDir, "../..")
|
|
315
|
+
const packagesDir = path.resolve(cliDir, "..")
|
|
316
|
+
const isWorkspacePackagesDir = path.basename(packagesDir) === "packages"
|
|
317
|
+
const cliPackageJsonPath = path.join(cliDir, "package.json")
|
|
318
|
+
const cliManifest = readJsonFile(cliPackageJsonPath)
|
|
319
|
+
const nativePackage = resolveOptionalWorkspacePackageInfo(
|
|
320
|
+
"@reset-framework/native",
|
|
321
|
+
path.join(packagesDir, "native"),
|
|
322
|
+
resolveOptionalPackageInfo("@reset-framework/native", path.join(packagesDir, "native"))
|
|
323
|
+
)
|
|
324
|
+
const sdkPackage = resolveWorkspacePackageInfo(
|
|
325
|
+
"@reset-framework/sdk",
|
|
326
|
+
path.join(packagesDir, "sdk"),
|
|
327
|
+
resolvePackageInfo("@reset-framework/sdk", path.join(packagesDir, "sdk"))
|
|
328
|
+
)
|
|
329
|
+
const schemaPackage = resolveWorkspacePackageInfo(
|
|
330
|
+
"@reset-framework/schema",
|
|
331
|
+
path.join(packagesDir, "schema"),
|
|
332
|
+
resolvePackageInfo("@reset-framework/schema", path.join(packagesDir, "schema"))
|
|
333
|
+
)
|
|
334
|
+
const runtimePackage = resolveRuntimePackage(packagesDir)
|
|
335
|
+
const isWorkspaceLayout =
|
|
336
|
+
isWorkspacePackagesDir &&
|
|
337
|
+
[cliDir, sdkPackage.packageRoot, schemaPackage.packageRoot].every((packageRoot) =>
|
|
338
|
+
isPathInside(packagesDir, packageRoot)
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
return {
|
|
342
|
+
cliDir,
|
|
343
|
+
cliPackage: {
|
|
344
|
+
packageName: cliManifest.name,
|
|
345
|
+
packageRoot: cliDir,
|
|
346
|
+
packageJsonPath: cliPackageJsonPath,
|
|
347
|
+
version: cliManifest.version ?? "0.0.0",
|
|
348
|
+
localFallback: isWorkspaceLayout
|
|
349
|
+
},
|
|
350
|
+
packagesDir,
|
|
351
|
+
frameworkRoot: nativePackage?.packageRoot ?? null,
|
|
352
|
+
frameworkPackage: nativePackage,
|
|
353
|
+
isWorkspaceLayout,
|
|
354
|
+
sdkPackage,
|
|
355
|
+
schemaPackage,
|
|
356
|
+
runtimePackage,
|
|
357
|
+
runtimeDir: nativePackage ? path.join(nativePackage.packageRoot, "runtime") : null,
|
|
358
|
+
rootCMakePath: nativePackage ? path.join(nativePackage.packageRoot, "CMakeLists.txt") : null,
|
|
359
|
+
cmakePresetsPath: nativePackage ? path.join(nativePackage.packageRoot, "CMakePresets.json") : null,
|
|
360
|
+
vcpkgManifestPath: nativePackage ? path.join(nativePackage.packageRoot, "vcpkg.json") : null,
|
|
361
|
+
templatesDir: path.join(cliDir, "templates")
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
224
365
|
export function resolveFrameworkBuildPaths(appPaths) {
|
|
225
366
|
const frameworkCacheRoot = path.join(appPaths.appRoot, ".reset", "framework")
|
|
226
367
|
const isWindows = process.platform === "win32"
|
|
@@ -275,8 +416,83 @@ export function resolveFrameworkBuildPaths(appPaths) {
|
|
|
275
416
|
}
|
|
276
417
|
}
|
|
277
418
|
|
|
278
|
-
export function
|
|
419
|
+
export function resolveFrameworkRuntimeStrategy(frameworkPaths, options = {}) {
|
|
420
|
+
const sourceRequested = isSourceRuntimeRequested(options)
|
|
421
|
+
const runtimePackage = frameworkPaths.runtimePackage
|
|
422
|
+
const hasPrebuiltRuntime =
|
|
423
|
+
Boolean(runtimePackage?.packageInfo) &&
|
|
424
|
+
Boolean(runtimePackage?.artifactRoot) &&
|
|
425
|
+
Boolean(runtimePackage?.binaryPath) &&
|
|
426
|
+
existsSync(runtimePackage.artifactRoot) &&
|
|
427
|
+
existsSync(runtimePackage.binaryPath)
|
|
428
|
+
const hasSourceRuntime = hasSourceRuntimeLayout(frameworkPaths)
|
|
429
|
+
|
|
430
|
+
if (sourceRequested) {
|
|
431
|
+
if (!hasSourceRuntime) {
|
|
432
|
+
throw new Error(
|
|
433
|
+
"Source runtime was requested, but @reset-framework/native is not installed in this CLI environment."
|
|
434
|
+
)
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
return {
|
|
438
|
+
kind: "source",
|
|
439
|
+
packageInfo: frameworkPaths.frameworkPackage,
|
|
440
|
+
label: `${frameworkPaths.frameworkPackage.packageName}@${frameworkPaths.frameworkPackage.version}`
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (hasPrebuiltRuntime) {
|
|
445
|
+
return {
|
|
446
|
+
kind: "prebuilt",
|
|
447
|
+
packageInfo: runtimePackage.packageInfo,
|
|
448
|
+
descriptor: runtimePackage.descriptor,
|
|
449
|
+
artifactRoot: runtimePackage.artifactRoot,
|
|
450
|
+
binaryPath: runtimePackage.binaryPath,
|
|
451
|
+
label: `${runtimePackage.packageInfo.packageName}@${runtimePackage.packageInfo.version}`
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
if (hasSourceRuntime) {
|
|
456
|
+
return {
|
|
457
|
+
kind: "source",
|
|
458
|
+
packageInfo: frameworkPaths.frameworkPackage,
|
|
459
|
+
label: `${frameworkPaths.frameworkPackage.packageName}@${frameworkPaths.frameworkPackage.version}`
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
if (runtimePackage?.packageInfo) {
|
|
464
|
+
throw new Error(
|
|
465
|
+
`Installed runtime package ${runtimePackage.packageInfo.packageName} is missing bundled runtime artifacts under ${runtimePackage.artifactRoot}.`
|
|
466
|
+
)
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
if (runtimePackage?.descriptor) {
|
|
470
|
+
throw new Error(
|
|
471
|
+
`No bundled runtime package is installed for ${process.platform}-${process.arch}. Expected ${runtimePackage.descriptor.packageName}.`
|
|
472
|
+
)
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
throw new Error(
|
|
476
|
+
`Reset Framework does not currently provide a bundled runtime for ${process.platform}-${process.arch}.`
|
|
477
|
+
)
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
export function resolveFrameworkRuntimeBinary(frameworkPaths, frameworkBuildPaths, mode, options = {}) {
|
|
279
481
|
const { mustExist = false } = options
|
|
482
|
+
const strategy = options.strategy ?? resolveFrameworkRuntimeStrategy(frameworkPaths, options)
|
|
483
|
+
|
|
484
|
+
if (strategy.kind === "prebuilt") {
|
|
485
|
+
if (existsSync(strategy.binaryPath)) {
|
|
486
|
+
return strategy.binaryPath
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
if (mustExist) {
|
|
490
|
+
throw new Error(`Missing bundled runtime executable at ${strategy.binaryPath}.`)
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
return strategy.binaryPath
|
|
494
|
+
}
|
|
495
|
+
|
|
280
496
|
const candidates =
|
|
281
497
|
mode === "release"
|
|
282
498
|
? (frameworkBuildPaths.releaseAppBinaryCandidates ?? [frameworkBuildPaths.releaseAppTemplate])
|
|
@@ -294,8 +510,22 @@ export function resolveFrameworkRuntimeBinary(frameworkBuildPaths, mode, options
|
|
|
294
510
|
return candidates[0]
|
|
295
511
|
}
|
|
296
512
|
|
|
297
|
-
export function resolveFrameworkRuntimeOutputDir(frameworkBuildPaths, mode, options = {}) {
|
|
513
|
+
export function resolveFrameworkRuntimeOutputDir(frameworkPaths, frameworkBuildPaths, mode, options = {}) {
|
|
298
514
|
const { mustExist = false } = options
|
|
515
|
+
const strategy = options.strategy ?? resolveFrameworkRuntimeStrategy(frameworkPaths, options)
|
|
516
|
+
|
|
517
|
+
if (strategy.kind === "prebuilt") {
|
|
518
|
+
if (existsSync(strategy.artifactRoot)) {
|
|
519
|
+
return strategy.artifactRoot
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
if (mustExist) {
|
|
523
|
+
throw new Error(`Missing bundled runtime output directory at ${strategy.artifactRoot}.`)
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
return strategy.artifactRoot
|
|
527
|
+
}
|
|
528
|
+
|
|
299
529
|
const candidates =
|
|
300
530
|
mode === "release"
|
|
301
531
|
? (frameworkBuildPaths.releaseRuntimeOutputCandidates ?? [])
|
|
@@ -314,163 +544,224 @@ export function resolveFrameworkRuntimeOutputDir(frameworkBuildPaths, mode, opti
|
|
|
314
544
|
return candidates[0]
|
|
315
545
|
}
|
|
316
546
|
|
|
317
|
-
return path.dirname(resolveFrameworkRuntimeBinary(frameworkBuildPaths, mode, options))
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
export function resolveAppPaths(appRoot) {
|
|
321
|
-
return {
|
|
322
|
-
appRoot,
|
|
323
|
-
appPackageJsonPath: path.join(appRoot, "package.json"),
|
|
324
|
-
frontendDir: path.join(appRoot, "frontend"),
|
|
325
|
-
resetConfigPath: path.join(appRoot, "reset.config.json"),
|
|
326
|
-
legacyResetConfigPath: path.join(appRoot, "frontend", "reset.config.json")
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
export function resolveConfigPath(appPaths) {
|
|
331
|
-
if (existsSync(appPaths.resetConfigPath)) {
|
|
332
|
-
return appPaths.resetConfigPath
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
if (existsSync(appPaths.legacyResetConfigPath)) {
|
|
336
|
-
return appPaths.legacyResetConfigPath
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
return appPaths.resetConfigPath
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
export function getFrameworkChecks(frameworkPaths) {
|
|
343
|
-
return [
|
|
344
|
-
["
|
|
345
|
-
["
|
|
346
|
-
["
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
]
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
.
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
export function
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
}
|
|
473
|
-
|
|
547
|
+
return path.dirname(resolveFrameworkRuntimeBinary(frameworkPaths, frameworkBuildPaths, mode, options))
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
export function resolveAppPaths(appRoot) {
|
|
551
|
+
return {
|
|
552
|
+
appRoot,
|
|
553
|
+
appPackageJsonPath: path.join(appRoot, "package.json"),
|
|
554
|
+
frontendDir: path.join(appRoot, "frontend"),
|
|
555
|
+
resetConfigPath: path.join(appRoot, "reset.config.json"),
|
|
556
|
+
legacyResetConfigPath: path.join(appRoot, "frontend", "reset.config.json")
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
export function resolveConfigPath(appPaths) {
|
|
561
|
+
if (existsSync(appPaths.resetConfigPath)) {
|
|
562
|
+
return appPaths.resetConfigPath
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
if (existsSync(appPaths.legacyResetConfigPath)) {
|
|
566
|
+
return appPaths.legacyResetConfigPath
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
return appPaths.resetConfigPath
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
export function getFrameworkChecks(frameworkPaths) {
|
|
573
|
+
return [
|
|
574
|
+
["sdk", frameworkPaths.sdkPackage.packageJsonPath],
|
|
575
|
+
["schema", frameworkPaths.schemaPackage.packageJsonPath],
|
|
576
|
+
["templates", frameworkPaths.templatesDir]
|
|
577
|
+
]
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
export function getFrameworkRuntimeChecks(frameworkPaths) {
|
|
581
|
+
const checks = []
|
|
582
|
+
|
|
583
|
+
if (frameworkPaths.runtimePackage?.packageInfo) {
|
|
584
|
+
checks.push(["runtime package", frameworkPaths.runtimePackage.packageInfo.packageJsonPath])
|
|
585
|
+
if (frameworkPaths.runtimePackage.artifactRoot) {
|
|
586
|
+
checks.push(["runtime artifact", frameworkPaths.runtimePackage.artifactRoot])
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
if (frameworkPaths.frameworkPackage) {
|
|
591
|
+
checks.push(["native source", frameworkPaths.frameworkPackage.packageJsonPath])
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
if (frameworkPaths.rootCMakePath) {
|
|
595
|
+
checks.push(["cmake", frameworkPaths.rootCMakePath])
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
if (frameworkPaths.runtimeDir) {
|
|
599
|
+
checks.push(["runtime source", frameworkPaths.runtimeDir])
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
if (frameworkPaths.vcpkgManifestPath) {
|
|
603
|
+
checks.push(["vcpkg", frameworkPaths.vcpkgManifestPath])
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
return checks
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
export function getFrameworkRuntimeModeSummary(frameworkPaths, options = {}) {
|
|
610
|
+
const strategy = resolveFrameworkRuntimeStrategy(frameworkPaths, options)
|
|
611
|
+
|
|
612
|
+
return {
|
|
613
|
+
kind: strategy.kind,
|
|
614
|
+
label: strategy.label
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
export function hasFrameworkSourcePackage(frameworkPaths) {
|
|
619
|
+
return hasSourceRuntimeLayout(frameworkPaths)
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
export function isFrameworkSourceRequested(options = {}) {
|
|
623
|
+
return isSourceRuntimeRequested(options)
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
export function assertFrameworkInstall(frameworkPaths) {
|
|
627
|
+
const missing = getFrameworkChecks(frameworkPaths)
|
|
628
|
+
.filter(([, filePath]) => !existsSync(filePath))
|
|
629
|
+
.map(([label]) => label)
|
|
630
|
+
|
|
631
|
+
if (missing.length > 0) {
|
|
632
|
+
throw new Error(
|
|
633
|
+
`Reset CLI installation is incomplete. Missing: ${missing.join(", ")}`
|
|
634
|
+
)
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
export function assertFrameworkSourceInstall(frameworkPaths) {
|
|
639
|
+
const missing = [
|
|
640
|
+
["native source", frameworkPaths.frameworkPackage?.packageJsonPath],
|
|
641
|
+
["sdk", frameworkPaths.sdkPackage.packageJsonPath],
|
|
642
|
+
["cmake", frameworkPaths.rootCMakePath],
|
|
643
|
+
["runtime", frameworkPaths.runtimeDir],
|
|
644
|
+
["vcpkg", frameworkPaths.vcpkgManifestPath],
|
|
645
|
+
["templates", frameworkPaths.templatesDir]
|
|
646
|
+
]
|
|
647
|
+
.filter(([, filePath]) => !filePath || !existsSync(filePath))
|
|
648
|
+
.map(([label]) => label)
|
|
649
|
+
|
|
650
|
+
if (missing.length > 0) {
|
|
651
|
+
throw new Error(
|
|
652
|
+
`Source runtime is unavailable in this CLI installation. Missing: ${missing.join(", ")}`
|
|
653
|
+
)
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
export function getAppChecks(appPaths) {
|
|
658
|
+
return [["config", resolveConfigPath(appPaths)]]
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
export function assertAppProject(appPaths, config) {
|
|
662
|
+
const checks = [...getAppChecks(appPaths)]
|
|
663
|
+
|
|
664
|
+
if (config) {
|
|
665
|
+
checks.unshift(["frontend", resolveFrontendDir(appPaths, config)])
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
const missing = checks
|
|
669
|
+
.filter(([, filePath]) => !existsSync(filePath))
|
|
670
|
+
.map(([label]) => label)
|
|
671
|
+
|
|
672
|
+
if (missing.length > 0) {
|
|
673
|
+
throw new Error(
|
|
674
|
+
`Current directory does not look like a Reset app. Missing: ${missing.join(", ")}`
|
|
675
|
+
)
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
export function validateResetConfig(rawConfig) {
|
|
680
|
+
const frontend = optionalObject(rawConfig, "frontend")
|
|
681
|
+
const build = optionalObject(rawConfig, "build")
|
|
682
|
+
const project = optionalObject(rawConfig, "project")
|
|
683
|
+
const security = optionalObject(rawConfig, "security")
|
|
684
|
+
const protocols = optionalObject(rawConfig, "protocols")
|
|
685
|
+
const windowConfig = optionalObject(rawConfig, "window")
|
|
686
|
+
const rawProtocolSchemes = Array.isArray(protocols.schemes) ? protocols.schemes : []
|
|
687
|
+
const seenProtocolSchemes = new Set()
|
|
688
|
+
|
|
689
|
+
return {
|
|
690
|
+
...rawConfig,
|
|
691
|
+
name: sanitizeName(requireString(rawConfig, "name", "config")),
|
|
692
|
+
productName: requireString(rawConfig, "productName", "config"),
|
|
693
|
+
appId: requireString(rawConfig, "appId", "config"),
|
|
694
|
+
version: requireString(rawConfig, "version", "config"),
|
|
695
|
+
window: {
|
|
696
|
+
title: optionalString(windowConfig, "title", "Reset App")
|
|
697
|
+
},
|
|
698
|
+
frontend: {
|
|
699
|
+
devUrl: requireString(frontend, "devUrl", "frontend"),
|
|
700
|
+
distDir: optionalString(frontend, "distDir", "dist"),
|
|
701
|
+
entryHtml: optionalString(frontend, "entryHtml", "index.html")
|
|
702
|
+
},
|
|
703
|
+
project: {
|
|
704
|
+
frontendDir: normalizeFrontendDir(optionalString(project, "frontendDir", "frontend")),
|
|
705
|
+
styling: normalizeStyling(optionalString(project, "styling", "css"))
|
|
706
|
+
},
|
|
707
|
+
build: {
|
|
708
|
+
outputDir: optionalString(build, "outputDir", ".reset/build")
|
|
709
|
+
},
|
|
710
|
+
security: {
|
|
711
|
+
permissions: Array.isArray(security.permissions)
|
|
712
|
+
? security.permissions.map((value) => {
|
|
713
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
714
|
+
throw new Error("Missing or invalid string field 'security.permissions'")
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
return value
|
|
718
|
+
})
|
|
719
|
+
: []
|
|
720
|
+
},
|
|
721
|
+
protocols: {
|
|
722
|
+
schemes: rawProtocolSchemes.map((entry) => {
|
|
723
|
+
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
|
|
724
|
+
throw new Error("protocols.schemes entries must be objects")
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
const scheme = normalizeProtocolScheme(entry.scheme)
|
|
728
|
+
if (seenProtocolSchemes.has(scheme)) {
|
|
729
|
+
throw new Error(`Duplicate protocol scheme '${scheme}'`)
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
seenProtocolSchemes.add(scheme)
|
|
733
|
+
|
|
734
|
+
return {
|
|
735
|
+
scheme,
|
|
736
|
+
name:
|
|
737
|
+
typeof entry.name === "string" && entry.name.trim() !== ""
|
|
738
|
+
? entry.name
|
|
739
|
+
: scheme,
|
|
740
|
+
role:
|
|
741
|
+
entry.role === undefined
|
|
742
|
+
? "Viewer"
|
|
743
|
+
: normalizeProtocolRole(entry.role)
|
|
744
|
+
}
|
|
745
|
+
})
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
export function loadResetConfig(appPaths) {
|
|
751
|
+
const configPath = resolveConfigPath(appPaths)
|
|
752
|
+
const raw = readFileSync(configPath, "utf8")
|
|
753
|
+
|
|
754
|
+
try {
|
|
755
|
+
return validateResetConfig(JSON.parse(raw))
|
|
756
|
+
} catch (error) {
|
|
757
|
+
if (error instanceof SyntaxError) {
|
|
758
|
+
throw new Error(`Invalid JSON in ${configPath}: ${error.message}`)
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
throw error
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
|
|
474
765
|
export function resolveAppOutputPaths(appPaths, config) {
|
|
475
766
|
const outputRoot = path.resolve(appPaths.appRoot, config.build.outputDir)
|
|
476
767
|
const frontendDir = resolveFrontendDir(appPaths, config)
|
|
@@ -496,109 +787,109 @@ export function resolveAppOutputPaths(appPaths, config) {
|
|
|
496
787
|
bundledFrontendDir: path.join(resourcesDir, config.frontend.distDir),
|
|
497
788
|
frontendDistDir: path.resolve(frontendDir, config.frontend.distDir),
|
|
498
789
|
frontendEntryFile: path.resolve(
|
|
499
|
-
frontendDir,
|
|
500
|
-
config.frontend.distDir,
|
|
501
|
-
config.frontend.entryHtml
|
|
790
|
+
frontendDir,
|
|
791
|
+
config.frontend.distDir,
|
|
792
|
+
config.frontend.entryHtml
|
|
502
793
|
),
|
|
503
794
|
packagesDir,
|
|
504
795
|
zipPath: path.join(packagesDir, `${config.name}-${isWindows ? "windows" : "macos"}.zip`)
|
|
505
796
|
}
|
|
506
797
|
}
|
|
507
|
-
|
|
508
|
-
export function resolveFrontendDir(appPaths, config) {
|
|
509
|
-
return path.resolve(appPaths.appRoot, config.project.frontendDir)
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
export function resolveDevServerOptions(config) {
|
|
513
|
-
const url = new URL(config.frontend.devUrl)
|
|
514
|
-
|
|
515
|
-
return {
|
|
516
|
-
host: url.hostname,
|
|
517
|
-
port: url.port || "5173",
|
|
518
|
-
url: url.toString()
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
export function makeAppMetadata(appName) {
|
|
523
|
-
const name = sanitizeName(appName)
|
|
524
|
-
const productName = toTitleCase(appName)
|
|
525
|
-
|
|
526
|
-
return {
|
|
527
|
-
name,
|
|
528
|
-
productName,
|
|
529
|
-
appId: `com.example.${name}`,
|
|
530
|
-
title: productName
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
export function resolveSdkDependencySpec(frameworkPaths) {
|
|
535
|
-
if (frameworkPaths.isWorkspaceLayout || frameworkPaths.sdkPackage.localFallback) {
|
|
536
|
-
return `file:${frameworkPaths.sdkPackage.packageRoot}`
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
return `^${frameworkPaths.sdkPackage.version}`
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
export function resolveCliDependencySpec(frameworkPaths) {
|
|
543
|
-
if (frameworkPaths.isWorkspaceLayout || frameworkPaths.cliPackage.localFallback) {
|
|
544
|
-
return `file:${frameworkPaths.cliPackage.packageRoot}`
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
return `^${frameworkPaths.cliPackage.version}`
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
function detectPackageManagerFromManifest(packageJsonPath) {
|
|
551
|
-
if (!fileExists(packageJsonPath)) {
|
|
552
|
-
return null
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
const manifest = readJsonFile(packageJsonPath)
|
|
556
|
-
const raw = typeof manifest.packageManager === "string" ? manifest.packageManager.trim() : ""
|
|
557
|
-
if (raw === "") {
|
|
558
|
-
return null
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
const [name] = raw.split("@")
|
|
562
|
-
if (name === "npm" || name === "pnpm" || name === "yarn" || name === "bun") {
|
|
563
|
-
return name
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
return null
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
function detectPackageManagerFromLocks(directory) {
|
|
570
|
-
if (!fileExists(directory)) {
|
|
571
|
-
return null
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
if (fileExists(path.join(directory, "bun.lock")) || fileExists(path.join(directory, "bun.lockb"))) {
|
|
575
|
-
return "bun"
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
if (fileExists(path.join(directory, "pnpm-lock.yaml"))) {
|
|
579
|
-
return "pnpm"
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
if (fileExists(path.join(directory, "yarn.lock"))) {
|
|
583
|
-
return "yarn"
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
if (fileExists(path.join(directory, "package-lock.json"))) {
|
|
587
|
-
return "npm"
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
return null
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
export function resolveAppPackageManager(appPaths, config) {
|
|
594
|
-
const frontendDir = resolveFrontendDir(appPaths, config)
|
|
595
|
-
const frontendPackageJsonPath = path.join(frontendDir, "package.json")
|
|
596
|
-
|
|
597
|
-
return (
|
|
598
|
-
detectPackageManagerFromManifest(appPaths.appPackageJsonPath) ??
|
|
599
|
-
detectPackageManagerFromManifest(frontendPackageJsonPath) ??
|
|
600
|
-
detectPackageManagerFromLocks(appPaths.appRoot) ??
|
|
601
|
-
detectPackageManagerFromLocks(frontendDir) ??
|
|
602
|
-
"npm"
|
|
603
|
-
)
|
|
604
|
-
}
|
|
798
|
+
|
|
799
|
+
export function resolveFrontendDir(appPaths, config) {
|
|
800
|
+
return path.resolve(appPaths.appRoot, config.project.frontendDir)
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
export function resolveDevServerOptions(config) {
|
|
804
|
+
const url = new URL(config.frontend.devUrl)
|
|
805
|
+
|
|
806
|
+
return {
|
|
807
|
+
host: url.hostname,
|
|
808
|
+
port: url.port || "5173",
|
|
809
|
+
url: url.toString()
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
export function makeAppMetadata(appName) {
|
|
814
|
+
const name = sanitizeName(appName)
|
|
815
|
+
const productName = toTitleCase(appName)
|
|
816
|
+
|
|
817
|
+
return {
|
|
818
|
+
name,
|
|
819
|
+
productName,
|
|
820
|
+
appId: `com.example.${name}`,
|
|
821
|
+
title: productName
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
export function resolveSdkDependencySpec(frameworkPaths) {
|
|
826
|
+
if (frameworkPaths.isWorkspaceLayout || frameworkPaths.sdkPackage.localFallback) {
|
|
827
|
+
return `file:${frameworkPaths.sdkPackage.packageRoot}`
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
return `^${frameworkPaths.sdkPackage.version}`
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
export function resolveCliDependencySpec(frameworkPaths) {
|
|
834
|
+
if (frameworkPaths.isWorkspaceLayout || frameworkPaths.cliPackage.localFallback) {
|
|
835
|
+
return `file:${frameworkPaths.cliPackage.packageRoot}`
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
return `^${frameworkPaths.cliPackage.version}`
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
function detectPackageManagerFromManifest(packageJsonPath) {
|
|
842
|
+
if (!fileExists(packageJsonPath)) {
|
|
843
|
+
return null
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
const manifest = readJsonFile(packageJsonPath)
|
|
847
|
+
const raw = typeof manifest.packageManager === "string" ? manifest.packageManager.trim() : ""
|
|
848
|
+
if (raw === "") {
|
|
849
|
+
return null
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
const [name] = raw.split("@")
|
|
853
|
+
if (name === "npm" || name === "pnpm" || name === "yarn" || name === "bun") {
|
|
854
|
+
return name
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
return null
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
function detectPackageManagerFromLocks(directory) {
|
|
861
|
+
if (!fileExists(directory)) {
|
|
862
|
+
return null
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
if (fileExists(path.join(directory, "bun.lock")) || fileExists(path.join(directory, "bun.lockb"))) {
|
|
866
|
+
return "bun"
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
if (fileExists(path.join(directory, "pnpm-lock.yaml"))) {
|
|
870
|
+
return "pnpm"
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
if (fileExists(path.join(directory, "yarn.lock"))) {
|
|
874
|
+
return "yarn"
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
if (fileExists(path.join(directory, "package-lock.json"))) {
|
|
878
|
+
return "npm"
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
return null
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
export function resolveAppPackageManager(appPaths, config) {
|
|
885
|
+
const frontendDir = resolveFrontendDir(appPaths, config)
|
|
886
|
+
const frontendPackageJsonPath = path.join(frontendDir, "package.json")
|
|
887
|
+
|
|
888
|
+
return (
|
|
889
|
+
detectPackageManagerFromManifest(appPaths.appPackageJsonPath) ??
|
|
890
|
+
detectPackageManagerFromManifest(frontendPackageJsonPath) ??
|
|
891
|
+
detectPackageManagerFromLocks(appPaths.appRoot) ??
|
|
892
|
+
detectPackageManagerFromLocks(frontendDir) ??
|
|
893
|
+
"npm"
|
|
894
|
+
)
|
|
895
|
+
}
|