@naru-pub/dev 0.0.0-stage → 1.1.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/LICENSE +661 -0
- package/README.md +169 -2
- package/dist/build.json +4 -0
- package/dist/chunk-CQFKRWOD.mjs +1230 -0
- package/dist/chunk-K7ZVYKB2.mjs +11 -0
- package/dist/cli.mjs +103 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.mjs +7 -0
- package/dist/sdk/1.0.0/naru.d.ts +207 -0
- package/dist/sdk/1.0.0/naru.js +722 -0
- package/dist/sdk/1.1.0/functions.d.ts +206 -0
- package/dist/sdk/1.1.0/naru.d.ts +349 -0
- package/dist/sdk/1.1.0/naru.js +1066 -0
- package/dist/testing.d.ts +1 -0
- package/dist/testing.mjs +7 -0
- package/dist/worker/05f16b7a30ddbe6e522bc3300013f93b30366682-metered.wasm +0 -0
- package/dist/worker/config.capnp +52 -0
- package/dist/worker/seoul.js +15357 -0
- package/package.json +61 -4
package/README.md
CHANGED
|
@@ -1,3 +1,170 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @naru-pub/dev
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Run and test a [Naru](https://naru.pub) site on your own machine: its pages,
|
|
4
|
+
the Data SDK, and its site code (`_naru/` migrations, queries, mutations,
|
|
5
|
+
routes, live queries) on the same edge Worker that serves `sdk.naru.pub`,
|
|
6
|
+
with one-click owner and member sign-in. No Naru account or checkout is
|
|
7
|
+
needed, and once installed it runs offline.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx @naru-pub/dev ./site --site demo
|
|
11
|
+
# naru-dev: demo at http://localhost:4000/
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Requires Node.js 20 or later, on macOS or Linux (arm64 or x64) or Windows
|
|
15
|
+
(x64): the platforms [workerd](https://www.npmjs.com/package/workerd), which
|
|
16
|
+
it runs, ships a binary for, and where naru-dev is tested.
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
Run it once with `npx @naru-pub/dev`, or add it to a project:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install --save-dev @naru-pub/dev
|
|
24
|
+
npx naru-dev ./site --site demo
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## The command
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
naru-dev [site folder] [options]
|
|
31
|
+
|
|
32
|
+
--site <name> the site's Naru name (<name>.naru.pub); default localsite
|
|
33
|
+
--port <port> default 4000; 0 picks a free one
|
|
34
|
+
--state <dir> where data is kept; default <site folder>/.naru-dev
|
|
35
|
+
--quiet print only the address
|
|
36
|
+
--version print the version and exit
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
It prints its version, the Naru commit it was built from and the SDK
|
|
40
|
+
versions it serves, then serves the folder on `http://localhost:<port>`:
|
|
41
|
+
|
|
42
|
+
- **Pages** as they are, with an import map added to each HTML page, so
|
|
43
|
+
`import ... from "https://sdk.naru.pub/sdk/1.1.0/naru.js"` (and `/sdk/1/`,
|
|
44
|
+
`/sdk/1.0.0/`) loads this machine's SDK, pointed at this server. Keep the
|
|
45
|
+
real URLs in your pages; they work unchanged on Naru.
|
|
46
|
+
- **`_naru/`**: every file is published at start and again whenever one
|
|
47
|
+
changes, migrations applied; `_naru/collections.json` is installed,
|
|
48
|
+
changes included. After each publication it writes
|
|
49
|
+
`_naru/types/database.d.ts`, the site's tables as interfaces for `ctx.sql`
|
|
50
|
+
and query builders.
|
|
51
|
+
- **Sign-in**: `naru.auth.signIn()` signs the owner in on one click
|
|
52
|
+
(collections it asks for are made private if missing, as on Naru);
|
|
53
|
+
`naru.members.signIn()` opens a page to pick or name a test member and
|
|
54
|
+
their status (approved, pending, banned).
|
|
55
|
+
- **Uploads** keep their `https://media.naru.pub/...` addresses; a service
|
|
56
|
+
worker on your pages serves them from `<state>/media/`.
|
|
57
|
+
|
|
58
|
+
Data, uploads, members and sign-ins are kept in `<site folder>/.naru-dev/`
|
|
59
|
+
(add it to `.gitignore`) and survive restarts. Delete the folder to start
|
|
60
|
+
over.
|
|
61
|
+
|
|
62
|
+
## Testing
|
|
63
|
+
|
|
64
|
+
`@naru-pub/dev/testing` starts the same server inside your test, on a free
|
|
65
|
+
port with a temporary state, and signs people in without clicking:
|
|
66
|
+
|
|
67
|
+
```js
|
|
68
|
+
import { startNaru } from "@naru-pub/dev/testing";
|
|
69
|
+
import { chromium } from "playwright";
|
|
70
|
+
|
|
71
|
+
const naru = await startNaru({ site: "./site", name: "demo", quiet: true });
|
|
72
|
+
const browser = await chromium.launch();
|
|
73
|
+
try {
|
|
74
|
+
const owner = await browser.newContext();
|
|
75
|
+
await naru.signIn(owner, "owner");
|
|
76
|
+
const page = await owner.newPage();
|
|
77
|
+
await page.goto(naru.url("/admin/"));
|
|
78
|
+
// ...the page finds the owner's session, as after a real sign-in.
|
|
79
|
+
|
|
80
|
+
const alice = await browser.newContext();
|
|
81
|
+
await naru.signIn(alice, "alice");
|
|
82
|
+
|
|
83
|
+
// Or call the data API yourself:
|
|
84
|
+
const { headers } = await naru.signIn(null, "bob");
|
|
85
|
+
await fetch(naru.url("/api/data/v1/demo/_mutate/notes:add"), {
|
|
86
|
+
method: "POST",
|
|
87
|
+
headers: { ...headers, "content-type": "application/json" },
|
|
88
|
+
body: JSON.stringify({ args: { text: "hi" } }),
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
await naru.reset(); // an empty site again, migrations applied
|
|
92
|
+
} finally {
|
|
93
|
+
await browser.close();
|
|
94
|
+
await naru.stop();
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
`startNaru(options)` resolves once the site answers. Options:
|
|
99
|
+
|
|
100
|
+
| Option | Default | What |
|
|
101
|
+
| ------- | ----------------- | -------------------------------------------------------- |
|
|
102
|
+
| `site` | (required) | The site's folder |
|
|
103
|
+
| `name` | `localsite` | The site's Naru name |
|
|
104
|
+
| `port` | `0` (a free port) | Where to serve |
|
|
105
|
+
| `state` | a new temp folder | Where data is kept; a temp folder is removed by `stop()` |
|
|
106
|
+
| `quiet` | `false` | Print nothing (`log` still has it) |
|
|
107
|
+
|
|
108
|
+
It returns:
|
|
109
|
+
|
|
110
|
+
- `origin`, such as `http://localhost:53412`, and `url(path)`;
|
|
111
|
+
- `signIn(target, who, { status, collections })`: `who` is `"owner"` or a
|
|
112
|
+
member's name (made if new, `status` kept). Given a Playwright `Page` or
|
|
113
|
+
`BrowserContext` (anything with `addInitScript`; Playwright is not a
|
|
114
|
+
dependency), its pages on this origin find the session where the SDK keeps
|
|
115
|
+
it from their next navigation, and at once for a page already there.
|
|
116
|
+
Resolves `{ accessToken, expiresAt, memberId, headers }` either way;
|
|
117
|
+
- `reset()`: empties the site's collections, tables and uploads and
|
|
118
|
+
publishes `_naru/` again; members and sign-ins stay;
|
|
119
|
+
- `stop()`; `log`, everything it printed; `name`; `state`.
|
|
120
|
+
|
|
121
|
+
## What's emulated, and what isn't
|
|
122
|
+
|
|
123
|
+
The site's data runs on Naru's own edge Worker (the code that serves
|
|
124
|
+
`sdk.naru.pub`) under workerd, with SQLite-backed Durable Objects: the
|
|
125
|
+
collections and their rules, the site's tables, queries, mutations, routes
|
|
126
|
+
and live queries, the QuickJS runtime and its limits, revision conditions
|
|
127
|
+
and batches, behave as on Naru. A process in front stands in for naru.pub's
|
|
128
|
+
part.
|
|
129
|
+
|
|
130
|
+
Not emulated: payments and supporter plans (every member may sign in),
|
|
131
|
+
the control plane's quotas and checks on media (size, counts, types),
|
|
132
|
+
custom domains, Naru's sign-in and consent pages, the media library, the
|
|
133
|
+
daily restore points, and the per-statement SQLite time budget of Naru's
|
|
134
|
+
own workerd build. The per-address read limit is lifted, since every
|
|
135
|
+
tab on your machine is one address. The site is always served at its own
|
|
136
|
+
origin, as on `<name>.naru.pub`.
|
|
137
|
+
|
|
138
|
+
## Versioning
|
|
139
|
+
|
|
140
|
+
The package's major and minor follow the Data SDK's newest version it
|
|
141
|
+
serves: 1.1.x serves SDK 1.0.0 and 1.1.0. Patch releases follow Naru's
|
|
142
|
+
server; `naru-dev --version` names the Naru commit a release was built from.
|
|
143
|
+
|
|
144
|
+
## Publishing
|
|
145
|
+
|
|
146
|
+
From the Naru repository (maintainers): set `version` in
|
|
147
|
+
`naru-dev/package.json`, commit, and push a tag `dev-v<version>`;
|
|
148
|
+
`.github/workflows/publish-naru-dev.yml` builds, checks and stages it with
|
|
149
|
+
the `NPM_TOKEN` secret, and it goes live once approved with 2FA (`npm stage
|
|
150
|
+
approve <stage-id>`, or the Staged Packages tab on npmjs.com).
|
|
151
|
+
`scripts/check-package.sh <dir>` does the same check locally.
|
|
152
|
+
|
|
153
|
+
## License
|
|
154
|
+
|
|
155
|
+
[AGPL-3.0-only](LICENSE), as Naru. The SDK files it serves are Naru's; your
|
|
156
|
+
site is your own.
|
|
157
|
+
|
|
158
|
+
## 한국어
|
|
159
|
+
|
|
160
|
+
`@naru-pub/dev`는 나루 사이트를 내 컴퓨터에서 실행하고 시험하는 도구입니다.
|
|
161
|
+
`npx @naru-pub/dev ./site --site demo`를 실행하면 http://localhost:4000 에서
|
|
162
|
+
사이트 파일과 데이터 SDK, `_naru/`의 마이그레이션·쿼리·뮤테이션·라우트·실시간
|
|
163
|
+
쿼리를 `sdk.naru.pub`과 같은 엣지 Worker로 제공합니다. 운영자와 회원
|
|
164
|
+
로그인은 한 번의 클릭으로 끝나고, `_naru/`를 고치면 바로 다시 게시합니다.
|
|
165
|
+
데이터는 사이트 폴더의 `.naru-dev/`에 남습니다.
|
|
166
|
+
|
|
167
|
+
테스트에서는 `@naru-pub/dev/testing`의 `startNaru()`로 빈 포트와 임시 폴더에
|
|
168
|
+
서버를 띄우고, `signIn(page, "owner")`나 `signIn(page, "회원이름")`으로 클릭
|
|
169
|
+
없이 로그인합니다. 결제, 미디어 용량 제한, 커스텀 도메인, 나루의 로그인·동의
|
|
170
|
+
화면은 흉내 내지 않습니다. 라이선스는 AGPL-3.0-only입니다.
|
package/dist/build.json
ADDED