@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
|
@@ -1,313 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
copyFileSync,
|
|
4
|
-
existsSync,
|
|
5
|
-
mkdirSync,
|
|
6
|
-
readFileSync,
|
|
7
|
-
renameSync,
|
|
8
|
-
writeFileSync,
|
|
9
|
-
} from 'node:fs'
|
|
10
|
-
import { dirname, join } from 'node:path'
|
|
11
|
-
import { fileURLToPath } from 'node:url'
|
|
12
|
-
import { configs } from './migrateModulePlayground.config.mjs'
|
|
13
|
-
|
|
14
|
-
const ROOT = join(dirname(fileURLToPath(import.meta.url)), '../../../../')
|
|
15
|
-
|
|
16
|
-
function fixAppPlugin(pluginPath, registerName) {
|
|
17
|
-
const raw = readFileSync(pluginPath, 'utf8')
|
|
18
|
-
const configVar = raw.match(/import (config\w+) from/)?.[1] || 'configApp'
|
|
19
|
-
writeFileSync(
|
|
20
|
-
pluginPath,
|
|
21
|
-
`import { defineNuxtPlugin } from 'nuxt/app'
|
|
22
|
-
import { defineDesktopApp } from '@owdproject/core/runtime/utils/utilDesktop'
|
|
23
|
-
import ${configVar} from './app.config'
|
|
24
|
-
|
|
25
|
-
export default defineNuxtPlugin({
|
|
26
|
-
name: '${registerName}',
|
|
27
|
-
async setup() {
|
|
28
|
-
if (import.meta.server) return
|
|
29
|
-
await defineDesktopApp(${configVar})
|
|
30
|
-
},
|
|
31
|
-
})
|
|
32
|
-
`,
|
|
33
|
-
)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function buildLaunchPlugin(cfg) {
|
|
37
|
-
const l = cfg.launch
|
|
38
|
-
if (l.fsDemo) {
|
|
39
|
-
return `import { nextTick } from 'vue'
|
|
40
|
-
import { defineNuxtPlugin } from 'nuxt/app'
|
|
41
|
-
import { useApplicationManager } from '@owdproject/core/runtime/composables/useApplicationManager'
|
|
42
|
-
import { openVfsFile } from '@owdproject/module-fs/runtime/utils/utilFsOpenFile'
|
|
43
|
-
|
|
44
|
-
const APP_ID = '${l.appId}'
|
|
45
|
-
|
|
46
|
-
export default defineNuxtPlugin({
|
|
47
|
-
name: '${l.pluginName}',
|
|
48
|
-
dependsOn: ['${l.dependsOn}'],
|
|
49
|
-
async setup(nuxtApp) {
|
|
50
|
-
if (!import.meta.dev) return
|
|
51
|
-
|
|
52
|
-
const applicationManager = useApplicationManager()
|
|
53
|
-
|
|
54
|
-
async function runDemo() {
|
|
55
|
-
if (!applicationManager.isAppDefined('org.owdproject.explorer')) return false
|
|
56
|
-
await applicationManager.execAppCommand('org.owdproject.explorer', 'explorer /mnt/test')
|
|
57
|
-
const opened = await openVfsFile('/mnt/test/demo.mp3')
|
|
58
|
-
if (!opened && applicationManager.isAppDefined(APP_ID)) {
|
|
59
|
-
await applicationManager.execAppCommand(APP_ID, ${JSON.stringify(l.command)})
|
|
60
|
-
}
|
|
61
|
-
return true
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
nuxtApp.hook('app:mounted', async () => {
|
|
65
|
-
await nextTick()
|
|
66
|
-
for (let i = 0; i < 80; i++) {
|
|
67
|
-
if (await runDemo()) return
|
|
68
|
-
await new Promise((r) => setTimeout(r, 50))
|
|
69
|
-
}
|
|
70
|
-
})
|
|
71
|
-
},
|
|
72
|
-
})
|
|
73
|
-
`
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return `import { nextTick } from 'vue'
|
|
77
|
-
import { defineNuxtPlugin } from 'nuxt/app'
|
|
78
|
-
import { useApplicationManager } from '@owdproject/core/runtime/composables/useApplicationManager'
|
|
79
|
-
|
|
80
|
-
const APP_ID = '${l.appId}'
|
|
81
|
-
const WINDOW_MODEL = 'main'
|
|
82
|
-
|
|
83
|
-
export default defineNuxtPlugin({
|
|
84
|
-
name: '${l.pluginName}',
|
|
85
|
-
dependsOn: ['${l.dependsOn}'],
|
|
86
|
-
async setup(nuxtApp) {
|
|
87
|
-
if (!import.meta.dev) return
|
|
88
|
-
|
|
89
|
-
const applicationManager = useApplicationManager()
|
|
90
|
-
|
|
91
|
-
async function surfaceWindow() {
|
|
92
|
-
if (!applicationManager.isAppDefined(APP_ID)) return false
|
|
93
|
-
const app = applicationManager.getAppById(APP_ID)!
|
|
94
|
-
if (app.storeWindows.$persistedState) {
|
|
95
|
-
await app.storeWindows.$persistedState.isReady()
|
|
96
|
-
}
|
|
97
|
-
app.closeAllWindows()
|
|
98
|
-
app.storeWindows.windows = {}
|
|
99
|
-
await applicationManager.execAppCommand(APP_ID, ${JSON.stringify(l.command)})
|
|
100
|
-
const window = app.getFirstWindowByModel(WINDOW_MODEL)
|
|
101
|
-
if (window) {
|
|
102
|
-
window.actions.setActive(true)
|
|
103
|
-
window.actions.bringToFront()
|
|
104
|
-
}
|
|
105
|
-
return Boolean(window)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
nuxtApp.hook('app:mounted', async () => {
|
|
109
|
-
await nextTick()
|
|
110
|
-
await surfaceWindow()
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
for (let attempt = 0; attempt < 80; attempt++) {
|
|
114
|
-
if (await surfaceWindow()) return
|
|
115
|
-
await new Promise((resolve) => setTimeout(resolve, 50))
|
|
116
|
-
}
|
|
117
|
-
},
|
|
118
|
-
})
|
|
119
|
-
`
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function buildPackageJson(cfg, old) {
|
|
123
|
-
const slug = cfg.slug
|
|
124
|
-
const deps = { '@nuxt/kit': '^4.3.0', ...(cfg.dependencies || {}) }
|
|
125
|
-
const devDeps = {
|
|
126
|
-
'@nuxt/module-builder': '^1.0.2',
|
|
127
|
-
'@nuxt/schema': '^4.3.0',
|
|
128
|
-
'@owdproject/core': 'workspace:*',
|
|
129
|
-
'@owdproject/theme-nova': '0.0.1',
|
|
130
|
-
nuxt: '^4.3.0',
|
|
131
|
-
typescript: '~5.9.3',
|
|
132
|
-
...(cfg.devDependencies || {}),
|
|
133
|
-
...(cfg.playgroundExtraDevDeps || {}),
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const pkg = {
|
|
137
|
-
name: cfg.name,
|
|
138
|
-
version: old.version || cfg.version,
|
|
139
|
-
description: old.description,
|
|
140
|
-
keywords: old.keywords || cfg.keywords,
|
|
141
|
-
license: old.license || 'MIT',
|
|
142
|
-
homepage: old.homepage || `https://github.com/owdproject/${slug}`,
|
|
143
|
-
author: old.author,
|
|
144
|
-
type: 'module',
|
|
145
|
-
exports: { '.': { types: './dist/types.d.mts', import: './dist/module.mjs' } },
|
|
146
|
-
main: './dist/module.mjs',
|
|
147
|
-
typesVersions: { '*': { '.': ['./dist/types.d.mts'] } },
|
|
148
|
-
files: ['dist'],
|
|
149
|
-
nx: { name: slug },
|
|
150
|
-
scripts: {
|
|
151
|
-
prepack: 'nuxt-module-build build',
|
|
152
|
-
dev: 'pnpm run dev:prepare && cd playground && pnpm exec nuxt dev',
|
|
153
|
-
'dev:build': 'nuxt build playground',
|
|
154
|
-
'dev:generate': `NUXT_APP_BASE_URL=\${NUXT_APP_BASE_URL:-/${slug}/} nuxt generate playground`,
|
|
155
|
-
'dev:prepare':
|
|
156
|
-
'nuxt-module-build build --stub && nuxt-module-build prepare && cd playground && pnpm exec nuxt prepare',
|
|
157
|
-
validate: 'desktop validate .',
|
|
158
|
-
},
|
|
159
|
-
dependencies: deps,
|
|
160
|
-
devDependencies: devDeps,
|
|
161
|
-
peerDependencies: old.peerDependencies || { '@owdproject/core': '^3.2.0' },
|
|
162
|
-
}
|
|
163
|
-
if (cfg.private || old.private) pkg.private = true
|
|
164
|
-
if (old.peerDependenciesMeta) pkg.peerDependenciesMeta = old.peerDependenciesMeta
|
|
165
|
-
return pkg
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function buildPlaygroundPkg(cfg) {
|
|
169
|
-
const deps = {
|
|
170
|
-
'@owdproject/core': 'workspace:*',
|
|
171
|
-
[cfg.name]: 'workspace:*',
|
|
172
|
-
nuxt: '^4.4.4',
|
|
173
|
-
...(cfg.playgroundExtraDevDeps || {}),
|
|
174
|
-
}
|
|
175
|
-
if (!cfg.playgroundTheme) deps['@owdproject/theme-nova'] = '0.0.1'
|
|
176
|
-
if (cfg.playgroundTheme) deps[cfg.playgroundTheme] = 'workspace:*'
|
|
177
|
-
return {
|
|
178
|
-
name: `${cfg.name}-playground`,
|
|
179
|
-
private: true,
|
|
180
|
-
type: 'module',
|
|
181
|
-
scripts: { dev: 'nuxt dev', build: 'nuxt build', generate: 'nuxt generate' },
|
|
182
|
-
dependencies: deps,
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
function buildDesktopConfig(cfg) {
|
|
187
|
-
const theme = cfg.playgroundTheme || '@owdproject/theme-nova'
|
|
188
|
-
const apps = cfg.playgroundApps || [cfg.name]
|
|
189
|
-
const modules = cfg.playgroundModules || []
|
|
190
|
-
let s = `import { defineDesktopConfig } from '@owdproject/core'\n\nexport default defineDesktopConfig({\n theme: '${theme}',\n`
|
|
191
|
-
if (apps.length) s += ` apps: [${apps.map((a) => `'${a}'`).join(', ')}],\n`
|
|
192
|
-
if (modules.length) s += ` modules: [${modules.map((m) => `'${m}'`).join(', ')}],\n`
|
|
193
|
-
s += ' systemBar: { enabled: true, startButton: true },\n'
|
|
194
|
-
if (cfg.fsMounts) {
|
|
195
|
-
s += ' fs: {\n mounts: {\n'
|
|
196
|
-
for (const [k, v] of Object.entries(cfg.fsMounts)) s += ` '${k}': '${v}',\n`
|
|
197
|
-
s += ' },\n },\n'
|
|
198
|
-
}
|
|
199
|
-
s += '})\n'
|
|
200
|
-
return s
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
const NUXT = `export default defineNuxtConfig({
|
|
204
|
-
modules: ['@owdproject/core'],
|
|
205
|
-
app: { baseURL: process.env.NUXT_APP_BASE_URL || '/' },
|
|
206
|
-
i18n: { strategy: 'no_prefix' },
|
|
207
|
-
devtools: { enabled: true },
|
|
208
|
-
compatibilityDate: 'latest',
|
|
209
|
-
ssr: false,
|
|
210
|
-
})
|
|
211
|
-
`
|
|
212
|
-
|
|
213
|
-
function pagesYml(slug) {
|
|
214
|
-
return `name: Deploy playground to GitHub Pages
|
|
215
|
-
on:
|
|
216
|
-
push:
|
|
217
|
-
branches: [main]
|
|
218
|
-
workflow_dispatch:
|
|
219
|
-
permissions:
|
|
220
|
-
contents: read
|
|
221
|
-
pages: write
|
|
222
|
-
id-token: write
|
|
223
|
-
concurrency:
|
|
224
|
-
group: pages
|
|
225
|
-
cancel-in-progress: true
|
|
226
|
-
jobs:
|
|
227
|
-
build:
|
|
228
|
-
runs-on: ubuntu-latest
|
|
229
|
-
steps:
|
|
230
|
-
- uses: actions/checkout@v6
|
|
231
|
-
- uses: actions/setup-node@v6
|
|
232
|
-
with:
|
|
233
|
-
node-version: 22
|
|
234
|
-
- run: npm i -g --force corepack@latest && corepack enable
|
|
235
|
-
- run: npx nypm@latest i
|
|
236
|
-
- run: npm run dev:prepare
|
|
237
|
-
- run: npm run dev:generate
|
|
238
|
-
env:
|
|
239
|
-
NUXT_APP_BASE_URL: /${slug}/
|
|
240
|
-
- uses: actions/upload-pages-artifact@v3
|
|
241
|
-
with:
|
|
242
|
-
path: playground/.output/public
|
|
243
|
-
deploy:
|
|
244
|
-
needs: build
|
|
245
|
-
runs-on: ubuntu-latest
|
|
246
|
-
environment:
|
|
247
|
-
name: github-pages
|
|
248
|
-
url: \${{ steps.deployment.outputs.page_url }}
|
|
249
|
-
steps:
|
|
250
|
-
- uses: actions/deploy-pages@v4
|
|
251
|
-
`
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
function migrate(cfg) {
|
|
255
|
-
const dir = join(ROOT, cfg.path)
|
|
256
|
-
const src = join(dir, 'src')
|
|
257
|
-
mkdirSync(src, { recursive: true })
|
|
258
|
-
if (existsSync(join(dir, 'module.ts'))) renameSync(join(dir, 'module.ts'), join(src, 'module.ts'))
|
|
259
|
-
if (existsSync(join(dir, 'runtime'))) renameSync(join(dir, 'runtime'), join(src, 'runtime'))
|
|
260
|
-
|
|
261
|
-
const registerName = `${cfg.moduleName}-register`
|
|
262
|
-
const pluginPath = join(src, 'runtime/plugin.ts')
|
|
263
|
-
if (existsSync(pluginPath)) fixAppPlugin(pluginPath, registerName)
|
|
264
|
-
|
|
265
|
-
const old = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8'))
|
|
266
|
-
writeFileSync(join(dir, 'package.json'), JSON.stringify(buildPackageJson(cfg, old), null, 2) + '\n')
|
|
267
|
-
|
|
268
|
-
writeFileSync(
|
|
269
|
-
join(dir, 'tsconfig.json'),
|
|
270
|
-
JSON.stringify(
|
|
271
|
-
{
|
|
272
|
-
extends: '../../tsconfig.base.json',
|
|
273
|
-
include: ['src/runtime', 'src/module.ts', '../../packages/core/types/index.d.ts'],
|
|
274
|
-
exclude: ['dist', 'node_modules', 'playground'],
|
|
275
|
-
compilerOptions: { outDir: 'dist' },
|
|
276
|
-
},
|
|
277
|
-
null,
|
|
278
|
-
2,
|
|
279
|
-
) + '\n',
|
|
280
|
-
)
|
|
281
|
-
|
|
282
|
-
writeFileSync(
|
|
283
|
-
join(dir, '.gitignore'),
|
|
284
|
-
'node_modules\n.nuxt\ndist\n.output\nplayground/.nuxt\nplayground/node_modules\n._*\n',
|
|
285
|
-
)
|
|
286
|
-
|
|
287
|
-
const pg = join(dir, 'playground')
|
|
288
|
-
mkdirSync(join(pg, 'app/plugins'), { recursive: true })
|
|
289
|
-
writeFileSync(join(pg, 'nuxt.config.ts'), NUXT)
|
|
290
|
-
writeFileSync(join(pg, 'tsconfig.json'), '{ "extends": "./.nuxt/tsconfig.json" }\n')
|
|
291
|
-
writeFileSync(join(pg, 'package.json'), JSON.stringify(buildPlaygroundPkg(cfg), null, 2) + '\n')
|
|
292
|
-
writeFileSync(join(pg, 'desktop.config.ts'), buildDesktopConfig(cfg))
|
|
293
|
-
writeFileSync(join(pg, 'app/app.vue'), '<template>\n <Desktop />\n</template>\n')
|
|
294
|
-
if (cfg.launch) {
|
|
295
|
-
writeFileSync(join(pg, 'app/plugins', cfg.launch.file), buildLaunchPlugin(cfg))
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
if (cfg.copyTestZip) {
|
|
299
|
-
mkdirSync(join(pg, 'public'), { recursive: true })
|
|
300
|
-
const srcZip = join(ROOT, 'desktop/public/test.zip')
|
|
301
|
-
if (existsSync(srcZip)) copyFileSync(srcZip, join(pg, 'public/test.zip'))
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
if (cfg.pagesYml) {
|
|
305
|
-
const wf = join(dir, '.github/workflows')
|
|
306
|
-
mkdirSync(wf, { recursive: true })
|
|
307
|
-
writeFileSync(join(wf, 'pages.yml'), pagesYml(cfg.slug))
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
console.log('OK', cfg.name)
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
for (const cfg of configs) migrate(cfg)
|
package/bin/lib/npmVersions.js
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import { execSync } from 'node:child_process'
|
|
2
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
|
|
3
|
-
import { join } from 'node:path'
|
|
4
|
-
import { desktopMetaDir } from './workspace.js'
|
|
5
|
-
|
|
6
|
-
const CACHE_TTL_MS = 60 * 60 * 1000
|
|
7
|
-
const SCOPE = '@owdproject/'
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @param {string} version
|
|
11
|
-
*/
|
|
12
|
-
export function formatCaretVersion(version) {
|
|
13
|
-
const trimmed = String(version).trim()
|
|
14
|
-
if (!trimmed) throw new Error('Invalid npm version (empty)')
|
|
15
|
-
if (trimmed.startsWith('^') || trimmed.startsWith('~') || trimmed.startsWith('>=')) {
|
|
16
|
-
return trimmed
|
|
17
|
-
}
|
|
18
|
-
return `^${trimmed}`
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* @param {unknown} error
|
|
23
|
-
*/
|
|
24
|
-
function isNpmLookupSkippableError(error) {
|
|
25
|
-
const msg = error?.stderr?.toString?.() || error?.message || String(error)
|
|
26
|
-
return (
|
|
27
|
-
/E404|404 Not Found/.test(msg) ||
|
|
28
|
-
/EAI_AGAIN|ENOTFOUND|ETIMEDOUT|ECONNREFUSED|network/i.test(msg)
|
|
29
|
-
)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* @param {string} pkgName
|
|
34
|
-
* @param {{ optional?: boolean }} [options]
|
|
35
|
-
* @returns {string | null}
|
|
36
|
-
*/
|
|
37
|
-
export function fetchLatestVersion(pkgName, options = {}) {
|
|
38
|
-
let out
|
|
39
|
-
try {
|
|
40
|
-
out = execSync(`npm view ${JSON.stringify(pkgName)} version`, {
|
|
41
|
-
encoding: 'utf8',
|
|
42
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
43
|
-
}).trim()
|
|
44
|
-
} catch (error) {
|
|
45
|
-
if (options.optional || isNpmLookupSkippableError(error)) return null
|
|
46
|
-
const msg = error.stderr?.toString?.() || error.message || String(error)
|
|
47
|
-
throw new Error(`npm view failed for ${pkgName}: ${msg}`)
|
|
48
|
-
}
|
|
49
|
-
return formatCaretVersion(out)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* @param {string[]} pkgNames
|
|
54
|
-
* @returns {Record<string, string>}
|
|
55
|
-
*/
|
|
56
|
-
export function fetchLatestVersions(pkgNames, options = {}) {
|
|
57
|
-
const unique = [...new Set(pkgNames.filter(Boolean))]
|
|
58
|
-
if (unique.length === 0) return {}
|
|
59
|
-
|
|
60
|
-
/** @type {Record<string, string>} */
|
|
61
|
-
const result = {}
|
|
62
|
-
for (const name of unique) {
|
|
63
|
-
const version = fetchLatestVersion(name, options)
|
|
64
|
-
if (version) result[name] = version
|
|
65
|
-
}
|
|
66
|
-
return result
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function cachePath(workspaceRoot) {
|
|
70
|
-
return join(desktopMetaDir(workspaceRoot), 'template-versions.json')
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* @param {string} workspaceRoot
|
|
75
|
-
* @param {string[]} pkgNames
|
|
76
|
-
* @param {{ useCache?: boolean }} [options]
|
|
77
|
-
*/
|
|
78
|
-
export function resolveLatestVersions(workspaceRoot, pkgNames, options = {}) {
|
|
79
|
-
const useCache = options.useCache !== false
|
|
80
|
-
const unique = [...new Set(pkgNames.filter(Boolean))]
|
|
81
|
-
const path = cachePath(workspaceRoot)
|
|
82
|
-
|
|
83
|
-
if (useCache && existsSync(path)) {
|
|
84
|
-
try {
|
|
85
|
-
const data = JSON.parse(readFileSync(path, 'utf8'))
|
|
86
|
-
if (Date.now() - data.fetchedAt < CACHE_TTL_MS && data.versions) {
|
|
87
|
-
const cached = data.versions
|
|
88
|
-
const missing = unique.filter((name) => !cached[name])
|
|
89
|
-
if (missing.length === 0) {
|
|
90
|
-
return Object.fromEntries(unique.map((name) => [name, cached[name]]))
|
|
91
|
-
}
|
|
92
|
-
const fresh = fetchLatestVersions(missing)
|
|
93
|
-
const merged = { ...cached, ...fresh }
|
|
94
|
-
writeVersionCache(workspaceRoot, merged)
|
|
95
|
-
return Object.fromEntries(unique.map((name) => [name, merged[name]]))
|
|
96
|
-
}
|
|
97
|
-
} catch {
|
|
98
|
-
/* ignore corrupt cache */
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const versions = fetchLatestVersions(unique)
|
|
103
|
-
if (useCache) writeVersionCache(workspaceRoot, versions)
|
|
104
|
-
return versions
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* @param {string} workspaceRoot
|
|
109
|
-
* @param {Record<string, string>} versions
|
|
110
|
-
*/
|
|
111
|
-
export function writeVersionCache(workspaceRoot, versions) {
|
|
112
|
-
mkdirSync(desktopMetaDir(workspaceRoot), { recursive: true })
|
|
113
|
-
writeFileSync(
|
|
114
|
-
cachePath(workspaceRoot),
|
|
115
|
-
JSON.stringify({ fetchedAt: Date.now(), versions }, null, 2) + '\n',
|
|
116
|
-
)
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* @param {string} pkgName
|
|
121
|
-
*/
|
|
122
|
-
export function isOwdScopedPackage(pkgName) {
|
|
123
|
-
return pkgName.startsWith(SCOPE)
|
|
124
|
-
}
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from 'node:fs'
|
|
2
|
-
import { dirname, join, resolve, sep } from 'node:path'
|
|
3
|
-
import { SCOPE } from './workspace.js'
|
|
4
|
-
|
|
5
|
-
const PLAYGROUND_CONFIG = join('playground', 'desktop.config.ts')
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @param {string} dir
|
|
9
|
-
* @returns {boolean}
|
|
10
|
-
*/
|
|
11
|
-
export function hasPlaygroundDesktopConfig(dir) {
|
|
12
|
-
return (
|
|
13
|
-
existsSync(join(dir, 'playground')) &&
|
|
14
|
-
existsSync(join(dir, PLAYGROUND_CONFIG))
|
|
15
|
-
)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @param {string} pkgPath
|
|
20
|
-
* @returns {{ name: string } | null}
|
|
21
|
-
*/
|
|
22
|
-
function readOwdPackageJson(pkgPath) {
|
|
23
|
-
if (!existsSync(pkgPath)) return null
|
|
24
|
-
try {
|
|
25
|
-
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'))
|
|
26
|
-
if (typeof pkg.name === 'string' && pkg.name.startsWith(SCOPE)) {
|
|
27
|
-
return { name: pkg.name }
|
|
28
|
-
}
|
|
29
|
-
} catch {
|
|
30
|
-
/* ignore */
|
|
31
|
-
}
|
|
32
|
-
return null
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Walk up from cwd until a package.json with @owdproject/* name and a playground
|
|
37
|
-
* with desktop.config.ts is found.
|
|
38
|
-
*
|
|
39
|
-
* @param {string} [startDir]
|
|
40
|
-
* @returns {string | null} Absolute package directory
|
|
41
|
-
*/
|
|
42
|
-
export function findOwdModulePackageRoot(startDir = process.cwd()) {
|
|
43
|
-
let dir = resolve(startDir)
|
|
44
|
-
for (;;) {
|
|
45
|
-
const meta = readOwdPackageJson(join(dir, 'package.json'))
|
|
46
|
-
if (meta && hasPlaygroundDesktopConfig(dir)) {
|
|
47
|
-
return dir
|
|
48
|
-
}
|
|
49
|
-
const parent = dirname(dir)
|
|
50
|
-
if (parent === dir) return null
|
|
51
|
-
dir = parent
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* @param {string} path
|
|
57
|
-
* @param {string} root
|
|
58
|
-
*/
|
|
59
|
-
function isPathInside(path, root) {
|
|
60
|
-
const normalized = resolve(path)
|
|
61
|
-
const base = resolve(root)
|
|
62
|
-
return normalized === base || normalized.startsWith(base + sep)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* @typedef {'workspace' | 'playground'} DevTargetMode
|
|
67
|
-
*/
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* @typedef {object} DevTarget
|
|
71
|
-
* @property {DevTargetMode} mode
|
|
72
|
-
* @property {string} workspaceRoot
|
|
73
|
-
* @property {string} packageDir Directory where `pnpm run dev` runs
|
|
74
|
-
* @property {string | null} packageName Set when mode is playground
|
|
75
|
-
* @property {string | null} playgroundDir Absolute path to playground/
|
|
76
|
-
*/
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* @param {string} packageDir
|
|
80
|
-
* @param {string} workspaceRoot
|
|
81
|
-
* @param {string} packageName
|
|
82
|
-
* @returns {DevTarget}
|
|
83
|
-
*/
|
|
84
|
-
function playgroundTarget(packageDir, workspaceRoot, packageName) {
|
|
85
|
-
return {
|
|
86
|
-
mode: 'playground',
|
|
87
|
-
workspaceRoot,
|
|
88
|
-
packageDir: resolve(packageDir),
|
|
89
|
-
packageName,
|
|
90
|
-
playgroundDir: join(resolve(packageDir), 'playground'),
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* @param {string} workspaceRoot
|
|
96
|
-
* @returns {DevTarget}
|
|
97
|
-
*/
|
|
98
|
-
function workspaceTarget(workspaceRoot) {
|
|
99
|
-
return {
|
|
100
|
-
mode: 'workspace',
|
|
101
|
-
workspaceRoot: resolve(workspaceRoot),
|
|
102
|
-
packageDir: resolve(workspaceRoot),
|
|
103
|
-
packageName: null,
|
|
104
|
-
playgroundDir: null,
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Resolve whether the CLI/TUI should start the monorepo desktop shell or a
|
|
110
|
-
* module package playground dev server.
|
|
111
|
-
*
|
|
112
|
-
* @param {string} [cwd]
|
|
113
|
-
* @param {string | null} workspaceRoot
|
|
114
|
-
* @param {{ forcePlayground?: boolean }} [options]
|
|
115
|
-
* @returns {DevTarget | null} null when workspaceRoot is missing
|
|
116
|
-
*/
|
|
117
|
-
export function resolveDevTarget(cwd, workspaceRoot, options = {}) {
|
|
118
|
-
if (!workspaceRoot) return null
|
|
119
|
-
|
|
120
|
-
const normalizedCwd = resolve(cwd ?? process.cwd())
|
|
121
|
-
const root = resolve(workspaceRoot)
|
|
122
|
-
const desktopDir = join(root, 'desktop')
|
|
123
|
-
const packageRoot = findOwdModulePackageRoot(normalizedCwd)
|
|
124
|
-
const forcePlayground = options.forcePlayground === true
|
|
125
|
-
|
|
126
|
-
if (packageRoot) {
|
|
127
|
-
const meta = readOwdPackageJson(join(packageRoot, 'package.json'))
|
|
128
|
-
const packageName = meta?.name ?? null
|
|
129
|
-
|
|
130
|
-
if (forcePlayground) {
|
|
131
|
-
return playgroundTarget(packageRoot, root, packageName)
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const atWorkspaceRoot = normalizedCwd === root
|
|
135
|
-
const underDesktopOnly =
|
|
136
|
-
isPathInside(normalizedCwd, desktopDir) && !isPathInside(normalizedCwd, packageRoot)
|
|
137
|
-
|
|
138
|
-
if (!atWorkspaceRoot && !underDesktopOnly && isPathInside(normalizedCwd, packageRoot)) {
|
|
139
|
-
return playgroundTarget(packageRoot, root, packageName)
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
if (forcePlayground) {
|
|
144
|
-
return null
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return workspaceTarget(root)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* @param {DevTarget | string | null | undefined} target
|
|
152
|
-
* @param {string} [workspaceRoot]
|
|
153
|
-
* @returns {DevTarget | null}
|
|
154
|
-
*/
|
|
155
|
-
export function normalizeDevTarget(target, workspaceRoot) {
|
|
156
|
-
if (!target) return workspaceRoot ? workspaceTarget(workspaceRoot) : null
|
|
157
|
-
if (typeof target === 'string') return workspaceTarget(target)
|
|
158
|
-
if (target.mode && target.workspaceRoot) return target
|
|
159
|
-
if (workspaceRoot) {
|
|
160
|
-
return {
|
|
161
|
-
...workspaceTarget(workspaceRoot),
|
|
162
|
-
...target,
|
|
163
|
-
workspaceRoot: resolve(workspaceRoot),
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
return null
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* @param {DevTarget | string} target
|
|
171
|
-
* @returns {string}
|
|
172
|
-
*/
|
|
173
|
-
export function devSpawnCwd(target) {
|
|
174
|
-
const resolved = typeof target === 'string' ? workspaceTarget(target) : target
|
|
175
|
-
return resolved.packageDir
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* @param {DevTarget | string} target
|
|
180
|
-
* @returns {string}
|
|
181
|
-
*/
|
|
182
|
-
export function devTargetLogLabel(target) {
|
|
183
|
-
const resolved = typeof target === 'string' ? workspaceTarget(target) : target
|
|
184
|
-
if (resolved.mode === 'playground' && resolved.packageName) {
|
|
185
|
-
return `playground ${resolved.packageName}`
|
|
186
|
-
}
|
|
187
|
-
return 'workspace desktop'
|
|
188
|
-
}
|