@burakboduroglu/nors 0.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.
Files changed (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +154 -0
  3. package/bin/nors.js +86 -0
  4. package/package.json +48 -0
  5. package/pb_migrations/1789000000_nors_notes.js +47 -0
  6. package/pb_public/nors/assets/abnfDiagram-VCTEODGH-72Hc1HpF.js +1 -0
  7. package/pb_public/nors/assets/arc-BEvzHx4o.js +1 -0
  8. package/pb_public/nors/assets/architecture-7GRP2DOG-HrDOEF9a.js +1 -0
  9. package/pb_public/nors/assets/architectureDiagram-5GKGNRK7-Dyvym86p.js +36 -0
  10. package/pb_public/nors/assets/array-BifhSqXX.js +1 -0
  11. package/pb_public/nors/assets/blockDiagram-I7D4REHJ-CDUU8dVT.js +129 -0
  12. package/pb_public/nors/assets/c4Diagram-7LVT6UL2-DO3ezHBq.js +38 -0
  13. package/pb_public/nors/assets/channel-Df8EOoqr.js +1 -0
  14. package/pb_public/nors/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  15. package/pb_public/nors/assets/chunk-4HAMMTFA-1EqQyQU7.js +62 -0
  16. package/pb_public/nors/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  17. package/pb_public/nors/assets/chunk-75Z2AOVW-Cwc7WThs.js +2 -0
  18. package/pb_public/nors/assets/chunk-DU6HZSFF-B5Wb9e-Z.js +127 -0
  19. package/pb_public/nors/assets/chunk-F27PBJKO-Bab3aPrd.js +1 -0
  20. package/pb_public/nors/assets/chunk-FOHPRMQF-DzxwRta7.js +161 -0
  21. package/pb_public/nors/assets/chunk-GMAD6QVW-BvxprKvk.js +72 -0
  22. package/pb_public/nors/assets/chunk-GVQU2GXP-CsbitBlJ.js +1 -0
  23. package/pb_public/nors/assets/chunk-IMKFNOWR-CPLySese.js +231 -0
  24. package/pb_public/nors/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  25. package/pb_public/nors/assets/chunk-L3NEJ4N5-CFPB-We8.js +1 -0
  26. package/pb_public/nors/assets/chunk-OSK3NFVY-BAJO2owD.js +10 -0
  27. package/pb_public/nors/assets/chunk-P2QGCYS3-f8ck-xGx.js +1 -0
  28. package/pb_public/nors/assets/chunk-POPQ4Y6H-B_VDFlEk.js +1 -0
  29. package/pb_public/nors/assets/chunk-PWAF6VOD-B32HYusP.js +1 -0
  30. package/pb_public/nors/assets/chunk-SHT3W25Y-CfjlZPrR.js +168 -0
  31. package/pb_public/nors/assets/chunk-SVP7TREG-DT0H529z.js +88 -0
  32. package/pb_public/nors/assets/chunk-TICWLB2K-BD3m0b83.js +206 -0
  33. package/pb_public/nors/assets/chunk-XXDRQBXY-DFBUG-OT.js +1 -0
  34. package/pb_public/nors/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  35. package/pb_public/nors/assets/classDiagram-ZZMXUADV-B17tfBoX.js +1 -0
  36. package/pb_public/nors/assets/classDiagram-v2-VYDZK3BY-B17tfBoX.js +1 -0
  37. package/pb_public/nors/assets/cose-bilkent-JH36ORCC-BiZdMhTY.js +1 -0
  38. package/pb_public/nors/assets/cynefin-OW5HDTMX-Bts7NCEe.js +1 -0
  39. package/pb_public/nors/assets/cynefinDiagram-5FMLGOSQ-DQtWZ8b_.js +62 -0
  40. package/pb_public/nors/assets/cytoscape.esm-Yq6u8L66.js +321 -0
  41. package/pb_public/nors/assets/dagre-C-rnJpZF.js +1 -0
  42. package/pb_public/nors/assets/dagre-GXQ25YYZ-9KsnELcz.js +4 -0
  43. package/pb_public/nors/assets/defaultLocale-BFoDCU3G.js +1 -0
  44. package/pb_public/nors/assets/diagram-S7CK7UJ4-BH9UWoqn.js +30 -0
  45. package/pb_public/nors/assets/diagram-UQ7AKVKN-CxwLdAs_.js +41 -0
  46. package/pb_public/nors/assets/diagram-VSXAHHWV-CZ09vgYE.js +3 -0
  47. package/pb_public/nors/assets/diagram-VX7I27RA-BOR_eKl1.js +24 -0
  48. package/pb_public/nors/assets/diagram-Z3DM3KII-CNxcZIX5.js +24 -0
  49. package/pb_public/nors/assets/dist-DTg6UBE_.js +1 -0
  50. package/pb_public/nors/assets/ebnfDiagram-PWID7BFC-Bd6A_szT.js +1 -0
  51. package/pb_public/nors/assets/erDiagram-RLTQ6QDP-Cg1LC0U7.js +99 -0
  52. package/pb_public/nors/assets/eventmodeling-NTZA5JFV-04EdYz80.js +1 -0
  53. package/pb_public/nors/assets/flowDiagram-HODETNUW-D2i1JVc0.js +1 -0
  54. package/pb_public/nors/assets/ganttDiagram-EL5Y4UJY-DvZJpWfe.js +292 -0
  55. package/pb_public/nors/assets/gitGraph-4MIJSDKK-CsEbmQD4.js +1 -0
  56. package/pb_public/nors/assets/gitGraphDiagram-WWUBYQGX-CVlXu2Qq.js +106 -0
  57. package/pb_public/nors/assets/graphlib-DS17s2tU.js +1 -0
  58. package/pb_public/nors/assets/index-BZ_XOI9a.js +71 -0
  59. package/pb_public/nors/assets/index-DpLWWzac.css +1 -0
  60. package/pb_public/nors/assets/info-A6RAGUB7-Cr_1btt8.js +1 -0
  61. package/pb_public/nors/assets/infoDiagram-27XIBGKW-B5T1nV5L.js +2 -0
  62. package/pb_public/nors/assets/init-C-OQMol4.js +1 -0
  63. package/pb_public/nors/assets/ishikawaDiagram-5VMMS53U-CBxNSCVW.js +70 -0
  64. package/pb_public/nors/assets/journeyDiagram-3NMN7TZE-Cr3ECa1U.js +139 -0
  65. package/pb_public/nors/assets/kanban-definition-UXKFOSKX-DePsUrbx.js +89 -0
  66. package/pb_public/nors/assets/katex-ZlcWpGUi.js +257 -0
  67. package/pb_public/nors/assets/line-DcGZsAWh.js +1 -0
  68. package/pb_public/nors/assets/linear-B6A2FQ2q.js +1 -0
  69. package/pb_public/nors/assets/mermaid-parser.core-BR6xQvT6.js +7 -0
  70. package/pb_public/nors/assets/mermaid.core-FEPUjAo_.js +44 -0
  71. package/pb_public/nors/assets/mindmap-definition-YA3MSWOX-7sU4YIM1.js +96 -0
  72. package/pb_public/nors/assets/ordinal-BDEzSJ7C.js +1 -0
  73. package/pb_public/nors/assets/packet-AYTQ26CC-TYEYjIA7.js +1 -0
  74. package/pb_public/nors/assets/path-fybaL0A-.js +1 -0
  75. package/pb_public/nors/assets/pegDiagram-XKGWAZYB-BGzYtGBp.js +1 -0
  76. package/pb_public/nors/assets/pie-WAS4IAKB-BAuhAqOa.js +1 -0
  77. package/pb_public/nors/assets/pieDiagram-E7YTZNPT-Dc1PZDwl.js +39 -0
  78. package/pb_public/nors/assets/quadrantDiagram-AXDQQJYC-D-d3azLW.js +7 -0
  79. package/pb_public/nors/assets/radar-RG4KPBEZ-CWKhbiay.js +1 -0
  80. package/pb_public/nors/assets/railroad-74A4TZTK-Cm0h6b91.js +1 -0
  81. package/pb_public/nors/assets/railroad-abnf-HS5TGJTU-DAMHMau8.js +1 -0
  82. package/pb_public/nors/assets/railroad-ebnf-LZEXJU2U-CqJSrz-5.js +1 -0
  83. package/pb_public/nors/assets/railroad-peg-WCYAUIDC-CjgiTUIW.js +1 -0
  84. package/pb_public/nors/assets/railroadDiagram-O6MQD6OU-nzjXgwpW.js +1 -0
  85. package/pb_public/nors/assets/requirementDiagram-BXWQKSXE-v6B3lGir.js +84 -0
  86. package/pb_public/nors/assets/rough.esm-Dy-Kn_BL.js +1 -0
  87. package/pb_public/nors/assets/sankeyDiagram-P5KCCOFB-CuyMtFNE.js +40 -0
  88. package/pb_public/nors/assets/sequenceDiagram-WJ2MYXX4-C2LyM7bh.js +162 -0
  89. package/pb_public/nors/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
  90. package/pb_public/nors/assets/src-BH-TyZbA.js +1 -0
  91. package/pb_public/nors/assets/stateDiagram-D77RDMKH-D1A2WBer.js +1 -0
  92. package/pb_public/nors/assets/stateDiagram-v2-MP3YSRHH-4A_XCUQM.js +1 -0
  93. package/pb_public/nors/assets/swimlanes-42K2YHIH-sCNSWX_N.js +1 -0
  94. package/pb_public/nors/assets/swimlanesDiagram-VR7AAH4N-D7VxXsS9.js +8 -0
  95. package/pb_public/nors/assets/timeline-definition-24CTP7MA-DCxtDLFB.js +120 -0
  96. package/pb_public/nors/assets/treeView-Q6P3EWNA-Bnjs5jw6.js +1 -0
  97. package/pb_public/nors/assets/treemap-WGGIJYW6-C5ajpoq6.js +1 -0
  98. package/pb_public/nors/assets/vennDiagram-4TSXK5OY-B5S6LN3U.js +34 -0
  99. package/pb_public/nors/assets/wardley-WFR3VGLG-zH3dSKZv.js +1 -0
  100. package/pb_public/nors/assets/wardleyDiagram-VM6X3IG4-BffSe1Zn.js +78 -0
  101. package/pb_public/nors/assets/xychartDiagram-S5SC5T6Z-zb3OjZUW.js +7 -0
  102. package/pb_public/nors/index.html +15 -0
  103. package/pb_public/nors/nors-mark.svg +8 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Burak Boduroğlu
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
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,154 @@
1
+ <div align="center">
2
+
3
+ <img src="assets/nors-mark-512.png" alt="Nors mark" width="112">
4
+
5
+ # Nors
6
+
7
+ **Personal ops notes that ride a PocketBase instance you already run.**
8
+
9
+ [![License](https://img.shields.io/github/license/burakboduroglu/nors?style=flat-square)](LICENSE)
10
+ [![npm](https://img.shields.io/npm/v/@burakboduroglu/nors?style=flat-square&color=000)](https://www.npmjs.com/package/@burakboduroglu/nors)
11
+ ![Self-hosted](https://img.shields.io/badge/self--hosted-only-000?style=flat-square)
12
+ ![No telemetry](https://img.shields.io/badge/telemetry-none-000?style=flat-square)
13
+ ![No Docker](https://img.shields.io/badge/Docker-not_required-000?style=flat-square&logo=docker)
14
+ ![Bun](https://img.shields.io/badge/Bun-runtime-000?style=flat-square&logo=bun)
15
+
16
+ </div>
17
+
18
+ ---
19
+
20
+ Nors is not an application you deploy. It is one migration and one static
21
+ page, copied into a PocketBase directory you already have. The database,
22
+ auth, HTTP server and backups are already running — a dedicated notes app
23
+ would duplicate all of them.
24
+
25
+ <div align="center">
26
+
27
+ <img src="assets/screenshot-dash.png" alt="Nors dashboard — note cards with kind tabs" width="760">
28
+
29
+ </div>
30
+
31
+ ## What it is
32
+
33
+ Notes live as cards on a dashboard, filed under four kinds: Diagram, Runbook,
34
+ Reference, Scratch. An agent drafts in markdown, you publish from the panel —
35
+ paste a blob, fix the title, pick a kind, done. Bodies render as markdown and
36
+ Mermaid fences become diagrams in the reader.
37
+
38
+ Writing stays minimal on purpose: title, kind, pinned, body. The slug grows
39
+ out of the title and the summary out of the first clean body line, so there
40
+ is nothing else to fill in.
41
+
42
+ ## Highlights
43
+
44
+ | | Feature | How it works |
45
+ | --- | ------- | ------------ |
46
+ | 🧩 | **No infrastructure of its own** | Files copied into an existing PocketBase. No container, no second database, no extra port. |
47
+ | 📝 | **Write four things, nothing else** | Title, kind, pinned, body. Slug and summary derive themselves. |
48
+ | 📊 | **Diagrams without a plugin** | Mermaid loads only on pages that hold a fence; everything else never downloads it. |
49
+ | ↔️ | **Order by dragging** | Native HTML5 drag-and-drop renumbers `sort`; pinned cards stay first by construction. No DnD library. |
50
+ | 📥 | **Seeds are upserts** | `bun run import-seeds` matches by slug — re-running updates instead of duplicating. |
51
+ | 🛡️ | **Unsaved work asks first** | Leaving the editor with edits pops a guard instead of silently dropping the draft. |
52
+ | 📵 | **No telemetry** | Zero outbound requests. The page talks to your PocketBase and nothing else. |
53
+
54
+ <div align="center">
55
+
56
+ <img src="assets/screenshot-reader.png" alt="Nors reader — CLI shelf note with rendered Mermaid diagrams" width="760">
57
+
58
+ </div>
59
+
60
+ ## Footprint
61
+
62
+ Measured with `du`:
63
+
64
+ | | |
65
+ | --- | --- |
66
+ | Installed files | **3.5 MB** — migration 4 KB, page the rest |
67
+ | First visit | **~87 KB** — entry JS ~79 KB (gzip ~24 KB), CSS ~7.5 KB |
68
+ | The other 3.4 MB | Mermaid diagram chunks, fetched only when a reader page holds a fence |
69
+ | Database growth | one `nors_notes` row per note, inside the existing `pb_data` |
70
+ | Extra processes | none |
71
+ | Extra ports | none |
72
+
73
+ If PocketBase is already running, the marginal cost of Nors is the file sizes.
74
+
75
+ ## Install
76
+
77
+ Install into a PocketBase directory with the packaged CLI:
78
+
79
+ ```bash
80
+ bunx @burakboduroglu/nors install /path/to/pocketbase
81
+ ```
82
+
83
+ This copies the migration and built page; it never touches `pb_data`. Then
84
+ restart PocketBase so the migration runs. **If it was already running, stop it
85
+ before copying and start it afterwards** — PocketBase watches its directories
86
+ and can race a service manager doing the same.
87
+
88
+ For a source checkout and remote host, the `deploy/` installer performs the
89
+ stop → copy → start sequence:
90
+
91
+ ```bash
92
+ scp -r pb_migrations pb_public deploy/install.sh host:/tmp/nors-stage/
93
+ ssh host
94
+ sudo /tmp/nors-stage/install.sh /tmp/nors-stage
95
+ ```
96
+
97
+ The page is served at `/nors/`. Gate `/nors` and
98
+ `/api/collections/nors_notes` in Cloudflare Access the way `/subs/` is gated
99
+ (see `deploy/access-caddy.md`). Then load the three seed notes through the API:
100
+
101
+ ```bash
102
+ NORS_PB_URL=https://your.host NORS_PB_EMAIL=... NORS_PB_PASSWORD=... \
103
+ bun run import-seeds
104
+ ```
105
+
106
+ ## How it works
107
+
108
+ ```
109
+ browser ──▶ /nors/ static page, superuser login
110
+ browser ──▶ /api/collections/nors_notes/* superuser only, CRUD + reorder
111
+ agent ──▶ drafts markdown ──▶ editor ──▶ publish
112
+ ```
113
+
114
+ Routes are hashes: `#/` dashboard, `#/n/<slug>` reader,
115
+ `#/edit/<slug|$new>` editor. `/nors/?new=1` is the stable external entry point
116
+ for a new note; it consumes the query and opens the `$new` editor route.
117
+
118
+ ## Security
119
+
120
+ The `nors_notes` collection has null API rules, which in PocketBase means
121
+ superuser only. The dashboard holds a superuser token in localStorage — anyone
122
+ with the browser profile has the keys, documented rather than hidden. There is
123
+ no audit log and no second user; this is a single-operator surface behind
124
+ Cloudflare Access, not a multi-user app.
125
+
126
+ ## What it deliberately does not do
127
+
128
+ No in-app LLM calls. No public notes or team sharing. No wiki search, tag
129
+ graph, or version history UI. No reminders. It does not replace a vault or a
130
+ knowledge base — it is the live dashboard above them.
131
+
132
+ ## Stack
133
+
134
+ PocketBase for storage, auth and HTTP. SolidJS + Vite UI compiled to static
135
+ files under `pb_public/nors/`. `marked` for markdown, Mermaid on demand, no
136
+ CSS library, no UI server. Bun as the package manager.
137
+
138
+ ## Develop the UI
139
+
140
+ Source lives in `web/`. The shipped page is built output:
141
+
142
+ ```bash
143
+ bun --cwd web install
144
+ bun run build # root script — emits pb_public/nors/
145
+ bun run dev # local UI; /api proxied to :8090 (NORS_PB_PORT to move it)
146
+ ```
147
+
148
+ Against a tunneled production box: `ssh -N -L 8090:127.0.0.1:8090 host`,
149
+ then `bun run dev` — the browser stays on localhost, so neither CORS nor
150
+ Cloudflare Access is in the path.
151
+
152
+ ## License
153
+
154
+ MIT — see [LICENSE](LICENSE).
package/bin/nors.js ADDED
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env node
2
+ // Nors's installer. It copies files into a PocketBase directory and prints the
3
+ // steps that cannot be copied for you. It never touches pb_data, never starts
4
+ // or stops anything, and never talks to the network.
5
+
6
+ import { readFile, mkdir, cp, access } from "node:fs/promises"
7
+ import { constants } from "node:fs"
8
+ import { join, dirname, resolve } from "node:path"
9
+ import { fileURLToPath } from "node:url"
10
+
11
+ const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..")
12
+ const pkg = JSON.parse(await readFile(join(ROOT, "package.json"), "utf8"))
13
+
14
+ const exists = async (p) => access(p, constants.F_OK).then(() => true, () => false)
15
+
16
+ const HELP = `
17
+ nors ${pkg.version} — personal ops notes on PocketBase
18
+
19
+ nors install <pocketbase-dir> copy the migration and the page into place
20
+ Options
21
+ --force install even if the target does not look like a PocketBase directory
22
+ -h, --help this
23
+ -v, --version
24
+
25
+ The install step only writes pb_migrations/ and pb_public/nors/.
26
+ Your data lives in pb_data/ and is never read or written.
27
+ `
28
+
29
+ // A PocketBase directory is recognised by the binary or by pb_data beside it.
30
+ // Getting this wrong would scatter files into an unrelated folder, so the check
31
+ // is a refusal rather than a warning.
32
+ async function assertPocketBase(dir, force) {
33
+ if (force) return
34
+ const looksRight =
35
+ (await exists(join(dir, "pocketbase"))) ||
36
+ (await exists(join(dir, "pocketbase.exe"))) ||
37
+ (await exists(join(dir, "pb_data")))
38
+ if (!looksRight) {
39
+ console.error(
40
+ `Refusing to install: ${dir} holds no pocketbase binary and no pb_data.\n` +
41
+ `Point at the directory the PocketBase executable lives in, or pass --force.`
42
+ )
43
+ process.exit(1)
44
+ }
45
+ }
46
+
47
+ async function install(dir, force) {
48
+ if (!dir) { console.error("Usage: nors install <pocketbase-dir>"); process.exit(1) }
49
+ const target = resolve(dir)
50
+ if (!(await exists(target))) { console.error(`No such directory: ${target}`); process.exit(1) }
51
+ await assertPocketBase(target, force)
52
+
53
+ const parts = [
54
+ ["pb_migrations", "pb_migrations"],
55
+ [join("pb_public", "nors"), join("pb_public", "nors")]
56
+ ]
57
+ for (const [from, to] of parts) {
58
+ const dest = join(target, to)
59
+ await mkdir(dirname(dest), { recursive: true })
60
+ await cp(join(ROOT, from), dest, { recursive: true })
61
+ console.log(` wrote ${to}/`)
62
+ }
63
+
64
+ console.log(`
65
+ Installed into ${target}
66
+
67
+ Next, and none of it is automatic:
68
+ 1. Restart PocketBase so the migration runs. If it was already running, stop
69
+ it before copying and start it after.
70
+ 2. Serve the page. It is at /nors/ once PocketBase is serving pb_public.
71
+ 3. Put an auth layer in front of /nors and
72
+ /api/collections/nors_notes. The collection is superuser-only on its own;
73
+ the page is a login form anyone could reach.
74
+ 4. A source checkout includes optional seed notes and the import-seeds script.
75
+ `)
76
+ }
77
+
78
+ const [cmd, ...rest] = process.argv.slice(2)
79
+ const force = rest.includes("--force")
80
+
81
+ if (cmd === "-v" || cmd === "--version") { console.log(pkg.version); process.exit(0) }
82
+ if (!cmd || cmd === "-h" || cmd === "--help") { console.log(HELP); process.exit(0) }
83
+ if (cmd === "install") { await install(rest.find((a) => !a.startsWith("--")), force); process.exit(0) }
84
+
85
+ console.error(`Unknown command: ${cmd}\n${HELP}`)
86
+ process.exit(1)
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@burakboduroglu/nors",
3
+ "version": "0.1.0",
4
+ "description": "Personal ops notes dashboard on PocketBase — Norse-named, Solid UI at /nors/",
5
+ "license": "MIT",
6
+ "author": "Burak Boduroğlu",
7
+ "type": "module",
8
+ "scripts": {
9
+ "dev": "bun --cwd web dev",
10
+ "build": "bun --cwd web build",
11
+ "prepack": "bun --cwd web build",
12
+ "preview": "bun --cwd web preview",
13
+ "import-seeds": "bun scripts/import-seeds.ts"
14
+ },
15
+ "bin": {
16
+ "nors": "bin/nors.js"
17
+ },
18
+ "files": [
19
+ "bin",
20
+ "pb_migrations",
21
+ "pb_public",
22
+ "LICENSE",
23
+ "README.md"
24
+ ],
25
+ "keywords": [
26
+ "notes",
27
+ "ops-notes",
28
+ "pocketbase",
29
+ "self-hosted",
30
+ "dashboard",
31
+ "mermaid",
32
+ "no-telemetry"
33
+ ],
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/burakboduroglu/nors.git"
37
+ },
38
+ "homepage": "https://github.com/burakboduroglu/nors#readme",
39
+ "bugs": {
40
+ "url": "https://github.com/burakboduroglu/nors/issues"
41
+ },
42
+ "engines": {
43
+ "node": ">=18"
44
+ },
45
+ "publishConfig": {
46
+ "access": "public"
47
+ }
48
+ }
@@ -0,0 +1,47 @@
1
+ /// <reference path="../pb_data/types.d.ts" />
2
+
3
+ // Nors: personal ops notes. Superuser-only (null API rules).
4
+ // Served as a Solid app from pb_public/nors/ behind Caddy + Access.
5
+ migrate((app) => {
6
+ const notes = new Collection({
7
+ name: "nors_notes",
8
+ type: "base",
9
+ fields: [
10
+ { name: "title", type: "text", required: true, max: 160 },
11
+ { name: "slug", type: "text", required: true, max: 80 },
12
+ { name: "summary", type: "text", max: 400 },
13
+ { name: "body", type: "editor", required: false },
14
+ {
15
+ name: "kind",
16
+ type: "select",
17
+ required: true,
18
+ maxSelect: 1,
19
+ values: ["diagram", "runbook", "reference", "scratch"],
20
+ },
21
+ { name: "tags", type: "json", maxSize: 8000 },
22
+ { name: "pinned", type: "bool" },
23
+ {
24
+ name: "status",
25
+ type: "select",
26
+ required: true,
27
+ maxSelect: 1,
28
+ values: ["draft", "published", "archived"],
29
+ },
30
+ { name: "sort", type: "number" },
31
+ { name: "created", type: "autodate", onCreate: true, onUpdate: false },
32
+ { name: "updated", type: "autodate", onCreate: true, onUpdate: true },
33
+ ],
34
+ indexes: [
35
+ "CREATE UNIQUE INDEX idx_nors_notes_slug ON nors_notes (slug)",
36
+ "CREATE INDEX idx_nors_notes_status ON nors_notes (status)",
37
+ "CREATE INDEX idx_nors_notes_sort ON nors_notes (sort)",
38
+ ],
39
+ })
40
+ app.save(notes)
41
+ }, (app) => {
42
+ try {
43
+ app.delete(app.findCollectionByNameOrId("nors_notes"))
44
+ } catch (_) {
45
+ // already gone
46
+ }
47
+ })
@@ -0,0 +1 @@
1
+ import{m as e}from"./src-BH-TyZbA.js";import{m as t,t as n}from"./mermaid-parser.core-BR6xQvT6.js";import{n as r}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import"./chunk-DU6HZSFF-B5Wb9e-Z.js";import{n as i,r as a,t as o}from"./chunk-SVP7TREG-DT0H529z.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";import"./mermaid.core-FEPUjAo_.js";var c=t().RailroadAbnf.parser.LangiumParser,l=r(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=r(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=r(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=r(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=r(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=r(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=r(e=>{s(e,o),e.title&&o.setTitle(e.title),e.rules.map(e=>o.addRule(m(e)))},`populateDb`),g={parser:{parse:r(t=>{o.clear(),e.debug(`[ABNF Parser] Starting Langium parse`);let r=c.parse(t);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new n(r);let i=r.value;e.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),e.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:o}},db:o,renderer:a,styles:i};export{g as diagram};
@@ -0,0 +1 @@
1
+ import{n as e,t}from"./path-fybaL0A-.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-DTg6UBE_.js";function m(e){return e.innerRadius}function h(e){return e.outerRadius}function g(e){return e.startAngle}function _(e){return e.endAngle}function v(e){return e&&e.padAngle}function y(e,t,n,r,i,a,o,s){var c=n-e,l=r-t,u=o-i,d=s-a,f=d*c-u*l;if(!(f*f<1e-12))return f=(u*(t-a)-d*(e-i))/f,[e+f*c,t+f*l]}function b(e,t,n,r,i,a,o){var c=e-n,l=t-r,u=(o?a:-a)/d(c*c+l*l),f=u*l,p=-u*c,m=e+f,h=t+p,g=n+f,_=r+p,v=(m+g)/2,y=(h+_)/2,b=g-m,x=_-h,S=b*b+x*x,C=i-a,w=m*_-g*h,T=(x<0?-1:1)*d(s(0,C*C*S-w*w)),E=(w*x-b*T)/S,D=(-w*b-x*T)/S,O=(w*x+b*T)/S,k=(-w*b+x*T)/S,A=E-v,j=D-y,M=O-v,N=k-y;return A*A+j*j>M*M+N*N&&(E=O,D=k),{cx:E,cy:D,x01:-f,y01:-p,x11:E*(i/C-1),y11:D*(i/C-1)}}function x(){var s=m,x=h,S=e(0),C=null,w=g,T=_,E=v,D=null,O=t(k);function k(){var e,t,m=+s.apply(this,arguments),h=+x.apply(this,arguments),g=w.apply(this,arguments)-r,_=T.apply(this,arguments)-r,v=l(_-g),k=_>g;if(D||=e=O(),h<m&&(t=h,h=m,m=t),!(h>1e-12))D.moveTo(0,0);else if(v>c-1e-12)D.moveTo(h*u(g),h*a(g)),D.arc(0,0,h,g,_,!k),m>1e-12&&(D.moveTo(m*u(_),m*a(_)),D.arc(0,0,m,_,g,k));else{var A=g,j=_,M=g,N=_,P=v,F=v,I=E.apply(this,arguments)/2,L=I>1e-12&&(C?+C.apply(this,arguments):d(m*m+h*h)),R=p(l(h-m)/2,+S.apply(this,arguments)),z=R,B=R,V,H;if(L>1e-12){var U=o(L/m*a(I)),W=o(L/h*a(I));(P-=U*2)>1e-12?(U*=k?1:-1,M+=U,N-=U):(P=0,M=N=(g+_)/2),(F-=W*2)>1e-12?(W*=k?1:-1,A+=W,j-=W):(F=0,A=j=(g+_)/2)}var G=h*u(A),K=h*a(A),q=m*u(N),J=m*a(N);if(R>1e-12){var Y=h*u(j),X=h*a(j),Z=m*u(M),Q=m*a(M),$;if(v<i){if($=y(G,K,Z,Q,Y,X,q,J)){var ee=G-$[0],te=K-$[1],ne=Y-$[0],re=X-$[1],ie=1/a(f((ee*ne+te*re)/(d(ee*ee+te*te)*d(ne*ne+re*re)))/2),ae=d($[0]*$[0]+$[1]*$[1]);z=p(R,(m-ae)/(ie-1)),B=p(R,(h-ae)/(ie+1))}else z=B=0}}F>1e-12?B>1e-12?(V=b(Z,Q,G,K,h,B,k),H=b(Y,X,q,J,h,B,k),D.moveTo(V.cx+V.x01,V.cy+V.y01),B<R?D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,h,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),!k),D.arc(H.cx,H.cy,B,n(H.y11,H.x11),n(H.y01,H.x01),!k))):(D.moveTo(G,K),D.arc(0,0,h,A,j,!k)):D.moveTo(G,K),!(m>1e-12)||!(P>1e-12)?D.lineTo(q,J):z>1e-12?(V=b(q,J,Y,X,m,-z,k),H=b(G,K,Z,Q,m,-z,k),D.lineTo(V.cx+V.x01,V.cy+V.y01),z<R?D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,m,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),k),D.arc(H.cx,H.cy,z,n(H.y11,H.x11),n(H.y01,H.x01),!k))):D.arc(0,0,m,N,M,k)}if(D.closePath(),e)return D=null,e+``||null}return k.centroid=function(){var e=(+s.apply(this,arguments)+ +x.apply(this,arguments))/2,t=(+w.apply(this,arguments)+ +T.apply(this,arguments))/2-i/2;return[u(t)*e,a(t)*e]},k.innerRadius=function(t){return arguments.length?(s=typeof t==`function`?t:e(+t),k):s},k.outerRadius=function(t){return arguments.length?(x=typeof t==`function`?t:e(+t),k):x},k.cornerRadius=function(t){return arguments.length?(S=typeof t==`function`?t:e(+t),k):S},k.padRadius=function(t){return arguments.length?(C=t==null?null:typeof t==`function`?t:e(+t),k):C},k.startAngle=function(t){return arguments.length?(w=typeof t==`function`?t:e(+t),k):w},k.endAngle=function(t){return arguments.length?(T=typeof t==`function`?t:e(+t),k):T},k.padAngle=function(t){return arguments.length?(E=typeof t==`function`?t:e(+t),k):E},k.context=function(e){return arguments.length?(D=e??null,k):D},k}export{x as t};
@@ -0,0 +1 @@
1
+ import"./chunk-FOHPRMQF-DzxwRta7.js";import{M as e}from"./mermaid-parser.core-BR6xQvT6.js";export{e as createArchitectureServices};