@owdproject/core 3.3.1 → 4.0.0-alpha.3
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 +91 -59
- package/dist/dom/index.d.mts +65 -0
- package/dist/dom/index.d.ts +65 -0
- package/dist/dom/index.mjs +224 -0
- package/dist/events/index.d.mts +70 -0
- package/dist/events/index.d.ts +70 -0
- package/dist/events/index.mjs +3 -0
- package/dist/index.d.mts +73 -0
- package/dist/index.d.ts +73 -0
- package/dist/index.mjs +115 -0
- package/dist/layout/index.d.mts +41 -0
- package/dist/layout/index.d.ts +41 -0
- package/dist/layout/index.mjs +64 -0
- package/dist/machines/index.d.mts +31 -0
- package/dist/machines/index.d.ts +31 -0
- package/dist/machines/index.mjs +2 -0
- package/dist/managers/index.d.mts +117 -0
- package/dist/managers/index.d.ts +117 -0
- package/dist/managers/index.mjs +6 -0
- package/dist/session/index.d.mts +57 -0
- package/dist/session/index.d.ts +57 -0
- package/dist/session/index.mjs +65 -0
- package/dist/shared/core.B0B0KfVK.mjs +865 -0
- package/dist/shared/core.B1XxB289.mjs +239 -0
- package/dist/shared/core.B3mp7ztE.mjs +237 -0
- package/dist/shared/core.BOvFdEVQ.d.ts +114 -0
- package/dist/shared/core.CsDFgGnX.mjs +40 -0
- package/dist/shared/core.Di1eFcr_.d.mts +114 -0
- package/dist/shared/core.Pd_Ogt4g.mjs +101 -0
- package/dist/shared/core.b3Xldzyu.mjs +29 -0
- package/dist/types/index.d.mts +266 -0
- package/dist/types/index.d.ts +266 -0
- package/dist/types/index.mjs +1 -0
- package/package.json +60 -87
- package/bin/cli.js +0 -395
- package/bin/desktop.js +0 -5
- package/bin/lib/catalog.js +0 -293
- package/bin/lib/config.js +0 -109
- package/bin/lib/desktopConfig.js +0 -56
- package/bin/lib/generateTemplate.js +0 -389
- package/bin/lib/install.js +0 -408
- package/bin/lib/migrateModulePlayground.config.mjs +0 -164
- package/bin/lib/migrateModulePlayground.mjs +0 -313
- package/bin/lib/npmVersions.js +0 -124
- package/bin/lib/playgroundContext.js +0 -188
- package/bin/lib/scaffold.js +0 -197
- package/bin/lib/status.js +0 -289
- package/bin/lib/validateModule.js +0 -697
- package/bin/lib/workspace.js +0 -182
- package/bin/owd.js +0 -5
- package/bin/tui.js +0 -1379
- package/dist/module.d.mts +0 -13
- package/dist/module.json +0 -9
- package/dist/module.mjs +0 -268
- package/dist/types.d.mts +0 -7
- package/index.ts +0 -5
- package/module.ts +0 -223
- package/runtime/components/Desktop/Application/DesktopApplicationRender.vue +0 -20
- package/runtime/components/Desktop/Application/DesktopApplicationWindowsRender.vue +0 -38
- package/runtime/components/Desktop/Background/DesktopBackground.vue +0 -16
- package/runtime/components/Desktop/Core/DesktopCore.vue +0 -90
- package/runtime/components/Desktop/Time/DesktopTime.vue +0 -56
- package/runtime/components/Desktop/Window/DesktopWindow.vue +0 -204
- package/runtime/components/Desktop/Window/DesktopWindowContent.vue +0 -28
- package/runtime/components/Desktop/Window/DesktopWindowNav.vue +0 -66
- package/runtime/composables/useApplicationEntries.ts +0 -51
- package/runtime/composables/useApplicationManager.ts +0 -285
- package/runtime/composables/useDesktopManager.ts +0 -49
- package/runtime/composables/useTerminalManager.ts +0 -66
- package/runtime/composables/useWorkspaceManager.ts +0 -41
- package/runtime/internal/controllers/ApplicationController.ts +0 -345
- package/runtime/internal/controllers/WindowController.ts +0 -462
- package/runtime/plugins/02.desktop-register-desktop-apps.client.ts +0 -17
- package/runtime/plugins/resize.client.ts +0 -6
- package/runtime/stores/storeApplicationMeta.ts +0 -59
- package/runtime/stores/storeApplicationWindows.ts +0 -20
- package/runtime/stores/storeDesktop.ts +0 -111
- package/runtime/stores/storeDesktopDefaultApps.ts +0 -53
- package/runtime/stores/storeDesktopVolume.ts +0 -18
- package/runtime/stores/storeDesktopWindow.ts +0 -20
- package/runtime/stores/storeDesktopWorkspace.ts +0 -75
- package/runtime/utils/captureElementToCanvas.ts +0 -21
- package/runtime/utils/explorerEntryPath.ts +0 -10
- package/runtime/utils/resolveDesktopConfigPath.ts +0 -52
- package/runtime/utils/splitDesktopUserConfig.ts +0 -85
- package/runtime/utils/utilApp.ts +0 -37
- package/runtime/utils/utilCommon.ts +0 -26
- package/runtime/utils/utilDebug.ts +0 -30
- package/runtime/utils/utilDesktop.ts +0 -35
- package/runtime/utils/utilTerminal.ts +0 -6
- package/runtime/utils/utilWindow.ts +0 -15
- package/runtime/utils/validateDesktopUserConfig.ts +0 -44
- package/types/index.d.ts +0 -420
package/bin/lib/config.js
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { readFileSync, existsSync, copyFileSync } from 'node:fs'
|
|
2
|
-
import { createRequire } from 'node:module'
|
|
3
|
-
import { join } from 'node:path'
|
|
4
|
-
import { SCOPE } from './workspace.js'
|
|
5
|
-
import { LEGACY_CONFIG_DEPRECATION } from './desktopConfig.js'
|
|
6
|
-
|
|
7
|
-
const require = createRequire(import.meta.url)
|
|
8
|
-
|
|
9
|
-
function loadTsMorph(workspaceRoot) {
|
|
10
|
-
const utilPath = join(
|
|
11
|
-
workspaceRoot,
|
|
12
|
-
'node_modules/@owdproject/nx/dist/utils/utilConfig.js',
|
|
13
|
-
)
|
|
14
|
-
if (!existsSync(utilPath)) {
|
|
15
|
-
throw new Error('Missing @owdproject/nx — run pnpm install at the repo root.')
|
|
16
|
-
}
|
|
17
|
-
const { Project, SyntaxKind } = require('ts-morph')
|
|
18
|
-
return { Project, SyntaxKind }
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function getConfigObject(sourceFile, SyntaxKind) {
|
|
22
|
-
const exportDefault = sourceFile.getExportAssignmentOrThrow((exp) => !exp.isExportEquals())
|
|
23
|
-
const callExpr = exportDefault.getExpressionIfKindOrThrow(SyntaxKind.CallExpression)
|
|
24
|
-
const args = callExpr.getArguments()
|
|
25
|
-
if (args.length === 0) throw new Error('defineDesktopConfig({}) is empty')
|
|
26
|
-
return args[0].asKindOrThrow(SyntaxKind.ObjectLiteralExpression)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function readArrayProperty(configObj, key, SyntaxKind) {
|
|
30
|
-
const prop = configObj.getProperty(key)?.asKind(SyntaxKind.PropertyAssignment)
|
|
31
|
-
if (!prop) return []
|
|
32
|
-
const init = prop.getInitializerIfKind(SyntaxKind.ArrayLiteralExpression)
|
|
33
|
-
if (!init) return []
|
|
34
|
-
return init
|
|
35
|
-
.getElements()
|
|
36
|
-
.map((el) => el.getText().trim().replace(/['"`]/g, ''))
|
|
37
|
-
.filter(Boolean)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function readTheme(configObj, SyntaxKind) {
|
|
41
|
-
const prop = configObj.getProperty('theme')?.asKind(SyntaxKind.PropertyAssignment)
|
|
42
|
-
if (!prop) return null
|
|
43
|
-
return prop.getInitializer()?.getText().trim().replace(/['"`]/g, '') ?? null
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function setArrayProperty(configObj, key, values, SyntaxKind) {
|
|
47
|
-
const quoted = values.map((v) => `'${v}'`).join(', ')
|
|
48
|
-
const initializer = `[ ${quoted} ]`
|
|
49
|
-
const existing = configObj.getProperty(key)?.asKind(SyntaxKind.PropertyAssignment)
|
|
50
|
-
if (existing) {
|
|
51
|
-
existing.setInitializer(initializer)
|
|
52
|
-
} else {
|
|
53
|
-
configObj.addPropertyAssignment({ name: key, initializer })
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function readDesktopConfig(configPath, workspaceRoot) {
|
|
58
|
-
const { Project, SyntaxKind } = loadTsMorph(workspaceRoot)
|
|
59
|
-
const project = new Project()
|
|
60
|
-
const sourceFile = project.addSourceFileAtPath(configPath)
|
|
61
|
-
const configObj = getConfigObject(sourceFile, SyntaxKind)
|
|
62
|
-
|
|
63
|
-
return {
|
|
64
|
-
theme: readTheme(configObj, SyntaxKind),
|
|
65
|
-
apps: readArrayProperty(configObj, 'apps', SyntaxKind),
|
|
66
|
-
modules: readArrayProperty(configObj, 'modules', SyntaxKind),
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* When saving from the TUI, always target desktop.config.ts (migrate from legacy on first save).
|
|
72
|
-
*
|
|
73
|
-
* @param {{ config: string, configWrite: string }} paths
|
|
74
|
-
*/
|
|
75
|
-
export function resolveConfigPathForWrite(paths) {
|
|
76
|
-
if (paths.config === paths.configWrite) {
|
|
77
|
-
return paths.configWrite
|
|
78
|
-
}
|
|
79
|
-
if (!existsSync(paths.configWrite) && existsSync(paths.config)) {
|
|
80
|
-
copyFileSync(paths.config, paths.configWrite)
|
|
81
|
-
console.warn(LEGACY_CONFIG_DEPRECATION)
|
|
82
|
-
}
|
|
83
|
-
return paths.configWrite
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export function writeDesktopConfig(configPath, workspaceRoot, state) {
|
|
87
|
-
const { Project, SyntaxKind } = loadTsMorph(workspaceRoot)
|
|
88
|
-
const project = new Project()
|
|
89
|
-
const sourceFile = project.addSourceFileAtPath(configPath)
|
|
90
|
-
const configObj = getConfigObject(sourceFile, SyntaxKind)
|
|
91
|
-
|
|
92
|
-
if (state.theme) {
|
|
93
|
-
const themeProp = configObj.getProperty('theme')?.asKind(SyntaxKind.PropertyAssignment)
|
|
94
|
-
if (themeProp) themeProp.setInitializer(`'${state.theme}'`)
|
|
95
|
-
else configObj.addPropertyAssignment({ name: 'theme', initializer: `'${state.theme}'` })
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (state.apps) setArrayProperty(configObj, 'apps', state.apps, SyntaxKind)
|
|
99
|
-
if (state.modules) setArrayProperty(configObj, 'modules', state.modules, SyntaxKind)
|
|
100
|
-
|
|
101
|
-
sourceFile.saveSync()
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export function readDesktopDependencies(packageJsonPath) {
|
|
105
|
-
if (!existsSync(packageJsonPath)) return []
|
|
106
|
-
const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf8'))
|
|
107
|
-
const deps = { ...pkg.dependencies, ...pkg.devDependencies }
|
|
108
|
-
return Object.keys(deps).filter((name) => name.startsWith(SCOPE))
|
|
109
|
-
}
|
package/bin/lib/desktopConfig.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs'
|
|
2
|
-
import { join } from 'node:path'
|
|
3
|
-
|
|
4
|
-
export const DESKTOP_CONFIG_FILENAME = 'desktop.config.ts'
|
|
5
|
-
export const LEGACY_DESKTOP_CONFIG_FILENAME = 'owd.config.ts'
|
|
6
|
-
|
|
7
|
-
export const LEGACY_CONFIG_DEPRECATION =
|
|
8
|
-
'[@owdproject/core] owd.config.ts is deprecated and kept only for backward compatibility; rename to desktop.config.ts (required from @owdproject/core 3.2).'
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Resolve the desktop config file under a Nuxt project root (or desktop/ folder).
|
|
12
|
-
*
|
|
13
|
-
* @param {string} rootDir
|
|
14
|
-
* @returns {{ path: string, file: string, legacy: boolean } | null}
|
|
15
|
-
*/
|
|
16
|
-
export function resolveDesktopConfigPath(rootDir) {
|
|
17
|
-
const desktopPath = join(rootDir, DESKTOP_CONFIG_FILENAME)
|
|
18
|
-
const legacyPath = join(rootDir, LEGACY_DESKTOP_CONFIG_FILENAME)
|
|
19
|
-
const hasDesktop = existsSync(desktopPath)
|
|
20
|
-
const hasLegacy = existsSync(legacyPath)
|
|
21
|
-
|
|
22
|
-
if (hasDesktop && hasLegacy) {
|
|
23
|
-
console.warn(
|
|
24
|
-
'[@owdproject/core] Both desktop.config.ts and owd.config.ts exist; using desktop.config.ts. Remove owd.config.ts.',
|
|
25
|
-
)
|
|
26
|
-
return { path: desktopPath, file: DESKTOP_CONFIG_FILENAME, legacy: false }
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (hasDesktop) {
|
|
30
|
-
return { path: desktopPath, file: DESKTOP_CONFIG_FILENAME, legacy: false }
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (hasLegacy) {
|
|
34
|
-
return { path: legacyPath, file: LEGACY_DESKTOP_CONFIG_FILENAME, legacy: true }
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return null
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* @param {{ legacy?: boolean, file?: string } | null | undefined} resolved
|
|
42
|
-
*/
|
|
43
|
-
export function warnLegacyDesktopConfig(resolved) {
|
|
44
|
-
if (resolved?.legacy) {
|
|
45
|
-
console.warn(LEGACY_CONFIG_DEPRECATION)
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Path used when creating or updating config from the CLI (always the new filename).
|
|
51
|
-
*
|
|
52
|
-
* @param {string} desktopDir
|
|
53
|
-
*/
|
|
54
|
-
export function desktopConfigWritePath(desktopDir) {
|
|
55
|
-
return join(desktopDir, DESKTOP_CONFIG_FILENAME)
|
|
56
|
-
}
|
|
@@ -1,389 +0,0 @@
|
|
|
1
|
-
import { execSync } from 'node:child_process'
|
|
2
|
-
import {
|
|
3
|
-
cpSync,
|
|
4
|
-
existsSync,
|
|
5
|
-
mkdtempSync,
|
|
6
|
-
mkdirSync,
|
|
7
|
-
readFileSync,
|
|
8
|
-
readdirSync,
|
|
9
|
-
rmSync,
|
|
10
|
-
statSync,
|
|
11
|
-
writeFileSync,
|
|
12
|
-
} from 'node:fs'
|
|
13
|
-
import { tmpdir } from 'node:os'
|
|
14
|
-
import { basename, dirname, join, relative, resolve } from 'node:path'
|
|
15
|
-
import { fileURLToPath } from 'node:url'
|
|
16
|
-
import {
|
|
17
|
-
fetchLatestVersions,
|
|
18
|
-
isOwdScopedPackage,
|
|
19
|
-
resolveLatestVersions,
|
|
20
|
-
} from './npmVersions.js'
|
|
21
|
-
|
|
22
|
-
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
23
|
-
const BLUEPRINT_ROOT = resolve(__dirname, '../../template-blueprint')
|
|
24
|
-
|
|
25
|
-
export const STARTER_DESKTOP_DEPS = [
|
|
26
|
-
'@owdproject/core',
|
|
27
|
-
'@owdproject/theme-nova',
|
|
28
|
-
'@owdproject/app-about',
|
|
29
|
-
'h3',
|
|
30
|
-
]
|
|
31
|
-
|
|
32
|
-
/** Used when a starter package is not on npm yet (before first publish). */
|
|
33
|
-
export const TEMPLATE_NPM_FALLBACK_VERSIONS = {
|
|
34
|
-
'@owdproject/theme-nova': '0.0.1',
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const DESKTOP_COPY_FILES = [
|
|
38
|
-
'tsconfig.json',
|
|
39
|
-
'tsconfig.app.json',
|
|
40
|
-
'tsconfig.spec.json',
|
|
41
|
-
'.npmrc',
|
|
42
|
-
]
|
|
43
|
-
|
|
44
|
-
const ROOT_COPY_FROM_MONOREPO = [
|
|
45
|
-
'nx.json',
|
|
46
|
-
'tsconfig.base.json',
|
|
47
|
-
'tsconfig.json',
|
|
48
|
-
'.editorconfig',
|
|
49
|
-
'.npmrc',
|
|
50
|
-
'.prettierrc',
|
|
51
|
-
'.prettierignore',
|
|
52
|
-
]
|
|
53
|
-
|
|
54
|
-
const DESKTOP_SKIP_NAMES = new Set([
|
|
55
|
-
'node_modules',
|
|
56
|
-
'.nuxt',
|
|
57
|
-
'.output',
|
|
58
|
-
'dist',
|
|
59
|
-
'.env',
|
|
60
|
-
'.data',
|
|
61
|
-
'vitest.config.ts',
|
|
62
|
-
'tsconfig.tsbuildinfo',
|
|
63
|
-
'package.json',
|
|
64
|
-
'desktop.config.ts',
|
|
65
|
-
'nuxt.config.ts',
|
|
66
|
-
'app',
|
|
67
|
-
])
|
|
68
|
-
|
|
69
|
-
const BLUEPRINT_SKIP_NAMES = new Set(['root-package.json'])
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* @param {string} blueprintRoot
|
|
73
|
-
*/
|
|
74
|
-
export function resolveBlueprintRoot(blueprintRoot = BLUEPRINT_ROOT) {
|
|
75
|
-
if (!existsSync(join(blueprintRoot, 'pnpm-workspace.yaml'))) {
|
|
76
|
-
throw new Error(`Template blueprint not found at ${blueprintRoot}`)
|
|
77
|
-
}
|
|
78
|
-
return blueprintRoot
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* @param {string} src
|
|
83
|
-
* @param {string} dest
|
|
84
|
-
* @param {Set<string>} [skipNames]
|
|
85
|
-
*/
|
|
86
|
-
function copyTree(src, dest, skipNames = new Set()) {
|
|
87
|
-
if (!existsSync(src)) return
|
|
88
|
-
const stat = statSync(src)
|
|
89
|
-
if (stat.isFile()) {
|
|
90
|
-
mkdirSync(dirname(dest), { recursive: true })
|
|
91
|
-
cpSync(src, dest)
|
|
92
|
-
return
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
mkdirSync(dest, { recursive: true })
|
|
96
|
-
for (const name of readdirSync(src)) {
|
|
97
|
-
if (skipNames.has(name)) continue
|
|
98
|
-
copyTree(join(src, name), join(dest, name), skipNames)
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* @param {string} workspaceRoot
|
|
104
|
-
*/
|
|
105
|
-
function readMonorepoPackageJson(workspaceRoot) {
|
|
106
|
-
const path = join(workspaceRoot, 'package.json')
|
|
107
|
-
return JSON.parse(readFileSync(path, 'utf8'))
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* @param {string} workspaceRoot
|
|
112
|
-
* @param {{ useCache?: boolean }} [options]
|
|
113
|
-
*/
|
|
114
|
-
export async function resolveTemplateVersions(workspaceRoot, options = {}) {
|
|
115
|
-
const monorepo = readMonorepoPackageJson(workspaceRoot)
|
|
116
|
-
const monorepoDevDeps = monorepo.devDependencies ?? {}
|
|
117
|
-
|
|
118
|
-
const owdPackages = [
|
|
119
|
-
...new Set([
|
|
120
|
-
...STARTER_DESKTOP_DEPS,
|
|
121
|
-
...Object.keys(monorepoDevDeps).filter(isOwdScopedPackage),
|
|
122
|
-
]),
|
|
123
|
-
]
|
|
124
|
-
|
|
125
|
-
const npmLatest = await resolveLatestVersions(workspaceRoot, owdPackages, options)
|
|
126
|
-
|
|
127
|
-
/** @type {Record<string, string>} */
|
|
128
|
-
const versions = { ...monorepoDevDeps, ...npmLatest }
|
|
129
|
-
for (const name of STARTER_DESKTOP_DEPS) {
|
|
130
|
-
versions[name] =
|
|
131
|
-
npmLatest[name] ?? TEMPLATE_NPM_FALLBACK_VERSIONS[name] ?? monorepoDevDeps[name]
|
|
132
|
-
if (!versions[name]) {
|
|
133
|
-
throw new Error(`Could not resolve version for ${name}`)
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
return versions
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* @param {Record<string, string>} versions
|
|
142
|
-
*/
|
|
143
|
-
function buildTemplateRootPackageJson(versions) {
|
|
144
|
-
const base = JSON.parse(readFileSync(join(BLUEPRINT_ROOT, 'root-package.json'), 'utf8'))
|
|
145
|
-
/** @type {Record<string, string>} */
|
|
146
|
-
const devDependencies = {}
|
|
147
|
-
for (const [name, range] of Object.entries(versions)) {
|
|
148
|
-
if (name === 'h3') continue
|
|
149
|
-
devDependencies[name] = range
|
|
150
|
-
}
|
|
151
|
-
base.devDependencies = Object.fromEntries(
|
|
152
|
-
Object.entries(devDependencies).sort(([a], [b]) => a.localeCompare(b)),
|
|
153
|
-
)
|
|
154
|
-
return `${JSON.stringify(base, null, 2)}\n`
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* @param {Record<string, string>} versions
|
|
159
|
-
*/
|
|
160
|
-
function buildTemplateDesktopPackageJson(versions) {
|
|
161
|
-
/** @type {Record<string, string>} */
|
|
162
|
-
const dependencies = {}
|
|
163
|
-
for (const name of STARTER_DESKTOP_DEPS) {
|
|
164
|
-
dependencies[name] = versions[name]
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const pkg = {
|
|
168
|
-
name: '@owdproject/client',
|
|
169
|
-
private: true,
|
|
170
|
-
nx: { name: 'desktop' },
|
|
171
|
-
scripts: {
|
|
172
|
-
build: 'nuxt generate',
|
|
173
|
-
dev: 'nuxt dev --host',
|
|
174
|
-
generate: 'nuxt generate --dev',
|
|
175
|
-
postinstall: 'nuxt prepare',
|
|
176
|
-
preview: 'nuxt preview',
|
|
177
|
-
},
|
|
178
|
-
dependencies: Object.fromEntries(
|
|
179
|
-
Object.entries(dependencies).sort(([a], [b]) => a.localeCompare(b)),
|
|
180
|
-
),
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return `${JSON.stringify(pkg, null, 2)}\n`
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* @param {string} srcPath
|
|
188
|
-
*/
|
|
189
|
-
function readProjectJson(srcPath) {
|
|
190
|
-
const raw = readFileSync(srcPath, 'utf8')
|
|
191
|
-
const data = JSON.parse(raw)
|
|
192
|
-
if (data.name === 'desktopx') data.name = 'desktop'
|
|
193
|
-
return `${JSON.stringify(data, null, 2)}\n`
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* @param {string} workspaceRoot
|
|
198
|
-
* @param {string} outputRoot
|
|
199
|
-
* @param {{ versions: Record<string, string> }} ctx
|
|
200
|
-
*/
|
|
201
|
-
function writeGeneratedFiles(workspaceRoot, outputRoot, ctx) {
|
|
202
|
-
const { versions } = ctx
|
|
203
|
-
const desktopSrc = join(workspaceRoot, 'desktop')
|
|
204
|
-
const desktopOut = join(outputRoot, 'desktop')
|
|
205
|
-
const blueprint = resolveBlueprintRoot()
|
|
206
|
-
|
|
207
|
-
mkdirSync(outputRoot, { recursive: true })
|
|
208
|
-
|
|
209
|
-
copyTree(blueprint, outputRoot, BLUEPRINT_SKIP_NAMES)
|
|
210
|
-
|
|
211
|
-
writeFileSync(join(outputRoot, 'package.json'), buildTemplateRootPackageJson(versions))
|
|
212
|
-
|
|
213
|
-
mkdirSync(desktopOut, { recursive: true })
|
|
214
|
-
for (const file of DESKTOP_COPY_FILES) {
|
|
215
|
-
const src = join(desktopSrc, file)
|
|
216
|
-
if (existsSync(src)) {
|
|
217
|
-
cpSync(src, join(desktopOut, file))
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const i18nBlueprint = join(blueprint, 'desktop/i18n')
|
|
222
|
-
if (existsSync(i18nBlueprint)) {
|
|
223
|
-
copyTree(i18nBlueprint, join(desktopOut, 'i18n'))
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
const projectJsonSrc = join(desktopSrc, 'project.json')
|
|
227
|
-
if (existsSync(projectJsonSrc)) {
|
|
228
|
-
writeFileSync(join(desktopOut, 'project.json'), readProjectJson(projectJsonSrc))
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
for (const file of ROOT_COPY_FROM_MONOREPO) {
|
|
232
|
-
const src = join(workspaceRoot, file)
|
|
233
|
-
if (existsSync(src)) {
|
|
234
|
-
cpSync(src, join(outputRoot, file))
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
writeFileSync(join(desktopOut, 'package.json'), buildTemplateDesktopPackageJson(versions))
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* @param {string} dir
|
|
243
|
-
* @returns {string[]}
|
|
244
|
-
*/
|
|
245
|
-
function listFilesRecursive(dir) {
|
|
246
|
-
if (!existsSync(dir)) return []
|
|
247
|
-
/** @type {string[]} */
|
|
248
|
-
const files = []
|
|
249
|
-
for (const name of readdirSync(dir)) {
|
|
250
|
-
const path = join(dir, name)
|
|
251
|
-
const stat = statSync(path)
|
|
252
|
-
if (stat.isDirectory()) {
|
|
253
|
-
if (name === 'node_modules' || name === '.git') continue
|
|
254
|
-
files.push(...listFilesRecursive(path))
|
|
255
|
-
} else {
|
|
256
|
-
files.push(path)
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
return files
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* @param {string} aRoot
|
|
264
|
-
* @param {string} bRoot
|
|
265
|
-
*/
|
|
266
|
-
export function diffTemplateTrees(aRoot, bRoot) {
|
|
267
|
-
const aFiles = new Set(listFilesRecursive(aRoot).map((p) => relative(aRoot, p)))
|
|
268
|
-
const bFiles = new Set(listFilesRecursive(bRoot).map((p) => relative(bRoot, p)))
|
|
269
|
-
/** @type {{ path: string, type: 'missing' | 'extra' | 'changed' }[]} */
|
|
270
|
-
const diffs = []
|
|
271
|
-
|
|
272
|
-
for (const rel of aFiles) {
|
|
273
|
-
if (!bFiles.has(rel)) {
|
|
274
|
-
diffs.push({ path: rel, type: 'missing' })
|
|
275
|
-
continue
|
|
276
|
-
}
|
|
277
|
-
const a = readFileSync(join(aRoot, rel))
|
|
278
|
-
const b = readFileSync(join(bRoot, rel))
|
|
279
|
-
if (!a.equals(b)) diffs.push({ path: rel, type: 'changed' })
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
for (const rel of bFiles) {
|
|
283
|
-
if (!aFiles.has(rel)) diffs.push({ path: rel, type: 'extra' })
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
return diffs.sort((x, y) => x.path.localeCompare(y.path))
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* @param {string} workspaceRoot
|
|
291
|
-
* @param {{ dryRun?: boolean, check?: boolean, useCache?: boolean }} [options]
|
|
292
|
-
*/
|
|
293
|
-
export async function generateTemplate(workspaceRoot, options = {}) {
|
|
294
|
-
const { dryRun = false, check = false, useCache = true } = options
|
|
295
|
-
const templateOut = join(workspaceRoot, 'template')
|
|
296
|
-
const desktopPath = join(workspaceRoot, 'desktop')
|
|
297
|
-
|
|
298
|
-
if (!existsSync(desktopPath)) {
|
|
299
|
-
throw new Error(`Monorepo desktop/ not found at ${desktopPath}`)
|
|
300
|
-
}
|
|
301
|
-
resolveBlueprintRoot()
|
|
302
|
-
|
|
303
|
-
const versions = await resolveTemplateVersions(workspaceRoot, { useCache })
|
|
304
|
-
|
|
305
|
-
if (dryRun) {
|
|
306
|
-
console.log('\nTemplate generation plan (dry run)\n')
|
|
307
|
-
console.log('Output:', templateOut)
|
|
308
|
-
console.log('\nStarter desktop dependencies:')
|
|
309
|
-
for (const name of STARTER_DESKTOP_DEPS) {
|
|
310
|
-
console.log(` ${name} ${versions[name]}`)
|
|
311
|
-
}
|
|
312
|
-
console.log('\nRoot devDependencies (@owdproject/* from npm):')
|
|
313
|
-
for (const [name, range] of Object.entries(versions).sort(([a], [b]) => a.localeCompare(b))) {
|
|
314
|
-
if (isOwdScopedPackage(name)) console.log(` ${name} ${range}`)
|
|
315
|
-
}
|
|
316
|
-
console.log('\nSources:')
|
|
317
|
-
console.log(` blueprint ${BLUEPRINT_ROOT}`)
|
|
318
|
-
console.log(` desktop/ ${desktopPath}`)
|
|
319
|
-
console.log(` monorepo ${workspaceRoot}`)
|
|
320
|
-
console.log('')
|
|
321
|
-
return { versions, outputRoot: templateOut }
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
const outputRoot = check ? mkdtempSync(join(tmpdir(), 'owd-template-check-')) : templateOut
|
|
325
|
-
|
|
326
|
-
try {
|
|
327
|
-
if (!check && existsSync(templateOut)) {
|
|
328
|
-
rmSync(templateOut, { recursive: true, force: true })
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
writeGeneratedFiles(workspaceRoot, outputRoot, { versions })
|
|
332
|
-
|
|
333
|
-
if (check) {
|
|
334
|
-
const diffs = diffTemplateTrees(templateOut, outputRoot)
|
|
335
|
-
if (diffs.length === 0) {
|
|
336
|
-
console.log('\n✓ template/ is up to date\n')
|
|
337
|
-
return { ok: true, versions }
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
console.error('\n✗ template/ is out of date\n')
|
|
341
|
-
for (const d of diffs.slice(0, 40)) {
|
|
342
|
-
const label =
|
|
343
|
-
d.type === 'missing'
|
|
344
|
-
? 'only in committed template'
|
|
345
|
-
: d.type === 'extra'
|
|
346
|
-
? 'missing from committed template'
|
|
347
|
-
: 'changed'
|
|
348
|
-
console.error(` ${label}: ${d.path}`)
|
|
349
|
-
}
|
|
350
|
-
if (diffs.length > 40) {
|
|
351
|
-
console.error(` … and ${diffs.length - 40} more`)
|
|
352
|
-
}
|
|
353
|
-
console.error('\nRun: pnpm desktop template\n')
|
|
354
|
-
return { ok: false, versions, diffs }
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
console.log('\n✓ Generated template/\n')
|
|
358
|
-
console.log('Starter packages:')
|
|
359
|
-
for (const name of STARTER_DESKTOP_DEPS) {
|
|
360
|
-
console.log(` ${name} ${versions[name]}`)
|
|
361
|
-
}
|
|
362
|
-
console.log('\nCommit template/ when ready.\n')
|
|
363
|
-
return { ok: true, versions, outputRoot }
|
|
364
|
-
} finally {
|
|
365
|
-
if (check && existsSync(outputRoot)) {
|
|
366
|
-
rmSync(outputRoot, { recursive: true, force: true })
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* @param {{ workspaceRoot: string, dryRun?: boolean, check?: boolean }} options
|
|
373
|
-
*/
|
|
374
|
-
export async function runGenerateTemplateCli(options) {
|
|
375
|
-
const { workspaceRoot, dryRun = false, check = false } = options
|
|
376
|
-
|
|
377
|
-
if (!workspaceRoot) {
|
|
378
|
-
console.error('\n✗ Not inside an OWD workspace.\n')
|
|
379
|
-
process.exit(1)
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
try {
|
|
383
|
-
const result = await generateTemplate(workspaceRoot, { dryRun, check })
|
|
384
|
-
if (check && result.ok === false) process.exit(1)
|
|
385
|
-
} catch (error) {
|
|
386
|
-
console.error(`\n✗ ${error.message ?? String(error)}\n`)
|
|
387
|
-
process.exit(1)
|
|
388
|
-
}
|
|
389
|
-
}
|