create-evikit 2.4.0 → 2.5.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/.woodpecker/test.yaml +18 -0
- package/README.md +36 -0
- package/bin/create-evikit.js +4 -4
- package/package.json +3 -3
- package/src/lib/db/index.js +5 -6
- package/src/routes/page.js +15 -11
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
when:
|
|
2
|
+
- event: push
|
|
3
|
+
branch: main
|
|
4
|
+
- event: pull_request
|
|
5
|
+
|
|
6
|
+
steps:
|
|
7
|
+
- name: build
|
|
8
|
+
image: node:24-alpine
|
|
9
|
+
commands:
|
|
10
|
+
- apk add git
|
|
11
|
+
# Are types correct?
|
|
12
|
+
- npm i
|
|
13
|
+
- npm run lint
|
|
14
|
+
- npm run build
|
|
15
|
+
# Does todo app example build?
|
|
16
|
+
- npm link
|
|
17
|
+
- npx create-evikit my-app
|
|
18
|
+
- (cd my-app; npm run build)
|
package/README.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# create-evikit
|
|
2
|
+
|
|
3
|
+
Create a monolith server-rendered Preact app with an API powered by a node:sqlite database, using [EviKit](https://evikit.js.org/):
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npm init evikit my-app
|
|
7
|
+
cd my-app
|
|
8
|
+
npm run dev
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Open http://localhost:5173/, try editing the example routes and see changes live.
|
|
12
|
+
|
|
13
|
+
You can continue with the [EviKit tutorial](https://codeberg.org/nykula/evikit#documentation). With this initializer, you don't have to manually install dependencies, add scripts to `package.json`, or create typical files such as `index.html` and `vite.config.js`.
|
|
14
|
+
|
|
15
|
+
> 😉 If you are new to Preact and the concept of Virtual DOM, it is a good idea to complete the [Preact tutorial](https://preactjs.com/tutorial/) first.
|
|
16
|
+
|
|
17
|
+
## Read more
|
|
18
|
+
|
|
19
|
+
Think of EviKit as an [LXDE](https://en.wikipedia.org/wiki/LXDE#Software_components_of_LXDE) of web frameworks, it stands on the shoulders of awesome libraries and tools from the Preact and Node.js ecosystems:
|
|
20
|
+
|
|
21
|
+
- **[valibot](https://valibot.dev/guides/introduction/)** - Lets you declare detabase schema and validate API input/output.
|
|
22
|
+
- **[hoofd/preact](https://github.com/0no-co/hoofd)** - Populates `<title>` and `<meta>` tags.
|
|
23
|
+
- **[gettext.js](https://github.com/smhg/gettext-parser)** - Lets you pluralize translated strings.
|
|
24
|
+
- **[vite](https://vite.dev/guide/)** - Builds your app for development and production.
|
|
25
|
+
- **[express](https://expressjs.com/)** - Lets you apply compression, serve static files and use other familiar middleware.
|
|
26
|
+
- [@fastify/busboy](https://github.com/fastify/busboy) - Parses forms, including uploaded files.
|
|
27
|
+
- [@preact/preset-vite](https://github.com/preactjs/preset-vite) - In development, shows your code changes without reloading the page.
|
|
28
|
+
- [env-paths](https://github.com/fastify/busboy) - Saves your database in standard system-specific directory.
|
|
29
|
+
- [gettext-parser](https://github.com/smhg/gettext-parser) - Parses translation files.
|
|
30
|
+
- [preact-iso](https://github.com/preactjs/preact-iso) - Handles routing and hydrates the server-rendered code on the client.
|
|
31
|
+
|
|
32
|
+
## License
|
|
33
|
+
|
|
34
|
+
SPDX-License-Identifier: 0BSD
|
|
35
|
+
|
|
36
|
+
Note: this license applies to this example application template. EviKit itself uses the MIT license.
|
package/bin/create-evikit.js
CHANGED
|
@@ -25,7 +25,7 @@ for (const file of [...template, "eslint.config.js", "tsconfig.json"]) {
|
|
|
25
25
|
path,
|
|
26
26
|
readFileSync(join(ownRoot, file), "utf8")
|
|
27
27
|
.replace(
|
|
28
|
-
/<link\s+href="[^"]+"
|
|
28
|
+
/<link\s+href="[^"]+"\s+media="[^"]+"\s+rel="[a-z]+"\s+\/>\s+/g,
|
|
29
29
|
"",
|
|
30
30
|
)
|
|
31
31
|
.replace(', "uk"', ""),
|
|
@@ -120,8 +120,8 @@ writeFileSync(
|
|
|
120
120
|
writeFileSync(
|
|
121
121
|
join(target, ".env"),
|
|
122
122
|
`
|
|
123
|
-
ORIGIN=http://localhost:
|
|
124
|
-
PORT=
|
|
123
|
+
ORIGIN=http://localhost:5173
|
|
124
|
+
PORT=5173
|
|
125
125
|
`.trimStart(),
|
|
126
126
|
);
|
|
127
127
|
|
|
@@ -146,6 +146,7 @@ const pkg = {
|
|
|
146
146
|
dependencies: {
|
|
147
147
|
"accept-language": dependencies["accept-language"],
|
|
148
148
|
classnames: dependencies.classnames,
|
|
149
|
+
"cross-env": dependencies["cross-env"],
|
|
149
150
|
evikit: dependencies.evikit,
|
|
150
151
|
express: dependencies.express,
|
|
151
152
|
"file-type": dependencies["file-type"],
|
|
@@ -163,7 +164,6 @@ const pkg = {
|
|
|
163
164
|
"@types/express": devDependencies["@types/express"],
|
|
164
165
|
"@types/node": devDependencies["@types/node"],
|
|
165
166
|
"@types/swagger-ui-express": devDependencies["@types/swagger-ui-express"],
|
|
166
|
-
"cross-env": devDependencies["cross-env"],
|
|
167
167
|
daisyui: devDependencies.daisyui,
|
|
168
168
|
eslint: devDependencies.eslint,
|
|
169
169
|
"eslint-config-prettier": devDependencies["eslint-config-prettier"],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-evikit",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": "bin/create-evikit.js",
|
|
6
6
|
"scripts": {
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
"@types/express": "^5.0.6",
|
|
22
22
|
"@types/node": "^26.1.0",
|
|
23
23
|
"@types/swagger-ui-express": "^4.1.8",
|
|
24
|
-
"cross-env": "^10.1.0",
|
|
25
24
|
"daisyui": "^5.6.14",
|
|
26
25
|
"eslint": "^10.6.0",
|
|
27
26
|
"eslint-config-prettier": "^10.1.8",
|
|
@@ -37,7 +36,8 @@
|
|
|
37
36
|
"@speed-highlight/core": "^1.2.17",
|
|
38
37
|
"accept-language": "^3.0.20",
|
|
39
38
|
"classnames": "^2.5.1",
|
|
40
|
-
"
|
|
39
|
+
"cross-env": "^10.1.0",
|
|
40
|
+
"evikit": "^2.5.0",
|
|
41
41
|
"express": "^5.2.1",
|
|
42
42
|
"file-type": "^22.0.1",
|
|
43
43
|
"hoofd": "^1.7.3",
|
package/src/lib/db/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { daemon } from "evikit/server";
|
|
1
2
|
import { sqlite } from "evikit/sqlite";
|
|
2
3
|
|
|
3
4
|
import pkg from "../../../package.json" with { type: "json" };
|
|
@@ -5,15 +6,13 @@ import * as schema from "./schema.js";
|
|
|
5
6
|
|
|
6
7
|
export const db = sqlite({ pkg, schema });
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
process.env["npm_lifecycle_event"] == "dev"
|
|
11
|
-
) {
|
|
12
|
-
setInterval(() => {
|
|
9
|
+
daemon(() => {
|
|
10
|
+
const interval = setInterval(() => {
|
|
13
11
|
db.Todo.delete({
|
|
14
12
|
text: db.Todo.select()
|
|
15
13
|
.filter(({ createdAt }) => createdAt < Date.now() - 10 * 60e3)
|
|
16
14
|
.map(({ text }) => text),
|
|
17
15
|
});
|
|
18
16
|
}, 1000);
|
|
19
|
-
|
|
17
|
+
return () => clearInterval(interval);
|
|
18
|
+
});
|
package/src/routes/page.js
CHANGED
|
@@ -168,11 +168,22 @@ npm run dev
|
|
|
168
168
|
|
|
169
169
|
h(
|
|
170
170
|
Code,
|
|
171
|
-
{
|
|
171
|
+
{
|
|
172
|
+
class: "row-span-2",
|
|
173
|
+
file: data?.File["src/routes/todo/page.js"],
|
|
174
|
+
lang: "js",
|
|
175
|
+
},
|
|
172
176
|
span(null, "src/routes/"),
|
|
173
177
|
b(null, "todo/page.js"),
|
|
174
178
|
),
|
|
175
179
|
|
|
180
|
+
h(
|
|
181
|
+
Code,
|
|
182
|
+
{ file: data?.File["src/lib/db/index.js"], lang: "js" },
|
|
183
|
+
span(null, "src/lib/"),
|
|
184
|
+
b(null, "db/index.js"),
|
|
185
|
+
),
|
|
186
|
+
|
|
176
187
|
h(
|
|
177
188
|
Code,
|
|
178
189
|
{ file: data?.File["src/routes/error.js"], lang: "js" },
|
|
@@ -227,13 +238,6 @@ npm run dev
|
|
|
227
238
|
b(null, "vite.config.js"),
|
|
228
239
|
),
|
|
229
240
|
|
|
230
|
-
h(
|
|
231
|
-
Code,
|
|
232
|
-
{ file: data?.File["src/lib/db/index.js"], lang: "js", tag: "details" },
|
|
233
|
-
span(null, "src/lib/"),
|
|
234
|
-
b(null, "db/index.js"),
|
|
235
|
-
),
|
|
236
|
-
|
|
237
241
|
h(
|
|
238
242
|
Code,
|
|
239
243
|
{ file: data?.File["index.html"], lang: "html", tag: "details" },
|
|
@@ -299,8 +303,8 @@ npm run dev
|
|
|
299
303
|
);
|
|
300
304
|
}
|
|
301
305
|
|
|
302
|
-
/** @param {{ children?: any, lang: string, file: string | undefined, note?: string, tag?: string }} props */
|
|
303
|
-
function Code({ children, file, lang, note, tag }) {
|
|
306
|
+
/** @param {{ children?: any, class?: string, lang: string, file: string | undefined, note?: string, tag?: string }} props */
|
|
307
|
+
function Code({ children, class: className, file, lang, note, tag }) {
|
|
304
308
|
const inner = pre(
|
|
305
309
|
{ class: "mt-4 overflow-auto text-sm" },
|
|
306
310
|
code(
|
|
@@ -319,7 +323,7 @@ function Code({ children, file, lang, note, tag }) {
|
|
|
319
323
|
),
|
|
320
324
|
);
|
|
321
325
|
const more = note ? p({ class: "mt-5", ...sanitize(note) }) : undefined;
|
|
322
|
-
const style = `${darkBg} mb-4 mx-0 overflow-hidden p-4 rounded-xl`;
|
|
326
|
+
const style = `${className} ${darkBg} mb-4 mx-0 overflow-hidden p-4 rounded-xl`;
|
|
323
327
|
return tag == "details"
|
|
324
328
|
? details({ class: style }, summary(null, children), inner, more)
|
|
325
329
|
: figure({ class: style }, figcaption(null, children), inner, more);
|