@tiddlywiki/mws 0.0.16 → 0.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -33
- package/dist/server.d.ts +15 -9
- package/dist/server.js +114 -45
- package/dist/server.js.map +1 -1
- package/editions/mws-docs/tiddlers/$__StoryList.tid +1 -3
- package/editions/mws-docs/tiddlers/2025-02-18 - User Management.md +56 -0
- package/editions/mws-docs/tiddlers/2025-02-18 - User Management.md.meta +5 -0
- package/editions/mws-docs/tiddlers/2025-04-03 - Phases of Development.md +64 -0
- package/editions/mws-docs/tiddlers/2025-04-03 - Phases of Development.md.meta +5 -0
- package/editions/mws-docs/tiddlers/2025-04-13 - Plugins.md +18 -0
- package/editions/mws-docs/tiddlers/2025-04-13 - Plugins.md.meta +5 -0
- package/editions/mws-docs/tiddlers/2025-05-04.md +13 -0
- package/editions/mws-docs/tiddlers/2025-05-04.md.meta +5 -0
- package/editions/mws-docs/tiddlers/2025-05-06.md +19 -0
- package/editions/mws-docs/tiddlers/2025-05-06.md.meta +5 -0
- package/editions/mws-docs/tiddlers/Checklists and Features.md +15 -0
- package/editions/mws-docs/tiddlers/Checklists and Features.md.meta +5 -0
- package/editions/mws-docs/tiddlers/MWS Architecture.md +15 -0
- package/editions/mws-docs/tiddlers/MWS Architecture.md.meta +5 -0
- package/editions/mws-docs/tiddlers/Notes.tid +5 -0
- package/editions/mws-docs/tiddlers/system/$__palettes_MUI-Dark +173 -0
- package/editions/mws-docs/tiddlers/system/$__palettes_MUI-Dark.meta +6 -0
- package/editions/mws-docs/tiddlers/system/$__palettes_MUI-Light +172 -0
- package/editions/mws-docs/tiddlers/system/$__palettes_MUI-Light.meta +6 -0
- package/package.json +9 -21
- package/plugins/client/tiddlers/readme.tid +0 -3
- package/react-user-mgmt/public/main.js +32 -32
- package/react-user-mgmt/public/main.js.map +4 -4
- package/react-user-mgmt/public/stats.json +1 -1
- package/scripts.mjs +34 -0
- package/.env-cmdrc +0 -5
package/README.md
CHANGED
|
@@ -1,8 +1,22 @@
|
|
|
1
1
|
# MultiWikiServer
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Multiple users, multiple wikis for TiddlyWiki.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- Bag & Recipe system for storing tiddlers.
|
|
6
|
+
- User and Role management with ACL.
|
|
7
|
+
- Multiple database engines supported, using Prisma.
|
|
8
|
+
- Third-party OAuth and password-based login.
|
|
9
|
+
|
|
10
|
+
## Flexible and Extendible
|
|
11
|
+
|
|
12
|
+
- Plugins can add routes and hooks.
|
|
13
|
+
- Abstractions everywhere, allowing flexibility.
|
|
14
|
+
- The source code is fully typed and easy to navigate.
|
|
15
|
+
- Admin endpoints can also be called from the CLI.
|
|
16
|
+
|
|
17
|
+
Most of these features are still in development.
|
|
18
|
+
|
|
19
|
+
## How to run
|
|
6
20
|
|
|
7
21
|
The init command creates a new folder and installs what you need to get started.
|
|
8
22
|
|
|
@@ -36,42 +50,15 @@ If there are any database changes, MWS should pick them up and apply them. The c
|
|
|
36
50
|
If you want to work on the project,
|
|
37
51
|
|
|
38
52
|
- `git clone https://github.com/TiddlyWiki/MultiWikiServer`
|
|
53
|
+
- `cd MultiWikiServer`
|
|
39
54
|
- `npm install` or `npm run install-android`
|
|
40
55
|
- `cd react-user-mgmt`
|
|
41
56
|
- `npm install`
|
|
42
57
|
- `cd ..`
|
|
43
|
-
- `npm run certs` - if you want https
|
|
58
|
+
- `npm run certs` - if you want https (unix only)
|
|
44
59
|
- `npm start` - this runs the build and test every time, but it's pretty fast
|
|
45
60
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
### The Server
|
|
49
|
-
|
|
50
|
-
- Supports HTTP and HTTPS listeners. All requests are funneled into one stack.
|
|
51
|
-
- Uses abstractions and state objects to make the server as flexible as possible.
|
|
52
|
-
- Supports overriding classes to implement custom handling of various features.
|
|
53
|
-
- All of the features from the old MWS branch have been converted to the new system.
|
|
54
|
-
|
|
55
|
-
### The Store
|
|
56
|
-
|
|
57
|
-
- Written using Prisma and entirely promise-based.
|
|
58
|
-
- Swapping to a different database engine should be a breeze. For sqlite it uses the libsql adapter, which also allows connections to libsql servers.
|
|
59
|
-
- The tiddler text attachment system, which stores some tiddler bodies on the file system, is promise-based and can be modified to store files in the cloud.
|
|
60
|
-
|
|
61
|
-
### The Features
|
|
62
|
-
|
|
63
|
-
- Bag & Recipe system for storing tiddlers.
|
|
64
|
-
- User and Role management with ACL.
|
|
65
|
-
- Attachment system for storing binary tiddlers on the file system.
|
|
66
|
-
- Various import and export commands (currently still in development).
|
|
67
|
-
- Customization of these features should be quite easy as they are fairly self-contained. The TypeScript code is fully typed and easy to navigate.
|
|
68
|
-
|
|
69
|
-
### Planned (hopefully) for the future
|
|
70
|
-
|
|
71
|
-
- AuthJS or a similar integration that supports third-party OAuth (you can already write your own).
|
|
72
|
-
- Compiling filters to SQL to optimize memory on both the client and server.
|
|
73
|
-
- Support for other database and storage systems. Most likely MariaDB and Postgres.
|
|
74
|
-
- Additional recipe strategies with features like prefixed bags and namespaces.
|
|
75
|
-
- Server rendering of pages, for a more wikipedia-like experience.
|
|
61
|
+
The development wiki will be active at http://localhost:8080/dev
|
|
76
62
|
|
|
63
|
+
You can change the listeners as explained in the mws.dev.mjs file.
|
|
77
64
|
|
package/dist/server.d.ts
CHANGED
|
@@ -5,13 +5,13 @@ import { PassThrough, Writable } from 'node:stream';
|
|
|
5
5
|
import * as z from 'zod';
|
|
6
6
|
import { z as z$1, ZodEffects } from 'zod';
|
|
7
7
|
import { PrismaClient, Prisma } from '@prisma/client';
|
|
8
|
-
import { ITXClientDenyList, Types } from '@prisma/client/runtime/library';
|
|
9
8
|
import * as fs from 'fs';
|
|
10
9
|
import * as tiddlywiki from 'tiddlywiki';
|
|
11
|
-
import { TW } from 'tiddlywiki';
|
|
12
|
-
import
|
|
10
|
+
import { TW, TiddlerFieldModule } from 'tiddlywiki';
|
|
11
|
+
import { ITXClientDenyList, Types } from '@prisma/client/runtime/library';
|
|
13
12
|
import * as commander from 'commander';
|
|
14
13
|
import { SqlMigrationAwareDriverAdapterFactory, SqlDriverAdapter } from '@prisma/driver-adapter-utils';
|
|
14
|
+
import * as http2 from 'node:http2';
|
|
15
15
|
import * as http2$1 from 'http2';
|
|
16
16
|
import { OutgoingHttpHeaders, IncomingHttpHeaders as IncomingHttpHeaders$1, IncomingMessage as IncomingMessage$1, ServerResponse as ServerResponse$1 } from 'node:http';
|
|
17
17
|
|
|
@@ -227,6 +227,7 @@ declare class StartupCommander {
|
|
|
227
227
|
config: MWSConfig;
|
|
228
228
|
$tw: TW;
|
|
229
229
|
PasswordService: PasswordService;
|
|
230
|
+
fieldModules: Record<string, TiddlerFieldModule>;
|
|
230
231
|
constructor(config: MWSConfig, $tw: TW, PasswordService: PasswordService);
|
|
231
232
|
init(): Promise<void>;
|
|
232
233
|
wikiPath: string;
|
|
@@ -298,7 +299,7 @@ declare class StateObject<B extends BodyFormat = BodyFormat, M extends AllowedMe
|
|
|
298
299
|
/** The bodyformat that ended up taking precedence. This should be correctly typed. */
|
|
299
300
|
bodyFormat: B;
|
|
300
301
|
user: AuthUser;
|
|
301
|
-
|
|
302
|
+
router: Router;
|
|
302
303
|
tiddlerCache: Router["tiddlerCache"];
|
|
303
304
|
z: typeof z;
|
|
304
305
|
STREAM_ENDED: typeof STREAM_ENDED;
|
|
@@ -336,7 +337,7 @@ declare class StateObject<B extends BodyFormat = BodyFormat, M extends AllowedMe
|
|
|
336
337
|
/** The array of Route tree nodes the request matched. */
|
|
337
338
|
routePath: RouteMatch[],
|
|
338
339
|
/** The bodyformat that ended up taking precedence. This should be correctly typed. */
|
|
339
|
-
bodyFormat: B, user: AuthUser,
|
|
340
|
+
bodyFormat: B, user: AuthUser, router: Router, tiddlerCache: Router["tiddlerCache"]);
|
|
340
341
|
okUser(): void;
|
|
341
342
|
okAdmin(): void;
|
|
342
343
|
$transaction: <T>(fn: (prisma: PrismaTxnClient) => Promise<T>) => Promise<T>;
|
|
@@ -784,15 +785,18 @@ declare const BodyFormats: readonly ["stream", "string", "json", "buffer", "www-
|
|
|
784
785
|
type BodyFormat = typeof BodyFormats[number];
|
|
785
786
|
declare class Router {
|
|
786
787
|
private rootRoute;
|
|
787
|
-
private commander;
|
|
788
788
|
private tiddlerCache;
|
|
789
789
|
static makeRouter(commander: Commander, enableDevServer: boolean): Promise<Router>;
|
|
790
|
-
pathPrefix: string;
|
|
791
790
|
enableBrowserCache: boolean;
|
|
792
791
|
enableGzip: boolean;
|
|
793
792
|
csrfDisable: boolean;
|
|
793
|
+
siteConfig: SiteConfig;
|
|
794
|
+
get pathPrefix(): string;
|
|
794
795
|
engine: Commander["engine"];
|
|
795
796
|
private SessionManager;
|
|
797
|
+
PasswordService: Commander["PasswordService"];
|
|
798
|
+
fieldModules: Commander["$tw"]["Tiddler"]["fieldModules"];
|
|
799
|
+
AttachmentService: Commander["AttachmentService"];
|
|
796
800
|
constructor(rootRoute: rootRoute$1, commander: Commander, tiddlerCache: CacheState);
|
|
797
801
|
handleIncomingRequest(req: http.IncomingMessage | http2$1.Http2ServerRequest, res: http.ServerResponse | http2$1.Http2ServerResponse): void;
|
|
798
802
|
handle(streamer: Streamer): Promise<void | typeof STREAM_ENDED>;
|
|
@@ -890,8 +894,10 @@ interface SiteConfig extends MWSConfigConfig {
|
|
|
890
894
|
storePath: string;
|
|
891
895
|
/**
|
|
892
896
|
* The path prefix is a essentially folder mount point.
|
|
893
|
-
*
|
|
894
|
-
*
|
|
897
|
+
*
|
|
898
|
+
* It starts with a slash, and ends without a slash (`"/dev"`).
|
|
899
|
+
*
|
|
900
|
+
* If there is not a prefix, it is an empty string (`""`).
|
|
895
901
|
*/
|
|
896
902
|
pathPrefix: string;
|
|
897
903
|
}
|
package/dist/server.js
CHANGED
|
@@ -11660,7 +11660,7 @@ var init_data_checks = __esm({
|
|
|
11660
11660
|
// allow unowned for any user (conditional for anon reads)
|
|
11661
11661
|
(user_id || allowAnon) && { acl: { none: {} }, owner_id: null },
|
|
11662
11662
|
// allow owner for user
|
|
11663
|
-
user_id && { owner_id: user_id },
|
|
11663
|
+
user_id && { owner_id: { equals: user_id, not: null } },
|
|
11664
11664
|
// allow acl for user
|
|
11665
11665
|
user_id && role_ids?.length && {
|
|
11666
11666
|
acl: {
|
|
@@ -12154,12 +12154,12 @@ var init_StateObject = __esm({
|
|
|
12154
12154
|
init_streamer();
|
|
12155
12155
|
init_utils2();
|
|
12156
12156
|
_StateObject = class _StateObject extends StreamerState {
|
|
12157
|
-
constructor(streamer, routePath, bodyFormat, user,
|
|
12157
|
+
constructor(streamer, routePath, bodyFormat, user, router, tiddlerCache) {
|
|
12158
12158
|
super(streamer);
|
|
12159
12159
|
this.routePath = routePath;
|
|
12160
12160
|
this.bodyFormat = bodyFormat;
|
|
12161
12161
|
this.user = user;
|
|
12162
|
-
this.
|
|
12162
|
+
this.router = router;
|
|
12163
12163
|
this.tiddlerCache = tiddlerCache;
|
|
12164
12164
|
this.z = z3;
|
|
12165
12165
|
this.STREAM_ENDED = STREAM_ENDED;
|
|
@@ -12170,9 +12170,9 @@ var init_StateObject = __esm({
|
|
|
12170
12170
|
this.$transaction = /* @__PURE__ */ __name(async (fn) => {
|
|
12171
12171
|
return await this.engine.$transaction((prisma) => fn(prisma));
|
|
12172
12172
|
}, "$transaction");
|
|
12173
|
-
this.engine =
|
|
12174
|
-
this.config =
|
|
12175
|
-
this.PasswordService =
|
|
12173
|
+
this.engine = router.engine;
|
|
12174
|
+
this.config = router.siteConfig;
|
|
12175
|
+
this.PasswordService = router.PasswordService;
|
|
12176
12176
|
this.readMultipartData = readMultipartData.bind(this);
|
|
12177
12177
|
this.sendResponse = sendResponse.bind(void 0, this.config, this);
|
|
12178
12178
|
this.pathParams = Object.fromEntries(routePath.map(
|
|
@@ -12222,7 +12222,7 @@ var init_StateObject = __esm({
|
|
|
12222
12222
|
* - **308 Permanent Redirect:** The resource has permanently moved; the client should use the new URL in future requests.
|
|
12223
12223
|
*/
|
|
12224
12224
|
redirect(location, pushLocation) {
|
|
12225
|
-
return this.sendEmpty(302, { "Location": location });
|
|
12225
|
+
return this.sendEmpty(302, { "Location": this.config.pathPrefix + location });
|
|
12226
12226
|
}
|
|
12227
12227
|
sendSSE(retryMilliseconds) {
|
|
12228
12228
|
if (retryMilliseconds !== void 0) {
|
|
@@ -12414,7 +12414,12 @@ var init_manager_recipes = __esm({
|
|
|
12414
12414
|
}
|
|
12415
12415
|
}
|
|
12416
12416
|
},
|
|
12417
|
-
where: isAdmin ? void 0 : {
|
|
12417
|
+
where: isAdmin ? void 0 : {
|
|
12418
|
+
OR: [
|
|
12419
|
+
{ recipe_bags: { every: { bag: { OR } } } },
|
|
12420
|
+
{ owner_id: { equals: user_id, not: null } }
|
|
12421
|
+
]
|
|
12422
|
+
}
|
|
12418
12423
|
});
|
|
12419
12424
|
const userListUser = !isAdmin && await prisma.users.findMany({
|
|
12420
12425
|
select: { user_id: true, username: true }
|
|
@@ -12601,7 +12606,7 @@ var init_manager_recipes = __esm({
|
|
|
12601
12606
|
const existing = await prisma.recipes.findUnique({ where: { recipe_name } });
|
|
12602
12607
|
this.assertCreateOrUpdate({ user, type: "recipe", isCreate, owner_id, existing });
|
|
12603
12608
|
const { isAdmin, user_id } = user;
|
|
12604
|
-
const OR = this.checks.getWhereACL({ permission: "ADMIN", user_id });
|
|
12609
|
+
const OR = isAdmin ? void 0 : this.checks.getWhereACL({ permission: "ADMIN", user_id });
|
|
12605
12610
|
const bags = new Map(
|
|
12606
12611
|
await prisma.bags.findMany({
|
|
12607
12612
|
where: { bag_name: { in: bag_names.map((e) => e.bag_name) } }
|
|
@@ -12609,14 +12614,12 @@ var init_manager_recipes = __esm({
|
|
|
12609
12614
|
);
|
|
12610
12615
|
const missing = bag_names.filter((e) => !bags.has(e.bag_name));
|
|
12611
12616
|
if (missing.length) throw "Some bags not found: " + JSON.stringify(missing);
|
|
12612
|
-
const bagsAcl = new Map(
|
|
12613
|
-
|
|
12614
|
-
|
|
12615
|
-
}).then((bags2) => bags2.map((bag) => [bag.bag_name, bag]))
|
|
12616
|
-
);
|
|
12617
|
+
const bagsAcl = new Map((await prisma.bags.findMany({
|
|
12618
|
+
where: { bag_name: { in: bag_names.map((e) => e.bag_name) }, OR }
|
|
12619
|
+
})).map((bag) => [bag.bag_name, bag]));
|
|
12617
12620
|
const createBags = bag_names.map((bag, position) => ({
|
|
12618
12621
|
bag_id: bags.get(bag.bag_name).bag_id,
|
|
12619
|
-
with_acl: bagsAcl
|
|
12622
|
+
with_acl: bagsAcl.has(bag.bag_name) && bag.with_acl,
|
|
12620
12623
|
position
|
|
12621
12624
|
}));
|
|
12622
12625
|
if (existing) {
|
|
@@ -12914,13 +12917,20 @@ var init_TiddlerStore = __esm({
|
|
|
12914
12917
|
init_esm_shims();
|
|
12915
12918
|
init_utils2();
|
|
12916
12919
|
_TiddlerStore = class _TiddlerStore {
|
|
12917
|
-
constructor(
|
|
12918
|
-
this.
|
|
12920
|
+
constructor(fieldModules, attachService, siteConfig, prisma) {
|
|
12921
|
+
this.fieldModules = fieldModules;
|
|
12922
|
+
this.attachService = attachService;
|
|
12923
|
+
this.siteConfig = siteConfig;
|
|
12919
12924
|
this.prisma = prisma;
|
|
12920
|
-
this.
|
|
12921
|
-
|
|
12922
|
-
|
|
12923
|
-
|
|
12925
|
+
this.storePath = this.siteConfig.storePath;
|
|
12926
|
+
}
|
|
12927
|
+
static fromCommander(commander2, prisma) {
|
|
12928
|
+
return new _TiddlerStore(
|
|
12929
|
+
commander2.$tw.Tiddler.fieldModules,
|
|
12930
|
+
new commander2.AttachmentService(commander2.siteConfig, prisma),
|
|
12931
|
+
commander2.siteConfig,
|
|
12932
|
+
prisma
|
|
12933
|
+
);
|
|
12924
12934
|
}
|
|
12925
12935
|
/*
|
|
12926
12936
|
Returns null if a bag/recipe name is valid, or a string error message if not
|
|
@@ -13170,7 +13180,7 @@ var init_TiddlerStore = __esm({
|
|
|
13170
13180
|
const stream = new Readable();
|
|
13171
13181
|
stream._read = () => {
|
|
13172
13182
|
const type = tiddlerInfo.tiddler.type || "text/plain";
|
|
13173
|
-
stream.push(tiddlerInfo.tiddler.text || "", (this.
|
|
13183
|
+
stream.push(tiddlerInfo.tiddler.text || "", (this.siteConfig.contentTypeInfo[type] || { encoding: "utf8" }).encoding);
|
|
13174
13184
|
stream.push(null);
|
|
13175
13185
|
};
|
|
13176
13186
|
return {
|
|
@@ -14093,7 +14103,13 @@ var init_bag_file_server = __esm({
|
|
|
14093
14103
|
import_sjcl = __toESM(require_sjcl(), 1);
|
|
14094
14104
|
_TiddlerServer = class _TiddlerServer extends TiddlerStore {
|
|
14095
14105
|
constructor(state, prisma) {
|
|
14096
|
-
|
|
14106
|
+
const router = state.router;
|
|
14107
|
+
super(
|
|
14108
|
+
router.fieldModules,
|
|
14109
|
+
new router.AttachmentService(router.siteConfig, prisma),
|
|
14110
|
+
router.siteConfig,
|
|
14111
|
+
prisma
|
|
14112
|
+
);
|
|
14097
14113
|
this.state = state;
|
|
14098
14114
|
}
|
|
14099
14115
|
toTiddlyWebJson(info12) {
|
|
@@ -14611,6 +14627,62 @@ var init_router_tiddlers = __esm({
|
|
|
14611
14627
|
}
|
|
14612
14628
|
});
|
|
14613
14629
|
|
|
14630
|
+
// src/routes/tw-test.ts
|
|
14631
|
+
import { TiddlyWiki } from "tiddlywiki";
|
|
14632
|
+
function DocsRoute(parent, config) {
|
|
14633
|
+
const wikiRouter = new TWRouter(config);
|
|
14634
|
+
parent.defineRoute({
|
|
14635
|
+
method: ["OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE"],
|
|
14636
|
+
bodyFormat: "stream",
|
|
14637
|
+
path: /^\/mws(\/|$)/,
|
|
14638
|
+
pathParams: []
|
|
14639
|
+
}, async (state) => {
|
|
14640
|
+
if (state.urlInfo.pathname === "/mws") throw state.redirect("/mws/");
|
|
14641
|
+
const { req, res } = state.streamer;
|
|
14642
|
+
if (req.url === "/mws") req.url = "/mws/";
|
|
14643
|
+
wikiRouter.twserver.requestHandler(req, res, {});
|
|
14644
|
+
return new Promise((r, c) => res.on("finish", r).on("error", c));
|
|
14645
|
+
});
|
|
14646
|
+
}
|
|
14647
|
+
var _TWRouter, TWRouter;
|
|
14648
|
+
var init_tw_test = __esm({
|
|
14649
|
+
"src/routes/tw-test.ts"() {
|
|
14650
|
+
"use strict";
|
|
14651
|
+
init_esm_shims();
|
|
14652
|
+
__name(DocsRoute, "DocsRoute");
|
|
14653
|
+
_TWRouter = class _TWRouter {
|
|
14654
|
+
constructor(config) {
|
|
14655
|
+
this.config = config;
|
|
14656
|
+
this.$tw = TiddlyWiki();
|
|
14657
|
+
this.$tw.boot.argv = [
|
|
14658
|
+
"+plugins/tiddlywiki/tiddlyweb",
|
|
14659
|
+
"+plugins/tiddlywiki/filesystem",
|
|
14660
|
+
"./editions/mws-docs"
|
|
14661
|
+
];
|
|
14662
|
+
this.$tw.preloadTiddler({
|
|
14663
|
+
text: "$protocol$//$host$" + this.config.pathPrefix + "/mws/",
|
|
14664
|
+
title: "$:/config/tiddlyweb/host"
|
|
14665
|
+
});
|
|
14666
|
+
this.$tw.boot.boot(() => {
|
|
14667
|
+
const Server2 = this.$tw.modules.execute("$:/core/modules/server/server.js", "tw-test.ts").Server;
|
|
14668
|
+
this.twserver = new Server2({
|
|
14669
|
+
wiki: this.$tw.wiki,
|
|
14670
|
+
variables: {
|
|
14671
|
+
// do not use a trailing slash
|
|
14672
|
+
"path-prefix": this.config.pathPrefix + "/mws",
|
|
14673
|
+
"root-tiddler": "$:/core/save/all"
|
|
14674
|
+
},
|
|
14675
|
+
routes: []
|
|
14676
|
+
});
|
|
14677
|
+
this.$tw.hooks.invokeHook("th-server-command-post-start", this.twserver, null, "mws");
|
|
14678
|
+
});
|
|
14679
|
+
}
|
|
14680
|
+
};
|
|
14681
|
+
__name(_TWRouter, "TWRouter");
|
|
14682
|
+
TWRouter = _TWRouter;
|
|
14683
|
+
}
|
|
14684
|
+
});
|
|
14685
|
+
|
|
14614
14686
|
// import("./**/*/**/*") in src/routes/index.ts
|
|
14615
14687
|
var globImport;
|
|
14616
14688
|
var init_ = __esm({
|
|
@@ -14627,9 +14699,10 @@ var init_ = __esm({
|
|
|
14627
14699
|
// src/routes/index.ts
|
|
14628
14700
|
import { Prisma } from "@prisma/client";
|
|
14629
14701
|
async function RootRoute(root, config) {
|
|
14702
|
+
if (process.env.ENABLE_DOCS_ROUTE) DocsRoute(root, config);
|
|
14630
14703
|
TiddlerRouter.defineRoutes(root);
|
|
14631
14704
|
ManagerRoutes(root, config);
|
|
14632
|
-
if (
|
|
14705
|
+
if (process.env.ENABLE_UNSAFE_PRISMA_ROUTE)
|
|
14633
14706
|
root.defineRoute({
|
|
14634
14707
|
method: ["POST"],
|
|
14635
14708
|
path: /^\/prisma$/,
|
|
@@ -14686,6 +14759,7 @@ var init_routes = __esm({
|
|
|
14686
14759
|
init_utils2();
|
|
14687
14760
|
init_managers();
|
|
14688
14761
|
init_router_tiddlers();
|
|
14762
|
+
init_tw_test();
|
|
14689
14763
|
init_();
|
|
14690
14764
|
__name(RootRoute, "RootRoute");
|
|
14691
14765
|
__name(importEsbuild, "importEsbuild");
|
|
@@ -14960,15 +15034,16 @@ var init_router = __esm({
|
|
|
14960
15034
|
_Router = class _Router {
|
|
14961
15035
|
constructor(rootRoute2, commander2, tiddlerCache) {
|
|
14962
15036
|
this.rootRoute = rootRoute2;
|
|
14963
|
-
this.commander = commander2;
|
|
14964
15037
|
this.tiddlerCache = tiddlerCache;
|
|
14965
|
-
this.pathPrefix = "";
|
|
14966
15038
|
this.enableBrowserCache = true;
|
|
14967
15039
|
this.enableGzip = false;
|
|
14968
15040
|
this.csrfDisable = false;
|
|
14969
15041
|
this.engine = commander2.engine;
|
|
14970
15042
|
this.SessionManager = commander2.SessionManager;
|
|
14971
|
-
this.
|
|
15043
|
+
this.siteConfig = commander2.siteConfig;
|
|
15044
|
+
this.PasswordService = commander2.PasswordService;
|
|
15045
|
+
this.fieldModules = commander2.$tw.Tiddler.fieldModules;
|
|
15046
|
+
this.AttachmentService = commander2.AttachmentService;
|
|
14972
15047
|
}
|
|
14973
15048
|
static async makeRouter(commander2, enableDevServer) {
|
|
14974
15049
|
const sendDevServer = await setupDevServer(enableDevServer, commander2.siteConfig.pathPrefix);
|
|
@@ -14984,6 +15059,9 @@ var init_router = __esm({
|
|
|
14984
15059
|
const cache = await startupCache(commander2);
|
|
14985
15060
|
return new _Router(rootRoute2, commander2, cache);
|
|
14986
15061
|
}
|
|
15062
|
+
get pathPrefix() {
|
|
15063
|
+
return this.siteConfig.pathPrefix;
|
|
15064
|
+
}
|
|
14987
15065
|
handleIncomingRequest(req, res) {
|
|
14988
15066
|
const [ok8, err, streamer] = function() {
|
|
14989
15067
|
try {
|
|
@@ -15019,7 +15097,7 @@ var init_router = __esm({
|
|
|
15019
15097
|
routePath,
|
|
15020
15098
|
bodyFormat,
|
|
15021
15099
|
authUser,
|
|
15022
|
-
this
|
|
15100
|
+
this,
|
|
15023
15101
|
this.tiddlerCache
|
|
15024
15102
|
)
|
|
15025
15103
|
);
|
|
@@ -15162,10 +15240,10 @@ var init_router = __esm({
|
|
|
15162
15240
|
});
|
|
15163
15241
|
|
|
15164
15242
|
// src/tiddlywiki.ts
|
|
15165
|
-
import { TiddlyWiki } from "tiddlywiki";
|
|
15243
|
+
import { TiddlyWiki as TiddlyWiki2 } from "tiddlywiki";
|
|
15166
15244
|
import { ok as ok5 } from "node:assert";
|
|
15167
15245
|
async function bootTiddlyWiki(wikiPath) {
|
|
15168
|
-
const $tw2 =
|
|
15246
|
+
const $tw2 = TiddlyWiki2();
|
|
15169
15247
|
$tw2.utils.eachAsync = eachAsync;
|
|
15170
15248
|
$tw2.boot.boot = async (callback) => {
|
|
15171
15249
|
$tw2.crypto = new $tw2.utils.Crypto();
|
|
@@ -15197,22 +15275,14 @@ async function bootTiddlyWiki(wikiPath) {
|
|
|
15197
15275
|
startup: /* @__PURE__ */ __name(() => {
|
|
15198
15276
|
}, "startup")
|
|
15199
15277
|
});
|
|
15200
|
-
$tw2.preloadTiddler({ title: "$:/plugins/tiddlywiki/multiwikiserver/startup.js" });
|
|
15201
|
-
$tw2.modules.define("$:/plugins/tiddlywiki/multiwikiserver/startup.js", "startup", {
|
|
15202
|
-
name: "multiwikiserver",
|
|
15203
|
-
platforms: ["node"],
|
|
15204
|
-
after: ["load-modules"],
|
|
15205
|
-
before: ["story", "commands"],
|
|
15206
|
-
synchronous: true,
|
|
15207
|
-
startup: /* @__PURE__ */ __name(() => {
|
|
15208
|
-
}, "startup")
|
|
15209
|
-
});
|
|
15210
15278
|
$tw2.boot.argv = [
|
|
15211
15279
|
"++" + dist_resolve("../plugins/client"),
|
|
15212
15280
|
"+plugins/tiddlywiki/tiddlyweb",
|
|
15281
|
+
// these are sane defaults, these should be in the recipe
|
|
15213
15282
|
"+themes/tiddlywiki/vanilla",
|
|
15214
15283
|
"+themes/tiddlywiki/snowwhite",
|
|
15215
15284
|
wikiPath
|
|
15285
|
+
// this should be inert
|
|
15216
15286
|
];
|
|
15217
15287
|
await new Promise((resolve13) => $tw2.boot.boot(resolve13));
|
|
15218
15288
|
ok5(!$tw2.boot.tasks.readBrowserTiddlers);
|
|
@@ -19004,7 +19074,7 @@ var init_load_plugin_bags = __esm({
|
|
|
19004
19074
|
console.time(`${info.name} complete`);
|
|
19005
19075
|
await loadPluginBags(
|
|
19006
19076
|
this.$tw,
|
|
19007
|
-
|
|
19077
|
+
TiddlerStore.fromCommander(this.commander, this.commander.engine),
|
|
19008
19078
|
this.commander.engine
|
|
19009
19079
|
);
|
|
19010
19080
|
console.timeEnd(`${info.name} complete`);
|
|
@@ -19160,7 +19230,7 @@ var init_load_wiki_folder = __esm({
|
|
|
19160
19230
|
bagDescription: this.params[2],
|
|
19161
19231
|
recipeName: this.params[3],
|
|
19162
19232
|
recipeDescription: this.params[4],
|
|
19163
|
-
store:
|
|
19233
|
+
store: TiddlerStore.fromCommander(this.commander, this.commander.engine),
|
|
19164
19234
|
$tw: this.commander.$tw
|
|
19165
19235
|
}));
|
|
19166
19236
|
console.log(info3.name, "complete:", this.params[0]);
|
|
@@ -19213,7 +19283,7 @@ var init_save_archive = __esm({
|
|
|
19213
19283
|
async execute() {
|
|
19214
19284
|
if (this.params.length < 1) throw "Missing pathname";
|
|
19215
19285
|
await this.commander.$transaction(async (prisma) => {
|
|
19216
|
-
this.store =
|
|
19286
|
+
this.store = TiddlerStore.fromCommander(this.commander, prisma);
|
|
19217
19287
|
await this.saveArchive();
|
|
19218
19288
|
this.store = void 0;
|
|
19219
19289
|
});
|
|
@@ -20012,6 +20082,7 @@ var init_commander = __esm({
|
|
|
20012
20082
|
this.PasswordService = PasswordService;
|
|
20013
20083
|
/** Signals that database setup is required. May be set to false by any qualified setup command. */
|
|
20014
20084
|
this.setupRequired = true;
|
|
20085
|
+
this.fieldModules = $tw2.Tiddler.fieldModules;
|
|
20015
20086
|
if (config.config?.pathPrefix) {
|
|
20016
20087
|
ok7(config.config.pathPrefix.startsWith("/"), "pathPrefix must start with a slash");
|
|
20017
20088
|
ok7(!config.config.pathPrefix.endsWith("/"), "pathPrefix must not end with a slash");
|
|
@@ -20067,7 +20138,6 @@ var init_commander = __esm({
|
|
|
20067
20138
|
config.listeners = [];
|
|
20068
20139
|
config.onListenersCreated = void 0;
|
|
20069
20140
|
this.create_mws_listen = (params) => {
|
|
20070
|
-
console.log(listeners);
|
|
20071
20141
|
return new listen_exports.Command(params, this, listeners, onListenersCreated);
|
|
20072
20142
|
};
|
|
20073
20143
|
}
|
|
@@ -20168,7 +20238,6 @@ var init_commander = __esm({
|
|
|
20168
20238
|
this.callback(params);
|
|
20169
20239
|
return;
|
|
20170
20240
|
}
|
|
20171
|
-
console.log(params);
|
|
20172
20241
|
new Promise(async (resolve13) => {
|
|
20173
20242
|
const { Command: Command13, info: info12 } = command;
|
|
20174
20243
|
try {
|