uniweb 0.9.0 → 0.9.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 +5 -5
- package/src/versions.js +136 -35
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uniweb",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Create structured Vite + React sites with content/code separation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -41,13 +41,13 @@
|
|
|
41
41
|
"js-yaml": "^4.1.0",
|
|
42
42
|
"prompts": "^2.4.2",
|
|
43
43
|
"tar": "^7.0.0",
|
|
44
|
-
"@uniweb/core": "0.6.
|
|
45
|
-
"@uniweb/runtime": "0.7.
|
|
46
|
-
"@uniweb/kit": "0.8.
|
|
44
|
+
"@uniweb/core": "0.6.1",
|
|
45
|
+
"@uniweb/runtime": "0.7.1",
|
|
46
|
+
"@uniweb/kit": "0.8.1"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"@uniweb/content-reader": "1.1.4",
|
|
50
|
-
"@uniweb/build": "0.9.
|
|
50
|
+
"@uniweb/build": "0.9.1",
|
|
51
51
|
"@uniweb/semantic-parser": "1.1.9"
|
|
52
52
|
},
|
|
53
53
|
"peerDependenciesMeta": {
|
package/src/versions.js
CHANGED
|
@@ -1,11 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Version resolution utility
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Produces npm-compatible version specs for every `@uniweb/*` package the
|
|
5
|
+
* scaffolder might reference when materializing a new project. The caller
|
|
6
|
+
* (templates/processor.js via the `{{version}}` Handlebars helper) never
|
|
7
|
+
* needs to know whether the CLI is running locally from a pnpm workspace
|
|
8
|
+
* or as an npm-installed binary — both code paths feed through here.
|
|
9
|
+
*
|
|
10
|
+
* ## How versions are resolved
|
|
11
|
+
*
|
|
12
|
+
* 1. Start from the CLI's own `package.json` dependencies. When the CLI
|
|
13
|
+
* was installed via npm, pnpm has already resolved every `workspace:*`
|
|
14
|
+
* spec into a concrete version like `^0.9.1`, so this step is
|
|
15
|
+
* usually enough.
|
|
16
|
+
* 2. For any dep that is still `workspace:*` (i.e. the CLI is running
|
|
17
|
+
* *from* the pnpm workspace — local dev, sandbox script, tests), fall
|
|
18
|
+
* back to reading the real `package.json` of each sibling package
|
|
19
|
+
* under `framework/<name>/` and using `^<that version>`. This is the
|
|
20
|
+
* path that keeps local sandboxes and templates aligned with whatever
|
|
21
|
+
* was last bumped in the monorepo.
|
|
22
|
+
* 3. Scan `framework/*` to catch any additional `@uniweb/*` package that
|
|
23
|
+
* wasn't explicitly listed as a CLI dep (press, loom, scholar, etc.).
|
|
24
|
+
* New packages get picked up by the scaffolder automatically.
|
|
25
|
+
*
|
|
26
|
+
* The previous implementation shipped a hardcoded fallback table and
|
|
27
|
+
* nothing kept it in sync with reality — see the audit note in
|
|
28
|
+
* `framework/CLAUDE.md` under "Publishing". Every workspace-based scaffold
|
|
29
|
+
* silently pinned against years-old versions. That table is gone. If this
|
|
30
|
+
* function ever fails to resolve a package, it returns `^0.0.0` rather
|
|
31
|
+
* than a stale best-guess, so the breakage is loud.
|
|
6
32
|
*/
|
|
7
33
|
|
|
8
|
-
import { readFileSync } from 'node:fs'
|
|
34
|
+
import { readFileSync, readdirSync, statSync } from 'node:fs'
|
|
9
35
|
import { dirname, join } from 'node:path'
|
|
10
36
|
import { fileURLToPath } from 'node:url'
|
|
11
37
|
|
|
@@ -32,37 +58,104 @@ export function getCliVersion() {
|
|
|
32
58
|
}
|
|
33
59
|
|
|
34
60
|
/**
|
|
35
|
-
*
|
|
61
|
+
* Locate the framework/ directory on disk. When the CLI is running from
|
|
62
|
+
* the pnpm workspace, this resolves to `<workspace>/framework/`. When the
|
|
63
|
+
* CLI is installed from npm, this directory won't exist — callers must
|
|
64
|
+
* handle that (return null) so the function doesn't pretend to know more
|
|
65
|
+
* than it does.
|
|
36
66
|
*/
|
|
37
|
-
function
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
67
|
+
function getFrameworkRoot() {
|
|
68
|
+
const candidate = join(__dirname, '..', '..')
|
|
69
|
+
try {
|
|
70
|
+
if (statSync(candidate).isDirectory()) {
|
|
71
|
+
return candidate
|
|
72
|
+
}
|
|
73
|
+
} catch {}
|
|
74
|
+
return null
|
|
41
75
|
}
|
|
42
76
|
|
|
43
77
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* @param {string} fallback - Fallback version if spec is not resolvable
|
|
49
|
-
* @returns {string} npm-compatible version spec
|
|
78
|
+
* Read the current on-disk version of a specific `@uniweb/*` package by
|
|
79
|
+
* looking up `framework/<last-segment>/package.json`. Returns a caret
|
|
80
|
+
* range string like `^0.6.0`, or null if the package isn't present on
|
|
81
|
+
* disk (i.e. the CLI is running from npm, not from the workspace).
|
|
50
82
|
*/
|
|
51
|
-
function
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
83
|
+
function readWorkspaceVersion(packageName) {
|
|
84
|
+
const root = getFrameworkRoot()
|
|
85
|
+
if (!root) return null
|
|
86
|
+
const shortName = packageName.startsWith('@uniweb/')
|
|
87
|
+
? packageName.slice('@uniweb/'.length)
|
|
88
|
+
: packageName
|
|
89
|
+
const pkgPath = join(root, shortName, 'package.json')
|
|
90
|
+
try {
|
|
91
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'))
|
|
92
|
+
if (pkg.name === packageName && pkg.version) {
|
|
93
|
+
return `^${pkg.version}`
|
|
94
|
+
}
|
|
95
|
+
} catch {}
|
|
96
|
+
return null
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Enumerate every `@uniweb/*` package under `framework/*` and return a
|
|
101
|
+
* map of `{ name: '^version' }`. Used to seed the resolved-versions
|
|
102
|
+
* cache so that packages not explicitly listed in the CLI's own deps
|
|
103
|
+
* (press, loom, scholar, schemas, etc.) still have a version available
|
|
104
|
+
* to templates that reference them.
|
|
105
|
+
*/
|
|
106
|
+
function discoverWorkspacePackages() {
|
|
107
|
+
const root = getFrameworkRoot()
|
|
108
|
+
if (!root) return {}
|
|
109
|
+
const found = {}
|
|
110
|
+
let entries
|
|
111
|
+
try {
|
|
112
|
+
entries = readdirSync(root, { withFileTypes: true })
|
|
113
|
+
} catch {
|
|
114
|
+
return {}
|
|
115
|
+
}
|
|
116
|
+
for (const entry of entries) {
|
|
117
|
+
if (!entry.isDirectory()) continue
|
|
118
|
+
if (entry.name.startsWith('.') || entry.name.startsWith('_')) continue
|
|
119
|
+
const pkgPath = join(root, entry.name, 'package.json')
|
|
120
|
+
try {
|
|
121
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'))
|
|
122
|
+
if (pkg.name && pkg.version && pkg.name.startsWith('@uniweb/')) {
|
|
123
|
+
found[pkg.name] = `^${pkg.version}`
|
|
124
|
+
}
|
|
125
|
+
} catch {}
|
|
126
|
+
}
|
|
127
|
+
return found
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Resolve a single version spec to something npm can install. A concrete
|
|
132
|
+
* spec like `^0.9.0` passes through untouched; `workspace:*` is replaced
|
|
133
|
+
* by the on-disk version of the named package; anything still unresolved
|
|
134
|
+
* returns null so the caller can fall back.
|
|
135
|
+
*/
|
|
136
|
+
function resolveVersionSpec(spec, packageName) {
|
|
137
|
+
if (!spec) return null
|
|
138
|
+
if (spec.startsWith('workspace:')) {
|
|
139
|
+
return readWorkspaceVersion(packageName)
|
|
140
|
+
}
|
|
55
141
|
return spec
|
|
56
142
|
}
|
|
57
143
|
|
|
58
144
|
/**
|
|
59
|
-
* Get resolved versions for @uniweb/* packages
|
|
145
|
+
* Get resolved versions for @uniweb/* packages.
|
|
60
146
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
147
|
+
* Priority (highest first):
|
|
148
|
+
* 1. A concrete version spec already in the CLI's own `package.json`
|
|
149
|
+
* (the state after an npm publish: `workspace:*` is resolved to a
|
|
150
|
+
* real version).
|
|
151
|
+
* 2. The on-disk version of the matching workspace package (the state
|
|
152
|
+
* during local development).
|
|
153
|
+
* 3. Discovery fallback — every `@uniweb/*` package found under
|
|
154
|
+
* `framework/*`, for packages that aren't in the CLI's own deps.
|
|
63
155
|
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
156
|
+
* The return shape is stable across both paths: a map of package names to
|
|
157
|
+
* npm-compatible version specs, plus the CLI's own version under the key
|
|
158
|
+
* `uniweb`.
|
|
66
159
|
*
|
|
67
160
|
* @returns {Object} Map of package names to version specs
|
|
68
161
|
*/
|
|
@@ -72,20 +165,28 @@ export function getResolvedVersions() {
|
|
|
72
165
|
const pkg = getCliPackageJson()
|
|
73
166
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies, ...pkg.peerDependencies }
|
|
74
167
|
|
|
75
|
-
//
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
'@uniweb/kit': resolveVersionSpec(deps['@uniweb/kit'], '^0.1.4'),
|
|
82
|
-
'@uniweb/runtime': resolveVersionSpec(deps['@uniweb/runtime'], '^0.2.3'),
|
|
83
|
-
'@uniweb/templates': resolveVersionSpec(deps['@uniweb/templates'], '^0.1.6'),
|
|
84
|
-
|
|
85
|
-
// CLI itself (use current version)
|
|
86
|
-
'uniweb': `^${pkg.version}`,
|
|
168
|
+
// Seed from the CLI's own deps (the authoritative set when installed from npm).
|
|
169
|
+
const result = {}
|
|
170
|
+
for (const [name, spec] of Object.entries(deps)) {
|
|
171
|
+
if (!name.startsWith('@uniweb/')) continue
|
|
172
|
+
const resolved = resolveVersionSpec(spec, name)
|
|
173
|
+
if (resolved) result[name] = resolved
|
|
87
174
|
}
|
|
88
175
|
|
|
176
|
+
// Merge in anything under framework/* that the CLI didn't list explicitly.
|
|
177
|
+
// A newly-added package (e.g. @uniweb/press) becomes reachable via
|
|
178
|
+
// {{version "@uniweb/press"}} without touching the CLI's package.json.
|
|
179
|
+
const discovered = discoverWorkspacePackages()
|
|
180
|
+
for (const [name, version] of Object.entries(discovered)) {
|
|
181
|
+
if (!result[name]) result[name] = version
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// CLI itself. Caret on the current version — templates referencing
|
|
185
|
+
// `{{version "uniweb"}}` pick up whatever patch/minor ships in the
|
|
186
|
+
// same publish cycle as the template.
|
|
187
|
+
result['uniweb'] = `^${pkg.version}`
|
|
188
|
+
|
|
189
|
+
resolvedVersions = result
|
|
89
190
|
return resolvedVersions
|
|
90
191
|
}
|
|
91
192
|
|