uniweb 0.10.9 → 0.10.12
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 +7 -7
- package/partials/agents.md +2 -0
- package/src/commands/deploy.js +152 -34
- package/src/framework-index.json +9 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uniweb",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.12",
|
|
4
4
|
"description": "Create structured Vite + React sites with content/code separation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -41,14 +41,14 @@
|
|
|
41
41
|
"js-yaml": "^4.1.0",
|
|
42
42
|
"prompts": "^2.4.2",
|
|
43
43
|
"tar": "^7.0.0",
|
|
44
|
-
"@uniweb/
|
|
45
|
-
"@uniweb/
|
|
46
|
-
"@uniweb/runtime": "0.8.
|
|
44
|
+
"@uniweb/kit": "0.9.8",
|
|
45
|
+
"@uniweb/core": "0.7.8",
|
|
46
|
+
"@uniweb/runtime": "0.8.9"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"@uniweb/
|
|
50
|
-
"@uniweb/content-reader": "1.1.
|
|
51
|
-
"@uniweb/
|
|
49
|
+
"@uniweb/build": "0.11.8",
|
|
50
|
+
"@uniweb/content-reader": "1.1.9",
|
|
51
|
+
"@uniweb/semantic-parser": "1.1.15"
|
|
52
52
|
},
|
|
53
53
|
"peerDependenciesMeta": {
|
|
54
54
|
"@uniweb/build": {
|
package/partials/agents.md
CHANGED
|
@@ -1316,6 +1316,8 @@ import LessonHeader from '../../components/LessonHeader'
|
|
|
1316
1316
|
|
|
1317
1317
|
Within the same directory (e.g., one component importing a sibling), use normal relative imports (`./AIFeedbackCard`).
|
|
1318
1318
|
|
|
1319
|
+
**Foundation entry shape (`src/foundation.js`).** A single `export default { … }` whose top-level keys are the capabilities the foundation provides — e.g. `name`, `description`, `defaultLayout`, `defaultSection`, `viewTransitions`, `props`, `defaultInsets`, `xref`, `outputs`, `handlers`. Optionally a named `vars` export for theme-variable metadata (see *Foundation variables*). Everything else (section types, layouts) is auto-discovered from `src/sections/` and `src/layouts/` and merged in by `@uniweb/build`. The build wraps your default export under `default.capabilities` in the produced `dist/foundation.js`; you don't write that wrapper yourself, and most foundation code never sees it. The one place it matters: when you import your **own** `src/foundation.js` from a foundation component (e.g., a download button calling `compileDocument(website, { foundation })`), you get the bare default object — pass it through directly, Press handles both shapes.
|
|
1320
|
+
|
|
1319
1321
|
### Website and Page APIs
|
|
1320
1322
|
|
|
1321
1323
|
```jsx
|
package/src/commands/deploy.js
CHANGED
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
* uniweb deploy --skip-build Don't rebuild even if dist/ is stale
|
|
30
30
|
* uniweb deploy --dry-run Resolve everything but skip the Worker POST
|
|
31
31
|
* uniweb deploy --skip-billing Admin-only: bypass billing gate (dev/testing)
|
|
32
|
+
* uniweb deploy --review Force the browser review path even when
|
|
33
|
+
* there's no drift (e.g., to change features)
|
|
32
34
|
*
|
|
33
35
|
* See kb/platform/plans/cli-site-deploy-decisions.md for the full design.
|
|
34
36
|
*/
|
|
@@ -103,6 +105,12 @@ export async function deploy(args = []) {
|
|
|
103
105
|
const dryRun = args.includes('--dry-run')
|
|
104
106
|
const skipAssets = args.includes('--skip-assets')
|
|
105
107
|
const skipBilling = args.includes('--skip-billing')
|
|
108
|
+
// --review forces the browser review path even when there's no drift.
|
|
109
|
+
// Useful for "I want to look at / change my features" without first
|
|
110
|
+
// having to edit site.yml. The toggles in the review page persist live
|
|
111
|
+
// to DB, so any change the user makes there ends up in site.yml after
|
|
112
|
+
// the loopback finalize roundtrip.
|
|
113
|
+
const forceReview = args.includes('--review')
|
|
106
114
|
|
|
107
115
|
const siteDir = await resolveSiteDir(args)
|
|
108
116
|
const backendUrl = getBackendUrl()
|
|
@@ -130,6 +138,12 @@ export async function deploy(args = []) {
|
|
|
130
138
|
say.dim(`Runtime: ${runtimeVersion} (latest; pin via \`runtime:\` in site.yml)`)
|
|
131
139
|
}
|
|
132
140
|
|
|
141
|
+
// Optional `features:` declaration. Acts as a "request" — CLI sends to
|
|
142
|
+
// PHP, PHP routes through review when it differs from the site's current
|
|
143
|
+
// metadata. Unknown names get warned + dropped before sending so a typo
|
|
144
|
+
// doesn't fail the whole deploy.
|
|
145
|
+
const desiredFeatures = readFeaturesFromYaml(siteYml)
|
|
146
|
+
|
|
133
147
|
const cliToken = await ensureAuth({ command: 'Deploying' })
|
|
134
148
|
|
|
135
149
|
// Always rebuild unless the user explicitly opts out with --skip-build.
|
|
@@ -167,6 +181,22 @@ export async function deploy(args = []) {
|
|
|
167
181
|
const defaultLanguage = siteContent?.config?.defaultLanguage || languages[0] || 'en'
|
|
168
182
|
const theme = await readTheme(siteDir, siteContent)
|
|
169
183
|
|
|
184
|
+
// Multi-locale: @uniweb/build emits dist/<lang>/site-content.json per
|
|
185
|
+
// non-default locale via buildLocalizedContent (translations applied via
|
|
186
|
+
// locales/<lang>.json + freeform/). Load each one so we can ship a full
|
|
187
|
+
// locales: map in the publish payload — same shape as Editor publish.
|
|
188
|
+
// Single-locale sites just have the default and skip the loop.
|
|
189
|
+
const localeContents = { [defaultLanguage]: siteContent }
|
|
190
|
+
for (const lang of languages) {
|
|
191
|
+
if (lang === defaultLanguage) continue
|
|
192
|
+
const localeContentPath = join(distDir, lang, 'site-content.json')
|
|
193
|
+
if (existsSync(localeContentPath)) {
|
|
194
|
+
localeContents[lang] = JSON.parse(await readFile(localeContentPath, 'utf8'))
|
|
195
|
+
} else {
|
|
196
|
+
say.warn(`Locale "${lang}" listed in site config but no dist/${lang}/site-content.json found — skipping.`)
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
170
200
|
if (dryRun) {
|
|
171
201
|
say.info('Dry run — showing what would be deployed:')
|
|
172
202
|
say.dim(`Site dir : ${siteDir}`)
|
|
@@ -185,7 +215,7 @@ export async function deploy(args = []) {
|
|
|
185
215
|
// needsReview=true on first deploy / billing drift in future phases).
|
|
186
216
|
const loopback = await startLoopback()
|
|
187
217
|
|
|
188
|
-
let publishToken, siteIdResolved, handleResolved, publishUrl, validateUrl
|
|
218
|
+
let publishToken, siteIdResolved, handleResolved, publishUrl, validateUrl, mintedFeatures
|
|
189
219
|
try {
|
|
190
220
|
say.info('Requesting deploy authorization…')
|
|
191
221
|
const authorizeBody = {
|
|
@@ -200,6 +230,14 @@ export async function deploy(args = []) {
|
|
|
200
230
|
callbackUrl: loopback.callbackUrl,
|
|
201
231
|
// Dev-only: admin-gated server-side. PHP rejects for non-admins.
|
|
202
232
|
skipBilling: skipBilling || undefined,
|
|
233
|
+
// site.yml-declared target feature set. PHP routes through review
|
|
234
|
+
// (with the desired set pre-applied) when it differs from DB.
|
|
235
|
+
// Always sent as an array; missing/empty `features:` in site.yml
|
|
236
|
+
// is normalized to `[]`, meaning "no paid features".
|
|
237
|
+
desiredFeatures,
|
|
238
|
+
// User-forced review (`uniweb deploy --review`). PHP refuses to
|
|
239
|
+
// fast-path even when nothing else has drifted.
|
|
240
|
+
forceReview: forceReview || undefined,
|
|
203
241
|
}
|
|
204
242
|
let authRes
|
|
205
243
|
try {
|
|
@@ -255,6 +293,10 @@ export async function deploy(args = []) {
|
|
|
255
293
|
publishToken = cb.publishToken
|
|
256
294
|
siteIdResolved = cb.siteId
|
|
257
295
|
handleResolved = cb.handle
|
|
296
|
+
// PHP echoes the live feature set in the loopback callback so the
|
|
297
|
+
// CLI can write `features:` back into site.yml accurately. Older
|
|
298
|
+
// PHP that doesn't include this field is a no-op.
|
|
299
|
+
mintedFeatures = Array.isArray(cb.features) ? cb.features : null
|
|
258
300
|
// Review path: Worker URLs are implicit (we derive them from config).
|
|
259
301
|
publishUrl = `${workerUrl}/api/publish/process`
|
|
260
302
|
validateUrl = `${workerUrl}/api/publish/validate`
|
|
@@ -264,6 +306,7 @@ export async function deploy(args = []) {
|
|
|
264
306
|
handleResolved = authRes.handle
|
|
265
307
|
publishUrl = authRes.publishUrl
|
|
266
308
|
validateUrl = authRes.validateUrl
|
|
309
|
+
mintedFeatures = Array.isArray(authRes.features) ? authRes.features : null
|
|
267
310
|
}
|
|
268
311
|
} finally {
|
|
269
312
|
loopback.close()
|
|
@@ -286,14 +329,16 @@ export async function deploy(args = []) {
|
|
|
286
329
|
process.exit(1)
|
|
287
330
|
}
|
|
288
331
|
|
|
289
|
-
// Asset pipeline — upload dist/assets/*
|
|
290
|
-
//
|
|
291
|
-
//
|
|
292
|
-
//
|
|
332
|
+
// Asset pipeline — upload dist/assets/* + favicon + fonts to S3, then
|
|
333
|
+
// rewrite each locale's siteContent so semantic-parser resolves CDN URLs
|
|
334
|
+
// at render time. Assets themselves are locale-shared (they live in
|
|
335
|
+
// dist/assets/ regardless of language), so the diff/upload runs once
|
|
336
|
+
// and the rewrite walks every locale's content tree in localeContents.
|
|
337
|
+
// Skipped with --skip-assets.
|
|
293
338
|
if (!skipAssets) {
|
|
294
339
|
await uploadAssetsAndRewriteContent({
|
|
295
340
|
siteDir,
|
|
296
|
-
|
|
341
|
+
localeContents,
|
|
297
342
|
siteYml,
|
|
298
343
|
theme,
|
|
299
344
|
backendUrl,
|
|
@@ -311,21 +356,41 @@ export async function deploy(args = []) {
|
|
|
311
356
|
theme,
|
|
312
357
|
languages,
|
|
313
358
|
defaultLanguage,
|
|
314
|
-
//
|
|
315
|
-
//
|
|
316
|
-
|
|
359
|
+
// Same shape as Editor publish — one entry per language. Single-locale
|
|
360
|
+
// sites end up with `{ [defaultLanguage]: siteContent }`; multi-locale
|
|
361
|
+
// sites carry per-locale translated content emitted by buildLocalizedContent.
|
|
362
|
+
locales: localeContents,
|
|
317
363
|
}
|
|
318
364
|
await callPublish({ url: publishUrl, token: publishToken, body: publishPayload })
|
|
319
365
|
|
|
320
|
-
// Write site.id / site.handle back to site.yml so
|
|
321
|
-
//
|
|
322
|
-
//
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
366
|
+
// Write site.id / site.handle / features back to site.yml so the file
|
|
367
|
+
// stays in sync with the live billing state. site.id and site.handle
|
|
368
|
+
// are written on first deploy and any time the server-side handle drifts.
|
|
369
|
+
// `features:` is rewritten whenever the live (server-confirmed) set
|
|
370
|
+
// differs from what's declared — including the case where the user
|
|
371
|
+
// declared `[]` and the live set is `[]` (no diff, no write).
|
|
372
|
+
const siteIdChanged = !!siteIdResolved && !siteYml.site?.id
|
|
373
|
+
const handleChanged = !!siteIdResolved && !!handleResolved && siteYml.site?.handle !== handleResolved
|
|
374
|
+
// desiredFeatures is what we sent to PHP (the simplified model: missing
|
|
375
|
+
// == empty), so comparing mintedFeatures against it tells us whether
|
|
376
|
+
// the file needs updating. Skip the write when nothing changed.
|
|
377
|
+
const featuresChanged = mintedFeatures !== null
|
|
378
|
+
&& !arrayEqualsAsSets(desiredFeatures, mintedFeatures)
|
|
379
|
+
|
|
380
|
+
if (siteIdChanged || handleChanged || featuresChanged) {
|
|
381
|
+
const updates = {}
|
|
382
|
+
if (siteIdChanged || handleChanged) {
|
|
383
|
+
updates.site = { id: siteIdResolved, handle: handleResolved }
|
|
384
|
+
}
|
|
385
|
+
if (featuresChanged) {
|
|
386
|
+
updates.features = mintedFeatures
|
|
387
|
+
}
|
|
388
|
+
await writeSiteYmlUpdates(siteYmlPath, siteYml, updates)
|
|
389
|
+
if (siteIdChanged) say.dim(`Linked site.yml to site.id=${siteIdResolved}`)
|
|
390
|
+
else if (handleChanged) say.dim(`Updated site.yml handle → ${handleResolved}`)
|
|
391
|
+
if (featuresChanged) {
|
|
392
|
+
say.dim(`Updated site.yml features → [${mintedFeatures.join(', ') || '(none)'}]`)
|
|
393
|
+
}
|
|
329
394
|
}
|
|
330
395
|
|
|
331
396
|
console.log('')
|
|
@@ -348,17 +413,62 @@ async function readSiteYml(path) {
|
|
|
348
413
|
}
|
|
349
414
|
}
|
|
350
415
|
|
|
416
|
+
// Recognized paid features. `features:` in site.yml uses these short
|
|
417
|
+
// names; the PHP backend maps them to internal metadata flags. Anything
|
|
418
|
+
// else gets dropped with a warning so a typo doesn't block a deploy.
|
|
419
|
+
const KNOWN_FEATURES = new Set(['search', 'analytics', 'lowTtl', 'intelligence'])
|
|
420
|
+
|
|
421
|
+
function readFeaturesFromYaml(siteYml) {
|
|
422
|
+
// site.yml's `features:` is the developer's declarative intent for what
|
|
423
|
+
// paid features they want billed. We treat absence and `features: []` as
|
|
424
|
+
// the same thing — both mean "no paid features". This keeps the model
|
|
425
|
+
// simple: what's in the file is what the user wants. No "no opinion"
|
|
426
|
+
// escape hatch. Legacy sites that have paid features in DB but no
|
|
427
|
+
// features: line yet will see a downgrade-review on their next deploy
|
|
428
|
+
// (they cancel and add the explicit list, or proceed and downgrade).
|
|
429
|
+
const raw = siteYml?.features
|
|
430
|
+
if (raw === undefined) return []
|
|
431
|
+
if (!Array.isArray(raw)) {
|
|
432
|
+
say.warn('site.yml `features:` should be a list (e.g. `features: [search]`). Treating as empty.')
|
|
433
|
+
return []
|
|
434
|
+
}
|
|
435
|
+
const valid = []
|
|
436
|
+
const unknown = []
|
|
437
|
+
for (const v of raw) {
|
|
438
|
+
if (typeof v !== 'string') continue
|
|
439
|
+
if (KNOWN_FEATURES.has(v)) valid.push(v)
|
|
440
|
+
else unknown.push(v)
|
|
441
|
+
}
|
|
442
|
+
if (unknown.length > 0) {
|
|
443
|
+
say.warn(`site.yml features: unknown name(s) ignored: ${unknown.join(', ')}`)
|
|
444
|
+
say.dim(`Known features: ${[...KNOWN_FEATURES].join(', ')}`)
|
|
445
|
+
}
|
|
446
|
+
// Dedupe + stable order so authorize compares the same way every time.
|
|
447
|
+
return [...new Set(valid)].sort()
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
function arrayEqualsAsSets(a, b) {
|
|
451
|
+
if (!Array.isArray(a) || !Array.isArray(b)) return false
|
|
452
|
+
if (a.length !== b.length) return false
|
|
453
|
+
const sa = new Set(a)
|
|
454
|
+
for (const x of b) if (!sa.has(x)) return false
|
|
455
|
+
return true
|
|
456
|
+
}
|
|
457
|
+
|
|
351
458
|
/**
|
|
352
|
-
* Write
|
|
459
|
+
* Write a partial set of updates back to site.yml, preserving other fields.
|
|
353
460
|
*
|
|
354
461
|
* Note: this is not a full YAML-preserving write — comments and exact
|
|
355
462
|
* formatting are NOT preserved. js-yaml's `dump` re-emits the document.
|
|
356
463
|
* Acceptable for now; the Phase 1 plan doesn't promise comment preservation.
|
|
357
464
|
*/
|
|
358
|
-
async function
|
|
359
|
-
const next = {
|
|
360
|
-
|
|
361
|
-
site
|
|
465
|
+
async function writeSiteYmlUpdates(path, current, updates) {
|
|
466
|
+
const next = { ...current }
|
|
467
|
+
if (updates.site) {
|
|
468
|
+
next.site = { ...(current.site || {}), ...updates.site }
|
|
469
|
+
}
|
|
470
|
+
if (updates.features !== undefined) {
|
|
471
|
+
next.features = [...updates.features].sort()
|
|
362
472
|
}
|
|
363
473
|
const dumped = yaml.dump(next, { lineWidth: 120, noRefs: true, quotingType: "'" })
|
|
364
474
|
await writeFile(path, dumped)
|
|
@@ -416,8 +526,8 @@ async function fetchLatestRuntime(workerUrl) {
|
|
|
416
526
|
function extractLanguages(siteContent) {
|
|
417
527
|
const langs = siteContent?.config?.languages
|
|
418
528
|
if (!Array.isArray(langs) || langs.length === 0) return ['en']
|
|
419
|
-
// Editor
|
|
420
|
-
return langs.map((l) => (typeof l === 'string' ? l : l?.value)).filter(Boolean)
|
|
529
|
+
// Three accepted shapes: plain `'en'`, Editor `{ value, label }`, site.yml `{ code, label }`.
|
|
530
|
+
return langs.map((l) => (typeof l === 'string' ? l : l?.value || l?.code)).filter(Boolean)
|
|
421
531
|
}
|
|
422
532
|
|
|
423
533
|
/**
|
|
@@ -535,7 +645,7 @@ async function callPublish({ url, token, body }) {
|
|
|
535
645
|
* siteContent is mutated in place so the caller's publish payload picks up
|
|
536
646
|
* the rewritten nodes without passing anything back.
|
|
537
647
|
*/
|
|
538
|
-
async function uploadAssetsAndRewriteContent({ siteDir,
|
|
648
|
+
async function uploadAssetsAndRewriteContent({ siteDir, localeContents, siteYml, theme, backendUrl, cliToken, siteId }) {
|
|
539
649
|
const distAssetsDir = join(siteDir, 'dist', 'assets')
|
|
540
650
|
const hasDistAssets = existsSync(distAssetsDir)
|
|
541
651
|
|
|
@@ -659,24 +769,32 @@ async function uploadAssetsAndRewriteContent({ siteDir, siteContent, siteYml, th
|
|
|
659
769
|
for (const u of confirmed) fresh.set(u.filename, u.identifier)
|
|
660
770
|
}
|
|
661
771
|
|
|
662
|
-
// 6. Rewrite
|
|
663
|
-
// src/href references a local /assets/{filename}
|
|
664
|
-
// pointing to the uploaded (or reused) asset.
|
|
772
|
+
// 6. Rewrite each locale's content in place. Image/document nodes whose
|
|
773
|
+
// src/href references a local /assets/{filename} get an info.identifier
|
|
774
|
+
// pointing to the uploaded (or reused) asset. Walking every locale
|
|
775
|
+
// means translated content (which still references the same image
|
|
776
|
+
// files via the source ProseMirror tree) gets the same rewrite.
|
|
665
777
|
const byFilenameAll = new Map([...reused, ...fresh])
|
|
666
|
-
|
|
778
|
+
let rewritten = 0
|
|
779
|
+
for (const lang of Object.keys(localeContents)) {
|
|
780
|
+
rewritten += rewriteAssetReferences(localeContents[lang], byFilenameAll)
|
|
781
|
+
}
|
|
667
782
|
if (rewritten > 0) {
|
|
668
|
-
say.dim(`Rewrote ${rewritten} asset reference(s)
|
|
783
|
+
say.dim(`Rewrote ${rewritten} asset reference(s) across ${Object.keys(localeContents).length} locale(s).`)
|
|
669
784
|
}
|
|
670
785
|
|
|
671
786
|
// 7. If a favicon was included above, inject its resolved CDN URL into
|
|
672
|
-
//
|
|
673
|
-
//
|
|
787
|
+
// every locale's config.favicon. Matches Editor publish (which sets
|
|
788
|
+
// favicon per-locale); Worker bakes <link rel="icon"> from the active
|
|
789
|
+
// locale's content.config.favicon.
|
|
674
790
|
if (faviconPath) {
|
|
675
791
|
const favName = faviconPath.split(sep).pop()
|
|
676
792
|
const favIdentifier = byFilenameAll.get(favName)
|
|
677
793
|
if (favIdentifier) {
|
|
678
794
|
const faviconUrl = resolveAssetCdnUrl(favIdentifier)
|
|
679
|
-
|
|
795
|
+
for (const lang of Object.keys(localeContents)) {
|
|
796
|
+
localeContents[lang].config = { ...(localeContents[lang].config || {}), favicon: faviconUrl }
|
|
797
|
+
}
|
|
680
798
|
say.dim(`Favicon: ${favName}`)
|
|
681
799
|
}
|
|
682
800
|
}
|
package/src/framework-index.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"generatedAt": "2026-04-
|
|
3
|
+
"generatedAt": "2026-04-27T18:45:58.952Z",
|
|
4
4
|
"packages": {
|
|
5
5
|
"@uniweb/build": {
|
|
6
|
-
"version": "0.11.
|
|
6
|
+
"version": "0.11.8",
|
|
7
7
|
"path": "framework/build",
|
|
8
8
|
"deps": [
|
|
9
9
|
"@uniweb/content-reader",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
]
|
|
15
15
|
},
|
|
16
16
|
"@uniweb/content-reader": {
|
|
17
|
-
"version": "1.1.
|
|
17
|
+
"version": "1.1.9",
|
|
18
18
|
"path": "framework/content-reader",
|
|
19
19
|
"deps": []
|
|
20
20
|
},
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"deps": []
|
|
25
25
|
},
|
|
26
26
|
"@uniweb/core": {
|
|
27
|
-
"version": "0.7.
|
|
27
|
+
"version": "0.7.8",
|
|
28
28
|
"path": "framework/core",
|
|
29
29
|
"deps": [
|
|
30
30
|
"@uniweb/semantic-parser",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"deps": []
|
|
43
43
|
},
|
|
44
44
|
"@uniweb/kit": {
|
|
45
|
-
"version": "0.9.
|
|
45
|
+
"version": "0.9.8",
|
|
46
46
|
"path": "framework/kit",
|
|
47
47
|
"deps": [
|
|
48
48
|
"@uniweb/core"
|
|
@@ -54,12 +54,12 @@
|
|
|
54
54
|
"deps": []
|
|
55
55
|
},
|
|
56
56
|
"@uniweb/press": {
|
|
57
|
-
"version": "0.4.
|
|
57
|
+
"version": "0.4.5",
|
|
58
58
|
"path": "framework/press",
|
|
59
59
|
"deps": []
|
|
60
60
|
},
|
|
61
61
|
"@uniweb/runtime": {
|
|
62
|
-
"version": "0.8.
|
|
62
|
+
"version": "0.8.9",
|
|
63
63
|
"path": "framework/runtime",
|
|
64
64
|
"deps": [
|
|
65
65
|
"@uniweb/core",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"deps": []
|
|
78
78
|
},
|
|
79
79
|
"@uniweb/semantic-parser": {
|
|
80
|
-
"version": "1.1.
|
|
80
|
+
"version": "1.1.15",
|
|
81
81
|
"path": "framework/semantic-parser",
|
|
82
82
|
"deps": []
|
|
83
83
|
},
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"deps": []
|
|
93
93
|
},
|
|
94
94
|
"@uniweb/unipress": {
|
|
95
|
-
"version": "0.2.
|
|
95
|
+
"version": "0.2.8",
|
|
96
96
|
"path": "framework/unipress",
|
|
97
97
|
"deps": [
|
|
98
98
|
"@uniweb/build",
|