@webjskit/cli 0.4.0 → 0.4.2
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/lib/create.js +21 -0
- package/lib/saas-template.js +48 -0
- package/package.json +2 -2
- package/templates/CONVENTIONS.md +75 -26
package/lib/create.js
CHANGED
|
@@ -266,6 +266,27 @@ export async function POST(req: Request) {
|
|
|
266
266
|
const body = await req.json();
|
|
267
267
|
return Response.json(await createUser(body));
|
|
268
268
|
}
|
|
269
|
+
`);
|
|
270
|
+
// Minimal test stub so the scaffold passes `webjs check` (tests-exist)
|
|
271
|
+
// and `webjs test` runs cleanly. Replace these with real assertions
|
|
272
|
+
// once you wire the action/query to a real data source.
|
|
273
|
+
await writeFile(join(appDir, 'test', 'unit', 'users.test.ts'), `import { test } from 'node:test';
|
|
274
|
+
import assert from 'node:assert/strict';
|
|
275
|
+
|
|
276
|
+
import { listUsers } from '../../modules/users/queries/list-users.server.ts';
|
|
277
|
+
import { createUser } from '../../modules/users/actions/create-user.server.ts';
|
|
278
|
+
|
|
279
|
+
test('listUsers returns an array', async () => {
|
|
280
|
+
const users = await listUsers();
|
|
281
|
+
assert.ok(Array.isArray(users));
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
test('createUser returns a success envelope with the input echoed back', async () => {
|
|
285
|
+
const result = await createUser({ name: 'Test', email: 'test@example.com' });
|
|
286
|
+
assert.equal(result.success, true);
|
|
287
|
+
assert.equal(result.data.name, 'Test');
|
|
288
|
+
assert.equal(result.data.email, 'test@example.com');
|
|
289
|
+
});
|
|
269
290
|
`);
|
|
270
291
|
await writeFile(join(appDir, 'modules', 'users', 'types.ts'), `export interface User {
|
|
271
292
|
id: string;
|
package/lib/saas-template.js
CHANGED
|
@@ -133,6 +133,54 @@ export async function writeSaasFiles(appDir) {
|
|
|
133
133
|
"",
|
|
134
134
|
].join('\n'));
|
|
135
135
|
|
|
136
|
+
// test/unit/auth.test.ts — minimal stub so the scaffold passes
|
|
137
|
+
// `webjs check` (tests-exist) and `webjs test` runs cleanly out of the
|
|
138
|
+
// box. The signup/current-user functions import from lib/prisma.ts and
|
|
139
|
+
// lib/auth.ts, both of which need `prisma generate` to have run before
|
|
140
|
+
// they can be imported — so we deliberately test only the runtime-
|
|
141
|
+
// dependency-free types.ts here. Replace with real tests once Prisma
|
|
142
|
+
// is set up (run `npm install && npx prisma migrate dev --name init`).
|
|
143
|
+
await writeFile(join(appDir, 'test', 'unit', 'auth.test.ts'), [
|
|
144
|
+
"import { test } from 'node:test';",
|
|
145
|
+
"import assert from 'node:assert/strict';",
|
|
146
|
+
"",
|
|
147
|
+
"import type { User, ActionResult } from '../../modules/auth/types.ts';",
|
|
148
|
+
"",
|
|
149
|
+
"test('User shape: id is numeric, email is required', () => {",
|
|
150
|
+
" const u: User = { id: 1, name: 'Test', email: 'test@example.com' };",
|
|
151
|
+
" assert.equal(typeof u.id, 'number');",
|
|
152
|
+
" assert.equal(typeof u.email, 'string');",
|
|
153
|
+
"});",
|
|
154
|
+
"",
|
|
155
|
+
"test('ActionResult: success envelope carries data', () => {",
|
|
156
|
+
" const r: ActionResult<User> = {",
|
|
157
|
+
" success: true,",
|
|
158
|
+
" data: { id: 1, name: 'Test', email: 'test@example.com' },",
|
|
159
|
+
" };",
|
|
160
|
+
" assert.equal(r.success, true);",
|
|
161
|
+
" if (r.success) assert.equal(r.data.email, 'test@example.com');",
|
|
162
|
+
"});",
|
|
163
|
+
"",
|
|
164
|
+
"test('ActionResult: failure envelope carries error + status', () => {",
|
|
165
|
+
" const r: ActionResult<User> = {",
|
|
166
|
+
" success: false,",
|
|
167
|
+
" error: 'Email already registered',",
|
|
168
|
+
" status: 409,",
|
|
169
|
+
" };",
|
|
170
|
+
" assert.equal(r.success, false);",
|
|
171
|
+
" if (!r.success) {",
|
|
172
|
+
" assert.equal(r.status, 409);",
|
|
173
|
+
" assert.ok(r.error.length > 0);",
|
|
174
|
+
" }",
|
|
175
|
+
"});",
|
|
176
|
+
"",
|
|
177
|
+
"// TODO: once you've run `npm install && npx prisma migrate dev` you can",
|
|
178
|
+
"// import { signup } from '../../modules/auth/actions/signup.server.ts'",
|
|
179
|
+
"// and { currentUser } from '../../modules/auth/queries/current-user.server.ts'",
|
|
180
|
+
"// and write real integration tests against a test SQLite DB.",
|
|
181
|
+
"",
|
|
182
|
+
].join('\n'));
|
|
183
|
+
|
|
136
184
|
// app/api/auth/[...path]/route.ts
|
|
137
185
|
await mkdir(join(appDir, 'app', 'api', 'auth', '[...path]'), { recursive: true });
|
|
138
186
|
await writeFile(join(appDir, 'app', 'api', 'auth', '[...path]', 'route.ts'), [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webjskit/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "webjs CLI — dev, start, create, db",
|
|
6
6
|
"bin": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"README.md"
|
|
14
14
|
],
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@webjskit/server": "0.4.
|
|
16
|
+
"@webjskit/server": "0.4.1"
|
|
17
17
|
},
|
|
18
18
|
"publishConfig": {
|
|
19
19
|
"access": "public"
|
package/templates/CONVENTIONS.md
CHANGED
|
@@ -6,7 +6,76 @@ how code should be structured, tested, and organized.
|
|
|
6
6
|
|
|
7
7
|
Sections marked `<!-- OVERRIDE -->` contain defaults you can customize.
|
|
8
8
|
Edit the content below the marker to change the convention for your project.
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## How `CONVENTIONS.md` relates to `webjs check`
|
|
13
|
+
|
|
14
|
+
These are **two separate mechanisms** that share a topic but don't read
|
|
15
|
+
each other:
|
|
16
|
+
|
|
17
|
+
| | This file (`CONVENTIONS.md`) | `webjs check` |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| **Kind** | Markdown documentation. | Programmatic linter (code in `node_modules/@webjskit/server/src/check.js`). |
|
|
20
|
+
| **Audience** | Humans + AI agents who read the project. | Run from the CLI / CI. |
|
|
21
|
+
| **Effect of editing this markdown** | Changes the rules AI agents follow when they write code. | **Zero.** The linter does not parse this file. |
|
|
22
|
+
| **How to customize the LINTER** | n/a — it's hardcoded in `@webjskit/server`. | Disable rules via `package.json` or `webjs.conventions.js` (see below). |
|
|
23
|
+
|
|
24
|
+
So when you edit a `<!-- OVERRIDE -->` section here, you're telling AI
|
|
25
|
+
agents to follow a different convention — but `webjs check` will still
|
|
26
|
+
enforce its hardcoded rules. If you want the linter to stop flagging
|
|
27
|
+
something it currently flags, you have to **disable that rule** as a
|
|
28
|
+
separate step.
|
|
29
|
+
|
|
30
|
+
### Disabling a `webjs check` rule
|
|
31
|
+
|
|
32
|
+
`webjs check --rules` prints the full list. To disable one, add to
|
|
33
|
+
`package.json`:
|
|
34
|
+
|
|
35
|
+
```jsonc
|
|
36
|
+
{
|
|
37
|
+
"webjs": {
|
|
38
|
+
"conventions": {
|
|
39
|
+
"tests-exist": false,
|
|
40
|
+
"actions-in-modules": false
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Or create `webjs.conventions.js`:
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
export default {
|
|
50
|
+
'tests-exist': false,
|
|
51
|
+
};
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Only `false` is meaningful — there's no way to tweak rule *behaviour* via
|
|
55
|
+
config today, only to switch a whole rule on or off.
|
|
56
|
+
|
|
57
|
+
### What `webjs check` enforces today
|
|
58
|
+
|
|
59
|
+
Run `webjs check --rules` for the current set with descriptions. As of
|
|
60
|
+
`@webjskit/server@0.4.1`:
|
|
61
|
+
|
|
62
|
+
- `actions-in-modules` — `.server.{js,ts}` / `'use server'` files belong
|
|
63
|
+
in `modules/<feature>/actions/` or `queries/`. `lib/` is exempt
|
|
64
|
+
(cross-cutting server infra).
|
|
65
|
+
- `one-function-per-action` — files inside `modules/*/actions/` or
|
|
66
|
+
`modules/*/queries/` should export exactly one async function.
|
|
67
|
+
- `components-have-register` — `WebComponent` subclasses must call
|
|
68
|
+
`Class.register('tag')` or `customElements.define`.
|
|
69
|
+
- `no-server-imports-in-components` — components must not import
|
|
70
|
+
`@prisma/client`, `node:*`, or `lib/*`.
|
|
71
|
+
- `reactive-props-use-declare` — props listed in `static properties` must
|
|
72
|
+
use the `declare propName: Type` + constructor-default pattern (class
|
|
73
|
+
field initializers clobber the framework's reactive accessor).
|
|
74
|
+
- `tag-name-has-hyphen` — custom element tags must contain a hyphen.
|
|
75
|
+
- `tests-exist` — each `modules/<feature>/` should have a test file.
|
|
76
|
+
- `no-json-data-files` — JSON files that look like a database (under
|
|
77
|
+
`data/`, or named `db.json` / `database.json` / `*-db.json`) are
|
|
78
|
+
forbidden; use Prisma + SQLite instead.
|
|
10
79
|
|
|
11
80
|
---
|
|
12
81
|
|
|
@@ -612,32 +681,12 @@ This project enforces a git workflow via agent-specific config files
|
|
|
612
681
|
|
|
613
682
|
## Overriding conventions
|
|
614
683
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
{
|
|
619
|
-
"webjs": {
|
|
620
|
-
"conventions": {
|
|
621
|
-
"actions-in-modules": false,
|
|
622
|
-
"one-function-per-action": false,
|
|
623
|
-
"tests-exist": false
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
```
|
|
628
|
-
|
|
629
|
-
Or create `webjs.config.js`:
|
|
630
|
-
|
|
631
|
-
```js
|
|
632
|
-
export default {
|
|
633
|
-
conventions: {
|
|
634
|
-
'actions-in-modules': false,
|
|
635
|
-
},
|
|
636
|
-
};
|
|
637
|
-
```
|
|
684
|
+
See the **"How `CONVENTIONS.md` relates to `webjs check`"** section at
|
|
685
|
+
the top of this file. Short version: disable specific linter rules via
|
|
686
|
+
`package.json` (`webjs.conventions.<rule>: false`) or `webjs.conventions.js`.
|
|
638
687
|
|
|
639
|
-
Run `webjs check` to validate
|
|
640
|
-
|
|
688
|
+
Run `webjs check` to validate. Run `webjs check --rules` to list every
|
|
689
|
+
rule with its description.
|
|
641
690
|
|
|
642
691
|
---
|
|
643
692
|
|