uniweb 0.69.4 → 0.70.0
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 +3 -1
- package/src/backend/site-sync.js +72 -3
- package/src/commands/build.js +8 -2
- package/src/commands/publish.js +23 -10
- package/src/commands/pull.js +17 -2
- package/src/commands/register.js +15 -6
- package/src/framework-index.json +10 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uniweb",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.70.0",
|
|
4
4
|
"description": "Create structured Vite + React sites with content/code separation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -41,17 +41,17 @@
|
|
|
41
41
|
"js-yaml": "^4.1.0",
|
|
42
42
|
"prompts": "^2.4.2",
|
|
43
43
|
"tar": "^7.0.0",
|
|
44
|
-
"@uniweb/runtime": "^0.27.4",
|
|
45
|
-
"@uniweb/schemas": "^0.7.0",
|
|
46
44
|
"@uniweb/content-writer": "^0.3.4",
|
|
47
|
-
"@uniweb/core": "^0.
|
|
48
|
-
"@uniweb/
|
|
45
|
+
"@uniweb/core": "^0.30.0",
|
|
46
|
+
"@uniweb/runtime": "^0.27.5",
|
|
47
|
+
"@uniweb/kit": "^0.19.5",
|
|
48
|
+
"@uniweb/schemas": "^0.7.0",
|
|
49
49
|
"@uniweb/semantic-parser": "^1.4.1"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
|
+
"@uniweb/build": "^0.64.0",
|
|
52
53
|
"@uniweb/content-reader": "^1.2.5",
|
|
53
|
-
"@uniweb/semantic-parser": "^1.4.1"
|
|
54
|
-
"@uniweb/build": "^0.63.3"
|
|
54
|
+
"@uniweb/semantic-parser": "^1.4.1"
|
|
55
55
|
},
|
|
56
56
|
"peerDependenciesMeta": {
|
|
57
57
|
"@uniweb/build": {
|
package/partials/agents.md
CHANGED
|
@@ -2717,6 +2717,8 @@ Running `extract` before a build is the usual first mistake — it reads the com
|
|
|
2717
2717
|
{ "e5f6g7h8": { "default": "Learn More", "overrides": { "/pricing:cta": "See Pricing" } } }
|
|
2718
2718
|
```
|
|
2719
2719
|
|
|
2720
|
+
An override key is the page's route and the section's id (`cta` for `2-cta.md`); a page's own title, label, description and keywords are `/pricing:_meta`, and in `locales/records/` a record is named by its manifest context (`std/article/launch`).
|
|
2721
|
+
|
|
2720
2722
|
*Free-form bodies* — when a language needs different structure, different images, or copy rewritten rather than translated. The file replaces one section's content:
|
|
2721
2723
|
|
|
2722
2724
|
```
|
|
@@ -2726,7 +2728,7 @@ locales/freeform/es/records/article/x.md # records work too
|
|
|
2726
2728
|
|
|
2727
2729
|
These are **body only — no frontmatter**; params and config still come from the source section. `uniweb i18n init-freeform es pages/about hero` creates one pre-filled and records a source hash, so `uniweb i18n status --freeform` can tell you when the original moved on (`update-hash` to acknowledge). `move`, `rename`, and `prune --freeform` keep them aligned when pages get reorganized.
|
|
2728
2730
|
|
|
2729
|
-
**Records translate in the same `extract` run**, into their own manifest at `locales/records/manifest.json` — keyed by the RECORD, so a record translated once is found by every query that returns it.
|
|
2731
|
+
**Records translate in the same `extract` run**, into their own manifest at `locales/records/manifest.json` — keyed by the RECORD, so a record translated once is found by every query that returns it. A record whose query has a data schema translates exactly the fields the schema says are text — never an enum, a URL, a date, a number, a file, a reference or a `translatable: false` field — which are the fields a push carries in each language; mark a string that is a code or a key `translatable: false` and no translator is asked for it. An excerpt the build derives is re-derived from each language's body.
|
|
2730
2732
|
|
|
2731
2733
|
**Component side.** Nothing to do: `content.title` arrives in the active language. The one thing a foundation builds is a switcher.
|
|
2732
2734
|
|
package/src/backend/site-sync.js
CHANGED
|
@@ -45,7 +45,8 @@ import {
|
|
|
45
45
|
removeYamlScalar,
|
|
46
46
|
harvestRecordItems,
|
|
47
47
|
storedRecordItems,
|
|
48
|
-
reprintRecordItems
|
|
48
|
+
reprintRecordItems,
|
|
49
|
+
matchStoredRecords
|
|
49
50
|
} from '@uniweb/build/uwx'
|
|
50
51
|
|
|
51
52
|
// First entity `$`-document out of a `.uwx` we produced or the backend served.
|
|
@@ -878,6 +879,64 @@ export async function recoverRecordItemUuids({ client, siteDir, uuids, note }) {
|
|
|
878
879
|
}
|
|
879
880
|
}
|
|
880
881
|
|
|
882
|
+
/**
|
|
883
|
+
* Recover the records lane's identity this copy lacks for the site it is bound to — which stored
|
|
884
|
+
* record each of its records is (`records`), each placement's in the folder (`folders`), and the
|
|
885
|
+
* list items of the records it matches (`recordItems`) — from one read of the backend's folder
|
|
886
|
+
* lane. What the copy already holds is kept.
|
|
887
|
+
*
|
|
888
|
+
* ⛔ Until 2026-09-25 nothing recovered these, and a copy whose `sync.json` had lost them — a
|
|
889
|
+
* blog site whose push was refused after its content landed, with an older CLI — was refused on
|
|
890
|
+
* every push after: its folder sent three placements with no `$uuid` while three were stored
|
|
891
|
+
* ("one section carries no item identity (section contents)"). Unrefused, its records would have
|
|
892
|
+
* gone up with none, and the backend would have made a second entity of each.
|
|
893
|
+
*
|
|
894
|
+
* Reads only when the package names a record the map does not, or the folder map is empty; a
|
|
895
|
+
* record new to the backend costs that read and finds nothing (`matchStoredRecords`).
|
|
896
|
+
*
|
|
897
|
+
* @param {object} params
|
|
898
|
+
* @param {object[]} params.index - the records the package sends (`pkg.records.index`)
|
|
899
|
+
* @returns {Promise<number>} how many records and placements were recovered
|
|
900
|
+
*/
|
|
901
|
+
export async function recoverRecordsIdentity({ client, siteDir, index, note }) {
|
|
902
|
+
const state = readBackendState(siteDir, client.origin)
|
|
903
|
+
const siteUuid = state.site?.uuid || null
|
|
904
|
+
const recordMap = state.records || {}
|
|
905
|
+
const records = (index || []).filter((e) => e?.ownId && e.model && e.slug)
|
|
906
|
+
const folders = readFolderItemUuids(siteDir, client.origin)
|
|
907
|
+
const unmapped = records.some((e) => !recordMap[e.ownId])
|
|
908
|
+
if (!siteUuid || !records.length || (!unmapped && Object.keys(folders).length)) return 0
|
|
909
|
+
try {
|
|
910
|
+
const res = await client.pullFolder(siteUuid)
|
|
911
|
+
if (!res?.ok) return 0
|
|
912
|
+
const docs = entityDocsFromUwx(Buffer.from(await res.arrayBuffer()))
|
|
913
|
+
const folderDoc = docs.find((d) => d?.$schema === '@uniweb/folder')
|
|
914
|
+
if (!folderDoc) return 0
|
|
915
|
+
const learned = matchStoredRecords({ index: records, recordMap, folderDoc })
|
|
916
|
+
const matched = Object.keys(learned).length
|
|
917
|
+
if (matched) {
|
|
918
|
+
updateBackendMap(siteDir, client.origin, 'records', learned)
|
|
919
|
+
const stored = new Map(docs.map((d) => [d?.$uuid, d]))
|
|
920
|
+
const items = {}
|
|
921
|
+
for (const theirs of Object.values(learned)) {
|
|
922
|
+
const doc = stored.get(theirs)
|
|
923
|
+
if (doc) items[theirs] = storedRecordItems(doc)
|
|
924
|
+
}
|
|
925
|
+
writeRecordItemUuids(siteDir, client.origin, items)
|
|
926
|
+
}
|
|
927
|
+
const placements = collectFolderItemUuids(folderDoc)
|
|
928
|
+
const missing = Object.fromEntries(Object.entries(placements).filter(([k]) => !folders[k]))
|
|
929
|
+
writeFolderItemUuids(siteDir, client.origin, missing)
|
|
930
|
+
const placed = Object.keys(missing).length
|
|
931
|
+
if (matched || placed) {
|
|
932
|
+
note?.(`Recovered the identity of ${matched} record(s) and ${placed} folder placement(s) from the backend.`)
|
|
933
|
+
}
|
|
934
|
+
return matched + placed
|
|
935
|
+
} catch {
|
|
936
|
+
return 0
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
|
|
881
940
|
/**
|
|
882
941
|
* The workspace this site was created in on `backend` — its owner, as the create
|
|
883
942
|
* answered it — in the header's form: `@handle`, a unit's bare uuid when that unit has
|
|
@@ -1263,8 +1322,9 @@ export async function recoverItemUuids({ client, siteDir, note }) {
|
|
|
1263
1322
|
|
|
1264
1323
|
/**
|
|
1265
1324
|
* Recover the identity a package just built went out without, when the backend may hold it —
|
|
1266
|
-
* a page or section (`itemIdentity.unknown`), or a
|
|
1267
|
-
* (`recordItemIdentity.unbanked`) — and say
|
|
1325
|
+
* a page or section (`itemIdentity.unknown`), a record or a folder placement
|
|
1326
|
+
* (`recoverRecordsIdentity`), or a record's list items (`recordItemIdentity.unbanked`) — and say
|
|
1327
|
+
* what to build the package again with.
|
|
1268
1328
|
*
|
|
1269
1329
|
* A page added since the last push is also without identity, and costs one read that finds
|
|
1270
1330
|
* nothing. That is the price of never sending as new an item the backend already holds.
|
|
@@ -1277,6 +1337,15 @@ export async function recoverUnbankedIdentity({ client, siteDir, pkg, note }) {
|
|
|
1277
1337
|
if (pkg?.itemIdentity?.unknown > 0 && (await recoverItemUuids({ client, siteDir, note }))) {
|
|
1278
1338
|
again = { ...again, itemUuids: readItemUuids(siteDir, client.origin) }
|
|
1279
1339
|
}
|
|
1340
|
+
// The records the package sends, and the folder placing them. The emit reads the `records`
|
|
1341
|
+
// map from sync.json itself, so it needs no option — only the build again.
|
|
1342
|
+
if (await recoverRecordsIdentity({ client, siteDir, index: pkg?.records?.index, note })) {
|
|
1343
|
+
again = {
|
|
1344
|
+
...again,
|
|
1345
|
+
folderItemUuids: readFolderItemUuids(siteDir, client.origin),
|
|
1346
|
+
recordItemUuids: readRecordItemUuids(siteDir, client.origin)
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1280
1349
|
const unbanked = pkg?.recordItemIdentity?.unbanked
|
|
1281
1350
|
if (unbanked?.length && (await recoverRecordItemUuids({ client, siteDir, uuids: unbanked, note }))) {
|
|
1282
1351
|
again = { ...again, recordItemUuids: readRecordItemUuids(siteDir, client.origin) }
|
package/src/commands/build.js
CHANGED
|
@@ -668,7 +668,10 @@ async function buildSiteLink(projectDir, options = {}) {
|
|
|
668
668
|
projectDir,
|
|
669
669
|
i18nConfig.localesDir,
|
|
670
670
|
'records'
|
|
671
|
-
)
|
|
671
|
+
),
|
|
672
|
+
// Free-form record translations live under it — the default was `locales/`
|
|
673
|
+
// whatever the site said.
|
|
674
|
+
localesDir: join(projectDir, i18nConfig.localesDir)
|
|
672
675
|
})
|
|
673
676
|
const recordCount = Object.values(recordOutputs).reduce(
|
|
674
677
|
(sum, localeOutputs) => sum + Object.keys(localeOutputs).length,
|
|
@@ -789,7 +792,10 @@ async function buildSite(projectDir, options = {}) {
|
|
|
789
792
|
projectDir,
|
|
790
793
|
i18nConfig.localesDir,
|
|
791
794
|
'records'
|
|
792
|
-
)
|
|
795
|
+
),
|
|
796
|
+
// Free-form record translations live under it — the default was `locales/`
|
|
797
|
+
// whatever the site said.
|
|
798
|
+
localesDir: join(projectDir, i18nConfig.localesDir)
|
|
793
799
|
})
|
|
794
800
|
|
|
795
801
|
// Count collections translated
|
package/src/commands/publish.js
CHANGED
|
@@ -37,9 +37,9 @@
|
|
|
37
37
|
* uniweb publish --no-save Do not record this publish in deploy.yml
|
|
38
38
|
*/
|
|
39
39
|
|
|
40
|
-
import { existsSync, readFileSync } from 'node:fs'
|
|
40
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs'
|
|
41
41
|
import { readFile } from 'node:fs/promises'
|
|
42
|
-
import { join } from 'node:path'
|
|
42
|
+
import { join, dirname } from 'node:path'
|
|
43
43
|
import { execSync } from 'node:child_process'
|
|
44
44
|
import yaml from 'js-yaml'
|
|
45
45
|
|
|
@@ -143,14 +143,27 @@ function readSiteYml(path) {
|
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
// Languages from the BUILT site
|
|
147
|
-
//
|
|
148
|
-
|
|
146
|
+
// Languages from the BUILT site — the authority after a build: `config.languages` where
|
|
147
|
+
// the site declares them (three accepted shapes: 'en', { value, label }, { code, label }),
|
|
148
|
+
// else its default and each language the build produced (`dist/<locale>/site-content.json`).
|
|
149
|
+
// ⛔ Until 2026-09-26 a site that declares no `languages:` — its languages made by its
|
|
150
|
+
// translation files — went live as `['en']`, though the build had produced the others.
|
|
151
|
+
export function languagesFromContent(siteContent, distDir = null) {
|
|
149
152
|
const langs = siteContent?.config?.languages
|
|
150
|
-
if (
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
153
|
+
if (Array.isArray(langs) && langs.length > 0) {
|
|
154
|
+
return langs
|
|
155
|
+
.map((l) => (typeof l === 'string' ? l : l?.value || l?.code))
|
|
156
|
+
.filter(Boolean)
|
|
157
|
+
}
|
|
158
|
+
const source = siteContent?.config?.defaultLanguage || 'en'
|
|
159
|
+
const built =
|
|
160
|
+
distDir && existsSync(distDir)
|
|
161
|
+
? readdirSync(distDir, { withFileTypes: true })
|
|
162
|
+
.filter((e) => e.isDirectory() && e.name !== source && existsSync(join(distDir, e.name, 'site-content.json')))
|
|
163
|
+
.map((e) => e.name)
|
|
164
|
+
.sort()
|
|
165
|
+
: []
|
|
166
|
+
return [source, ...built]
|
|
154
167
|
}
|
|
155
168
|
|
|
156
169
|
// Languages from site.yml — used only for the dry-run summary (no build yet).
|
|
@@ -1005,7 +1018,7 @@ export async function publish(args = []) {
|
|
|
1005
1018
|
|
|
1006
1019
|
// 7. Go live — make the just-pushed composite live (its current backend state).
|
|
1007
1020
|
const siteContent = JSON.parse(await readFile(contentPath, 'utf8'))
|
|
1008
|
-
const languages = languagesFromContent(siteContent)
|
|
1021
|
+
const languages = languagesFromContent(siteContent, dirname(contentPath))
|
|
1009
1022
|
say.info(`Publishing to ${c.dim}${client.origin}${c.reset} …`)
|
|
1010
1023
|
let pubRes
|
|
1011
1024
|
try {
|
package/src/commands/pull.js
CHANGED
|
@@ -684,6 +684,8 @@ export async function pull(args = [], deps = {}) {
|
|
|
684
684
|
args,
|
|
685
685
|
command: 'Pulling'
|
|
686
686
|
})
|
|
687
|
+
// One reader of Models for the whole pull, so a Model is read once whichever lane asks first.
|
|
688
|
+
const readModel = makeModelResolver({ client })
|
|
687
689
|
|
|
688
690
|
// ⭐ No scope check any more — and none is needed. This project's identity on
|
|
689
691
|
// `client.origin` is read from that origin's own section of sync.json, so a
|
|
@@ -942,9 +944,23 @@ export async function pull(args = [], deps = {}) {
|
|
|
942
944
|
// which is the pre-existing behaviour and right for a fresh clone.
|
|
943
945
|
}
|
|
944
946
|
|
|
947
|
+
// ⭐ The Models the site's queries name — what a clone, with no foundation to read them from,
|
|
948
|
+
// tells a query's derived `deferred:` from its author's by. ⛔ Until 2026-09-26 a clone wrote
|
|
949
|
+
// the derivation into its queries as though authored. One that cannot be read is judged
|
|
950
|
+
// without it, which keeps the value: the safe direction.
|
|
951
|
+
const models = {}
|
|
952
|
+
for (const model of pulledQueryModels) {
|
|
953
|
+
try {
|
|
954
|
+
const declaration = await readModel(model)
|
|
955
|
+
if (declaration) models[model] = declaration
|
|
956
|
+
} catch {
|
|
957
|
+
// unreadable here
|
|
958
|
+
}
|
|
959
|
+
}
|
|
945
960
|
const report = siteContentDocumentToProject({
|
|
946
961
|
document: siteDoc,
|
|
947
962
|
siteRoot: siteDir,
|
|
963
|
+
models,
|
|
948
964
|
// Which backend's asset ids to read back as the author's own paths. Without
|
|
949
965
|
// it a pull leaves every image pointing at a backend route.
|
|
950
966
|
backend: client.origin,
|
|
@@ -985,7 +1001,7 @@ export async function pull(args = [], deps = {}) {
|
|
|
985
1001
|
if (folder && !folder.notModified && folder.docs?.length) {
|
|
986
1002
|
const { folderDoc, recordDocs } = splitRecordsPull(folder.docs)
|
|
987
1003
|
pulledRecordDocs = recordDocs
|
|
988
|
-
const resolveModel =
|
|
1004
|
+
const resolveModel = readModel
|
|
989
1005
|
const declByModel = new Map()
|
|
990
1006
|
pulledDeclarations = declByModel
|
|
991
1007
|
for (const model of [
|
|
@@ -1102,7 +1118,6 @@ export async function pull(args = [], deps = {}) {
|
|
|
1102
1118
|
// in the project (a clone's) resolves none of them otherwise: every template clone
|
|
1103
1119
|
// said "could not re-bank" until 2026-09-25, and banked nothing.
|
|
1104
1120
|
const declarations = pulledDeclarations || new Map()
|
|
1105
|
-
const readModel = makeModelResolver({ client })
|
|
1106
1121
|
for (const model of pulledQueryModels) {
|
|
1107
1122
|
if (declarations.has(model)) continue
|
|
1108
1123
|
try {
|
package/src/commands/register.js
CHANGED
|
@@ -835,10 +835,18 @@ async function runRegister(args = []) {
|
|
|
835
835
|
if (!res.ok) {
|
|
836
836
|
// Resume path: a registered version is immutable, so re-running after a
|
|
837
837
|
// partial code delivery hits the duplicate rejection here — a STRUCTURED
|
|
838
|
-
// 409 (problem+json, title "Conflict"
|
|
839
|
-
// code-uploads plan authorizes against the REGISTERED
|
|
840
|
-
// already stores come back `present` and are skipped).
|
|
841
|
-
|
|
838
|
+
// 409 (problem+json, title "Conflict", naming the `version` it refused) — and
|
|
839
|
+
// proceeds to phase 2 (the code-uploads plan authorizes against the REGISTERED
|
|
840
|
+
// version; files it already stores come back `present` and are skipped).
|
|
841
|
+
//
|
|
842
|
+
// ⛔ ONE STATUS, MORE THAN ONE MEANING. A 409 that names no version is another
|
|
843
|
+
// refusal — a data schema changed where the backend holds records of it
|
|
844
|
+
// (`reason: "destructive_republish"`) — and until 2026-09-26 it was read as a
|
|
845
|
+
// resume too: "already registered — resuming code delivery", then a 404 for a
|
|
846
|
+
// version that was never registered, and the refusal's own sentence never shown.
|
|
847
|
+
// A body with no shape to read resumes, as it always did.
|
|
848
|
+
const isDuplicate =
|
|
849
|
+
!standalone && res.status === 409 && (!parsedBody || typeof parsedBody !== 'object' || parsedBody.version !== undefined)
|
|
842
850
|
if (isDuplicate) {
|
|
843
851
|
alreadyRegistered = true
|
|
844
852
|
info(
|
|
@@ -869,8 +877,9 @@ async function runRegister(args = []) {
|
|
|
869
877
|
// because a 422 the CLI did not know about arrived exactly that way.
|
|
870
878
|
if (parsedBody?.detail) {
|
|
871
879
|
log(` ${parsedBody.detail}`)
|
|
872
|
-
|
|
873
|
-
|
|
880
|
+
const code = parsedBody.code ?? parsedBody.reason
|
|
881
|
+
if (code) {
|
|
882
|
+
log(` ${colors.dim}(${code})${colors.reset}`)
|
|
874
883
|
}
|
|
875
884
|
} else if (rawBody) {
|
|
876
885
|
log(` ${colors.dim}${rawBody.slice(0, 500)}${colors.reset}`)
|
package/src/framework-index.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"generatedAt": "2026-09-
|
|
3
|
+
"generatedAt": "2026-09-26T17:05:22.846Z",
|
|
4
4
|
"packages": {
|
|
5
5
|
"@uniweb/api": {
|
|
6
|
-
"version": "0.6.
|
|
6
|
+
"version": "0.6.3",
|
|
7
7
|
"path": "framework/api",
|
|
8
8
|
"deps": [
|
|
9
9
|
"@uniweb/core"
|
|
10
10
|
]
|
|
11
11
|
},
|
|
12
12
|
"@uniweb/build": {
|
|
13
|
-
"version": "0.
|
|
13
|
+
"version": "0.64.0",
|
|
14
14
|
"path": "framework/build",
|
|
15
15
|
"deps": [
|
|
16
16
|
"@uniweb/content-reader",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"deps": []
|
|
36
36
|
},
|
|
37
37
|
"@uniweb/core": {
|
|
38
|
-
"version": "0.
|
|
38
|
+
"version": "0.30.0",
|
|
39
39
|
"path": "framework/core",
|
|
40
40
|
"deps": [
|
|
41
41
|
"@uniweb/semantic-parser",
|
|
@@ -48,14 +48,14 @@
|
|
|
48
48
|
"deps": []
|
|
49
49
|
},
|
|
50
50
|
"@uniweb/icons": {
|
|
51
|
-
"version": "0.4.
|
|
51
|
+
"version": "0.4.21",
|
|
52
52
|
"path": "framework/icons",
|
|
53
53
|
"deps": [
|
|
54
54
|
"@uniweb/core"
|
|
55
55
|
]
|
|
56
56
|
},
|
|
57
57
|
"@uniweb/kit": {
|
|
58
|
-
"version": "0.19.
|
|
58
|
+
"version": "0.19.5",
|
|
59
59
|
"path": "framework/kit",
|
|
60
60
|
"deps": [
|
|
61
61
|
"@uniweb/core",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"deps": []
|
|
76
76
|
},
|
|
77
77
|
"@uniweb/projections": {
|
|
78
|
-
"version": "0.7.
|
|
78
|
+
"version": "0.7.4",
|
|
79
79
|
"path": "framework/projections",
|
|
80
80
|
"deps": [
|
|
81
81
|
"@uniweb/content-writer",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
]
|
|
84
84
|
},
|
|
85
85
|
"@uniweb/runtime": {
|
|
86
|
-
"version": "0.27.
|
|
86
|
+
"version": "0.27.5",
|
|
87
87
|
"path": "framework/runtime",
|
|
88
88
|
"deps": [
|
|
89
89
|
"@uniweb/core",
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
"deps": []
|
|
117
117
|
},
|
|
118
118
|
"@uniweb/templates": {
|
|
119
|
-
"version": "0.17.
|
|
119
|
+
"version": "0.17.3",
|
|
120
120
|
"path": "framework/templates",
|
|
121
121
|
"deps": []
|
|
122
122
|
},
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
"deps": []
|
|
127
127
|
},
|
|
128
128
|
"@uniweb/unipress": {
|
|
129
|
-
"version": "0.10.
|
|
129
|
+
"version": "0.10.7",
|
|
130
130
|
"path": "framework/unipress",
|
|
131
131
|
"deps": [
|
|
132
132
|
"@uniweb/build",
|