@tiddlywiki/mws 0.0.12 → 0.0.14

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 (66) hide show
  1. package/.env-cmdrc +5 -0
  2. package/README.md +3 -1
  3. package/dist/server.d.ts +923 -0
  4. package/dist/server.js +1763 -1415
  5. package/dist/server.js.map +1 -1
  6. package/editions/mws-docs/tiddlers/$__StoryList.tid +3 -3
  7. package/editions/mws-docs/tiddlers/MWS and SQLite.md +11 -0
  8. package/editions/mws-docs/tiddlers/Request Server.md +20 -0
  9. package/editions/mws-docs/tiddlers/Request Server.md.meta +5 -0
  10. package/package.json +17 -10
  11. package/prisma/schema.prisma +1 -0
  12. package/react-user-mgmt/package-lock.json +76 -321
  13. package/react-user-mgmt/package.json +2 -5
  14. package/react-user-mgmt/public/chunk-YALWN5OT.js +2 -0
  15. package/react-user-mgmt/public/chunk-YALWN5OT.js.map +7 -0
  16. package/react-user-mgmt/public/esm-QKDFEP3B.js +3 -0
  17. package/react-user-mgmt/public/esm-QKDFEP3B.js.map +7 -0
  18. package/react-user-mgmt/public/index.html +1 -26
  19. package/react-user-mgmt/public/main.js +68 -109
  20. package/react-user-mgmt/public/main.js.map +4 -4
  21. package/react-user-mgmt/public/stats.css +597 -0
  22. package/react-user-mgmt/public/stats.html +59 -0
  23. package/react-user-mgmt/public/stats.js +2013 -0
  24. package/react-user-mgmt/public/stats.json +1 -0
  25. package/react-user-mgmt/public/stats.svg +4 -0
  26. package/react-user-mgmt/tsconfig.json +3 -0
  27. package/dist/server.cjs +0 -16677
  28. package/dist/server.cjs.map +0 -1
  29. package/src/StateObject.ts +0 -316
  30. package/src/commander.ts +0 -417
  31. package/src/commands/divider.ts +0 -20
  32. package/src/commands/index.ts +0 -24
  33. package/src/commands/mws-init-store.ts +0 -77
  34. package/src/commands/mws-listen.ts +0 -136
  35. package/src/commands/mws-load-archive.ts +0 -281
  36. package/src/commands/mws-load-plugin-bags.ts +0 -151
  37. package/src/commands/mws-load-tiddlers.ts +0 -37
  38. package/src/commands/mws-load-wiki-folder.ts +0 -124
  39. package/src/commands/mws-render-tiddlywiki5.ts +0 -55
  40. package/src/commands/mws-save-archive.ts +0 -111
  41. package/src/commands/mws-save-tiddler-text.ts +0 -33
  42. package/src/commands/tests-complete.ts +0 -21
  43. package/src/global.ts +0 -247
  44. package/src/routes/TiddlerStore.ts +0 -722
  45. package/src/routes/bag-file-server.ts +0 -340
  46. package/src/routes/cache.ts +0 -25
  47. package/src/routes/index.ts +0 -138
  48. package/src/routes/managers/index.ts +0 -17
  49. package/src/routes/managers/manager-recipes.ts +0 -438
  50. package/src/routes/managers/manager-users.ts +0 -201
  51. package/src/routes/managers/router-tiddlers.ts +0 -313
  52. package/src/routes/router.ts +0 -429
  53. package/src/routes/services/PasswordService.ts +0 -178
  54. package/src/routes/services/attachments.ts +0 -259
  55. package/src/routes/services/sessions.ts +0 -166
  56. package/src/routes/tw-test.ts +0 -65
  57. package/src/server.ts +0 -151
  58. package/src/setupDevServer.ts +0 -71
  59. package/src/streamer.ts +0 -430
  60. package/src/tiddlywiki.ts +0 -94
  61. package/src/utils/data-checks.ts +0 -172
  62. package/src/utils/index.ts +0 -4
  63. package/src/utils/rootRoute.ts +0 -237
  64. package/src/utils/utils.ts +0 -403
  65. package/src/utils/zodAssert.ts +0 -269
  66. /package/prisma/{migrations/notes.md → notes.md} +0 -0
@@ -1,281 +0,0 @@
1
-
2
- import { Commander, CommandInfo } from "../commander";
3
- import { TiddlerStore } from "../routes/TiddlerStore";
4
- import { join, resolve } from "path";
5
- import { Prisma } from "@prisma/client";
6
- import { Command as SaveArchiveCommand } from "./mws-save-archive";
7
- import * as _fsp from "fs/promises";
8
- import { createStrictAwaitProxy } from "../utils";
9
- import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library";
10
- import { existsSync } from "fs";
11
- const fsp = createStrictAwaitProxy(_fsp);
12
-
13
- export const info: CommandInfo = {
14
- name: "mws-load-archive",
15
- synchronous: true
16
- };
17
- export class Command {
18
-
19
- constructor(
20
- public params: string[],
21
- public commander: Commander,
22
- public callback: (err?: any) => void
23
- ) {
24
-
25
-
26
- }
27
-
28
- async execute() {
29
- if (this.params.length < 1) throw "Missing pathname";
30
- const archivePath = this.params[0] as string;
31
-
32
- const index: { version: number } = existsSync(resolve(archivePath, "index.json"))
33
- ? JSON.parse(await fsp.readFile(resolve(archivePath, "index.json"), "utf8"))
34
- : { version: 1 };
35
- // this is all the versions in this repo.
36
- // the multi-wiki-support branch from the TW5 repo is not supported.
37
- switch (index.version) {
38
- case 1:
39
- await new Archiver1(this.commander).loadArchive(archivePath);
40
- break;
41
- case 2:
42
- await new Archiver2(this.commander).loadArchive(archivePath);
43
- break;
44
- default:
45
- throw new Error(`Unsupported archive version ${index.version}`);
46
- }
47
-
48
- this.commander.setupRequired = false;
49
-
50
- }
51
-
52
- }
53
-
54
- class Archiver {
55
- constructor(
56
- public commander: Commander,
57
- ) {
58
-
59
- }
60
- }
61
-
62
- ////////////////////////////////////////////////////////////////////////////////////////
63
- ////////////////////////////////////////////////////////////////////////////////////////
64
- ////////////////////////////////////////////////////////////////////////////////////////
65
- ////////////////////////////////////////////////////////////////////////////////////////
66
- ////////////////////////////////////////////////////////////////////////////////////////
67
- ////////////////////////////////////////////////////////////////////////////////////////
68
- ////////////////////////////////////////////////////////////////////////////////////////
69
-
70
- class Archiver1 extends Archiver {
71
-
72
- async loadArchive(archivePath: string) {
73
- await this.commander.$transaction(async (prisma) => {
74
- // load roles from roles/roles.json
75
- const roles = JSON.parse(await fsp.readFile(resolve(archivePath, "roles", "roles.json"), "utf8"));
76
- await prisma.roles.createMany({ data: roles });
77
- // load users from users/{user_id}.json
78
- const userFiles = await fsp.readdir(resolve(archivePath, "users"));
79
- const users = await Promise.all(userFiles.map(async (userFile) => {
80
- return JSON.parse(await fsp.readFile(resolve(archivePath, "users", userFile), "utf8"));
81
- }));
82
- await prisma.users.createMany({ data: users });
83
- // Iterate the bags
84
- const bagNames = await fsp.readdir(resolve(archivePath, "bags"));
85
- for (const bagFilename of bagNames) {
86
- const stat = await fsp.stat(resolve(archivePath, "bags", bagFilename));
87
- if (!stat.isDirectory()) continue;
88
- console.log(`Reading bag ${decodeURIComponent(bagFilename)}`);
89
- await this.restoreBag(resolve(archivePath, "bags", bagFilename), prisma);
90
- }
91
- // Iterate the recipes
92
- const recipeNames = await fsp.readdir(resolve(archivePath, "recipes"));
93
- for (const recipeFilename of recipeNames) {
94
- if (!recipeFilename.endsWith(".json")) continue;
95
- console.log(`Reading recipe ${decodeURIComponent(recipeFilename)}`);
96
- await this.restoreRecipe(resolve(archivePath, "recipes", recipeFilename), prisma);
97
- }
98
-
99
- }).catch(e => {
100
- if (e instanceof PrismaClientKnownRequestError) {
101
- console.log(e.code, e.meta, e.message);
102
- throw e.message;
103
- } else {
104
- throw e;
105
- }
106
- });
107
- }
108
- private async restoreRecipe(file: string, prisma: PrismaTxnClient) {
109
- type RecipeInfo = Awaited<ReturnType<SaveArchiveCommand["getRecipes"]>>[number];
110
- const recipeInfo: RecipeInfo = JSON.parse(await fsp.readFile(file, "utf8"));
111
- await prisma.recipes.create({
112
- data: {
113
- recipe_id: recipeInfo.recipe_id,
114
- recipe_name: recipeInfo.recipe_name,
115
- description: recipeInfo.description,
116
- owner_id: recipeInfo.owner_id,
117
- acl: { createMany: { data: recipeInfo.acl } },
118
- recipe_bags: {
119
- createMany: {
120
- data: recipeInfo.recipe_bags.map(e => ({
121
- bag_id: e.bag_id,
122
- position: e.position,
123
- with_acl: e.with_acl,
124
- }))
125
- }
126
- }
127
- }
128
- });
129
- }
130
- private async restoreBag(folder: string, prisma: PrismaTxnClient) {
131
- type BagInfo = Awaited<ReturnType<SaveArchiveCommand["getBags"]>>[number];
132
- const bagInfo: BagInfo = JSON.parse(await fsp.readFile(join(folder, "meta.json"), "utf8"));
133
- await prisma.bags.create({
134
- data: {
135
- bag_id: bagInfo.bag_id,
136
- bag_name: bagInfo.bag_name,
137
- description: bagInfo.description,
138
- owner_id: bagInfo.owner_id,
139
- is_plugin: bagInfo.bag_name.startsWith("$:/"),
140
- acl: { createMany: { data: bagInfo.acl } },
141
- }
142
- });
143
- type TiddlerData = Awaited<ReturnType<SaveArchiveCommand["getBags"]>>[number]["tiddlers"][number];
144
- const tiddlerFiles = await fsp.readdir(join(folder, "tiddlers"));
145
- const tiddlers: TiddlerData[] = await Promise.all(tiddlerFiles.map(async (tiddlerFilename) => {
146
- if (!tiddlerFilename.endsWith(".json")) return;
147
- const value = await fsp.readFile(join(folder, "tiddlers", tiddlerFilename), "utf8");
148
- return JSON.parse(value);
149
- }));
150
- await prisma.tiddlers.createMany({
151
- data: tiddlers.flatMap((tiddler): Prisma.TiddlersCreateManyInput => ({
152
- bag_id: bagInfo.bag_id,
153
- title: tiddler.title,
154
- is_deleted: tiddler.is_deleted,
155
- attachment_hash: tiddler.attachment_hash,
156
- tiddler_id: tiddler.tiddler_id,
157
- }))
158
- });
159
- await prisma.fields.createMany({
160
- data: tiddlers.flatMap(({ tiddler_id, fields }) => Object.entries(fields)
161
- .map(([field_name, field_value]): Prisma.FieldsCreateManyInput =>
162
- ({ tiddler_id, field_name, field_value, })
163
- )
164
- )
165
- });
166
- }
167
- }
168
-
169
-
170
- ////////////////////////////////////////////////////////////////////////////////////////
171
- ////////////////////////////////////////////////////////////////////////////////////////
172
- ////////////////////////////////////////////////////////////////////////////////////////
173
- ////////////////////////////////////////////////////////////////////////////////////////
174
- ////////////////////////////////////////////////////////////////////////////////////////
175
- ////////////////////////////////////////////////////////////////////////////////////////
176
- ////////////////////////////////////////////////////////////////////////////////////////
177
-
178
- class Archiver2 extends Archiver {
179
-
180
- async loadArchive(archivePath: string) {
181
- await this.commander.$transaction(async (prisma) => {
182
- const roles = JSON.parse(await fsp.readFile(resolve(archivePath, "roles.json"), "utf8"));
183
- await prisma.roles.createMany({ data: roles });
184
- const users: Awaited<ReturnType<SaveArchiveCommand["getUsers"]>> = JSON.parse(await fsp.readFile(resolve(archivePath, "users.json"), "utf8"));
185
- await Promise.all(users.map(e => prisma.users.create({
186
- data: ({
187
- user_id: e.user_id,
188
- email: e.email,
189
- password: e.password,
190
- username: e.username,
191
- created_at: e.created_at,
192
- last_login: e.last_login,
193
- roles: ({ connect: e.roles.map(e => ({ role_id: e.role_id })) }),
194
- } satisfies Prisma.UsersUncheckedCreateInput)
195
- })));
196
-
197
- // Iterate the bags
198
- const bagNames = await fsp.readdir(resolve(archivePath, "bags"));
199
- for (const bagFilename of bagNames) {
200
- const stat = await fsp.stat(resolve(archivePath, "bags", bagFilename));
201
- if (!stat.isDirectory()) continue;
202
- console.log(`Reading bag ${decodeURIComponent(bagFilename)}`);
203
- await this.restoreBag(resolve(archivePath, "bags", bagFilename), prisma);
204
- }
205
- // Iterate the recipes
206
- const recipeNames = await fsp.readdir(resolve(archivePath, "recipes"));
207
- for (const recipeFilename of recipeNames) {
208
- if (!recipeFilename.endsWith(".json")) continue;
209
- console.log(`Reading recipe ${decodeURIComponent(recipeFilename)}`);
210
- await this.restoreRecipe(resolve(archivePath, "recipes", recipeFilename), prisma);
211
- }
212
-
213
- }).catch(e => {
214
- if (e instanceof PrismaClientKnownRequestError) {
215
- console.log(e.code, e.meta, e.message);
216
- throw e.message;
217
- } else {
218
- throw e;
219
- }
220
- });
221
- }
222
- private async restoreRecipe(file: string, prisma: PrismaTxnClient) {
223
- type RecipeInfo = Awaited<ReturnType<SaveArchiveCommand["getRecipes"]>>[number];
224
- const recipeInfo: RecipeInfo = JSON.parse(await fsp.readFile(file, "utf8"));
225
- await prisma.recipes.create({
226
- data: {
227
- recipe_id: recipeInfo.recipe_id,
228
- recipe_name: recipeInfo.recipe_name,
229
- description: recipeInfo.description,
230
- owner_id: recipeInfo.owner_id,
231
- acl: { createMany: { data: recipeInfo.acl } },
232
- recipe_bags: {
233
- createMany: {
234
- data: recipeInfo.recipe_bags.map(e => ({
235
- bag_id: e.bag_id,
236
- position: e.position,
237
- with_acl: e.with_acl,
238
- }))
239
- }
240
- }
241
- }
242
- });
243
- }
244
- private async restoreBag(folder: string, prisma: PrismaTxnClient) {
245
- type BagInfo = Awaited<ReturnType<SaveArchiveCommand["getBags"]>>[number];
246
- const bagInfo: BagInfo = JSON.parse(await fsp.readFile(join(folder, "meta.json"), "utf8"));
247
- await prisma.bags.create({
248
- data: {
249
- bag_id: bagInfo.bag_id,
250
- bag_name: bagInfo.bag_name,
251
- description: bagInfo.description,
252
- owner_id: bagInfo.owner_id,
253
- is_plugin: bagInfo.is_plugin,
254
- acl: { createMany: { data: bagInfo.acl } },
255
- }
256
- });
257
- type TiddlerData = Awaited<ReturnType<SaveArchiveCommand["getBags"]>>[number]["tiddlers"][number];
258
- const tiddlerFiles = await fsp.readdir(join(folder, "tiddlers"));
259
- const tiddlers: TiddlerData[] = await Promise.all(tiddlerFiles.map(async (tiddlerFilename) => {
260
- if (!tiddlerFilename.endsWith(".json")) return;
261
- const value = await fsp.readFile(join(folder, "tiddlers", tiddlerFilename), "utf8");
262
- return JSON.parse(value);
263
- }));
264
- await prisma.tiddlers.createMany({
265
- data: tiddlers.flatMap((tiddler): Prisma.TiddlersCreateManyInput => ({
266
- bag_id: bagInfo.bag_id,
267
- title: tiddler.title,
268
- is_deleted: tiddler.is_deleted,
269
- attachment_hash: tiddler.attachment_hash,
270
- tiddler_id: tiddler.tiddler_id,
271
- }))
272
- });
273
- await prisma.fields.createMany({
274
- data: tiddlers.flatMap(({ tiddler_id, fields }) => Object.entries(fields)
275
- .map(([field_name, field_value]): Prisma.FieldsCreateManyInput =>
276
- ({ tiddler_id, field_name, field_value, })
277
- )
278
- )
279
- });
280
- }
281
- }
@@ -1,151 +0,0 @@
1
- import { resolve } from "node:path";
2
-
3
- import { Commander, CommandInfo } from "../commander";
4
- import { TiddlerStore } from "../routes/TiddlerStore";
5
- import { TiddlerFields } from "../routes/services/attachments";
6
- import { truthy, tryParseJSON } from "../utils";
7
- import { Prisma, PrismaClient, PrismaPromise } from "@prisma/client";
8
-
9
- export const info: CommandInfo = {
10
- name: "mws-load-plugin-bags",
11
- synchronous: true,
12
-
13
- };
14
-
15
-
16
- export class Command {
17
-
18
- get $tw() { return this.commander.$tw; }
19
- constructor(
20
- public params: string[],
21
- public commander: Commander,
22
- public callback: (err?: any) => void
23
- ) {
24
-
25
- }
26
- async execute() {
27
- console.time(`${info.name} complete`);
28
- await loadPluginBags(
29
- this.$tw,
30
- new TiddlerStore(this.commander, this.commander.engine),
31
- this.commander.engine
32
- );
33
- console.timeEnd(`${info.name} complete`);
34
- }
35
- }
36
-
37
-
38
- async function loadPluginBags($tw: any, store: TiddlerStore, engine: PrismaClient) {
39
-
40
- // Copy plugins
41
- function makePluginBagName(type: string, publisher: string | undefined, name: string) {
42
- return "$:/" + type + "/" + (publisher ? publisher + "/" : "") + name;
43
- }
44
- function savePlugin(
45
- pluginFields: TiddlerFields,
46
- // tiddlers: Record<string, TiddlerFields>,
47
- type: string,
48
- publisher: string | undefined,
49
- name: string
50
- ) {
51
-
52
- const bagName = makePluginBagName(type, publisher, name) as PrismaField<"Bags", "bag_name">;
53
- const description = (pluginFields.description ?? "(no description)") as PrismaField<"Bags", "description">;
54
- const is_plugin = true as PrismaField<"Bags", "is_plugin">;
55
- // await store.saveBagTiddler(pluginFields, bagName);
56
- return [
57
- store.upsertBag_PrismaPromise(bagName, description, is_plugin, { allowPrivilegedCharacters: true }),
58
- ...store.saveBagTiddlerFields_PrismaArray(pluginFields, bagName, null),
59
- // ...Object.values(tiddlers).flatMap((fields) => store.saveBagTiddlerFields_PrismaArray(fields, bagName, null))
60
- ].filter(truthy);
61
-
62
- }
63
- function collectPlugins(folder: string, type: string, publisher?: string | undefined) {
64
- var pluginFolders = $tw.utils.getSubdirectories(folder) || [];
65
- const prismaPromiseArray: PrismaPromise<any>[] = [];
66
- for (var p = 0; p < pluginFolders.length; p++) {
67
- const pluginFolderName = pluginFolders[p];
68
- if ($tw.boot.excludeRegExp.test(pluginFolderName)) continue;
69
-
70
- const pluginFields: TiddlerFields = $tw.loadPluginFolder(resolve(folder, pluginFolderName));
71
- if (!pluginFields?.title) continue;
72
-
73
- // const { tiddlers = {} } = tryParseJSON<{
74
- // tiddlers: Record<string, TiddlerFields>
75
- // }>(pluginFields.text) ?? {};
76
- // delete pluginFields.text;
77
-
78
- prismaPromiseArray.push(...savePlugin(pluginFields, type, publisher, pluginFolderName));
79
-
80
- // console.log(`Import plugin ${pluginFields.title}`);
81
- }
82
- prismaPromiseArray.forEach(e => {
83
- if (e[Symbol.toStringTag] !== "PrismaPromise") console.log(e)
84
- })
85
- return prismaPromiseArray;
86
- }
87
- function collectPublisherPlugins(folder: string, type: string) {
88
- var publisherFolders: string[] = $tw.utils.getSubdirectories(folder) || [];
89
- return publisherFolders.flatMap((publisherFolderName) => {
90
- if ($tw.boot.excludeRegExp.test(publisherFolderName)) return [];
91
- return collectPlugins(resolve(folder, publisherFolderName), type, publisherFolderName);
92
- });
93
- };
94
- const plugins = $tw.getLibraryItemSearchPaths($tw.config.pluginsPath, $tw.config.pluginsEnvVar);
95
- const themes = $tw.getLibraryItemSearchPaths($tw.config.themesPath, $tw.config.themesEnvVar);
96
- const languages = $tw.getLibraryItemSearchPaths($tw.config.languagesPath, $tw.config.languagesEnvVar);
97
- const prismaPromiseArray = [
98
- ...plugins.flatMap((folder: string) => collectPublisherPlugins(folder, "plugins")),
99
- ...themes.flatMap((folder: string) => collectPublisherPlugins(folder, "themes")),
100
- ...languages.flatMap((folder: string) => collectPlugins(folder, "languages")),
101
- ];
102
- prismaPromiseArray.forEach(e => {
103
- if (e[Symbol.toStringTag] !== "PrismaPromise") {
104
- if (Array.isArray(e)) console.log(e.length);
105
- else console.log(e);
106
- }
107
- })
108
- await engine.$transaction(prismaPromiseArray);
109
-
110
- }
111
-
112
-
113
-
114
- // // these are the main type definitions for the generator function.
115
- // // Modify these if you use a typed sql framework.
116
- // type YieldInput = Prisma.PrismaPromise<any>;
117
- // type YieldOutput<Input extends YieldInput> = Awaited<Input>;
118
- // // this is the generator type
119
- // type PrismaGenerator<T> = Generator<YieldInput[], T, YieldOutput<YieldInput>[]>;
120
-
121
- // const prisma = new PrismaClient();
122
- // prisma.bagAcl.aggregate
123
-
124
-
125
- // type MapInputToOutput<T extends YieldInput[]> = T extends [
126
- // infer First extends YieldInput,
127
- // ...infer Rest extends YieldInput[]
128
- // ] ? [YieldOutput<First>, ...MapInputToOutput<Rest>] : [];
129
-
130
- // /** This just types the yield output according to the input. Make sure you call it with `yield*` */
131
- // function* Yielder<const I extends YieldInput[]>(...input: I)
132
- // : PrismaGenerator<MapInputToOutput<I>> { return (yield input) as MapInputToOutput<I>; }
133
-
134
- // function prismaYielder(prisma: PrismaClient) {
135
- // return function* yielder<const I extends YieldInput[]>(...input: I)
136
- // : PrismaGenerator<MapInputToOutput<I>> { return (yield input) as MapInputToOutput<I>; }
137
- // }
138
-
139
- // // this section is an example usage of the above functions
140
-
141
- // function* prismaBatchTransaction(yielder: typeof Yielder): PrismaGenerator<{ titles: string[] }> {
142
- // // yield* is essentially a spread operator for generators
143
- // // yielder yeilds one value then returns the result.
144
- // // this just gives us a way to type the output of a yield according to the input
145
- // // so if we give it a typed sql query input, it can return a typed result
146
-
147
- // const [result1] = yield* yielder(prisma.bagAcl.aggregate({}));
148
-
149
- // return { titles: [] };
150
-
151
- // }
@@ -1,37 +0,0 @@
1
- import { resolve } from "path";
2
- import { CommandInfo, Commander } from "../commander";
3
- import { TiddlerStore } from "../routes/TiddlerStore";
4
- import { SiteConfig } from "../routes/router";
5
- import { TiddlerFields } from "../routes/services/attachments";
6
-
7
- export const info: CommandInfo = {
8
- name: "mws-load-tiddlers",
9
- synchronous: true
10
- };
11
-
12
- export class Command {
13
- get $tw() { return this.commander.$tw; }
14
- config: SiteConfig;
15
- tiddlersPath: string;
16
- bagName: PrismaField<"Bags", "bag_name">;
17
- constructor(
18
- public params: string[],
19
- public commander: Commander,
20
- public callback: (err?: any) => void
21
- ) {
22
- this.config = this.commander.siteConfig;
23
- this.tiddlersPath = resolve(this.params[0] as string);
24
- this.bagName = this.params[1] as PrismaField<"Bags", "bag_name">;
25
- }
26
- async execute() {
27
- if (this.params.length < 2) return "Missing pathname and/or bag name";
28
- await this.commander.$transaction(async (prisma) => {
29
- const store = new TiddlerStore(this.commander, prisma);
30
- var tiddlersFromPath = this.$tw.loadTiddlersFromPath(this.tiddlersPath);
31
- //@ts-ignore
32
- await store.saveTiddlersFromPath(tiddlersFromPath, this.bagName);
33
- });
34
- return null;
35
-
36
- }
37
- }
@@ -1,124 +0,0 @@
1
- /*\
2
- title: $:/plugins/tiddlywiki/multiwikiserver/commands/mws-load-wiki-folder.js
3
- type: application/javascript
4
- module-type: command
5
-
6
- Command to create and load a bag for the specified core editions
7
-
8
- --mws-load-wiki-folder <path> <bag-name> <bag-description> <recipe-name> <recipe-description>
9
-
10
- \*/
11
-
12
-
13
- import { resolve } from "path";
14
- import { Commander, CommandInfo } from "../commander";
15
- import { TiddlerStore } from "../routes/TiddlerStore";
16
- import { TiddlerFields } from "../routes/services/attachments";
17
- import { Prisma, PrismaClient } from "@prisma/client";
18
-
19
- export const info: CommandInfo = {
20
- name: "mws-load-wiki-folder",
21
- synchronous: true
22
- };
23
- // tiddlywiki --load ./mywiki.html --savewikifolder ./mywikifolder
24
- export class Command {
25
- constructor(
26
- public params: string[],
27
- public commander: Commander,
28
- public callback: (err?: any) => void
29
- ) {
30
-
31
- }
32
- async execute() {
33
-
34
- // Check parameters
35
- if (this.params.length < 5) {
36
- return "Missing parameters for --mws-load-wiki-folder command";
37
- }
38
-
39
- await this.commander.engine.$transaction(loadWikiFolder({
40
- wikiPath: this.params[0] as string,
41
- bagName: this.params[1] as PrismaField<"Bags", "bag_name">,
42
- bagDescription: this.params[2] as PrismaField<"Bags", "description">,
43
- recipeName: this.params[3] as PrismaField<"Recipes", "recipe_name">,
44
- recipeDescription: this.params[4] as PrismaField<"Recipes", "description">,
45
- store: new TiddlerStore(this.commander, this.commander.engine),
46
- $tw: this.commander.$tw
47
- }));
48
- console.log(info.name, "complete:", this.params[0])
49
- return null;
50
- }
51
- }
52
-
53
-
54
- // Function to convert a plugin name to a bag name
55
- function makePluginBagName(type: string, publisher: string | undefined, name: string) {
56
- return "$:/" + type + "/" + (publisher ? publisher + "/" : "") + name;
57
- }
58
-
59
- // Copy TiddlyWiki core editions
60
- function loadWikiFolder({ $tw, store, ...options }: {
61
- wikiPath: string,
62
- bagName: PrismaField<"Bags", "bag_name">,
63
- bagDescription: PrismaField<"Bags", "description">,
64
- recipeName: PrismaField<"Recipes", "recipe_name">,
65
- recipeDescription: PrismaField<"Recipes", "description">,
66
- store: TiddlerStore,
67
- $tw: any
68
- }) {
69
- const path = require("path"),
70
- fs = require("fs");
71
- // Read the tiddlywiki.info file
72
- const wikiInfoPath = path.resolve(options.wikiPath, $tw.config.wikiInfo);
73
- let wikiInfo;
74
- if (fs.existsSync(wikiInfoPath)) {
75
- wikiInfo = $tw.utils.parseJSONSafe(fs.readFileSync(wikiInfoPath, "utf8"), function () { return null; });
76
- }
77
- if (!wikiInfo) return [];
78
- // Add plugins to the recipe list
79
- const recipeList = [];
80
- const processPlugins = function (type: string, plugins: string[]) {
81
- $tw.utils.each(plugins, function (pluginName: string) {
82
- const parts = pluginName.split("/");
83
- let publisher, name;
84
- if (parts.length === 2) {
85
- publisher = parts[0];
86
- name = parts[1];
87
- } else {
88
- name = parts[0];
89
- }
90
- recipeList.push({ bag_name: makePluginBagName(type, publisher, name as string), with_acl: false });
91
- });
92
- };
93
- processPlugins("plugins", wikiInfo.plugins);
94
- processPlugins("themes", wikiInfo.themes);
95
- processPlugins("languages", wikiInfo.languages);
96
- // Create the recipe
97
- recipeList.push({
98
- bag_name: options.bagName,
99
- with_acl: true as PrismaField<"Recipe_bags", "with_acl">,
100
- });
101
- recipeList.reverse()
102
-
103
-
104
- const tiddler_files_path = path.resolve(options.wikiPath, $tw.config.wikiTiddlersSubDir)
105
- const tiddlersFromPath: TiddlerInfo[] = $tw.loadTiddlersFromPath(
106
- resolve($tw.boot.corePath, $tw.config.editionsPath, tiddler_files_path)
107
- );
108
-
109
- const is_plugin = false as PrismaField<"Bags", "is_plugin">;
110
- return [
111
- // create the bag
112
- store.upsertBag_PrismaPromise(options.bagName, options.bagDescription, is_plugin),
113
- // create the recipe and recipe_bags entries
114
- ...store.upsertRecipe_PrismaArray(
115
- options.recipeName,
116
- options.recipeDescription,
117
- recipeList,
118
- ),
119
- // save the tiddlers (this will skip attachments)
120
- ...store.saveTiddlersFromPath_PrismaArray(tiddlersFromPath, options.bagName)
121
- ];
122
-
123
- }
124
- interface TiddlerInfo { tiddlers: TiddlerFields[], filepath: string, type: string, hasMetaFile: boolean }
@@ -1,55 +0,0 @@
1
- /*\
2
- title: $:/plugins/tiddlywiki/multiwikiserver/commands/mws-render-tiddler.js
3
- type: application/javascript
4
- module-type: command
5
-
6
- Command to create and load a bag for the specified core editions
7
-
8
-
9
-
10
- \*/
11
-
12
-
13
- import { resolve } from "node:path";
14
- import { Commander, CommandInfo } from "../commander";
15
-
16
- const { writeFileSync } = require("fs");
17
-
18
- export const info: CommandInfo = {
19
- name: "mws-render-tiddlywiki5",
20
- synchronous: true
21
- };
22
-
23
- export class Command {
24
-
25
- constructor(
26
- public params: string[],
27
- public commander: Commander,
28
- public callback: (err?: any) => void
29
- ) {
30
-
31
- }
32
- async execute() {
33
-
34
- const result = this.commander.$tw.wiki.renderTiddler("text/plain", "$:/core/templates/tiddlywiki5.html", {
35
- variables: {
36
- saveTiddlerFilter: `
37
- $:/boot/boot.css
38
- $:/boot/boot.js
39
- $:/boot/bootprefix.js
40
- $:/core
41
- $:/library/sjcl.js
42
- $:/plugins/tiddlywiki/tiddlyweb
43
- $:/plugins/tiddlywiki/multiwikiclient
44
- $:/themes/tiddlywiki/snowwhite
45
- $:/themes/tiddlywiki/vanilla
46
- `
47
- }
48
- });
49
-
50
- const filepath = resolve(this.commander.wikiPath, "tiddlywiki5.html")
51
-
52
- writeFileSync(filepath, result);
53
- }
54
- };
55
-