jxp 3.0.0 → 4.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 (229) hide show
  1. package/.env.sample +43 -6
  2. package/README.md +27 -13
  3. package/dist/bin/init_db.d.ts +3 -0
  4. package/dist/bin/init_db.d.ts.map +1 -0
  5. package/dist/bin/init_db.js +48 -0
  6. package/dist/bin/init_db.js.map +1 -0
  7. package/dist/bin/server.d.ts +4 -0
  8. package/dist/bin/server.d.ts.map +1 -0
  9. package/dist/bin/server.js +132 -0
  10. package/dist/bin/server.js.map +1 -0
  11. package/dist/bin/setup.d.ts +3 -0
  12. package/dist/bin/setup.d.ts.map +1 -0
  13. package/dist/bin/setup.js +185 -0
  14. package/dist/bin/setup.js.map +1 -0
  15. package/dist/globals.d.ts +14 -0
  16. package/dist/globals.d.ts.map +1 -0
  17. package/dist/globals.js +3 -0
  18. package/dist/globals.js.map +1 -0
  19. package/dist/libs/aggregate_guard.d.ts +5 -0
  20. package/dist/libs/aggregate_guard.d.ts.map +1 -0
  21. package/dist/libs/aggregate_guard.js +58 -0
  22. package/dist/libs/aggregate_guard.js.map +1 -0
  23. package/dist/libs/bulkwrite_guard.d.ts +5 -0
  24. package/dist/libs/bulkwrite_guard.d.ts.map +1 -0
  25. package/dist/libs/bulkwrite_guard.js +44 -0
  26. package/dist/libs/bulkwrite_guard.js.map +1 -0
  27. package/dist/libs/cache.d.ts +2 -0
  28. package/dist/libs/cache.d.ts.map +1 -0
  29. package/dist/libs/cache.js +94 -0
  30. package/dist/libs/cache.js.map +1 -0
  31. package/dist/libs/call_guard.d.ts +3 -0
  32. package/dist/libs/call_guard.d.ts.map +1 -0
  33. package/dist/libs/call_guard.js +17 -0
  34. package/dist/libs/call_guard.js.map +1 -0
  35. package/dist/libs/connection_string.d.ts +3 -0
  36. package/dist/libs/connection_string.d.ts.map +1 -0
  37. package/dist/libs/connection_string.js +4 -0
  38. package/dist/libs/connection_string.js.map +1 -0
  39. package/dist/libs/datamunging.d.ts +2 -0
  40. package/dist/libs/datamunging.d.ts.map +1 -0
  41. package/dist/libs/datamunging.js +320 -0
  42. package/dist/libs/datamunging.js.map +1 -0
  43. package/dist/libs/docs-auth.d.ts +25 -0
  44. package/dist/libs/docs-auth.d.ts.map +1 -0
  45. package/dist/libs/docs-auth.js +205 -0
  46. package/dist/libs/docs-auth.js.map +1 -0
  47. package/dist/libs/docs.d.ts +2 -0
  48. package/dist/libs/docs.d.ts.map +1 -0
  49. package/dist/libs/docs.js +328 -0
  50. package/dist/libs/docs.js.map +1 -0
  51. package/dist/libs/groups.d.ts +2 -0
  52. package/dist/libs/groups.d.ts.map +1 -0
  53. package/dist/libs/groups.js +136 -0
  54. package/dist/libs/groups.js.map +1 -0
  55. package/dist/libs/jxp.d.ts +4 -0
  56. package/dist/libs/jxp.d.ts.map +1 -0
  57. package/dist/libs/jxp.js +1176 -0
  58. package/dist/libs/jxp.js.map +1 -0
  59. package/dist/libs/link_index.d.ts +14 -0
  60. package/dist/libs/link_index.d.ts.map +1 -0
  61. package/dist/libs/link_index.js +37 -0
  62. package/dist/libs/link_index.js.map +1 -0
  63. package/dist/libs/load-config.d.ts +16 -0
  64. package/dist/libs/load-config.d.ts.map +1 -0
  65. package/dist/libs/load-config.js +166 -0
  66. package/dist/libs/load-config.js.map +1 -0
  67. package/dist/libs/login.d.ts +2 -0
  68. package/dist/libs/login.d.ts.map +1 -0
  69. package/dist/libs/login.js +244 -0
  70. package/dist/libs/login.js.map +1 -0
  71. package/dist/libs/login_rate_limit.d.ts +16 -0
  72. package/dist/libs/login_rate_limit.d.ts.map +1 -0
  73. package/dist/libs/login_rate_limit.js +49 -0
  74. package/dist/libs/login_rate_limit.js.map +1 -0
  75. package/dist/libs/modeldir.d.ts +5 -0
  76. package/dist/libs/modeldir.d.ts.map +1 -0
  77. package/dist/libs/modeldir.js +15 -0
  78. package/dist/libs/modeldir.js.map +1 -0
  79. package/dist/libs/query_limits.d.ts +2 -0
  80. package/dist/libs/query_limits.d.ts.map +1 -0
  81. package/dist/libs/query_limits.js +84 -0
  82. package/dist/libs/query_limits.js.map +1 -0
  83. package/dist/libs/query_manipulation.d.ts +3 -0
  84. package/dist/libs/query_manipulation.d.ts.map +1 -0
  85. package/{libs → dist/libs}/query_manipulation.js +22 -21
  86. package/dist/libs/query_manipulation.js.map +1 -0
  87. package/dist/libs/query_sanitize.d.ts +5 -0
  88. package/dist/libs/query_sanitize.d.ts.map +1 -0
  89. package/dist/libs/query_sanitize.js +109 -0
  90. package/dist/libs/query_sanitize.js.map +1 -0
  91. package/dist/libs/response_sanitize.d.ts +7 -0
  92. package/dist/libs/response_sanitize.d.ts.map +1 -0
  93. package/dist/libs/response_sanitize.js +57 -0
  94. package/dist/libs/response_sanitize.js.map +1 -0
  95. package/dist/libs/safe_error.d.ts +3 -0
  96. package/dist/libs/safe_error.d.ts.map +1 -0
  97. package/dist/libs/safe_error.js +14 -0
  98. package/dist/libs/safe_error.js.map +1 -0
  99. package/dist/libs/schema.d.ts +14 -0
  100. package/dist/libs/schema.d.ts.map +1 -0
  101. package/dist/libs/schema.js +98 -0
  102. package/dist/libs/schema.js.map +1 -0
  103. package/dist/libs/schema_description.d.ts +3 -0
  104. package/dist/libs/schema_description.d.ts.map +1 -0
  105. package/{libs → dist/libs}/schema_description.js +12 -21
  106. package/dist/libs/schema_description.js.map +1 -0
  107. package/dist/libs/security.d.ts +2 -0
  108. package/dist/libs/security.d.ts.map +1 -0
  109. package/dist/libs/security.js +428 -0
  110. package/dist/libs/security.js.map +1 -0
  111. package/dist/libs/setup.d.ts +2 -0
  112. package/dist/libs/setup.d.ts.map +1 -0
  113. package/dist/libs/setup.js +87 -0
  114. package/dist/libs/setup.js.map +1 -0
  115. package/dist/libs/startup-deprecations.d.ts +2 -0
  116. package/dist/libs/startup-deprecations.d.ts.map +1 -0
  117. package/dist/libs/startup-deprecations.js +21 -0
  118. package/dist/libs/startup-deprecations.js.map +1 -0
  119. package/dist/libs/startup.d.ts +16 -0
  120. package/dist/libs/startup.d.ts.map +1 -0
  121. package/dist/libs/startup.js +63 -0
  122. package/dist/libs/startup.js.map +1 -0
  123. package/dist/libs/ws.d.ts +2 -0
  124. package/dist/libs/ws.d.ts.map +1 -0
  125. package/{libs → dist/libs}/ws.js +91 -73
  126. package/dist/libs/ws.js.map +1 -0
  127. package/dist/models/apikey_model.d.ts +10 -0
  128. package/dist/models/apikey_model.d.ts.map +1 -0
  129. package/dist/models/apikey_model.js +14 -0
  130. package/dist/models/apikey_model.js.map +1 -0
  131. package/dist/models/link_model.d.ts +9 -0
  132. package/dist/models/link_model.d.ts.map +1 -0
  133. package/dist/models/link_model.js +20 -0
  134. package/dist/models/link_model.js.map +1 -0
  135. package/dist/models/refreshtoken_model.d.ts +11 -0
  136. package/dist/models/refreshtoken_model.d.ts.map +1 -0
  137. package/dist/models/refreshtoken_model.js +22 -0
  138. package/dist/models/refreshtoken_model.js.map +1 -0
  139. package/dist/models/test_model.d.ts +24 -0
  140. package/dist/models/test_model.d.ts.map +1 -0
  141. package/dist/models/test_model.js +44 -0
  142. package/dist/models/test_model.js.map +1 -0
  143. package/dist/models/token_model.d.ts +14 -0
  144. package/dist/models/token_model.d.ts.map +1 -0
  145. package/dist/models/token_model.js +25 -0
  146. package/dist/models/token_model.js.map +1 -0
  147. package/dist/models/user_model.d.ts +15 -0
  148. package/dist/models/user_model.d.ts.map +1 -0
  149. package/dist/models/user_model.js +38 -0
  150. package/dist/models/user_model.js.map +1 -0
  151. package/dist/models/usergroups_model.d.ts +9 -0
  152. package/dist/models/usergroups_model.d.ts.map +1 -0
  153. package/dist/models/usergroups_model.js +18 -0
  154. package/dist/models/usergroups_model.js.map +1 -0
  155. package/dist/types/jxp-config.d.ts +151 -0
  156. package/dist/types/jxp-config.d.ts.map +1 -0
  157. package/dist/types/jxp-config.js +3 -0
  158. package/dist/types/jxp-config.js.map +1 -0
  159. package/dist/types/schema-fields.d.ts +43 -0
  160. package/dist/types/schema-fields.d.ts.map +1 -0
  161. package/dist/types/schema-fields.js +3 -0
  162. package/dist/types/schema-fields.js.map +1 -0
  163. package/docs/aggregations.md +40 -21
  164. package/docs/api.md +55 -15
  165. package/docs/authentication.md +60 -37
  166. package/docs/bulk_writes.md +11 -8
  167. package/docs/caching.md +28 -11
  168. package/docs/changelog.md +258 -31
  169. package/docs/configuration.md +126 -115
  170. package/docs/hooks.md +12 -8
  171. package/docs/index.md +17 -17
  172. package/docs/installation.md +23 -18
  173. package/docs/permissions.md +33 -19
  174. package/docs/queries.md +9 -5
  175. package/docs/schemas.md +21 -10
  176. package/docs/special.md +4 -4
  177. package/docs/typescript.md +86 -0
  178. package/docs/websocket.md +99 -1
  179. package/mkdocs.yml +1 -0
  180. package/package.json +121 -69
  181. package/templates/api.pug +32 -0
  182. package/templates/app-server.js +43 -0
  183. package/templates/app.env.sample +8 -0
  184. package/templates/assets/api-console.js +151 -0
  185. package/templates/assets/docs-login.js +66 -0
  186. package/templates/assets/docs.css +244 -0
  187. package/templates/index.pug +67 -2
  188. package/templates/layout.pug +21 -11
  189. package/templates/login.pug +39 -0
  190. package/templates/md.pug +1 -1
  191. package/templates/model.pug +117 -68
  192. package/templates/navbar.pug +25 -21
  193. package/templates/sidebar.pug +30 -0
  194. package/.env +0 -9
  195. package/.eslintrc.json +0 -20
  196. package/.jshintrc +0 -4
  197. package/.vscode/launch.json +0 -34
  198. package/.vscode/settings.json +0 -3
  199. package/Dockerfile +0 -7
  200. package/bin/init_db.js +0 -54
  201. package/bin/server.js +0 -131
  202. package/bin/setup.js +0 -190
  203. package/config_sample.json +0 -10
  204. package/docker-compose.yml +0 -32
  205. package/libs/cache.js +0 -92
  206. package/libs/connection_string.js +0 -24
  207. package/libs/datamunging.js +0 -335
  208. package/libs/docs.js +0 -162
  209. package/libs/groups.js +0 -133
  210. package/libs/jxp.js +0 -1208
  211. package/libs/login.js +0 -222
  212. package/libs/modeldir.js +0 -14
  213. package/libs/schema.js +0 -99
  214. package/libs/security.js +0 -410
  215. package/libs/setup.js +0 -90
  216. package/models/apikey_model.js +0 -10
  217. package/models/link_model.js +0 -17
  218. package/models/refreshtoken_model.js +0 -20
  219. package/models/test_model.js +0 -50
  220. package/models/token_model.js +0 -23
  221. package/models/user_model.js +0 -38
  222. package/models/usergroups_model.js +0 -15
  223. package/setup.sh +0 -3
  224. package/test/.eslintrc.json +0 -13
  225. package/test/auth.js +0 -190
  226. package/test/init.js +0 -92
  227. package/test/setup.test.js +0 -62
  228. package/test/test.js +0 -1527
  229. package/test/wstest.js.old +0 -124
@@ -0,0 +1,244 @@
1
+ :root {
2
+ --docs-sidebar-width: 280px;
3
+ --docs-topbar-height: 56px;
4
+ --docs-accent: #0d6efd;
5
+ --docs-sidebar-bg: #f8f9fa;
6
+ --docs-border: #dee2e6;
7
+ }
8
+
9
+ body.docs-body {
10
+ min-height: 100vh;
11
+ background: #fff;
12
+ }
13
+
14
+ .docs-topbar {
15
+ height: var(--docs-topbar-height);
16
+ border-bottom: 1px solid var(--docs-border);
17
+ background: #fff;
18
+ z-index: 1030;
19
+ }
20
+
21
+ .docs-brand {
22
+ font-weight: 600;
23
+ font-size: 1.1rem;
24
+ color: #212529;
25
+ text-decoration: none;
26
+ }
27
+
28
+ .docs-brand:hover {
29
+ color: var(--docs-accent);
30
+ }
31
+
32
+ .docs-shell {
33
+ display: flex;
34
+ min-height: calc(100vh - var(--docs-topbar-height));
35
+ }
36
+
37
+ .docs-sidebar {
38
+ width: var(--docs-sidebar-width);
39
+ flex-shrink: 0;
40
+ border-right: 1px solid var(--docs-border);
41
+ background: var(--docs-sidebar-bg);
42
+ overflow-y: auto;
43
+ padding: 1rem 0;
44
+ position: sticky;
45
+ top: var(--docs-topbar-height);
46
+ height: calc(100vh - var(--docs-topbar-height));
47
+ }
48
+
49
+ .docs-main {
50
+ flex: 1;
51
+ min-width: 0;
52
+ padding: 1.5rem 2rem 3rem;
53
+ max-width: 960px;
54
+ }
55
+
56
+ .docs-sidebar-section {
57
+ padding: 0 1rem;
58
+ margin-bottom: 1.25rem;
59
+ }
60
+
61
+ .docs-sidebar-title {
62
+ font-size: 0.7rem;
63
+ font-weight: 700;
64
+ text-transform: uppercase;
65
+ letter-spacing: 0.06em;
66
+ color: #6c757d;
67
+ margin-bottom: 0.5rem;
68
+ }
69
+
70
+ .docs-nav-link {
71
+ display: block;
72
+ padding: 0.35rem 0.75rem;
73
+ font-size: 0.875rem;
74
+ color: #495057;
75
+ text-decoration: none;
76
+ border-radius: 0.375rem;
77
+ border-left: 3px solid transparent;
78
+ }
79
+
80
+ .docs-nav-link:hover {
81
+ background: rgba(13, 110, 253, 0.08);
82
+ color: var(--docs-accent);
83
+ }
84
+
85
+ .docs-nav-link.active {
86
+ background: rgba(13, 110, 253, 0.12);
87
+ color: var(--docs-accent);
88
+ border-left-color: var(--docs-accent);
89
+ font-weight: 500;
90
+ }
91
+
92
+ .docs-api-key-wrap {
93
+ max-width: 220px;
94
+ }
95
+
96
+ .docs-api-key-wrap .form-control {
97
+ font-size: 0.8rem;
98
+ font-family: ui-monospace, monospace;
99
+ }
100
+
101
+ @media (max-width: 991.98px) {
102
+ .docs-sidebar {
103
+ display: none;
104
+ }
105
+
106
+ .docs-main {
107
+ padding: 1rem;
108
+ }
109
+ }
110
+
111
+ .docs-hero {
112
+ padding: 2.5rem 0 2rem;
113
+ border-bottom: 1px solid var(--docs-border);
114
+ margin-bottom: 2rem;
115
+ }
116
+
117
+ .docs-hero h1 {
118
+ font-size: 2.25rem;
119
+ font-weight: 700;
120
+ margin-bottom: 0.5rem;
121
+ }
122
+
123
+ .docs-hero .lead {
124
+ color: #6c757d;
125
+ max-width: 36rem;
126
+ }
127
+
128
+ .docs-content h1,
129
+ .docs-content h2,
130
+ .docs-content h3 {
131
+ margin-top: 1.5rem;
132
+ margin-bottom: 0.75rem;
133
+ }
134
+
135
+ .docs-content pre {
136
+ background: #f8f9fa;
137
+ border: 1px solid var(--docs-border);
138
+ border-radius: 0.375rem;
139
+ padding: 1rem;
140
+ overflow-x: auto;
141
+ font-size: 0.85rem;
142
+ }
143
+
144
+ .docs-content code {
145
+ font-size: 0.875em;
146
+ color: #d63384;
147
+ }
148
+
149
+ .docs-content pre code {
150
+ color: inherit;
151
+ }
152
+
153
+ .docs-content table {
154
+ margin: 1rem 0;
155
+ }
156
+
157
+ .method-badge {
158
+ font-family: ui-monospace, monospace;
159
+ font-size: 0.75rem;
160
+ font-weight: 700;
161
+ min-width: 4.5rem;
162
+ text-align: center;
163
+ }
164
+
165
+ .method-get { background-color: #198754 !important; }
166
+ .method-post { background-color: #0d6efd !important; }
167
+ .method-put { background-color: #fd7e14 !important; }
168
+ .method-delete { background-color: #dc3545 !important; }
169
+
170
+ .endpoint-path {
171
+ font-family: ui-monospace, monospace;
172
+ font-size: 0.9rem;
173
+ }
174
+
175
+ .api-try-panel {
176
+ border: 1px solid var(--docs-border);
177
+ border-radius: 0.375rem;
178
+ padding: 1rem;
179
+ background: #fafbfc;
180
+ margin-top: 0.75rem;
181
+ }
182
+
183
+ .api-response {
184
+ font-family: ui-monospace, monospace;
185
+ font-size: 0.8rem;
186
+ background: #212529;
187
+ color: #e9ecef;
188
+ border-radius: 0.375rem;
189
+ padding: 1rem;
190
+ max-height: 320px;
191
+ overflow: auto;
192
+ white-space: pre-wrap;
193
+ word-break: break-word;
194
+ margin-top: 0.75rem;
195
+ }
196
+
197
+ .api-response.empty {
198
+ background: #f8f9fa;
199
+ color: #6c757d;
200
+ border: 1px dashed var(--docs-border);
201
+ }
202
+
203
+ .api-response-meta {
204
+ font-size: 0.8rem;
205
+ color: #6c757d;
206
+ margin-top: 0.5rem;
207
+ }
208
+
209
+ .field-details pre {
210
+ font-size: 0.75rem;
211
+ max-height: 200px;
212
+ overflow: auto;
213
+ }
214
+
215
+ .feature-card {
216
+ height: 100%;
217
+ border: 1px solid var(--docs-border);
218
+ transition: box-shadow 0.15s ease;
219
+ }
220
+
221
+ .feature-card:hover {
222
+ box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.08);
223
+ }
224
+
225
+ .docs-security-note {
226
+ font-size: 0.8rem;
227
+ }
228
+
229
+ .docs-main-full {
230
+ max-width: 480px;
231
+ margin: 0 auto;
232
+ padding-top: 2rem;
233
+ }
234
+
235
+ .docs-login-wrap {
236
+ display: flex;
237
+ justify-content: center;
238
+ padding: 1rem 0 3rem;
239
+ }
240
+
241
+ .docs-login-card {
242
+ width: 100%;
243
+ max-width: 400px;
244
+ }
@@ -1,4 +1,69 @@
1
1
  extends layout
2
2
 
3
- block content
4
- include:markdown-it ../docs/index.md
3
+ block content
4
+ .docs-hero
5
+ h1= name
6
+ p.lead
7
+ | REST API powered by
8
+ a(href="https://jxp.readthedocs.io" target="_blank" rel="noopener") JXP
9
+ | — define Mongoose schemas, get a full API with auth, permissions, and smart queries.
10
+ .d-flex.flex-wrap.gap-2.mt-3
11
+ if first_guide_url
12
+ a.btn.btn-primary(href=first_guide_url) Get started
13
+ a.btn.btn-outline-primary(href="/docs/api") Browse API
14
+ a.btn.btn-outline-secondary(href="/docs/md/api.md") REST reference
15
+
16
+ .row.g-4.mb-4
17
+ .col-md-6
18
+ .card.h-100
19
+ .card-header.fw-semibold Quick start
20
+ .card-body
21
+ p.mb-2 Authenticate with an API key header#{docs_access === 'public' ? ' (optional for exploring docs; required for live calls)' : ''}:
22
+ pre.mb-3
23
+ code.
24
+ curl -H "X-API-Key: YOUR_KEY" \
25
+ "#{base_url}/api/MODEL?limit=5"
26
+ p.mb-0.small.text-muted
27
+ if docs_access === 'protected'
28
+ | After signing in, your API key is filled in automatically for
29
+ strong Try it
30
+ | panels on API resource pages.
31
+ else
32
+ | Set your key in the top bar to use
33
+ strong Try it
34
+ | panels on API resource pages. Keys are stored in the browser only when “Remember” is checked.
35
+ .col-md-6
36
+ .card.h-100
37
+ .card-header.fw-semibold API at a glance
38
+ .card-body
39
+ p.mb-2
40
+ strong= model_list.length
41
+ | resource#{model_list.length !== 1 ? 's' : ''} registered
42
+ if model_list.length
43
+ .d-flex.flex-wrap.gap-1
44
+ each m in model_list.slice(0, 12)
45
+ a.badge.text-bg-light.text-decoration-none(href="/docs/model/" + m)= m
46
+ if model_list.length > 12
47
+ a.badge.text-bg-secondary.text-decoration-none(href="/docs/api") +#{model_list.length - 12} more
48
+ else
49
+ p.text-muted.mb-0 No models loaded yet.
50
+
51
+ h2.h4.mb-3 Features
52
+ .row.g-3.mb-4
53
+ each feature in features
54
+ .col-md-6.col-lg-4
55
+ .card.feature-card
56
+ .card-body
57
+ h3.h6.card-title= feature.title
58
+ p.card-text.small.text-muted.mb-0= feature.description
59
+
60
+ h2.h4.mb-3 Links
61
+ ul.list-unstyled
62
+ li.mb-1
63
+ a(href="https://www.npmjs.com/package/jxp" target="_blank" rel="noopener") JXP on NPM
64
+ li.mb-1
65
+ a(href="https://github.com/WorkSpaceMan/jxp" target="_blank" rel="noopener") GitHub
66
+ li.mb-1
67
+ a(href="https://www.npmjs.com/package/jxp-helper" target="_blank" rel="noopener") jxp-helper client
68
+ li
69
+ a(href="https://jxp.readthedocs.io" target="_blank" rel="noopener") Read the Docs
@@ -1,12 +1,22 @@
1
1
  doctype html
2
- html
3
- head
4
- title= title
5
- link(rel='stylesheet', href='https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css')
6
- body
7
- include navbar
8
- .container
9
- block content
10
- script(src="https://code.jquery.com/jquery-3.5.1.min.js")
11
- script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.bundle.min.js")
12
- block javascripts
2
+ html(lang="en" data-docs-access=docs_access)
3
+ head
4
+ meta(charset="utf-8")
5
+ meta(name="viewport" content="width=device-width, initial-scale=1")
6
+ title= title
7
+ link(rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" crossorigin="anonymous")
8
+ link(rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css")
9
+ link(rel="stylesheet" href="/docs/assets/docs.css")
10
+ body.docs-body
11
+ include navbar
12
+ if hide_sidebar
13
+ main.docs-main.docs-main-full
14
+ block content
15
+ else
16
+ .docs-shell
17
+ include sidebar
18
+ main.docs-main
19
+ block content
20
+ script(src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous")
21
+ script(src="/docs/assets/api-console.js" defer)
22
+ block javascripts
@@ -0,0 +1,39 @@
1
+ extends layout
2
+
3
+ block content
4
+ .docs-login-wrap
5
+ .card.docs-login-card.shadow-sm
6
+ .card-body.p-4
7
+ h1.h4.mb-1 Sign in to explore the API
8
+ p.text-muted.small.mb-4
9
+ | Use your normal API account (
10
+ code POST /login
11
+ | ). Guides and this site stay open; model pages and “Try it” need a session.
12
+ #docs-login-error.alert.alert-danger(role="alert" hidden)
13
+ form#docs-login-form
14
+ input(type="hidden" name="next" value=docs_next)
15
+ .mb-3
16
+ label.form-label(for="docs-login-email") Email
17
+ input#docs-login-email.form-control(
18
+ type="email"
19
+ name="email"
20
+ value=docs_user_email
21
+ required
22
+ autocomplete="username"
23
+ )
24
+ .mb-3
25
+ label.form-label(for="docs-login-password") Password
26
+ input#docs-login-password.form-control(
27
+ type="password"
28
+ name="password"
29
+ required
30
+ autocomplete="current-password"
31
+ )
32
+ button.btn.btn-primary.w-100(type="submit") Sign in
33
+ p.mt-3.mb-0.small.text-muted
34
+ a(href="/") Back to home
35
+ | ·
36
+ a(href="/docs/md/api.md") Read API docs without signing in
37
+
38
+ block javascripts
39
+ script(src="/docs/assets/docs-login.js" defer)
package/templates/md.pug CHANGED
@@ -1,5 +1,5 @@
1
1
  extends layout
2
2
 
3
3
  block content
4
+ article.docs-content
4
5
  != md_contents
5
-
@@ -1,75 +1,124 @@
1
1
  extends layout
2
2
 
3
3
  block content
4
- h1= "Model " + model.collection.name
5
- hr
6
- h2 Permissions
7
- if perms
8
- table.table
9
- thead
10
- tr
11
- th User Group
12
- th Create?
13
- th Read?
14
- th Update?
15
- th Delete?
16
- tbody
17
- each value, key in perms
18
- tr
19
- td= key
20
- td= value.includes("c") ? "x" : ""
21
- td= value.includes("r") ? "x" : ""
22
- td= value.includes("u") ? "x" : ""
23
- td= value.includes("d") ? "x" : ""
24
- else
25
- .alert.alert-warning No permissions defined for this model, it will not be accessible through the API
4
+ nav.mb-3(aria-label="breadcrumb")
5
+ ol.breadcrumb
6
+ li.breadcrumb-item
7
+ a(href="/docs/api") API
8
+ li.breadcrumb-item.active(aria-current="page")= model_slug
26
9
 
27
- hr
28
- h2 Fields
29
- table.table
10
+ h1.mb-1= model_slug
11
+ p.text-muted
12
+ | Collection:
13
+ code= collection_name
14
+ | ·
15
+ a(href="/docs/md/api.md") Query & filter docs
16
+
17
+ h2.h4.mt-4.mb-3 Endpoints
18
+ p.small.text-muted.mb-3
19
+ | Optional
20
+ code X-API-Key
21
+ | in the top bar.
22
+ span.text-warning Keys in the browser are for development only.
23
+
24
+ .accordion#apiEndpointsAccordion
25
+ each endpoint, idx in endpoints
26
+ .accordion-item
27
+ h2.accordion-header(id="heading-" + idx)
28
+ button.accordion-button(class=(idx === 0 ? '' : 'collapsed') type="button" data-bs-toggle="collapse" data-bs-target="#collapse-" + idx aria-expanded=(idx === 0 ? 'true' : 'false') aria-controls="collapse-" + idx)
29
+ span.badge.method-badge.me-2(class='method-' + endpoint.method.toLowerCase())= endpoint.method
30
+ span.endpoint-path= endpoint.path
31
+ .accordion-collapse.collapse(class=(idx === 0 ? 'show' : '') id="collapse-" + idx aria-labelledby="heading-" + idx data-bs-parent="#apiEndpointsAccordion")
32
+ .accordion-body
33
+ p.mb-2= endpoint.description
34
+ if endpoint.queryHint
35
+ p.small.text-muted= endpoint.queryHint
36
+ .api-try-panel(data-method=endpoint.method data-default-path=endpoint.path)
37
+ .mb-2
38
+ label.form-label.small.fw-semibold Request URL
39
+ .input-group.input-group-sm
40
+ span.input-group-text= endpoint.method
41
+ input.form-control.api-path-input(type="text" value=endpoint.path)
42
+ if endpoint.hasBody
43
+ .mb-2
44
+ label.form-label.small.fw-semibold JSON body
45
+ textarea.form-control.api-body-input.font-monospace(rows="4" placeholder='{"field": "value"}') {}
46
+ button.btn.btn-primary.btn-sm.api-send-btn(type="button")
47
+ i.bi.bi-play-fill.me-1
48
+ | Send request
49
+ .api-response.empty(role="status") Response will appear here…
50
+ .api-response-meta
51
+
52
+ hr.my-4
53
+
54
+ h2.h4 Permissions
55
+ if perms
56
+ .table-responsive
57
+ table.table.table-striped.table-sm
30
58
  thead
31
- tr
32
- th Name
33
- th Type
34
- th Link
35
- th Maps To
36
- th Default
37
- th Indexed?
38
- th Unique?
39
- th Required?
59
+ tr
60
+ th User Group
61
+ th Create
62
+ th Read
63
+ th Update
64
+ th Delete
40
65
  tbody
41
- each fieldname in fields
42
- - let field = safeFields[fieldname]
43
- if (field.path)
44
- tr
45
- td= field.path
46
- td
47
- if field.arrayType
48
- | Array of #{field.arrayType}
49
- else
50
- = field.instance
51
- td= field.options.link
52
- td= field.options.map_to
53
- td= field.defaultValue
54
- td= (field.options.index) ? "x" : ""
55
- td= (field.options.unique) ? "x" : ""
56
- td= field.isRequired ? "x" : ""
57
- hr
58
- h2 Field Details
59
- each fieldname in fields
60
- - let field = safeFields[fieldname]
61
- if field
62
- .field-details
63
- h3= field.path
64
- pre.pre= JSON.stringify(field, null, 2)
65
- if field.schema
66
- h4 Nested Schema
67
- ul
68
- each nestedField in field.schema
69
- li #{nestedField.path}: #{nestedField.type}
70
- if field.validators && field.validators.length
71
- h4 Validators
72
- ul
73
- each validator in field.validators
74
- li #{validator.type}: #{validator.message}
66
+ each value, key in perms
67
+ tr
68
+ td= key
69
+ td= value.includes("c") ? "✓" : ""
70
+ td= value.includes("r") ? "✓" : ""
71
+ td= value.includes("u") ? "✓" : ""
72
+ td= value.includes("d") ? "✓" : ""
73
+ else
74
+ .alert.alert-warning No permissions defined — this resource may not be accessible via the API.
75
+
76
+ h2.h4.mt-4 Fields
77
+ .table-responsive
78
+ table.table.table-striped.table-sm
79
+ thead
80
+ tr
81
+ th Name
82
+ th Type
83
+ th Link
84
+ th Maps To
85
+ th Default
86
+ th Indexed
87
+ th Unique
88
+ th Required
89
+ tbody
90
+ each fieldname in fields
91
+ - let field = safeFields[fieldname]
92
+ if field && field.path
93
+ tr
94
+ td
95
+ code= field.path
96
+ td
97
+ if field.arrayType
98
+ span.badge.text-bg-info Array of #{field.arrayType}
99
+ else
100
+ span.badge.text-bg-light.text-dark= field.instance
101
+ td= field.options.link || ''
102
+ td= field.options.map_to || ''
103
+ td.small= field.defaultValue != null ? field.defaultValue : ''
104
+ td= field.options.index ? "✓" : ""
105
+ td= field.options.unique ? "✓" : ""
106
+ td= field.isRequired ? "✓" : ""
75
107
 
108
+ h2.h4.mt-4 Field details
109
+ each fieldname in fields
110
+ - let field = safeFields[fieldname]
111
+ if field
112
+ .field-details.mb-3
113
+ h3.h6= field.path
114
+ pre.pre.small.bg-light.p-2.rounded= JSON.stringify(field, null, 2)
115
+ if field.schema
116
+ h4.h6 Nested schema
117
+ ul.small
118
+ each nestedField in field.schema
119
+ li #{nestedField.path}: #{nestedField.type}
120
+ if field.validators && field.validators.length
121
+ h4.h6 Validators
122
+ ul.small
123
+ each validator in field.validators
124
+ li #{validator.type}: #{validator.message}
@@ -1,21 +1,25 @@
1
- nav.navbar.navbar-expand-lg.navbar-light
2
- a.navbar-brand(href="/")
3
- h1= name
4
- button.navbar-toggler(type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation")
5
- span.navbar-toggler-icon
6
- #navbarSupportedContent.collapse.navbar-collapse
7
- ul.navbar-nav.mr-auto
8
- li.nav-item.dropdown(class=models)
9
- a#navbarDropdown.nav-link.dropdown-toggle(href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false") Model Reference
10
- .dropdown-menu(aria-labelledby="navbarDropdown")
11
- each model_name in model_list
12
- a.dropdown-item.btn(href="/docs/model/" + model_name)= model_name
13
- li.nav-item.dropdown(class=documentation)
14
- a#navbarDropdown.nav-link.dropdown-toggle(href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false") Guides
15
- .dropdown-menu(aria-labelledby="navbarDropdown")
16
- each nav of guide_nav
17
- a.dropdown-item.btn(href="/docs/md/" + Object.values(nav)[0])= Object.keys(nav)[0]
18
- = "v" + version
19
- //- form.form-inline.my-2.my-lg-0(method="GET" action="/search")
20
- //- input.form-control.mr-sm-2(name="query" type="search" placeholder="Search" aria-label="Search" value=query)
21
- //- button.btn.btn-outline-success.my-2.my-sm-0(type="submit") Search
1
+ header.docs-topbar.navbar.navbar-expand-lg.sticky-top
2
+ .container-fluid.px-3
3
+ button.btn.btn-outline-secondary.btn-sm.d-lg-none.me-2(type="button" data-bs-toggle="offcanvas" data-bs-target="#docsSidebarOffcanvas" aria-controls="docsSidebarOffcanvas" aria-label="Open navigation")
4
+ i.bi.bi-list
5
+ a.docs-brand.navbar-brand.mb-0(href="/")= name
6
+ span.badge.bg-secondary.ms-2.align-self-center v#{version}
7
+ .ms-auto.d-flex.align-items-center.gap-2.flex-wrap
8
+ if docs_access === 'protected' && !docs_authenticated
9
+ a.btn.btn-sm.btn-outline-primary(href="/docs/login?next=/docs/api") Explore API
10
+ if docs_access !== 'disabled' && (docs_access !== 'protected' || docs_authenticated)
11
+ .docs-api-key-wrap
12
+ label.visually-hidden(for="docs-api-key") API Key
13
+ input#docs-api-key.form-control.form-control-sm(
14
+ type="password"
15
+ placeholder=docs_access === 'protected' ? "X-API-Key" : "X-API-Key (optional)"
16
+ autocomplete="off"
17
+ )
18
+ .form-check.form-check-inline.mb-0.docs-security-note
19
+ input#docs-remember-key.form-check-input(type="checkbox")
20
+ label.form-check-label(for="docs-remember-key") Remember
21
+ if docs_access === 'protected'
22
+ form.d-inline(method="post" action="/docs/logout")
23
+ button.btn.btn-sm.btn-link.text-muted(type="submit") Sign out
24
+ else
25
+ span.docs-security-note.text-muted.d-none.d-md-inline Dev only
@@ -0,0 +1,30 @@
1
+ nav.docs-sidebar#docsSidebarDesktop(aria-label="Documentation navigation")
2
+ .docs-sidebar-section
3
+ .docs-sidebar-title Guides
4
+ each nav in guide_nav
5
+ - const label = Object.keys(nav)[0]
6
+ - const file = Object.values(nav)[0]
7
+ a.docs-nav-link(href="/docs/md/" + file class=(active_guide === file ? 'active' : ''))= label
8
+ .docs-sidebar-section
9
+ .docs-sidebar-title API
10
+ a.docs-nav-link(href="/docs/api" class=(active_section === 'api' && !active_model ? 'active' : '')) Overview
11
+ each model_name in model_list
12
+ a.docs-nav-link(href="/docs/model/" + model_name class=(active_model === model_name ? 'active' : ''))= model_name
13
+
14
+ //- Mobile offcanvas (same links)
15
+ .offcanvas.offcanvas-start#docsSidebarOffcanvas(tabindex="-1" aria-labelledby="docsSidebarOffcanvasLabel")
16
+ .offcanvas-header
17
+ h5.offcanvas-title#docsSidebarOffcanvasLabel Navigation
18
+ button.btn-close(type="button" data-bs-dismiss="offcanvas" aria-label="Close")
19
+ .offcanvas-body.p-0
20
+ .docs-sidebar-section
21
+ .docs-sidebar-title Guides
22
+ each nav in guide_nav
23
+ - const label = Object.keys(nav)[0]
24
+ - const file = Object.values(nav)[0]
25
+ a.docs-nav-link(href="/docs/md/" + file class=(active_guide === file ? 'active' : ''))= label
26
+ .docs-sidebar-section
27
+ .docs-sidebar-title API
28
+ a.docs-nav-link(href="/docs/api" class=(active_section === 'api' && !active_model ? 'active' : '')) Overview
29
+ each model_name in model_list
30
+ a.docs-nav-link(href="/docs/model/" + model_name class=(active_model === model_name ? 'active' : ''))= model_name
package/.env DELETED
@@ -1,9 +0,0 @@
1
- MONGODB_HOST=127.0.0.1
2
- MONGODB_PORT=27017
3
- MONGODB_NAME=dev
4
- MONGODB_AUTH_DB=admin
5
- MONGODB_USER=
6
- MONGODB_PASS=
7
-
8
- NODE_LOCAL_PORT=4001
9
- NODE_DOCKER_PORT=4001