reset-framework-cli 1.0.2 → 1.1.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reset-framework-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Command-line tooling for Reset Framework.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
"node": ">=20.19.0"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@reset-framework/native": "1.
|
|
15
|
-
"@reset-framework/schema": "1.
|
|
16
|
-
"@reset-framework/sdk": "1.
|
|
14
|
+
"@reset-framework/native": "1.1.1",
|
|
15
|
+
"@reset-framework/schema": "1.1.1",
|
|
16
|
+
"@reset-framework/sdk": "1.1.1"
|
|
17
17
|
},
|
|
18
18
|
"bin": {
|
|
19
19
|
"reset-framework-cli": "src/index.js"
|
package/src/commands/init.js
CHANGED
|
@@ -34,6 +34,7 @@ const standaloneViteConfig = `import { defineConfig } from 'vite'
|
|
|
34
34
|
import react from '@vitejs/plugin-react'
|
|
35
35
|
|
|
36
36
|
export default defineConfig({
|
|
37
|
+
base: './',
|
|
37
38
|
plugins: [react()],
|
|
38
39
|
})
|
|
39
40
|
`
|
|
@@ -43,6 +44,7 @@ import react from '@vitejs/plugin-react'
|
|
|
43
44
|
import tailwindcss from '@tailwindcss/vite'
|
|
44
45
|
|
|
45
46
|
export default defineConfig({
|
|
47
|
+
base: './',
|
|
46
48
|
plugins: [react(), tailwindcss()],
|
|
47
49
|
})
|
|
48
50
|
`
|
package/src/lib/output.js
CHANGED
|
@@ -1,9 +1,99 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from "node:path"
|
|
2
|
+
import { cp, mkdir, rm, writeFile } from "node:fs/promises"
|
|
2
3
|
import { existsSync } from "node:fs"
|
|
3
4
|
|
|
4
5
|
import { logger } from "./logger.js"
|
|
5
6
|
import { runCommand } from "./process.js"
|
|
6
7
|
|
|
8
|
+
function escapePlistString(value) {
|
|
9
|
+
return value
|
|
10
|
+
.replaceAll("&", "&")
|
|
11
|
+
.replaceAll("<", "<")
|
|
12
|
+
.replaceAll(">", ">")
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function serializePlistValue(value, indentLevel = 1) {
|
|
16
|
+
const indent = " ".repeat(indentLevel)
|
|
17
|
+
|
|
18
|
+
if (Array.isArray(value)) {
|
|
19
|
+
if (value.length === 0) {
|
|
20
|
+
return `${indent}<array/>\n`
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
`${indent}<array>\n` +
|
|
25
|
+
value.map((entry) => serializePlistValue(entry, indentLevel + 1)).join("") +
|
|
26
|
+
`${indent}</array>\n`
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (typeof value === "object" && value !== null) {
|
|
31
|
+
const entries = Object.entries(value)
|
|
32
|
+
if (entries.length === 0) {
|
|
33
|
+
return `${indent}<dict/>\n`
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
`${indent}<dict>\n` +
|
|
38
|
+
entries
|
|
39
|
+
.map(
|
|
40
|
+
([key, entryValue]) =>
|
|
41
|
+
`${" ".repeat(indentLevel + 1)}<key>${escapePlistString(key)}</key>\n${serializePlistValue(entryValue, indentLevel + 1)}`
|
|
42
|
+
)
|
|
43
|
+
.join("") +
|
|
44
|
+
`${indent}</dict>\n`
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (typeof value === "boolean") {
|
|
49
|
+
return `${indent}<${value ? "true" : "false"}/>\n`
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (typeof value === "number") {
|
|
53
|
+
return `${indent}<integer>${value}</integer>\n`
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return `${indent}<string>${escapePlistString(String(value))}</string>\n`
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function buildMacOSInfoPlist(config) {
|
|
60
|
+
const urlTypes = Array.isArray(config.protocols?.schemes)
|
|
61
|
+
? config.protocols.schemes.map((schemeConfig) => ({
|
|
62
|
+
CFBundleTypeRole: schemeConfig.role ?? "Viewer",
|
|
63
|
+
CFBundleURLName:
|
|
64
|
+
typeof schemeConfig.name === "string" && schemeConfig.name.trim() !== ""
|
|
65
|
+
? schemeConfig.name
|
|
66
|
+
: `${config.appId}.${schemeConfig.scheme}`,
|
|
67
|
+
CFBundleURLSchemes: [schemeConfig.scheme]
|
|
68
|
+
}))
|
|
69
|
+
: []
|
|
70
|
+
|
|
71
|
+
const plist = {
|
|
72
|
+
CFBundleDevelopmentRegion: "English",
|
|
73
|
+
CFBundleDisplayName: config.productName,
|
|
74
|
+
CFBundleExecutable: "reset-framework",
|
|
75
|
+
CFBundleIdentifier: config.appId,
|
|
76
|
+
CFBundleInfoDictionaryVersion: "6.0",
|
|
77
|
+
CFBundleName: config.productName,
|
|
78
|
+
CFBundlePackageType: "APPL",
|
|
79
|
+
CFBundleShortVersionString: config.version,
|
|
80
|
+
CFBundleVersion: config.version,
|
|
81
|
+
CSResourcesFileMapped: true
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (urlTypes.length > 0) {
|
|
85
|
+
plist.CFBundleURLTypes = urlTypes
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
`<?xml version="1.0" encoding="UTF-8"?>\n` +
|
|
90
|
+
`<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n` +
|
|
91
|
+
`<plist version="1.0">\n` +
|
|
92
|
+
serializePlistValue(plist, 0) +
|
|
93
|
+
`</plist>\n`
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
|
|
7
97
|
export async function stageMacOSAppBundle(frameworkBuildPaths, appPaths, config, options = {}) {
|
|
8
98
|
const { dryRun = false, outputPaths, configPath } = options
|
|
9
99
|
|
|
@@ -40,6 +130,11 @@ export async function stageMacOSAppBundle(frameworkBuildPaths, appPaths, config,
|
|
|
40
130
|
await cp(configPath, outputPaths.bundledConfigPath, { force: true })
|
|
41
131
|
await rm(outputPaths.bundledFrontendDir, { recursive: true, force: true })
|
|
42
132
|
await cp(outputPaths.frontendDistDir, outputPaths.bundledFrontendDir, { recursive: true })
|
|
133
|
+
await writeFile(
|
|
134
|
+
path.join(outputPaths.appBundlePath, "Contents", "Info.plist"),
|
|
135
|
+
buildMacOSInfoPlist(config),
|
|
136
|
+
"utf8"
|
|
137
|
+
)
|
|
43
138
|
|
|
44
139
|
return outputPaths
|
|
45
140
|
}
|
package/src/lib/project.js
CHANGED
|
@@ -76,6 +76,29 @@ function normalizeStyling(value) {
|
|
|
76
76
|
throw new Error("project.styling must be either 'css' or 'tailwindcss'")
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
function normalizeProtocolScheme(value) {
|
|
80
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
81
|
+
throw new Error("protocols.schemes[].scheme must be a non-empty string")
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const normalized = value.trim().toLowerCase()
|
|
85
|
+
if (!/^[a-z][a-z0-9+.-]*$/.test(normalized)) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
"protocols.schemes[].scheme must start with a letter and only contain letters, numbers, '+', '-', and '.'"
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return normalized
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function normalizeProtocolRole(value) {
|
|
95
|
+
if (value === "Editor" || value === "Viewer" || value === "Shell" || value === "None") {
|
|
96
|
+
return value
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
throw new Error("protocols.schemes[].role must be one of Editor, Viewer, Shell, None")
|
|
100
|
+
}
|
|
101
|
+
|
|
79
102
|
function toTitleCase(value) {
|
|
80
103
|
return value
|
|
81
104
|
.split(/[^a-zA-Z0-9]+/)
|
|
@@ -290,7 +313,10 @@ export function validateResetConfig(rawConfig) {
|
|
|
290
313
|
const build = optionalObject(rawConfig, "build")
|
|
291
314
|
const project = optionalObject(rawConfig, "project")
|
|
292
315
|
const security = optionalObject(rawConfig, "security")
|
|
316
|
+
const protocols = optionalObject(rawConfig, "protocols")
|
|
293
317
|
const windowConfig = optionalObject(rawConfig, "window")
|
|
318
|
+
const rawProtocolSchemes = Array.isArray(protocols.schemes) ? protocols.schemes : []
|
|
319
|
+
const seenProtocolSchemes = new Set()
|
|
294
320
|
|
|
295
321
|
return {
|
|
296
322
|
...rawConfig,
|
|
@@ -323,6 +349,32 @@ export function validateResetConfig(rawConfig) {
|
|
|
323
349
|
return value
|
|
324
350
|
})
|
|
325
351
|
: []
|
|
352
|
+
},
|
|
353
|
+
protocols: {
|
|
354
|
+
schemes: rawProtocolSchemes.map((entry) => {
|
|
355
|
+
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
|
|
356
|
+
throw new Error("protocols.schemes entries must be objects")
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
const scheme = normalizeProtocolScheme(entry.scheme)
|
|
360
|
+
if (seenProtocolSchemes.has(scheme)) {
|
|
361
|
+
throw new Error(`Duplicate protocol scheme '${scheme}'`)
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
seenProtocolSchemes.add(scheme)
|
|
365
|
+
|
|
366
|
+
return {
|
|
367
|
+
scheme,
|
|
368
|
+
name:
|
|
369
|
+
typeof entry.name === "string" && entry.name.trim() !== ""
|
|
370
|
+
? entry.name
|
|
371
|
+
: scheme,
|
|
372
|
+
role:
|
|
373
|
+
entry.role === undefined
|
|
374
|
+
? "Viewer"
|
|
375
|
+
: normalizeProtocolRole(entry.role)
|
|
376
|
+
}
|
|
377
|
+
})
|
|
326
378
|
}
|
|
327
379
|
}
|
|
328
380
|
}
|