@morphemecms/cms 0.4.0-next-20261104164754 → 0.4.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/CHANGELOG.md +3 -1
- package/defaults/editor.ts +12 -1
- package/icons/lucide/LICENSE-material-design-icons +19 -19
- package/icons/material-symbols/LICENSE-material-design-icons +19 -19
- package/icons/phosphor/LICENSE +20 -20
- package/lib/side-block.test.mjs +1 -1
- package/package.json +6 -1
- package/scripts/check-cms-update.mjs +14 -3
- package/site/icons.mjs +3 -1
- package/src/CmsPage.tsx +3 -2
- package/src/EntryForm.tsx +6 -2
- package/src/SideColumn.tsx +6 -1
- package/src/cmsView.mjs +3 -0
- package/src/cmsView.test.mjs +6 -0
- package/src/i18n/da-DK/cms.ts +1 -0
- package/src/i18n/en-US/cms.ts +1 -0
- package/starter/package.json +1 -1
- package/theme/layouts/PageLayout.astro +2 -1
- package/worker/cms-update.js +6 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @morphemecms/cms
|
|
2
2
|
|
|
3
|
-
## 0.4.0
|
|
3
|
+
## 0.4.0
|
|
4
4
|
|
|
5
5
|
### Minor Changes
|
|
6
6
|
|
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
|
|
10
10
|
### Patch Changes
|
|
11
11
|
|
|
12
|
+
- dd9ab22: Settings › Morpheme says when the site has no KV storage (PUSH), and no longer fails to open when the site runs a pre-release of Morpheme.
|
|
12
13
|
- cf9f144: Keep the line breaks of a file's front matter (CRLF or LF) when the editor writes it back.
|
|
14
|
+
- 6cb2c17: `check:worker` passes when the site runs a pre-release of Morpheme (as the staging site does).
|
|
13
15
|
- 682da97: New sites from the starter can reach the Morpheme store on the same Cloudflare account, and Prettier skips store theme files.
|
|
14
16
|
|
|
15
17
|
## 0.3.0
|
package/defaults/editor.ts
CHANGED
|
@@ -158,7 +158,18 @@ export const groups: { title: string; ids: string[] }[] = [
|
|
|
158
158
|
|
|
159
159
|
/** The settings of the whole site, not on the start screen but on "Indstillinger" (#indstillinger, Library.tsx
|
|
160
160
|
* Settings), which the gear in the top bar opens (Screen.tsx SettingsLink); A–Å as a group's. */
|
|
161
|
-
export const settings: string[] = [
|
|
161
|
+
export const settings: string[] = [
|
|
162
|
+
'udseende',
|
|
163
|
+
'apps',
|
|
164
|
+
'appstore',
|
|
165
|
+
'morpheme',
|
|
166
|
+
'maaling',
|
|
167
|
+
'promovering',
|
|
168
|
+
'privatliv',
|
|
169
|
+
'seo',
|
|
170
|
+
'avanceret',
|
|
171
|
+
'licenser',
|
|
172
|
+
];
|
|
162
173
|
|
|
163
174
|
/** The site's own short lists, on a screen of their own under "Lister" (#lister), with those the standard blocks
|
|
164
175
|
* bring ("Udtalelser") and the apps (their lists.ts). */
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
Pictogrammers Free License
|
|
2
|
-
--------------------------
|
|
3
|
-
|
|
4
|
-
This icon collection is released as free, open source, and GPL friendly by
|
|
5
|
-
the [Pictogrammers](http://pictogrammers.com/) icon group. You may use it
|
|
6
|
-
for commercial projects, open source projects, or anything really.
|
|
7
|
-
|
|
8
|
-
# Icons: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
|
|
9
|
-
Some of the icons are redistributed under the Apache 2.0 license. All other
|
|
10
|
-
icons are either redistributed under their respective licenses or are
|
|
11
|
-
distributed under the Apache 2.0 license.
|
|
12
|
-
|
|
13
|
-
# Fonts: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
|
|
14
|
-
All web and desktop fonts are distributed under the Apache 2.0 license. Web
|
|
15
|
-
and desktop fonts contain some icons that are redistributed under the Apache
|
|
16
|
-
2.0 license. All other icons are either redistributed under their respective
|
|
17
|
-
licenses or are distributed under the Apache 2.0 license.
|
|
18
|
-
|
|
19
|
-
# Code: MIT (https://opensource.org/licenses/MIT)
|
|
1
|
+
Pictogrammers Free License
|
|
2
|
+
--------------------------
|
|
3
|
+
|
|
4
|
+
This icon collection is released as free, open source, and GPL friendly by
|
|
5
|
+
the [Pictogrammers](http://pictogrammers.com/) icon group. You may use it
|
|
6
|
+
for commercial projects, open source projects, or anything really.
|
|
7
|
+
|
|
8
|
+
# Icons: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
|
|
9
|
+
Some of the icons are redistributed under the Apache 2.0 license. All other
|
|
10
|
+
icons are either redistributed under their respective licenses or are
|
|
11
|
+
distributed under the Apache 2.0 license.
|
|
12
|
+
|
|
13
|
+
# Fonts: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
|
|
14
|
+
All web and desktop fonts are distributed under the Apache 2.0 license. Web
|
|
15
|
+
and desktop fonts contain some icons that are redistributed under the Apache
|
|
16
|
+
2.0 license. All other icons are either redistributed under their respective
|
|
17
|
+
licenses or are distributed under the Apache 2.0 license.
|
|
18
|
+
|
|
19
|
+
# Code: MIT (https://opensource.org/licenses/MIT)
|
|
20
20
|
The MIT license applies to all non-font and non-icon files.
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
Pictogrammers Free License
|
|
2
|
-
--------------------------
|
|
3
|
-
|
|
4
|
-
This icon collection is released as free, open source, and GPL friendly by
|
|
5
|
-
the [Pictogrammers](http://pictogrammers.com/) icon group. You may use it
|
|
6
|
-
for commercial projects, open source projects, or anything really.
|
|
7
|
-
|
|
8
|
-
# Icons: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
|
|
9
|
-
Some of the icons are redistributed under the Apache 2.0 license. All other
|
|
10
|
-
icons are either redistributed under their respective licenses or are
|
|
11
|
-
distributed under the Apache 2.0 license.
|
|
12
|
-
|
|
13
|
-
# Fonts: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
|
|
14
|
-
All web and desktop fonts are distributed under the Apache 2.0 license. Web
|
|
15
|
-
and desktop fonts contain some icons that are redistributed under the Apache
|
|
16
|
-
2.0 license. All other icons are either redistributed under their respective
|
|
17
|
-
licenses or are distributed under the Apache 2.0 license.
|
|
18
|
-
|
|
19
|
-
# Code: MIT (https://opensource.org/licenses/MIT)
|
|
1
|
+
Pictogrammers Free License
|
|
2
|
+
--------------------------
|
|
3
|
+
|
|
4
|
+
This icon collection is released as free, open source, and GPL friendly by
|
|
5
|
+
the [Pictogrammers](http://pictogrammers.com/) icon group. You may use it
|
|
6
|
+
for commercial projects, open source projects, or anything really.
|
|
7
|
+
|
|
8
|
+
# Icons: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
|
|
9
|
+
Some of the icons are redistributed under the Apache 2.0 license. All other
|
|
10
|
+
icons are either redistributed under their respective licenses or are
|
|
11
|
+
distributed under the Apache 2.0 license.
|
|
12
|
+
|
|
13
|
+
# Fonts: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
|
|
14
|
+
All web and desktop fonts are distributed under the Apache 2.0 license. Web
|
|
15
|
+
and desktop fonts contain some icons that are redistributed under the Apache
|
|
16
|
+
2.0 license. All other icons are either redistributed under their respective
|
|
17
|
+
licenses or are distributed under the Apache 2.0 license.
|
|
18
|
+
|
|
19
|
+
# Code: MIT (https://opensource.org/licenses/MIT)
|
|
20
20
|
The MIT license applies to all non-font and non-icon files.
|
package/icons/phosphor/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2023 Phosphor Icons
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Phosphor Icons
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
SOFTWARE.
|
package/lib/side-block.test.mjs
CHANGED
|
@@ -54,7 +54,7 @@ test('besideInSource reads export const beside = true', () => {
|
|
|
54
54
|
assert.equal(besideInSource('export const beside = false;'), false);
|
|
55
55
|
assert.equal(besideInSource('// export const beside = true;'), false);
|
|
56
56
|
assert.equal(besideInSource('export const load = 1;'), false);
|
|
57
|
-
});
|
|
57
|
+
});
|
|
58
58
|
|
|
59
59
|
test('sideChoices lists installed blocks with beside, by label', () => {
|
|
60
60
|
const blocks = [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@morphemecms/cms",
|
|
3
|
-
"version": "0.4.0
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Morpheme CMS: the editor for a site built with Astro, its screens, its blocks and the rules a site gives it. See README.md.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Lars Adolfsen",
|
|
@@ -41,6 +41,8 @@
|
|
|
41
41
|
"scripts": {
|
|
42
42
|
"build": "node scripts/demo-build.mjs",
|
|
43
43
|
"icons": "node scripts/icon-packs.mjs",
|
|
44
|
+
"format": "prettier --write .",
|
|
45
|
+
"format:check": "prettier --check .",
|
|
44
46
|
"release:version": "changeset version && node scripts/starter.mjs",
|
|
45
47
|
"prepack": "node scripts/types.mjs write",
|
|
46
48
|
"postpack": "node scripts/types.mjs clean"
|
|
@@ -118,6 +120,9 @@
|
|
|
118
120
|
"jsdom": "^29.1.1",
|
|
119
121
|
"motion": "^14.0.0",
|
|
120
122
|
"playwright": "^1.64.1",
|
|
123
|
+
"prettier": "^3.9.10",
|
|
124
|
+
"prettier-plugin-astro": "^1.1.2",
|
|
125
|
+
"prettier-plugin-tailwindcss": "^0.8.1",
|
|
121
126
|
"react": "^19.3.0",
|
|
122
127
|
"react-dom": "^19.3.0",
|
|
123
128
|
"rehype-raw": "^7.0.0",
|
|
@@ -384,20 +384,31 @@ for (const [what, patch] of [
|
|
|
384
384
|
|
|
385
385
|
// The page's notes: from the running version up to the newest, newest first.
|
|
386
386
|
{
|
|
387
|
-
const
|
|
387
|
+
const running = RUNNING.split('-')[0];
|
|
388
|
+
const [major, minor, patch] = running.split('.').map(Number);
|
|
388
389
|
const next1 = `${major}.${minor}.${patch + 1}`;
|
|
389
390
|
const next2 = `${major}.${minor}.${patch + 2}`;
|
|
390
391
|
const w = world();
|
|
391
|
-
for (const v of ['0.0.0',
|
|
392
|
+
for (const v of ['0.0.0', running, next1, next2, '9.9.9'])
|
|
392
393
|
await w.kv.put(`cms:notes:${v}`, JSON.stringify({ version: v, text: `Notes ${v}` }));
|
|
393
394
|
await w.kv.put('cms:checked', JSON.stringify({ at: new Date(T0).toISOString(), latest: next2 }));
|
|
394
|
-
const { notes } = await cmsStatus(w.env);
|
|
395
|
+
const { notes } = await cmsStatus(w.env, running);
|
|
395
396
|
expect(
|
|
396
397
|
notes.map((n) => n.version).join() === `${next2},${next1}`,
|
|
397
398
|
`noterne var ${notes.map((n) => n.version).join()}, ikke ${next2},${next1}`,
|
|
398
399
|
);
|
|
399
400
|
}
|
|
400
401
|
|
|
402
|
+
// A pre-release running: the status answers, with no notes.
|
|
403
|
+
{
|
|
404
|
+
const w = world();
|
|
405
|
+
for (const v of ['0.1.0', '0.2.0']) await w.kv.put(`cms:notes:${v}`, JSON.stringify({ version: v, text: `Notes ${v}` }));
|
|
406
|
+
await w.kv.put('cms:checked', JSON.stringify({ at: new Date(T0).toISOString(), latest: '0.2.0' }));
|
|
407
|
+
const status = await cmsStatus(w.env, '0.2.0-next-1').catch((e) => e);
|
|
408
|
+
expect(status?.running === '0.2.0-next-1', `en forudgivelse gav ${status?.message ?? status?.running}, ikke status`);
|
|
409
|
+
expect(Array.isArray(status?.notes) && status.notes.length === 0, 'en forudgivelse gav noter');
|
|
410
|
+
}
|
|
411
|
+
|
|
401
412
|
if (problems.length) {
|
|
402
413
|
console.error(problems.map((p) => `- ${p}`).join('\n'));
|
|
403
414
|
process.exit(1);
|
package/site/icons.mjs
CHANGED
|
@@ -416,7 +416,9 @@ export const PACK_MAPS = { 'material-symbols': MATERIAL_SYMBOLS, lucide: LUCIDE
|
|
|
416
416
|
/** The names of Phosphor's pack: the icons the site and the editor draw (`used`), and every name the other system
|
|
417
417
|
* packs' maps name (an app's icon, which the CMS itself may not draw), sorted. */
|
|
418
418
|
export const phosphorNames = (used) =>
|
|
419
|
-
[
|
|
419
|
+
[
|
|
420
|
+
...new Set([...used, ...Object.values(PACK_MAPS).flatMap(Object.keys), ...Object.values(MATERIAL_DESIGN_ICONS).flatMap(Object.keys)]),
|
|
421
|
+
].sort();
|
|
420
422
|
|
|
421
423
|
/** The names the system's pack has an icon by in its maps (its set's and Material Design Icons'); all for Phosphor's. */
|
|
422
424
|
const mapped = (pack) => (PACK_MAPS[pack] ? [...Object.keys(PACK_MAPS[pack]), ...Object.keys(MATERIAL_DESIGN_ICONS[pack] ?? {})] : null);
|
package/src/CmsPage.tsx
CHANGED
|
@@ -12,7 +12,7 @@ import { when } from './when';
|
|
|
12
12
|
|
|
13
13
|
export const CMS_ROUTE = 'morpheme';
|
|
14
14
|
|
|
15
|
-
type Problem = 'unreachable' | 'cannot-write' | 'no-token' | 'not-managed' | 'slow-undo';
|
|
15
|
+
type Problem = 'unreachable' | 'cannot-write' | 'no-token' | 'no-kv' | 'not-managed' | 'slow-undo';
|
|
16
16
|
type UpdateState = 'waiting' | 'undoing' | 'done' | 'undone' | 'stuck';
|
|
17
17
|
type View = {
|
|
18
18
|
running: string;
|
|
@@ -130,10 +130,11 @@ export default function CmsPage() {
|
|
|
130
130
|
);
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
const kindText: Record<Problem, 'unreachable' | 'cannotWrite' | 'noToken' | 'notManaged' | 'slowUndo'> = {
|
|
133
|
+
const kindText: Record<Problem, 'unreachable' | 'cannotWrite' | 'noToken' | 'noKv' | 'notManaged' | 'slowUndo'> = {
|
|
134
134
|
unreachable: 'unreachable',
|
|
135
135
|
'cannot-write': 'cannotWrite',
|
|
136
136
|
'no-token': 'noToken',
|
|
137
|
+
'no-kv': 'noKv',
|
|
137
138
|
'not-managed': 'notManaged',
|
|
138
139
|
'slow-undo': 'slowUndo',
|
|
139
140
|
};
|
package/src/EntryForm.tsx
CHANGED
|
@@ -134,7 +134,10 @@ const same = (a: unknown, b: unknown) => JSON.stringify(a) === JSON.stringify(b)
|
|
|
134
134
|
// "Sidekolonne") leaves the file when it is on (booleanWrite).
|
|
135
135
|
const inForm = (fields: Field[], values: Record<string, unknown>) =>
|
|
136
136
|
Object.fromEntries(
|
|
137
|
-
fields.map((f) => [
|
|
137
|
+
fields.map((f) => [
|
|
138
|
+
f.name,
|
|
139
|
+
inUse(f, fields, values) ? (f.type === 'boolean' ? booleanWrite(values[f.name], f.missing) : values[f.name]) : '',
|
|
140
|
+
]),
|
|
138
141
|
);
|
|
139
142
|
|
|
140
143
|
type Props = { collection: MarkdownCollection; file: RepoFile; env: Env };
|
|
@@ -642,7 +645,8 @@ function Form({
|
|
|
642
645
|
// "Sidekolonne" only while src/data/side.json chooses a block and the page is not "Hele bredden" (sideSwitchShown).
|
|
643
646
|
const sideShown = sideSwitchShown({ block: sideSettingOf(env.files) }, values);
|
|
644
647
|
const field = (f: Field) =>
|
|
645
|
-
inUse(f, collection.fields, values) &&
|
|
648
|
+
inUse(f, collection.fields, values) &&
|
|
649
|
+
(f.name !== 'side' || sideShown) && <FieldInput key={f.name} field={f} value={values[f.name]} onChange={(v) => onChange(f, v)} />;
|
|
646
650
|
|
|
647
651
|
return (
|
|
648
652
|
<Fields.Provider value={fields}>
|
package/src/SideColumn.tsx
CHANGED
|
@@ -72,7 +72,12 @@ export default function SideColumn({ env, files }: { env: Env; files: RepoFile[]
|
|
|
72
72
|
return (
|
|
73
73
|
<Screen title={t.common.parts.sideColumn} wide back={back}>
|
|
74
74
|
<Group>
|
|
75
|
-
<ChoiceRow
|
|
75
|
+
<ChoiceRow
|
|
76
|
+
selected={!chosen}
|
|
77
|
+
onClick={() => choose(null, t.library.sideNone)}
|
|
78
|
+
headline={t.library.sideNone}
|
|
79
|
+
supporting={t.library.sideNoneHint}
|
|
80
|
+
/>
|
|
76
81
|
{choices.map((x) => (
|
|
77
82
|
<ChoiceRow key={x.type} selected={x.type === chosen} onClick={() => choose(x.type, x.label)} headline={x.label} />
|
|
78
83
|
))}
|
package/src/cmsView.mjs
CHANGED
|
@@ -64,6 +64,9 @@ export function cmsView(status, now = Date.now()) {
|
|
|
64
64
|
if (status.token === false) {
|
|
65
65
|
problems.push('no-token');
|
|
66
66
|
}
|
|
67
|
+
if (status.kv === false) {
|
|
68
|
+
problems.push('no-kv');
|
|
69
|
+
}
|
|
67
70
|
if (status.checked?.problem) {
|
|
68
71
|
const kind = status.checked.problem.kind;
|
|
69
72
|
if (kind === 'unreachable' || kind === 'cannot-write' || kind === 'not-managed') {
|
package/src/cmsView.test.mjs
CHANGED
|
@@ -103,6 +103,12 @@ test('no token', () => {
|
|
|
103
103
|
assert.deepEqual(view.problems, ['no-token']);
|
|
104
104
|
});
|
|
105
105
|
|
|
106
|
+
test('no kv', () => {
|
|
107
|
+
const status = makeStatus({ kv: false });
|
|
108
|
+
const view = cmsView(status, now);
|
|
109
|
+
assert.deepEqual(view.problems, ['no-kv']);
|
|
110
|
+
});
|
|
111
|
+
|
|
106
112
|
test('cannot write', () => {
|
|
107
113
|
const status = makeStatus({ checked: { problem: { kind: 'cannot-write' } } });
|
|
108
114
|
const view = cmsView(status, now);
|
package/src/i18n/da-DK/cms.ts
CHANGED
|
@@ -20,6 +20,7 @@ export const cms: Messages['cms'] = {
|
|
|
20
20
|
unreachable: 'npm eller GitHub kunne ikke nås.',
|
|
21
21
|
cannotWrite: 'Sitets GitHub-nøgle kan ikke gemme. Giv den Contents: Read and write.',
|
|
22
22
|
noToken: 'Sitet har ingen GitHub-nøgle (GITHUB_PUBLISH_TOKEN).',
|
|
23
|
+
noKv: 'Sitet har intet KV-lager (PUSH), så det kan ikke se efter nye versioner.',
|
|
23
24
|
notManaged: 'Sitets package.json bestemmer versionen.',
|
|
24
25
|
slowUndo: 'Nøglen kan ikke læse check runs, så en fejlet opdatering fortrydes først efter 20 minutter.',
|
|
25
26
|
notifyDone: (v) => `Morpheme er opdateret til ${v}`,
|
package/src/i18n/en-US/cms.ts
CHANGED
|
@@ -23,6 +23,7 @@ export const cms = {
|
|
|
23
23
|
unreachable: 'npm or GitHub couldn’t be reached.',
|
|
24
24
|
cannotWrite: 'The site’s GitHub token can’t save. Give it Contents: Read and write.',
|
|
25
25
|
noToken: 'The site has no GitHub token (GITHUB_PUBLISH_TOKEN).',
|
|
26
|
+
noKv: 'The site has no KV storage (PUSH), so it can’t look for new versions.',
|
|
26
27
|
notManaged: 'The site’s package.json decides the version.',
|
|
27
28
|
slowUndo: 'The token can’t read check runs, so a failed update is undone after 20 minutes.',
|
|
28
29
|
/** The site's notifications (Notifications.tsx) and the commits the Worker writes, in the site's language. */
|
package/starter/package.json
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@fontsource-variable/roboto": "^5.3.0",
|
|
32
32
|
"@material/material-color-utilities": "^0.3.0",
|
|
33
33
|
"@milkdown/kit": "^7.22.3",
|
|
34
|
-
"@morphemecms/cms": "0.
|
|
34
|
+
"@morphemecms/cms": "0.4.0",
|
|
35
35
|
"@phosphor-icons/core": "^2.1.1",
|
|
36
36
|
"@phosphor-icons/react": "^2.1.10",
|
|
37
37
|
"@tailwindcss/typography": "^0.5.20",
|
|
@@ -67,7 +67,8 @@ const review = (page.data.review ?? '').trim();
|
|
|
67
67
|
const sideType = sideBlock(page.data);
|
|
68
68
|
const sideText = end ? end.html : html;
|
|
69
69
|
const side =
|
|
70
|
-
sideType &&
|
|
70
|
+
sideType &&
|
|
71
|
+
(await blockLoads[sideType].load({}, { texts: blockTexts[sideType] ?? {}, index: 0, path: current, preview, html: sideText })) !== null
|
|
71
72
|
? sideType
|
|
72
73
|
: null;
|
|
73
74
|
---
|
package/worker/cms-update.js
CHANGED
|
@@ -200,18 +200,19 @@ export async function watchUpdate(env, deps = defaultDeps, now = Date.now()) {
|
|
|
200
200
|
return tell(env, deps, 'notifyStuck', update.to, true);
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
-
/** What the page shows: the running version, the token, what npm said, the update, the skipped versions and the notes. */
|
|
204
|
-
export async function cmsStatus(env) {
|
|
203
|
+
/** What the page shows: the running version, the token, what npm said, the update, the skipped versions and the notes; no notes when the running version is a pre-release. */
|
|
204
|
+
export async function cmsStatus(env, running = RUNNING) {
|
|
205
205
|
const kv = env.PUSH;
|
|
206
|
-
const status = { running
|
|
206
|
+
const status = { running, token: !!env.GITHUB_PUBLISH_TOKEN, kv: !!kv, checked: null, update: null, skipped: [], notes: [] };
|
|
207
|
+
const plain = /^\d+\.\d+\.\d+$/;
|
|
207
208
|
if (!kv) return status;
|
|
208
209
|
status.checked = await kv.get('cms:checked', 'json');
|
|
209
210
|
status.update = await kv.get('cms:update', 'json');
|
|
210
211
|
status.skipped = await versionsUnder(kv, 'cms:skip:');
|
|
211
|
-
|
|
212
|
+
if (!plain.test(running)) return status;
|
|
212
213
|
const wanted = (await versionsUnder(kv, 'cms:notes:')).filter(
|
|
213
214
|
(v) =>
|
|
214
|
-
plain.test(v) && compareVersions(v,
|
|
215
|
+
plain.test(v) && compareVersions(v, running) === 1 && (!status.checked?.latest || compareVersions(v, status.checked.latest) <= 0),
|
|
215
216
|
);
|
|
216
217
|
wanted.sort((a, b) => compareVersions(b, a));
|
|
217
218
|
const notes = await Promise.all(wanted.map((v) => kv.get(`cms:notes:${v}`, 'json')));
|