kempo 4.2.35 → 4.2.37
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
CHANGED
|
@@ -416,6 +416,8 @@ npm test
|
|
|
416
416
|
|
|
417
417
|
`.env.example` has the matching `DATABASE_URL`. The suite seeds its own groups and permissions, and cleans up the rows it creates.
|
|
418
418
|
|
|
419
|
+
`npm test` (`kempo-test -n`) only runs the Node-side suite. Admin components that need a real DOM run in an actual browser via `npm run test:browser` — no database or running server required, since it exercises the real component/SDK code with only `window.fetch` intercepted for canned responses. It temporarily junctions `/kempo-ui`, `/kempo-css` and `/kempo` onto `node_modules`/`dist` at the project root so the admin bundle's absolute imports resolve against kempo-testing-framework's static test server, and removes them afterward regardless of pass/fail.
|
|
420
|
+
|
|
419
421
|
### Building for Distribution
|
|
420
422
|
|
|
421
423
|
When preparing the framework for npm release, minify and optimize the source code:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kempo",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.37",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A fullstack CMS framework for creating websites with user authentication",
|
|
6
6
|
"scripts": {
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"test:email": "node ./scripts/test-email.js",
|
|
15
15
|
"test": "kempo-test -n",
|
|
16
16
|
"test:node": "kempo-test -n",
|
|
17
|
+
"test:browser": "node scripts/run-browser-tests.js",
|
|
17
18
|
"link:local": "npm install ../kempo-server ../kempo-ui --no-save",
|
|
18
19
|
"db:reset": "node ./scripts/reset-db.js"
|
|
19
20
|
},
|
package/server/sdk.js
CHANGED
|
@@ -82,6 +82,7 @@ export { default as userHasSomePermissions } from './utils/permissions/userHasSo
|
|
|
82
82
|
Settings
|
|
83
83
|
*/
|
|
84
84
|
|
|
85
|
+
export { default as declaredValue } from './utils/settings/declaredValue.js';
|
|
85
86
|
export { default as deleteSetting } from './utils/settings/deleteSetting.js';
|
|
86
87
|
export { default as getPublicSettings } from './utils/settings/getPublicSettings.js';
|
|
87
88
|
export { default as getSetting } from './utils/settings/getSetting.js';
|
|
@@ -9,6 +9,7 @@ import { randomUUID } from 'crypto';
|
|
|
9
9
|
import triggerHook, { clearHandlerCache } from '../hooks/triggerHook.js';
|
|
10
10
|
import createHook from '../hooks/createHook.js';
|
|
11
11
|
import setSetting from '../settings/setSetting.js';
|
|
12
|
+
import declaredValue from '../settings/declaredValue.js';
|
|
12
13
|
import createTablesFromSchema from './createTablesFromSchema.js';
|
|
13
14
|
import { invalidateScopeCache } from './scopeCache.js';
|
|
14
15
|
import { getUnmetDependencies } from './dependencies.js';
|
|
@@ -91,7 +92,7 @@ export default async ({ name }) => {
|
|
|
91
92
|
Create declarative settings
|
|
92
93
|
*/
|
|
93
94
|
for(const { name: settingName, value, type, description } of kempoConfig.settings || []){
|
|
94
|
-
await setSetting(name, settingName, value, type || null, false, description || null);
|
|
95
|
+
await setSetting(name, settingName, declaredValue(value, type), type || null, false, description || null);
|
|
95
96
|
}
|
|
96
97
|
|
|
97
98
|
/*
|
|
@@ -9,6 +9,7 @@ import { execSync } from 'child_process';
|
|
|
9
9
|
import triggerHook, { clearHandlerCache } from '../hooks/triggerHook.js';
|
|
10
10
|
import createHook from '../hooks/createHook.js';
|
|
11
11
|
import setSetting from '../settings/setSetting.js';
|
|
12
|
+
import declaredValue from '../settings/declaredValue.js';
|
|
12
13
|
import createTablesFromSchema from './createTablesFromSchema.js';
|
|
13
14
|
|
|
14
15
|
const requireFromProject = createRequire(join(process.cwd(), 'package.json'));
|
|
@@ -97,7 +98,7 @@ export default async ({ name, version = 'latest' }) => {
|
|
|
97
98
|
const oldSettingNames = new Set((oldKempo.settings || []).map(s => s.name));
|
|
98
99
|
for(const { name: settingName, value, type, description } of newKempo.settings || []){
|
|
99
100
|
if(!oldSettingNames.has(settingName)){
|
|
100
|
-
await setSetting(name, settingName, value, type || null, false, description || null);
|
|
101
|
+
await setSetting(name, settingName, declaredValue(value, type), type || null, false, description || null);
|
|
101
102
|
}
|
|
102
103
|
}
|
|
103
104
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*
|
|
2
|
+
A declared setting's default, turned into the value `setSetting` expects.
|
|
3
|
+
|
|
4
|
+
kempo-config.json declares defaults as strings — `"value": "10"` for a number, `"value": "true"`
|
|
5
|
+
for a boolean — and that is what the extension docs tell authors to write. `setSetting` takes the
|
|
6
|
+
*real* value and serialises it according to the type it is given, and for every scalar type the
|
|
7
|
+
two happen to agree: `serializeValue('10', 'number')` is `String('10')`, which is `'10'`.
|
|
8
|
+
|
|
9
|
+
For `json` they do not. A declared `"value": "[{\"label\":\"sm\"}]"` is a string, and
|
|
10
|
+
`serializeValue(aString, 'json')` is `JSON.stringify(aString)` — the array gets encoded a second
|
|
11
|
+
time, and reading the setting back returns the JSON *text* rather than the array. Nothing errors;
|
|
12
|
+
the extension simply behaves as though the setting were empty, which is a very quiet way to break.
|
|
13
|
+
|
|
14
|
+
So a json default is parsed here before it is stored. A value that is already a real array or
|
|
15
|
+
object (perfectly legal in kempo-config.json, and what you get if you write the JSON inline) is
|
|
16
|
+
passed through untouched, and a string that is not valid JSON is left as-is rather than thrown —
|
|
17
|
+
a malformed default is the author's problem to see in their own settings screen, not a reason to
|
|
18
|
+
fail the whole install.
|
|
19
|
+
*/
|
|
20
|
+
export default (value, type) => {
|
|
21
|
+
if(type !== 'json' || typeof value !== 'string') return value;
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(value);
|
|
25
|
+
} catch {
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
};
|