@tiddlywiki/mws 0.0.20 → 0.0.21
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 +4 -0
- package/dist/server.d.ts +9 -0
- package/dist/server.js +177 -63
- package/dist/server.js.map +1 -1
- package/editions/mws-docs/tiddlers/$__StoryList.tid +2 -1
- package/package.json +1 -1
- package/react-user-mgmt/public/main.js +25 -25
- package/react-user-mgmt/public/main.js.map +4 -4
- package/react-user-mgmt/public/stats.json +1 -1
- package/scripts.mjs +2 -2
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# MultiWikiServer
|
|
2
2
|
|
|
3
|
+
**This is not ready for primetime. Do not use it to protect feelings or intellectual property.**
|
|
4
|
+
|
|
5
|
+
*You really shouldn't be using it to store anything important yet. It is still in the VERY early stages of development and we don't even have proper tests verifying the security mechanisms yet. So please try it out, kick the tires, import your multi-gigabyte wikis and play around with it, but don't actually store anything you want to keep. We'll hopefully get there soon, but even the database schema itself is still in flux as we figure out what the best layout is for all the stuff we have planned.*
|
|
6
|
+
|
|
3
7
|
Multiple users, multiple wikis for TiddlyWiki.
|
|
4
8
|
|
|
5
9
|
- Bag & Recipe system for storing tiddlers.
|
package/dist/server.d.ts
CHANGED
|
@@ -228,6 +228,10 @@ declare class StartupCommander {
|
|
|
228
228
|
$tw: TW;
|
|
229
229
|
PasswordService: PasswordService;
|
|
230
230
|
fieldModules: Record<string, TiddlerFieldModule>;
|
|
231
|
+
versions: {
|
|
232
|
+
tiddlywiki: any;
|
|
233
|
+
mws: string;
|
|
234
|
+
};
|
|
231
235
|
constructor(config: MWSConfig, $tw: TW, PasswordService: PasswordService);
|
|
232
236
|
init(): Promise<void>;
|
|
233
237
|
wikiPath: string;
|
|
@@ -333,6 +337,7 @@ declare class StateObject<B extends BodyFormat = BodyFormat, M extends AllowedMe
|
|
|
333
337
|
private engine;
|
|
334
338
|
config: SiteConfig;
|
|
335
339
|
PasswordService: PasswordService;
|
|
340
|
+
get pathPrefix(): string;
|
|
336
341
|
constructor(streamer: Streamer,
|
|
337
342
|
/** The array of Route tree nodes the request matched. */
|
|
338
343
|
routePath: RouteMatch[],
|
|
@@ -798,6 +803,10 @@ declare class Router {
|
|
|
798
803
|
engine: Commander["engine"];
|
|
799
804
|
private SessionManager;
|
|
800
805
|
PasswordService: Commander["PasswordService"];
|
|
806
|
+
versions: {
|
|
807
|
+
tiddlywiki: any;
|
|
808
|
+
mws: string;
|
|
809
|
+
};
|
|
801
810
|
fieldModules: Commander["$tw"]["Tiddler"]["fieldModules"];
|
|
802
811
|
AttachmentService: Commander["AttachmentService"];
|
|
803
812
|
constructor(rootRoute: rootRoute$1, commander: Commander, tiddlerCache: CacheState);
|
package/dist/server.js
CHANGED
|
@@ -1621,7 +1621,7 @@ var require_destroy = __commonJS({
|
|
|
1621
1621
|
"node_modules/destroy/index.js"(exports, module2) {
|
|
1622
1622
|
"use strict";
|
|
1623
1623
|
init_esm_shims();
|
|
1624
|
-
var
|
|
1624
|
+
var EventEmitter2 = __require("events").EventEmitter;
|
|
1625
1625
|
var ReadStream = __require("fs").ReadStream;
|
|
1626
1626
|
var Stream = __require("stream");
|
|
1627
1627
|
var Zlib = __require("zlib");
|
|
@@ -1688,7 +1688,7 @@ var require_destroy = __commonJS({
|
|
|
1688
1688
|
}
|
|
1689
1689
|
__name(hasDestroy, "hasDestroy");
|
|
1690
1690
|
function isEventEmitter(val) {
|
|
1691
|
-
return val instanceof
|
|
1691
|
+
return val instanceof EventEmitter2;
|
|
1692
1692
|
}
|
|
1693
1693
|
__name(isEventEmitter, "isEventEmitter");
|
|
1694
1694
|
function isFsReadStream(stream) {
|
|
@@ -11569,7 +11569,8 @@ var init_data_checks = __esm({
|
|
|
11569
11569
|
init_esm_shims();
|
|
11570
11570
|
init_utils();
|
|
11571
11571
|
_DataChecks = class _DataChecks {
|
|
11572
|
-
constructor(
|
|
11572
|
+
constructor(config) {
|
|
11573
|
+
this.config = config;
|
|
11573
11574
|
this.isPermissionName = /* @__PURE__ */ __name((e) => {
|
|
11574
11575
|
const test2 = e;
|
|
11575
11576
|
switch (test2) {
|
|
@@ -11586,8 +11587,6 @@ var init_data_checks = __esm({
|
|
|
11586
11587
|
this.permissions = { READ: "READ", WRITE: "WRITE", ADMIN: "ADMIN" };
|
|
11587
11588
|
this.isEntityType = /* @__PURE__ */ __name((x) => ["recipe", "bag"].includes(x), "isEntityType");
|
|
11588
11589
|
this.entityTypes = { recipe: "recipe", bag: "bag" };
|
|
11589
|
-
this.allowAnonReads = options.allowAnonReads;
|
|
11590
|
-
this.allowAnonWrites = options.allowAnonWrites;
|
|
11591
11590
|
}
|
|
11592
11591
|
okTiddlerFields(tiddlerFields) {
|
|
11593
11592
|
ok2(tiddlerFields.title, "title must not be empty");
|
|
@@ -11648,17 +11647,11 @@ var init_data_checks = __esm({
|
|
|
11648
11647
|
].filter(truthy);
|
|
11649
11648
|
}
|
|
11650
11649
|
getWhereACL({ permission, user_id, role_ids }) {
|
|
11651
|
-
const { allowAnonReads, allowAnonWrites } = this;
|
|
11652
|
-
const anonRead = allowAnonReads && permission === "READ";
|
|
11653
|
-
const anonWrite = allowAnonWrites && permission === "WRITE";
|
|
11654
|
-
const allowAnon = anonRead || anonWrite;
|
|
11655
11650
|
const allperms = ["READ", "WRITE", "ADMIN"];
|
|
11656
11651
|
const index = allperms.indexOf(permission);
|
|
11657
11652
|
if (index === -1) throw new Error("Invalid permission");
|
|
11658
11653
|
const checkPerms = allperms.slice(index);
|
|
11659
11654
|
return [
|
|
11660
|
-
// allow unowned for any user (conditional for anon reads)
|
|
11661
|
-
(user_id || allowAnon) && { acl: { none: {} }, owner_id: null },
|
|
11662
11655
|
// allow owner for user
|
|
11663
11656
|
user_id && { owner_id: { equals: user_id, not: null } },
|
|
11664
11657
|
// allow acl for user
|
|
@@ -11669,7 +11662,9 @@ var init_data_checks = __esm({
|
|
|
11669
11662
|
role_id: { in: role_ids }
|
|
11670
11663
|
}
|
|
11671
11664
|
}
|
|
11672
|
-
}
|
|
11665
|
+
},
|
|
11666
|
+
{ owner_id: { equals: null, not: null } }
|
|
11667
|
+
// dud to make sure that at least one condition exists
|
|
11673
11668
|
].filter(truthy);
|
|
11674
11669
|
}
|
|
11675
11670
|
};
|
|
@@ -11814,8 +11809,9 @@ var init_streamer = __esm({
|
|
|
11814
11809
|
if (error === STREAM_ENDED) return;
|
|
11815
11810
|
const tag = this.urlInfo.href;
|
|
11816
11811
|
console.error(tag, error);
|
|
11817
|
-
if (!this.headersSent)
|
|
11812
|
+
if (!this.headersSent) {
|
|
11818
11813
|
this.sendEmpty(500, { "x-reason": "Internal Server Error (catcher)" });
|
|
11814
|
+
}
|
|
11819
11815
|
}, "catcher");
|
|
11820
11816
|
this.readBody = /* @__PURE__ */ __name(() => new Promise((resolve13) => {
|
|
11821
11817
|
const chunks = [];
|
|
@@ -12178,6 +12174,9 @@ var init_StateObject = __esm({
|
|
|
12178
12174
|
get method() {
|
|
12179
12175
|
return super.method;
|
|
12180
12176
|
}
|
|
12177
|
+
get pathPrefix() {
|
|
12178
|
+
return this.config.pathPrefix;
|
|
12179
|
+
}
|
|
12181
12180
|
okUser() {
|
|
12182
12181
|
if (!this.user.isLoggedIn) throw "User not authenticated";
|
|
12183
12182
|
}
|
|
@@ -12406,8 +12405,8 @@ var init_manager_recipes = __esm({
|
|
|
12406
12405
|
where: isAdmin ? void 0 : {
|
|
12407
12406
|
OR: [
|
|
12408
12407
|
{ recipe_bags: { every: { bag: { OR } } } },
|
|
12409
|
-
{ owner_id: { equals: user_id, not: null } }
|
|
12410
|
-
]
|
|
12408
|
+
user_id && { owner_id: { equals: user_id, not: null } }
|
|
12409
|
+
].filter((e) => e)
|
|
12411
12410
|
}
|
|
12412
12411
|
});
|
|
12413
12412
|
const userListUser = !isAdmin && await prisma.users.findMany({
|
|
@@ -12428,7 +12427,8 @@ var init_manager_recipes = __esm({
|
|
|
12428
12427
|
username,
|
|
12429
12428
|
isLoggedIn: state.user.isLoggedIn,
|
|
12430
12429
|
allowAnonReads: state.config.allowAnonReads,
|
|
12431
|
-
allowAnonWrites: state.config.allowAnonWrites
|
|
12430
|
+
allowAnonWrites: state.config.allowAnonWrites,
|
|
12431
|
+
versions: state.router.versions
|
|
12432
12432
|
};
|
|
12433
12433
|
});
|
|
12434
12434
|
this.recipe_create = zodManage((z5) => z5.object({
|
|
@@ -12585,8 +12585,7 @@ var init_manager_recipes = __esm({
|
|
|
12585
12585
|
});
|
|
12586
12586
|
return null;
|
|
12587
12587
|
});
|
|
12588
|
-
|
|
12589
|
-
this.checks = new DataChecks({ allowAnonReads, allowAnonWrites });
|
|
12588
|
+
this.checks = new DataChecks(config);
|
|
12590
12589
|
}
|
|
12591
12590
|
static defineRoutes(root, config) {
|
|
12592
12591
|
registerZodRoutes(root, new _RecipeManager(config), Object.keys(RecipeKeyMap));
|
|
@@ -13190,13 +13189,15 @@ var init_TiddlerStore = __esm({
|
|
|
13190
13189
|
recipe_bags: {
|
|
13191
13190
|
// we're saving to the top most bag
|
|
13192
13191
|
where: { position: 0 },
|
|
13193
|
-
select: { bag: { select: { bag_id: true, bag_name: true } } }
|
|
13192
|
+
select: { bag: { select: { bag_id: true, bag_name: true, is_plugin: true } } }
|
|
13194
13193
|
}
|
|
13195
13194
|
}
|
|
13196
13195
|
});
|
|
13197
13196
|
if (!recipe) throw new UserError("Recipe not found");
|
|
13198
13197
|
const bag_name = recipe.recipe_bags[0]?.bag.bag_name;
|
|
13199
13198
|
if (!bag_name) throw new UserError("Recipe has no bag at position 0");
|
|
13199
|
+
if (recipe.recipe_bags[0]?.bag.is_plugin)
|
|
13200
|
+
throw new UserError("Saving to plugin bags is not currently supported. Please use a normal bag. This error occurs if a plugin bag is at the top of the recipe.\n");
|
|
13200
13201
|
var { tiddler_id } = await this.saveBagTiddlerFields(tiddlerFields, bag_name, attachment_hash);
|
|
13201
13202
|
return { tiddler_id, bag_name };
|
|
13202
13203
|
}
|
|
@@ -14676,58 +14677,62 @@ var init_router_tiddlers = __esm({
|
|
|
14676
14677
|
|
|
14677
14678
|
// src/routes/tw-routes.ts
|
|
14678
14679
|
import { TiddlyWiki } from "tiddlywiki";
|
|
14679
|
-
|
|
14680
|
-
|
|
14681
|
-
|
|
14682
|
-
|
|
14680
|
+
import { basename } from "path";
|
|
14681
|
+
import EventEmitter from "events";
|
|
14682
|
+
function DocsRoute(rootRoute2, mountPath, singleFile) {
|
|
14683
|
+
const $tw2 = TiddlyWiki();
|
|
14684
|
+
const last = basename(mountPath);
|
|
14685
|
+
$tw2.preloadTiddler({
|
|
14686
|
+
title: "$:/config/tiddlyweb/host",
|
|
14687
|
+
// if the page url doesn't end with a slash, we have to include the basename here
|
|
14688
|
+
text: singleFile ? last + "/" : ""
|
|
14689
|
+
});
|
|
14690
|
+
$tw2.boot.argv = [
|
|
14691
|
+
"+plugins/tiddlywiki/tiddlyweb",
|
|
14692
|
+
"+plugins/tiddlywiki/filesystem",
|
|
14693
|
+
// relative to the cwd
|
|
14694
|
+
"./editions/mws-docs"
|
|
14695
|
+
];
|
|
14696
|
+
const hooks = new EventEmitter();
|
|
14697
|
+
$tw2.boot.boot(() => {
|
|
14698
|
+
const Server2 = $tw2.modules.execute("$:/core/modules/server/server.js", "tw-test.ts").Server;
|
|
14699
|
+
const twserver = new Server2({
|
|
14700
|
+
wiki: $tw2.wiki,
|
|
14701
|
+
variables: {
|
|
14702
|
+
// path prefix gets set per-request
|
|
14703
|
+
"path-prefix": "",
|
|
14704
|
+
"root-tiddler": "$:/core/save/all"
|
|
14705
|
+
},
|
|
14706
|
+
routes: []
|
|
14707
|
+
});
|
|
14708
|
+
$tw2.hooks.invokeHook("th-server-command-post-start", twserver, null, "mws");
|
|
14709
|
+
hooks.on("req", (req, res, pathPrefix) => {
|
|
14710
|
+
twserver.requestHandler(req, res, { pathPrefix });
|
|
14711
|
+
});
|
|
14712
|
+
});
|
|
14713
|
+
rootRoute2.defineRoute({
|
|
14683
14714
|
method: ["OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE"],
|
|
14684
14715
|
bodyFormat: "stream",
|
|
14685
|
-
path:
|
|
14716
|
+
path: new RegExp("^" + mountPath + "(/|$)"),
|
|
14686
14717
|
pathParams: []
|
|
14687
14718
|
}, async (state) => {
|
|
14688
|
-
if (state.urlInfo.pathname ===
|
|
14719
|
+
if (singleFile && state.urlInfo.pathname === mountPath + "/")
|
|
14720
|
+
throw state.redirect(mountPath);
|
|
14721
|
+
if (!singleFile && state.urlInfo.pathname === mountPath)
|
|
14722
|
+
throw state.redirect(mountPath + "/");
|
|
14689
14723
|
const { req, res } = state.streamer;
|
|
14690
|
-
if (req.url ===
|
|
14691
|
-
|
|
14692
|
-
|
|
14724
|
+
if (req.url === state.pathPrefix + mountPath)
|
|
14725
|
+
req.url = state.pathPrefix + mountPath + "/";
|
|
14726
|
+
const prom = new Promise((r, c) => res.on("finish", r).on("error", c));
|
|
14727
|
+
hooks.emit("req", req, res, state.pathPrefix + mountPath);
|
|
14728
|
+
return prom;
|
|
14693
14729
|
});
|
|
14694
14730
|
}
|
|
14695
|
-
var _TWRouter, TWRouter;
|
|
14696
14731
|
var init_tw_routes = __esm({
|
|
14697
14732
|
"src/routes/tw-routes.ts"() {
|
|
14698
14733
|
"use strict";
|
|
14699
14734
|
init_esm_shims();
|
|
14700
14735
|
__name(DocsRoute, "DocsRoute");
|
|
14701
|
-
_TWRouter = class _TWRouter {
|
|
14702
|
-
constructor(config) {
|
|
14703
|
-
this.config = config;
|
|
14704
|
-
this.$tw = TiddlyWiki();
|
|
14705
|
-
this.$tw.boot.argv = [
|
|
14706
|
-
"+plugins/tiddlywiki/tiddlyweb",
|
|
14707
|
-
"+plugins/tiddlywiki/filesystem",
|
|
14708
|
-
"./editions/mws-docs"
|
|
14709
|
-
];
|
|
14710
|
-
this.$tw.preloadTiddler({
|
|
14711
|
-
text: "$protocol$//$host$" + this.config.pathPrefix + "/mws/",
|
|
14712
|
-
title: "$:/config/tiddlyweb/host"
|
|
14713
|
-
});
|
|
14714
|
-
this.$tw.boot.boot(() => {
|
|
14715
|
-
const Server2 = this.$tw.modules.execute("$:/core/modules/server/server.js", "tw-test.ts").Server;
|
|
14716
|
-
this.twserver = new Server2({
|
|
14717
|
-
wiki: this.$tw.wiki,
|
|
14718
|
-
variables: {
|
|
14719
|
-
// do not use a trailing slash
|
|
14720
|
-
"path-prefix": this.config.pathPrefix + "/mws",
|
|
14721
|
-
"root-tiddler": "$:/core/save/all"
|
|
14722
|
-
},
|
|
14723
|
-
routes: []
|
|
14724
|
-
});
|
|
14725
|
-
this.$tw.hooks.invokeHook("th-server-command-post-start", this.twserver, null, "mws");
|
|
14726
|
-
});
|
|
14727
|
-
}
|
|
14728
|
-
};
|
|
14729
|
-
__name(_TWRouter, "TWRouter");
|
|
14730
|
-
TWRouter = _TWRouter;
|
|
14731
14736
|
}
|
|
14732
14737
|
});
|
|
14733
14738
|
|
|
@@ -14747,7 +14752,7 @@ var init_ = __esm({
|
|
|
14747
14752
|
// src/routes/index.ts
|
|
14748
14753
|
import { Prisma } from "@prisma/client";
|
|
14749
14754
|
async function RootRoute(root, config) {
|
|
14750
|
-
if (process.env.ENABLE_DOCS_ROUTE) DocsRoute(root,
|
|
14755
|
+
if (process.env.ENABLE_DOCS_ROUTE) DocsRoute(root, "/mws-docs", false);
|
|
14751
14756
|
TiddlerRouter.defineRoutes(root);
|
|
14752
14757
|
ManagerRoutes(root, config);
|
|
14753
14758
|
if (process.env.ENABLE_UNSAFE_PRISMA_ROUTE)
|
|
@@ -14995,7 +15000,6 @@ import * as path3 from "path";
|
|
|
14995
15000
|
import * as crypto from "crypto";
|
|
14996
15001
|
async function startupCache(rootRoute2, commander2) {
|
|
14997
15002
|
const $tw2 = commander2.$tw;
|
|
14998
|
-
console.log(commander2.siteConfig.enablePluginCache);
|
|
14999
15003
|
const { tiddlerFiles, tiddlerHashes } = commander2.siteConfig.enablePluginCache ? await importTW5(path3.join($tw2.boot.corePath, ".."), commander2.cachePath, "client", $tw2) : { tiddlerFiles: /* @__PURE__ */ new Map(), tiddlerHashes: /* @__PURE__ */ new Map() };
|
|
15000
15004
|
rootRoute2.defineRoute({
|
|
15001
15005
|
method: ["GET", "HEAD"],
|
|
@@ -15151,6 +15155,7 @@ var init_router = __esm({
|
|
|
15151
15155
|
this.PasswordService = commander2.PasswordService;
|
|
15152
15156
|
this.fieldModules = commander2.$tw.Tiddler.fieldModules;
|
|
15153
15157
|
this.AttachmentService = commander2.AttachmentService;
|
|
15158
|
+
this.versions = commander2.versions;
|
|
15154
15159
|
}
|
|
15155
15160
|
static async makeRouter(commander2, enableDevServer) {
|
|
15156
15161
|
const sendDevServer = await setupDevServer(enableDevServer, commander2.siteConfig.pathPrefix);
|
|
@@ -15332,8 +15337,10 @@ var init_router = __esm({
|
|
|
15332
15337
|
if (error === STREAM_ENDED) {
|
|
15333
15338
|
return error;
|
|
15334
15339
|
} else if (typeof error === "string") {
|
|
15340
|
+
console.log(error);
|
|
15335
15341
|
return state.sendString(400, { "x-reason": "zod-handler" }, error, "utf8");
|
|
15336
15342
|
} else if (error instanceof Error && error.name === "UserError") {
|
|
15343
|
+
console.log(error.stack);
|
|
15337
15344
|
return state.sendString(400, { "x-reason": "user-error" }, error.message, "utf8");
|
|
15338
15345
|
} else {
|
|
15339
15346
|
throw error;
|
|
@@ -16878,7 +16885,7 @@ var require_command = __commonJS({
|
|
|
16878
16885
|
"node_modules/commander/lib/command.js"(exports) {
|
|
16879
16886
|
"use strict";
|
|
16880
16887
|
init_esm_shims();
|
|
16881
|
-
var
|
|
16888
|
+
var EventEmitter2 = __require("node:events").EventEmitter;
|
|
16882
16889
|
var childProcess = __require("node:child_process");
|
|
16883
16890
|
var path6 = __require("node:path");
|
|
16884
16891
|
var fs4 = __require("node:fs");
|
|
@@ -16888,7 +16895,7 @@ var require_command = __commonJS({
|
|
|
16888
16895
|
var { Help: Help2, stripColor } = require_help();
|
|
16889
16896
|
var { Option: Option2, DualOptions } = require_option();
|
|
16890
16897
|
var { suggestSimilar } = require_suggestSimilar();
|
|
16891
|
-
var _Command12 = class _Command12 extends
|
|
16898
|
+
var _Command12 = class _Command12 extends EventEmitter2 {
|
|
16892
16899
|
/**
|
|
16893
16900
|
* Initialize a new `Command`.
|
|
16894
16901
|
*
|
|
@@ -20134,6 +20141,23 @@ var init_sqlite_adapter = __esm({
|
|
|
20134
20141
|
argTypes: []
|
|
20135
20142
|
}).then((e) => e.rows.map((e2) => e2[0]))
|
|
20136
20143
|
);
|
|
20144
|
+
if (applied_migrations.size && !applied_migrations.has("20250406213424_init")) {
|
|
20145
|
+
console.log("Unknown migrations have been found in the database.");
|
|
20146
|
+
console.log("There is no way to guarentee the integrity of the database under these conditions.");
|
|
20147
|
+
console.log("The only way I know of that you could be seeing this message is if you installed this verion of MWS in a project either from the PR branch or from a newer version of MWS.");
|
|
20148
|
+
console.log("Please revert back to the version you had installed before.");
|
|
20149
|
+
console.log("The sqlite database can be opened manually with any third-party SQLite tool to retrieve your data. If you do this, make sure you keep all the files in the store folder together, as they are all an integral part of your sqlite database and deleting any of them manually is very likely to cause data loss.");
|
|
20150
|
+
process.exit();
|
|
20151
|
+
} else {
|
|
20152
|
+
console.log([
|
|
20153
|
+
"=======================================================================================",
|
|
20154
|
+
"This version of MWS is no longer supported. It is an alpha version",
|
|
20155
|
+
"and you shouldn't be using it in production anyway. Please export any",
|
|
20156
|
+
"wikis you want to keep by opening them and downloading them as single-file",
|
|
20157
|
+
"wikis by clicking on the cloud status icon and then 'save snapshot for offline use'.",
|
|
20158
|
+
"======================================================================================="
|
|
20159
|
+
].join("\n"));
|
|
20160
|
+
}
|
|
20137
20161
|
const migrations = await readdir(dist_resolve("../prisma/migrations"));
|
|
20138
20162
|
migrations.sort();
|
|
20139
20163
|
const new_migrations = migrations.filter((m) => !applied_migrations.has(m) && m !== "migration_lock.toml");
|
|
@@ -20168,6 +20192,78 @@ var init_sqlite_adapter = __esm({
|
|
|
20168
20192
|
}
|
|
20169
20193
|
});
|
|
20170
20194
|
|
|
20195
|
+
// package.json
|
|
20196
|
+
var package_default;
|
|
20197
|
+
var init_package = __esm({
|
|
20198
|
+
"package.json"() {
|
|
20199
|
+
package_default = {
|
|
20200
|
+
name: "@tiddlywiki/mws",
|
|
20201
|
+
description: "TiddlyWiki Multiple Wiki Server",
|
|
20202
|
+
private: false,
|
|
20203
|
+
version: "0.0.21",
|
|
20204
|
+
type: "module",
|
|
20205
|
+
exports: {
|
|
20206
|
+
types: "./src/server.ts",
|
|
20207
|
+
require: "./dist/server.cjs",
|
|
20208
|
+
import: "./dist/server.js"
|
|
20209
|
+
},
|
|
20210
|
+
files: [
|
|
20211
|
+
"dist",
|
|
20212
|
+
"prisma",
|
|
20213
|
+
"react-user-mgmt",
|
|
20214
|
+
"tiddlywiki-types",
|
|
20215
|
+
"editions/mws-docs",
|
|
20216
|
+
"plugins/client",
|
|
20217
|
+
"scripts.mjs"
|
|
20218
|
+
],
|
|
20219
|
+
engines: {
|
|
20220
|
+
node: ">=18"
|
|
20221
|
+
},
|
|
20222
|
+
scripts: {
|
|
20223
|
+
docs: "node scripts.mjs docs",
|
|
20224
|
+
start: "node scripts.mjs start",
|
|
20225
|
+
certs: "(cd runtime-config && bash localhost_certs.sh)",
|
|
20226
|
+
tsc: "tsc -p tsconfig.json --skipLibCheck",
|
|
20227
|
+
build: "npm run tsc && tsup && node mws.dev.mjs --client-build",
|
|
20228
|
+
"install-android": `GYP_DEFINES="android_ndk_path=''" npm install`,
|
|
20229
|
+
postinstall: "node scripts.mjs prisma:generate",
|
|
20230
|
+
env: "env",
|
|
20231
|
+
"test:pack": "(git clean -dfx tests && npm pack --pack-destination tests && cd tests && npm install && npm install ./tiddlywiki-mws-$npm_package_version.tgz --no-save && npm test)",
|
|
20232
|
+
test: "(git clean -dfx tests && cd tests && npm install .. --no-save && npm test)",
|
|
20233
|
+
fulltest: "mv node_modules node_modules_old; npm run test:pack; mv node_modules_old node_modules",
|
|
20234
|
+
prepublishOnly: "npm run build"
|
|
20235
|
+
},
|
|
20236
|
+
dependencies: {
|
|
20237
|
+
"@prisma/adapter-better-sqlite3": "6.7.0-dev.48",
|
|
20238
|
+
"@prisma/client": "6.6.0",
|
|
20239
|
+
"@serenity-kit/opaque": "^0.8.4",
|
|
20240
|
+
"@types/mime-types": "^2.1.4",
|
|
20241
|
+
"@types/node": "^22.13.1",
|
|
20242
|
+
"@types/send": "^0.17.4",
|
|
20243
|
+
"@types/sjcl": "^1.0.34",
|
|
20244
|
+
"@types/tiddlywiki": "file:tiddlywiki-types",
|
|
20245
|
+
prisma: "6.6.0",
|
|
20246
|
+
"source-map-support": "^0.5.21",
|
|
20247
|
+
zod: "^3.24.2"
|
|
20248
|
+
},
|
|
20249
|
+
devDependencies: {
|
|
20250
|
+
commander: "^13.1.0",
|
|
20251
|
+
esbuild: "0.25.2",
|
|
20252
|
+
"mime-types": "^2.1.35",
|
|
20253
|
+
send: "^1.1.0",
|
|
20254
|
+
sjcl: "^1.0.8",
|
|
20255
|
+
tiddlywiki: "^5.1.22",
|
|
20256
|
+
tsup: "^8.4.0",
|
|
20257
|
+
typescript: "^5.7.3",
|
|
20258
|
+
uuid: "^11.1.0"
|
|
20259
|
+
},
|
|
20260
|
+
peerDependencies: {
|
|
20261
|
+
tiddlywiki: "^5.1.22"
|
|
20262
|
+
}
|
|
20263
|
+
};
|
|
20264
|
+
}
|
|
20265
|
+
});
|
|
20266
|
+
|
|
20171
20267
|
// src/commander.ts
|
|
20172
20268
|
import * as path5 from "node:path";
|
|
20173
20269
|
import { PrismaClient as PrismaClient2 } from "@prisma/client";
|
|
@@ -20184,6 +20280,7 @@ var init_commander = __esm({
|
|
|
20184
20280
|
init_esm();
|
|
20185
20281
|
init_commands();
|
|
20186
20282
|
init_sqlite_adapter();
|
|
20283
|
+
init_package();
|
|
20187
20284
|
_StartupCommander = class _StartupCommander {
|
|
20188
20285
|
constructor(config, $tw2, PasswordService) {
|
|
20189
20286
|
this.config = config;
|
|
@@ -20224,6 +20321,10 @@ var init_commander = __esm({
|
|
|
20224
20321
|
this.AttachmentService = config.AttachmentService || AttachmentService;
|
|
20225
20322
|
this.adapter = new SqliteAdapter(this.databasePath);
|
|
20226
20323
|
this.engine = new PrismaClient2({ log: ["info", "warn"], adapter: this.adapter.adapter });
|
|
20324
|
+
this.versions = {
|
|
20325
|
+
tiddlywiki: $tw2.packageInfo.version,
|
|
20326
|
+
mws: package_default.version
|
|
20327
|
+
};
|
|
20227
20328
|
}
|
|
20228
20329
|
async init() {
|
|
20229
20330
|
await this.adapter.init();
|
|
@@ -20231,6 +20332,19 @@ var init_commander = __esm({
|
|
|
20231
20332
|
const users = await this.engine.users.count();
|
|
20232
20333
|
if (!users) {
|
|
20233
20334
|
this.setupRequired = true;
|
|
20335
|
+
} else {
|
|
20336
|
+
const checkBags = await this.engine.bags.findMany({
|
|
20337
|
+
where: { bag_name: { startsWith: "$:/" } },
|
|
20338
|
+
select: { bag_name: true, tiddlers: { select: { title: true } } }
|
|
20339
|
+
});
|
|
20340
|
+
checkBags.forEach((e) => {
|
|
20341
|
+
e.tiddlers.forEach((f) => {
|
|
20342
|
+
if (f.title !== e.bag_name) {
|
|
20343
|
+
if (e.bag_name === "$:/plugins/tiddlywiki/codemirror-fullscreen-editing" && f.title === "$:/plugins/tiddlywiki/codemirror-fullscreen") return;
|
|
20344
|
+
console.log(`The bag ${e.bag_name} has a tiddler ${f.title}, in the future this will be unsupported. This can occur if the top bag in a recipe is one of the system bags (starting with $:/)`);
|
|
20345
|
+
}
|
|
20346
|
+
});
|
|
20347
|
+
});
|
|
20234
20348
|
}
|
|
20235
20349
|
}
|
|
20236
20350
|
$transaction(fn, options) {
|