@tiddlywiki/mws 0.0.12 → 0.0.13

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 (65) hide show
  1. package/README.md +3 -1
  2. package/dist/server.d.ts +923 -0
  3. package/dist/server.js +1763 -1415
  4. package/dist/server.js.map +1 -1
  5. package/editions/mws-docs/tiddlers/$__StoryList.tid +3 -3
  6. package/editions/mws-docs/tiddlers/MWS and SQLite.md +11 -0
  7. package/editions/mws-docs/tiddlers/Request Server.md +20 -0
  8. package/editions/mws-docs/tiddlers/Request Server.md.meta +5 -0
  9. package/package.json +16 -10
  10. package/prisma/schema.prisma +1 -0
  11. package/react-user-mgmt/package-lock.json +76 -321
  12. package/react-user-mgmt/package.json +2 -5
  13. package/react-user-mgmt/public/chunk-YALWN5OT.js +2 -0
  14. package/react-user-mgmt/public/chunk-YALWN5OT.js.map +7 -0
  15. package/react-user-mgmt/public/esm-QKDFEP3B.js +3 -0
  16. package/react-user-mgmt/public/esm-QKDFEP3B.js.map +7 -0
  17. package/react-user-mgmt/public/index.html +1 -26
  18. package/react-user-mgmt/public/main.js +68 -109
  19. package/react-user-mgmt/public/main.js.map +4 -4
  20. package/react-user-mgmt/public/stats.css +597 -0
  21. package/react-user-mgmt/public/stats.html +59 -0
  22. package/react-user-mgmt/public/stats.js +2013 -0
  23. package/react-user-mgmt/public/stats.json +1 -0
  24. package/react-user-mgmt/public/stats.svg +4 -0
  25. package/react-user-mgmt/tsconfig.json +3 -0
  26. package/dist/server.cjs +0 -16677
  27. package/dist/server.cjs.map +0 -1
  28. package/src/StateObject.ts +0 -316
  29. package/src/commander.ts +0 -417
  30. package/src/commands/divider.ts +0 -20
  31. package/src/commands/index.ts +0 -24
  32. package/src/commands/mws-init-store.ts +0 -77
  33. package/src/commands/mws-listen.ts +0 -136
  34. package/src/commands/mws-load-archive.ts +0 -281
  35. package/src/commands/mws-load-plugin-bags.ts +0 -151
  36. package/src/commands/mws-load-tiddlers.ts +0 -37
  37. package/src/commands/mws-load-wiki-folder.ts +0 -124
  38. package/src/commands/mws-render-tiddlywiki5.ts +0 -55
  39. package/src/commands/mws-save-archive.ts +0 -111
  40. package/src/commands/mws-save-tiddler-text.ts +0 -33
  41. package/src/commands/tests-complete.ts +0 -21
  42. package/src/global.ts +0 -247
  43. package/src/routes/TiddlerStore.ts +0 -722
  44. package/src/routes/bag-file-server.ts +0 -340
  45. package/src/routes/cache.ts +0 -25
  46. package/src/routes/index.ts +0 -138
  47. package/src/routes/managers/index.ts +0 -17
  48. package/src/routes/managers/manager-recipes.ts +0 -438
  49. package/src/routes/managers/manager-users.ts +0 -201
  50. package/src/routes/managers/router-tiddlers.ts +0 -313
  51. package/src/routes/router.ts +0 -429
  52. package/src/routes/services/PasswordService.ts +0 -178
  53. package/src/routes/services/attachments.ts +0 -259
  54. package/src/routes/services/sessions.ts +0 -166
  55. package/src/routes/tw-test.ts +0 -65
  56. package/src/server.ts +0 -151
  57. package/src/setupDevServer.ts +0 -71
  58. package/src/streamer.ts +0 -430
  59. package/src/tiddlywiki.ts +0 -94
  60. package/src/utils/data-checks.ts +0 -172
  61. package/src/utils/index.ts +0 -4
  62. package/src/utils/rootRoute.ts +0 -237
  63. package/src/utils/utils.ts +0 -403
  64. package/src/utils/zodAssert.ts +0 -269
  65. /package/prisma/{migrations/notes.md → notes.md} +0 -0
@@ -1,313 +0,0 @@
1
- import { StateObject } from "../../StateObject";
2
- import { STREAM_ENDED } from "../../streamer";
3
- import { tryParseJSON, ZodAssert as zodAssert } from "../../utils";
4
- import { registerZodRoutes, zodRoute, RouterKeyMap, RouterRouteMap } from "../router";
5
- import { TiddlerServer } from "../bag-file-server";
6
-
7
-
8
- export const TiddlerKeyMap: RouterKeyMap<TiddlerRouter, true> = {
9
- handleCreateRecipeTiddler: true,
10
- handleDeleteRecipeTiddler: true,
11
- handleGetBagTiddler: true,
12
- handleGetBagTiddlerBlob: true,
13
- handleGetRecipeStatus: true,
14
- handleGetRecipeTiddler: true,
15
- handleListRecipeTiddlers: true,
16
- handleSaveRecipeTiddler: true,
17
- handleGetWikiIndex: true,
18
- }
19
-
20
- export type TiddlerManagerMap = RouterRouteMap<TiddlerRouter>;
21
-
22
- export class TiddlerRouter {
23
- static defineRoutes = (root: rootRoute) => {
24
- registerZodRoutes(root, new TiddlerRouter(), Object.keys(TiddlerKeyMap));
25
- }
26
-
27
- handleGetRecipeStatus = zodRoute(
28
- ["GET", "HEAD"],
29
- "/recipes/:recipe_name/status",
30
- z => ({
31
- recipe_name: z.prismaField("Recipes", "recipe_name", "string"),
32
- }),
33
- "ignore",
34
- z => z.undefined(),
35
- async (state) => {
36
-
37
- const { recipe_name } = state.pathParams;
38
-
39
- const { recipe, canRead, canWrite } = await state.getRecipeACL(recipe_name, true);
40
-
41
- if (!recipe) throw state.sendEmpty(404, { "x-reason": "recipe not found" });
42
- if (!canRead) throw state.sendEmpty(403, { "x-reason": "read access denied" });
43
-
44
- const { isAdmin, user_id, username } = state.user;
45
-
46
- return {
47
- isAdmin,
48
- user_id,
49
- username,
50
- isLoggedIn: state.user.isLoggedIn,
51
- isReadOnly: !canWrite,
52
- allowAnonReads: state.config.allowAnonReads,
53
- allowAnonWrites: state.config.allowAnonWrites,
54
- };
55
- }
56
- );
57
-
58
- handleGetRecipeTiddler = zodRoute(
59
- ["GET", "HEAD"],
60
- "/recipes/:recipe_name/tiddlers/:title",
61
- z => ({
62
- recipe_name: z.prismaField("Recipes", "recipe_name", "string"),
63
- title: z.prismaField("Tiddlers", "title", "string"),
64
- }),
65
- "ignore",
66
- z => z.undefined(),
67
- async (state) => {
68
- const { recipe_name, title } = state.pathParams;
69
-
70
- await state.assertRecipeACL(recipe_name, false);
71
-
72
- throw await state.$transaction(async prisma => {
73
- const server = new TiddlerServer(state, prisma);
74
- const bag = await server.getRecipeBagWithTiddler({ recipe_name, title });
75
- return server.sendBagTiddler({ state, bag_id: bag?.bag_id, title });
76
- });
77
-
78
- }
79
- )
80
-
81
- handleGetBagTiddler = zodRoute(
82
- ["GET", "HEAD"],
83
- "/bags/:bag_name/tiddlers/:title",
84
- z => ({
85
- bag_name: z.prismaField("Bags", "bag_name", "string"),
86
- title: z.prismaField("Tiddlers", "title", "string"),
87
- }),
88
- "ignore",
89
- z => z.undefined(),
90
- async (state) => {
91
-
92
- await state.assertBagACL(state.pathParams.bag_name, false);
93
-
94
- throw await state.$transaction(async prisma => {
95
- const server = new TiddlerServer(state, prisma);
96
- // return await server.getBagTiddler(state.pathParams);
97
- return server.sendBagTiddler({ state, ...state.pathParams });
98
- });
99
-
100
- // return this.sendTiddlerInfo(state, tiddlerInfo);
101
-
102
- });
103
-
104
- handleGetBagTiddlerBlob = zodRoute(
105
- ["GET", "HEAD"],
106
- "/bags/:bag_name/tiddlers/:title/blob",
107
- z => ({
108
- bag_name: z.prismaField("Bags", "bag_name", "string"),
109
- title: z.prismaField("Tiddlers", "title", "string"),
110
- }),
111
- "ignore",
112
- z => z.undefined(),
113
- async (state) => {
114
- const { bag_name, title } = state.pathParams;
115
-
116
- await state.assertBagACL(bag_name, false);
117
-
118
- const result = await state.$transaction(async prisma => {
119
- const server = new TiddlerServer(state, prisma);
120
- return await server.getBagTiddlerStream(title, bag_name);
121
- });
122
-
123
- if (!result) throw state.sendEmpty(404, { "x-reason": "no result" });
124
-
125
- throw state.sendStream(200, {
126
- Etag: state.makeTiddlerEtag(result),
127
- "Content-Type": result.type
128
- }, result.stream);
129
- });
130
-
131
- handleListRecipeTiddlers = zodRoute(
132
- ["GET", "HEAD"],
133
- "/recipes/:recipe_name/tiddlers.json",
134
- z => ({
135
- recipe_name: z.prismaField("Recipes", "recipe_name", "string"),
136
- }),
137
- "ignore",
138
- z => z.undefined(),
139
- async (state) => {
140
- zodAssert.queryParams(state, z => ({
141
- include_deleted: z.string().array().optional(),
142
- last_known_tiddler_id: z.string().array().optional(),
143
- }));
144
-
145
- const { recipe_name } = state.pathParams;
146
- const include_deleted = state.queryParams.include_deleted?.[0] === "true";
147
- const last_known_tiddler_id = +(state.queryParams.last_known_tiddler_id?.[0] ?? 0) || undefined;
148
-
149
- await state.assertRecipeACL(recipe_name, false);
150
-
151
- const result = await state.$transaction(async prisma => {
152
- const server = new TiddlerServer(state, prisma);
153
- const options = { include_deleted, last_known_tiddler_id };
154
- let result = await server.getRecipeTiddlers(recipe_name);
155
- return result
156
- .filter(tiddler => options.include_deleted || !tiddler.is_deleted)
157
- .filter(tiddler => !options.last_known_tiddler_id || tiddler.tiddler_id > options.last_known_tiddler_id);
158
- });
159
- return result;
160
- }
161
- )
162
-
163
- parseFields(input: string, ctype: string | undefined) {
164
-
165
- if (ctype?.startsWith("application/json"))
166
- return tryParseJSON<any>(input);
167
-
168
- if (ctype?.startsWith("application/x-mws-tiddler")) {
169
- //https://jsperf.app/mukuro
170
- // for a big text field (100k random characters)
171
- // splitting the string is 1000x faster!
172
- // but I don't really trust getFieldStringBlock
173
- // because it doesn't check for fields with colon names
174
-
175
- const headerEnd = input.indexOf("\n\n");
176
- if (headerEnd === -1) return tryParseJSON<any>(input);
177
- const header = input.slice(0, headerEnd);
178
- const body = input.slice(headerEnd + 2);
179
-
180
- const fields = tryParseJSON<any>(header);
181
- if (!fields) return undefined;
182
- fields.text = body;
183
- return fields;
184
- }
185
- }
186
-
187
- handleSaveRecipeTiddler = zodRoute(
188
- ["PUT"],
189
- "/recipes/:recipe_name/tiddlers/:title",
190
- z => ({
191
- recipe_name: z.prismaField("Recipes", "recipe_name", "string"),
192
- title: z.prismaField("Tiddlers", "title", "string"),
193
- }),
194
- "string",
195
- z => z.string(),
196
- // z => z.object({
197
- // title: z.prismaField("Tiddlers", "title", "string", false),
198
- // }).and(z.record(z.string())),
199
- async (state) => {
200
-
201
- const { recipe_name } = state.pathParams;
202
-
203
- await state.assertRecipeACL(recipe_name, true);
204
-
205
- const fields = this.parseFields(state.data, state.headers["content-type"]);
206
-
207
- if (fields === undefined) throw state.sendEmpty(400, { "x-reason": "PUT tiddler expects a valid json or x-mws-tiddler body" })
208
-
209
- const { bag_name, tiddler_id } = await state.$transaction(async prisma => {
210
- const server = new TiddlerServer(state, prisma);
211
- return await server.saveRecipeTiddler(fields, state.pathParams.recipe_name);
212
- });
213
-
214
- return { bag_name, tiddler_id };
215
-
216
- });
217
-
218
-
219
- handleDeleteRecipeTiddler = zodRoute(
220
- ["DELETE"],
221
- "/recipes/:recipe_name/tiddlers/:title",
222
- z => ({
223
- recipe_name: z.prismaField("Recipes", "recipe_name", "string"),
224
- title: z.prismaField("Tiddlers", "title", "string"),
225
- }),
226
- "json",
227
- z => z.undefined(),
228
- async (state) => {
229
-
230
- const { recipe_name, title } = state.pathParams;
231
- if (!recipe_name || !title) throw state.sendEmpty(404, { "x-reason": "bag_name or title not found" });
232
-
233
- await state.assertRecipeACL(recipe_name, true);
234
-
235
- const { bag_name, tiddler_id } = await state.$transaction(async prisma => {
236
- const server = new TiddlerServer(state, prisma);
237
- return await server.deleteRecipeTiddler(recipe_name, title);
238
- });
239
-
240
- return { bag_name, tiddler_id };
241
-
242
- });
243
-
244
- // this is not used by the sync adaptor. I'm not sure what uses it.
245
- handleCreateRecipeTiddler = zodRoute(
246
- ["POST"],
247
- "/recipes/:recipe_name/tiddlers",
248
- z => ({
249
- recipe_name: z.prismaField("Recipes", "recipe_name", "string"),
250
- }),
251
- "json",
252
- z => z.object({
253
- title: z.prismaField("Tiddlers", "title", "string", false),
254
- }).and(z.record(z.string())),
255
- async (state) => {
256
-
257
- await state.assertRecipeACL(state.pathParams.recipe_name, true);
258
-
259
- const recipe_name = state.pathParams.recipe_name;
260
-
261
- return await state.$transaction(async prisma => {
262
- const server = new TiddlerServer(state, prisma);
263
- const { bag_name } = await server.getRecipeWritableBag(recipe_name) ?? {};
264
- if (!bag_name) throw state.sendEmpty(404, { "x-reason": "bag not found" });
265
- return { bag_name, results: await server.processIncomingStream(bag_name) };
266
- });
267
-
268
- });
269
-
270
- handleGetWikiIndex = zodRoute(
271
- ["GET", "HEAD"],
272
- "/wiki/:recipe_name",
273
- z => ({
274
- recipe_name: z.prismaField("Recipes", "recipe_name", "string"),
275
- }),
276
- "ignore",
277
- z => z.undefined(),
278
- async (state) => {
279
- await state.assertRecipeACL(state.pathParams.recipe_name, false);
280
-
281
- await state.$transaction(async prisma => {
282
- const server = new TiddlerServer(state, prisma);
283
- await server.serveIndexFile(state.pathParams.recipe_name);
284
- });
285
-
286
- throw STREAM_ENDED;
287
- });
288
-
289
- private sendTiddlerInfo = async (
290
- state: StateObject,
291
- tiddlerInfo: Awaited<ReturnType<TiddlerServer["getBagTiddler"]>>
292
- ) => {
293
-
294
- zodAssert.queryParams(state, z => ({
295
- fallback: z.array(z.string()).optional()
296
- }));
297
- // fallbacks are kind of slow, I'm not sure if this is a good idea
298
- if (!tiddlerInfo || !tiddlerInfo.tiddler) {
299
- // Redirect to fallback URL if tiddler not found
300
- const fallback = state.queryParams.fallback?.[0];
301
- if (fallback) {
302
- // await state.pushStream(fallback);
303
- throw state.redirect(fallback);
304
- } else {
305
- throw state.sendEmpty(404, { "x-reason": "tiddler not found (no fallback)" });
306
- }
307
- }
308
-
309
- return tiddlerInfo;
310
- }
311
-
312
-
313
- }