@tiddlywiki/mws 0.0.18 → 0.0.19

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/dist/server.js CHANGED
@@ -15,10 +15,10 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
15
15
  if (typeof require !== "undefined") return require.apply(this, arguments);
16
16
  throw Error('Dynamic require of "' + x + '" is not supported');
17
17
  });
18
- var __glob = (map) => (path5) => {
19
- var fn = map[path5];
18
+ var __glob = (map) => (path6) => {
19
+ var fn = map[path6];
20
20
  if (fn) return fn();
21
- throw new Error("Module not found in bundle: " + path5);
21
+ throw new Error("Module not found in bundle: " + path6);
22
22
  };
23
23
  var __esm = (fn, res) => function __init() {
24
24
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
@@ -195,7 +195,7 @@ var require_depd = __commonJS({
195
195
  "node_modules/depd/index.js"(exports, module2) {
196
196
  "use strict";
197
197
  init_esm_shims();
198
- var relative = __require("path").relative;
198
+ var relative2 = __require("path").relative;
199
199
  module2.exports = depd;
200
200
  var basePath = process.cwd();
201
201
  function containsNamespace(str, namespace) {
@@ -401,7 +401,7 @@ var require_depd = __commonJS({
401
401
  }
402
402
  __name(formatColor, "formatColor");
403
403
  function formatLocation(callSite) {
404
- return relative(basePath, callSite[0]) + ":" + callSite[1] + ":" + callSite[2];
404
+ return relative2(basePath, callSite[0]) + ":" + callSite[1] + ":" + callSite[2];
405
405
  }
406
406
  __name(formatLocation, "formatLocation");
407
407
  function getStack() {
@@ -1786,14 +1786,14 @@ var require_etag = __commonJS({
1786
1786
  "use strict";
1787
1787
  init_esm_shims();
1788
1788
  module2.exports = etag;
1789
- var crypto = __require("crypto");
1789
+ var crypto2 = __require("crypto");
1790
1790
  var Stats = __require("fs").Stats;
1791
1791
  var toString = Object.prototype.toString;
1792
1792
  function entitytag(entity) {
1793
1793
  if (entity.length === 0) {
1794
1794
  return '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"';
1795
1795
  }
1796
- var hash = crypto.createHash("sha1").update(entity, "utf8").digest("base64").substring(0, 27);
1796
+ var hash = crypto2.createHash("sha1").update(entity, "utf8").digest("base64").substring(0, 27);
1797
1797
  var len = typeof entity === "string" ? Buffer.byteLength(entity, "utf8") : entity.length;
1798
1798
  return '"' + len.toString(16) + "-" + hash + '"';
1799
1799
  }
@@ -10497,11 +10497,11 @@ var require_mime_types = __commonJS({
10497
10497
  return exts[0];
10498
10498
  }
10499
10499
  __name(extension, "extension");
10500
- function lookup(path5) {
10501
- if (!path5 || typeof path5 !== "string") {
10500
+ function lookup(path6) {
10501
+ if (!path6 || typeof path6 !== "string") {
10502
10502
  return false;
10503
10503
  }
10504
- var extension2 = extname("x." + path5).toLowerCase().substr(1);
10504
+ var extension2 = extname("x." + path6).toLowerCase().substr(1);
10505
10505
  if (!extension2) {
10506
10506
  return false;
10507
10507
  }
@@ -10812,33 +10812,33 @@ var require_send = __commonJS({
10812
10812
  var escapeHtml = require_escape_html();
10813
10813
  var etag = require_etag();
10814
10814
  var fresh = require_fresh();
10815
- var fs3 = __require("fs");
10815
+ var fs4 = __require("fs");
10816
10816
  var mime = require_mime_types();
10817
10817
  var ms = require_ms();
10818
10818
  var onFinished = require_on_finished();
10819
10819
  var parseRange = require_range_parser();
10820
- var path5 = __require("path");
10820
+ var path6 = __require("path");
10821
10821
  var statuses = require_statuses();
10822
10822
  var Stream = __require("stream");
10823
10823
  var util = __require("util");
10824
- var extname = path5.extname;
10825
- var join3 = path5.join;
10826
- var normalize = path5.normalize;
10827
- var resolve13 = path5.resolve;
10828
- var sep2 = path5.sep;
10824
+ var extname = path6.extname;
10825
+ var join4 = path6.join;
10826
+ var normalize2 = path6.normalize;
10827
+ var resolve13 = path6.resolve;
10828
+ var sep2 = path6.sep;
10829
10829
  var BYTES_RANGE_REGEXP = /^ *bytes=/;
10830
10830
  var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1e3;
10831
10831
  var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
10832
10832
  module2.exports = send2;
10833
- function send2(req, path6, options) {
10834
- return new SendStream(req, path6, options);
10833
+ function send2(req, path7, options) {
10834
+ return new SendStream(req, path7, options);
10835
10835
  }
10836
10836
  __name(send2, "send");
10837
- function SendStream(req, path6, options) {
10837
+ function SendStream(req, path7, options) {
10838
10838
  Stream.call(this);
10839
10839
  var opts = options || {};
10840
10840
  this.options = opts;
10841
- this.path = path6;
10841
+ this.path = path7;
10842
10842
  this.req = req;
10843
10843
  this._acceptRanges = opts.acceptRanges !== void 0 ? Boolean(opts.acceptRanges) : true;
10844
10844
  this._cacheControl = opts.cacheControl !== void 0 ? Boolean(opts.cacheControl) : true;
@@ -10953,10 +10953,10 @@ var require_send = __commonJS({
10953
10953
  var lastModified = this.res.getHeader("Last-Modified");
10954
10954
  return parseHttpDate(lastModified) <= parseHttpDate(ifRange);
10955
10955
  }, "isRangeFresh");
10956
- SendStream.prototype.redirect = /* @__PURE__ */ __name(function redirect(path6) {
10956
+ SendStream.prototype.redirect = /* @__PURE__ */ __name(function redirect(path7) {
10957
10957
  var res = this.res;
10958
10958
  if (hasListeners(this, "directory")) {
10959
- this.emit("directory", res, path6);
10959
+ this.emit("directory", res, path7);
10960
10960
  return;
10961
10961
  }
10962
10962
  if (this.hasTrailingSlash()) {
@@ -10976,38 +10976,38 @@ var require_send = __commonJS({
10976
10976
  SendStream.prototype.pipe = /* @__PURE__ */ __name(function pipe(res) {
10977
10977
  var root = this._root;
10978
10978
  this.res = res;
10979
- var path6 = decode(this.path);
10980
- if (path6 === -1) {
10979
+ var path7 = decode(this.path);
10980
+ if (path7 === -1) {
10981
10981
  this.error(400);
10982
10982
  return res;
10983
10983
  }
10984
- if (~path6.indexOf("\0")) {
10984
+ if (~path7.indexOf("\0")) {
10985
10985
  this.error(400);
10986
10986
  return res;
10987
10987
  }
10988
10988
  var parts;
10989
10989
  if (root !== null) {
10990
- if (path6) {
10991
- path6 = normalize("." + sep2 + path6);
10990
+ if (path7) {
10991
+ path7 = normalize2("." + sep2 + path7);
10992
10992
  }
10993
- if (UP_PATH_REGEXP.test(path6)) {
10994
- debug('malicious path "%s"', path6);
10993
+ if (UP_PATH_REGEXP.test(path7)) {
10994
+ debug('malicious path "%s"', path7);
10995
10995
  this.error(403);
10996
10996
  return res;
10997
10997
  }
10998
- parts = path6.split(sep2);
10999
- path6 = normalize(join3(root, path6));
10998
+ parts = path7.split(sep2);
10999
+ path7 = normalize2(join4(root, path7));
11000
11000
  } else {
11001
- if (UP_PATH_REGEXP.test(path6)) {
11002
- debug('malicious path "%s"', path6);
11001
+ if (UP_PATH_REGEXP.test(path7)) {
11002
+ debug('malicious path "%s"', path7);
11003
11003
  this.error(403);
11004
11004
  return res;
11005
11005
  }
11006
- parts = normalize(path6).split(sep2);
11007
- path6 = resolve13(path6);
11006
+ parts = normalize2(path7).split(sep2);
11007
+ path7 = resolve13(path7);
11008
11008
  }
11009
11009
  if (containsDotFile(parts)) {
11010
- debug('%s dotfile "%s"', this._dotfiles, path6);
11010
+ debug('%s dotfile "%s"', this._dotfiles, path7);
11011
11011
  switch (this._dotfiles) {
11012
11012
  case "allow":
11013
11013
  break;
@@ -11021,13 +11021,13 @@ var require_send = __commonJS({
11021
11021
  }
11022
11022
  }
11023
11023
  if (this._index.length && this.hasTrailingSlash()) {
11024
- this.sendIndex(path6);
11024
+ this.sendIndex(path7);
11025
11025
  return res;
11026
11026
  }
11027
- this.sendFile(path6);
11027
+ this.sendFile(path7);
11028
11028
  return res;
11029
11029
  }, "pipe");
11030
- SendStream.prototype.send = /* @__PURE__ */ __name(function send3(path6, stat) {
11030
+ SendStream.prototype.send = /* @__PURE__ */ __name(function send3(path7, stat) {
11031
11031
  var len = stat.size;
11032
11032
  var options = this.options;
11033
11033
  var opts = {};
@@ -11039,9 +11039,9 @@ var require_send = __commonJS({
11039
11039
  this.headersAlreadySent();
11040
11040
  return;
11041
11041
  }
11042
- debug('pipe "%s"', path6);
11043
- this.setHeader(path6, stat);
11044
- this.type(path6);
11042
+ debug('pipe "%s"', path7);
11043
+ this.setHeader(path7, stat);
11044
+ this.type(path7);
11045
11045
  if (this.isConditionalGET()) {
11046
11046
  if (this.isPreconditionFailure()) {
11047
11047
  this.error(412);
@@ -11090,30 +11090,30 @@ var require_send = __commonJS({
11090
11090
  res.end();
11091
11091
  return;
11092
11092
  }
11093
- this.stream(path6, opts);
11093
+ this.stream(path7, opts);
11094
11094
  }, "send");
11095
- SendStream.prototype.sendFile = /* @__PURE__ */ __name(function sendFile(path6) {
11095
+ SendStream.prototype.sendFile = /* @__PURE__ */ __name(function sendFile(path7) {
11096
11096
  var i = 0;
11097
11097
  var self = this;
11098
- debug('stat "%s"', path6);
11099
- fs3.stat(path6, /* @__PURE__ */ __name(function onstat(err, stat) {
11100
- var pathEndsWithSep = path6[path6.length - 1] === sep2;
11101
- if (err && err.code === "ENOENT" && !extname(path6) && !pathEndsWithSep) {
11098
+ debug('stat "%s"', path7);
11099
+ fs4.stat(path7, /* @__PURE__ */ __name(function onstat(err, stat) {
11100
+ var pathEndsWithSep = path7[path7.length - 1] === sep2;
11101
+ if (err && err.code === "ENOENT" && !extname(path7) && !pathEndsWithSep) {
11102
11102
  return next(err);
11103
11103
  }
11104
11104
  if (err) return self.onStatError(err);
11105
- if (stat.isDirectory()) return self.redirect(path6);
11105
+ if (stat.isDirectory()) return self.redirect(path7);
11106
11106
  if (pathEndsWithSep) return self.error(404);
11107
- self.emit("file", path6, stat);
11108
- self.send(path6, stat);
11107
+ self.emit("file", path7, stat);
11108
+ self.send(path7, stat);
11109
11109
  }, "onstat"));
11110
11110
  function next(err) {
11111
11111
  if (self._extensions.length <= i) {
11112
11112
  return err ? self.onStatError(err) : self.error(404);
11113
11113
  }
11114
- var p = path6 + "." + self._extensions[i++];
11114
+ var p = path7 + "." + self._extensions[i++];
11115
11115
  debug('stat "%s"', p);
11116
- fs3.stat(p, function(err2, stat) {
11116
+ fs4.stat(p, function(err2, stat) {
11117
11117
  if (err2) return next(err2);
11118
11118
  if (stat.isDirectory()) return next();
11119
11119
  self.emit("file", p, stat);
@@ -11122,7 +11122,7 @@ var require_send = __commonJS({
11122
11122
  }
11123
11123
  __name(next, "next");
11124
11124
  }, "sendFile");
11125
- SendStream.prototype.sendIndex = /* @__PURE__ */ __name(function sendIndex(path6) {
11125
+ SendStream.prototype.sendIndex = /* @__PURE__ */ __name(function sendIndex(path7) {
11126
11126
  var i = -1;
11127
11127
  var self = this;
11128
11128
  function next(err) {
@@ -11130,9 +11130,9 @@ var require_send = __commonJS({
11130
11130
  if (err) return self.onStatError(err);
11131
11131
  return self.error(404);
11132
11132
  }
11133
- var p = join3(path6, self._index[i]);
11133
+ var p = join4(path7, self._index[i]);
11134
11134
  debug('stat "%s"', p);
11135
- fs3.stat(p, function(err2, stat) {
11135
+ fs4.stat(p, function(err2, stat) {
11136
11136
  if (err2) return next(err2);
11137
11137
  if (stat.isDirectory()) return next();
11138
11138
  self.emit("file", p, stat);
@@ -11142,10 +11142,10 @@ var require_send = __commonJS({
11142
11142
  __name(next, "next");
11143
11143
  next();
11144
11144
  }, "sendIndex");
11145
- SendStream.prototype.stream = /* @__PURE__ */ __name(function stream(path6, options) {
11145
+ SendStream.prototype.stream = /* @__PURE__ */ __name(function stream(path7, options) {
11146
11146
  var self = this;
11147
11147
  var res = this.res;
11148
- var stream2 = fs3.createReadStream(path6, options);
11148
+ var stream2 = fs4.createReadStream(path7, options);
11149
11149
  this.emit("stream", stream2);
11150
11150
  stream2.pipe(res);
11151
11151
  function cleanup() {
@@ -11161,17 +11161,17 @@ var require_send = __commonJS({
11161
11161
  self.emit("end");
11162
11162
  }, "onend"));
11163
11163
  }, "stream");
11164
- SendStream.prototype.type = /* @__PURE__ */ __name(function type(path6) {
11164
+ SendStream.prototype.type = /* @__PURE__ */ __name(function type(path7) {
11165
11165
  var res = this.res;
11166
11166
  if (res.getHeader("Content-Type")) return;
11167
- var ext = extname(path6);
11167
+ var ext = extname(path7);
11168
11168
  var type2 = mime.contentType(ext) || "application/octet-stream";
11169
11169
  debug("content-type %s", type2);
11170
11170
  res.setHeader("Content-Type", type2);
11171
11171
  }, "type");
11172
- SendStream.prototype.setHeader = /* @__PURE__ */ __name(function setHeader(path6, stat) {
11172
+ SendStream.prototype.setHeader = /* @__PURE__ */ __name(function setHeader(path7, stat) {
11173
11173
  var res = this.res;
11174
- this.emit("headers", res, path6, stat);
11174
+ this.emit("headers", res, path7, stat);
11175
11175
  if (this._acceptRanges && !res.getHeader("Accept-Ranges")) {
11176
11176
  debug("accept ranges");
11177
11177
  res.setHeader("Accept-Ranges", "bytes");
@@ -11236,9 +11236,9 @@ var require_send = __commonJS({
11236
11236
  return err instanceof Error ? createError(status, err, { expose: false }) : createError(status, err);
11237
11237
  }
11238
11238
  __name(createHttpError, "createHttpError");
11239
- function decode(path6) {
11239
+ function decode(path7) {
11240
11240
  try {
11241
- return decodeURIComponent(path6);
11241
+ return decodeURIComponent(path7);
11242
11242
  } catch (err) {
11243
11243
  return -1;
11244
11244
  }
@@ -14257,7 +14257,7 @@ var init_bag_file_server = __esm({
14257
14257
  if (!recipe_name) {
14258
14258
  return state.sendEmpty(404);
14259
14259
  }
14260
- const bagTiddlers = await this.prisma.recipe_bags.findMany({
14260
+ const bags = await this.prisma.recipe_bags.findMany({
14261
14261
  where: { recipe: { recipe_name } },
14262
14262
  select: {
14263
14263
  position: true,
@@ -14265,36 +14265,28 @@ var init_bag_file_server = __esm({
14265
14265
  select: {
14266
14266
  bag_id: true,
14267
14267
  bag_name: true,
14268
- is_plugin: true,
14269
- tiddlers: {
14270
- select: {
14271
- title: true,
14272
- tiddler_id: true,
14273
- is_deleted: true,
14274
- attachment_hash: true,
14275
- fields: true
14276
- },
14277
- where: {
14278
- is_deleted: false
14279
- }
14280
- }
14268
+ is_plugin: true
14281
14269
  }
14282
14270
  }
14283
14271
  }
14284
14272
  });
14285
- bagTiddlers.sort((a, b) => a.position - b.position);
14286
- const recipeTiddlers = Array.from(new Map(bagTiddlers.flatMap(
14287
- (bag) => bag.bag.tiddlers.map((tiddler) => [tiddler.title, { bag: bag.bag, tiddler }])
14288
- )).values());
14273
+ const lastTiddlerId = await this.prisma.tiddlers.aggregate({
14274
+ _max: { tiddler_id: true },
14275
+ where: { bag_id: { in: bags.map((e) => e.bag.bag_id) } }
14276
+ });
14289
14277
  const template = readFileSync(resolve2(this.state.config.wikiPath, "tiddlywiki5.html"), "utf8");
14290
14278
  const hash = createHash2("md5");
14291
14279
  hash.update(template);
14292
- hash.update(recipeTiddlers.map((e) => e.tiddler.tiddler_id).join("|"));
14280
+ hash.update(bags.map((e) => e.bag.bag_name).join(","));
14281
+ hash.update(`${lastTiddlerId._max.tiddler_id}`);
14293
14282
  const contentDigest = hash.digest("hex");
14283
+ if ('"' + contentDigest + '"' === state.headers["if-none-match"])
14284
+ return state.sendEmpty(304, { "x-reason": "if-none-match" });
14294
14285
  state.writeHead(200, {
14295
14286
  "Content-Type": "text/html",
14296
14287
  "Etag": '"' + contentDigest + '"',
14297
- "Cache-Control": "max-age=0, must-revalidate"
14288
+ // TODO: WHY IS THIS DISABLED???
14289
+ "Cache-Control": "max-age=1000, must-revalidate"
14298
14290
  });
14299
14291
  if (state.method === "HEAD") return state.end();
14300
14292
  var marker = `<script class="tiddlywiki-tiddler-store" type="application/json">[`, markerPos = template.indexOf(marker);
@@ -14306,7 +14298,89 @@ var init_bag_file_server = __esm({
14306
14298
  state.write(",\n");
14307
14299
  }
14308
14300
  __name(writeTiddler, "writeTiddler");
14309
- state.write(template.substring(0, markerPos + marker.length));
14301
+ state.write(template.substring(0, markerPos));
14302
+ if (state.config.enablePluginCache) {
14303
+ const preloadMarkup = `
14304
+ ${"<"}script>
14305
+ window.$tw = window.$tw || Object.create(null);
14306
+ $tw.preloadTiddlers = $tw.preloadTiddlers || [];
14307
+ $tw.preloadTiddler = function(fields) {
14308
+ $tw.preloadTiddlers.push(fields);
14309
+ };
14310
+ ${"</"}script>
14311
+ `;
14312
+ state.write(preloadMarkup);
14313
+ const pluginMarkup = /* @__PURE__ */ __name((plugin, hash2) => `
14314
+ <script
14315
+ src="${state.config.pathPrefix}/$cache/${plugin}/plugin.js"
14316
+ integrity="${hash2}"
14317
+ crossorigin="anonymous"></script>
14318
+ `, "pluginMarkup");
14319
+ const plugins = [...(/* @__PURE__ */ new Set([
14320
+ "$:/core",
14321
+ "$:/plugins/tiddlywiki/multiwikiclient",
14322
+ "$:/plugins/tiddlywiki/tiddlyweb",
14323
+ "$:/themes/tiddlywiki/snowwhite",
14324
+ "$:/themes/tiddlywiki/vanilla",
14325
+ ...bags.map((e) => e.bag.bag_name)
14326
+ ])).values()].filter((e) => state.tiddlerCache.tiddlerFiles.has(e)).map((e) => pluginMarkup(
14327
+ state.tiddlerCache.tiddlerFiles.get(e),
14328
+ state.tiddlerCache.tiddlerHashes.get(e)
14329
+ ));
14330
+ state.write(plugins.join("\n"));
14331
+ }
14332
+ state.write(marker);
14333
+ const bagOrder = new Map(bags.map((e) => [e.bag.bag_id, e.position]));
14334
+ const bagIDs = bags.filter((e) => !state.tiddlerCache.tiddlerFiles.has(e.bag.bag_name)).map((e) => e.bag.bag_id);
14335
+ await this.serveStoreTiddlers(bagIDs, bagOrder, writeTiddler);
14336
+ writeTiddler({
14337
+ title: "$:/config/multiwikiclient/recipe",
14338
+ text: recipe_name
14339
+ });
14340
+ writeTiddler({
14341
+ title: "$:/state/multiwikiclient/recipe/last_tiddler_id",
14342
+ text: (lastTiddlerId._max.tiddler_id ?? 0).toString()
14343
+ });
14344
+ writeTiddler({
14345
+ title: "$:/config/multiwikiclient/host",
14346
+ text: "$protocol$//$host$" + this.state.config.pathPrefix + "/"
14347
+ });
14348
+ state.write(template.substring(markerPos + marker.length));
14349
+ return state.end();
14350
+ }
14351
+ async serveStoreTiddlers(bagKeys, bagOrder, writeTiddler) {
14352
+ const bagTiddlers = await this.prisma.bags.findMany({
14353
+ where: { bag_id: { in: bagKeys } },
14354
+ select: {
14355
+ bag_id: true,
14356
+ bag_name: true,
14357
+ is_plugin: true,
14358
+ description: true,
14359
+ owner_id: true,
14360
+ tiddlers: {
14361
+ select: {
14362
+ title: true,
14363
+ tiddler_id: true,
14364
+ is_deleted: true,
14365
+ attachment_hash: true,
14366
+ fields: true
14367
+ },
14368
+ where: {
14369
+ is_deleted: false,
14370
+ bag: { is_plugin: false }
14371
+ }
14372
+ }
14373
+ }
14374
+ });
14375
+ if (!bagTiddlers.every((e) => bagOrder.has(e.bag_id))) {
14376
+ console.log(bagTiddlers.map((e) => e.bag_id));
14377
+ console.log(bagOrder);
14378
+ throw new Error("Bags missing from bag order");
14379
+ }
14380
+ bagTiddlers.sort((a, b) => bagOrder.get(b.bag_id) - bagOrder.get(a.bag_id));
14381
+ const recipeTiddlers = Array.from(new Map(bagTiddlers.flatMap(
14382
+ (bag) => bag.tiddlers.map((tiddler) => [tiddler.title, { bag, tiddler }])
14383
+ )).values());
14310
14384
  const bagInfo = {}, revisionInfo = {};
14311
14385
  for (const recipeTiddlerInfo of recipeTiddlers) {
14312
14386
  const { title, tiddler_id, attachment_hash, fields } = recipeTiddlerInfo.tiddler;
@@ -14335,21 +14409,6 @@ var init_bag_file_server = __esm({
14335
14409
  text: JSON.stringify(revisionInfo),
14336
14410
  type: "application/json"
14337
14411
  });
14338
- writeTiddler({
14339
- title: "$:/config/multiwikiclient/recipe",
14340
- text: recipe_name
14341
- });
14342
- const lastTiddlerId = await this.prisma.tiddlers.aggregate({ _max: { tiddler_id: true } });
14343
- writeTiddler({
14344
- title: "$:/state/multiwikiclient/recipe/last_tiddler_id",
14345
- text: (lastTiddlerId._max.tiddler_id ?? 0).toString()
14346
- });
14347
- writeTiddler({
14348
- title: "$:/config/multiwikiclient/host",
14349
- text: "$protocol$//$host$" + this.state.config.pathPrefix + "/"
14350
- });
14351
- state.write(template.substring(markerPos + marker.length));
14352
- return state.end();
14353
14412
  }
14354
14413
  };
14355
14414
  __name(_TiddlerServer, "TiddlerServer");
@@ -14616,26 +14675,27 @@ var init_router_tiddlers = __esm({
14616
14675
  }
14617
14676
  });
14618
14677
 
14619
- // src/routes/tw-test.ts
14678
+ // src/routes/tw-routes.ts
14620
14679
  import { TiddlyWiki } from "tiddlywiki";
14621
14680
  function DocsRoute(parent, config) {
14622
14681
  const wikiRouter = new TWRouter(config);
14682
+ console.log("The mws-docs tiddlywiki is being served at " + config.pathPrefix + "/mws-docs");
14623
14683
  parent.defineRoute({
14624
14684
  method: ["OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE"],
14625
14685
  bodyFormat: "stream",
14626
- path: /^\/mws(\/|$)/,
14686
+ path: /^\/mwsp-docs(\/|$)/,
14627
14687
  pathParams: []
14628
14688
  }, async (state) => {
14629
- if (state.urlInfo.pathname === "/mws") throw state.redirect("/mws/");
14689
+ if (state.urlInfo.pathname === "/mws-docs") throw state.redirect("/mws-docs/");
14630
14690
  const { req, res } = state.streamer;
14631
- if (req.url === "/mws") req.url = "/mws/";
14691
+ if (req.url === "/mws-docs") req.url = "/mws-docs/";
14632
14692
  wikiRouter.twserver.requestHandler(req, res, {});
14633
14693
  return new Promise((r, c) => res.on("finish", r).on("error", c));
14634
14694
  });
14635
14695
  }
14636
14696
  var _TWRouter, TWRouter;
14637
- var init_tw_test = __esm({
14638
- "src/routes/tw-test.ts"() {
14697
+ var init_tw_routes = __esm({
14698
+ "src/routes/tw-routes.ts"() {
14639
14699
  "use strict";
14640
14700
  init_esm_shims();
14641
14701
  __name(DocsRoute, "DocsRoute");
@@ -14712,7 +14772,6 @@ async function RootRoute(root, config) {
14712
14772
  return state.sendJSON(200, await fn.call(table, state.data.arg));
14713
14773
  });
14714
14774
  });
14715
- await importEsbuild(root);
14716
14775
  }
14717
14776
  async function importEsbuild(root) {
14718
14777
  root.defineRoute({
@@ -14748,7 +14807,7 @@ var init_routes = __esm({
14748
14807
  init_utils2();
14749
14808
  init_managers();
14750
14809
  init_router_tiddlers();
14751
- init_tw_test();
14810
+ init_tw_routes();
14752
14811
  init_();
14753
14812
  __name(RootRoute, "RootRoute");
14754
14813
  __name(importEsbuild, "importEsbuild");
@@ -14933,7 +14992,10 @@ var init_setupDevServer = __esm({
14933
14992
 
14934
14993
  // src/routes/cache.ts
14935
14994
  import { ok as ok4 } from "assert";
14936
- async function startupCache(commander2) {
14995
+ import * as fs2 from "fs";
14996
+ import * as path3 from "path";
14997
+ import * as crypto from "crypto";
14998
+ async function startupCache(rootRoute2, commander2) {
14937
14999
  const $tw2 = commander2.$tw;
14938
15000
  const bootTiddlers = $tw2.loadTiddlersFromPath($tw2.boot.bootPath).flatMap((file) => file.tiddlers);
14939
15001
  const coreTiddler = $tw2.loadPluginFolder($tw2.boot.corePath);
@@ -14943,7 +15005,71 @@ async function startupCache(commander2) {
14943
15005
  [coreTiddler.title, JSON.stringify(coreTiddler)]
14944
15006
  ]);
14945
15007
  const tiddlerFileCache = /* @__PURE__ */ new Map();
14946
- return { tiddlerFileCache, tiddlerMemoryCache };
15008
+ const { tiddlerFiles, tiddlerHashes } = await importTW5(path3.join($tw2.boot.corePath, ".."), commander2.cachePath, "client", $tw2);
15009
+ rootRoute2.defineRoute({
15010
+ method: ["GET", "HEAD"],
15011
+ path: /^\/\$cache\/(.*)\/plugin\.js$/,
15012
+ bodyFormat: "ignore",
15013
+ pathParams: ["plugin"]
15014
+ }, async (state) => {
15015
+ ZodAssert.pathParams(state, (z5) => ({
15016
+ plugin: z5.string()
15017
+ }));
15018
+ return state.sendFile(200, {}, {
15019
+ root: commander2.cachePath,
15020
+ reqpath: state.pathParams.plugin + "/plugin.js"
15021
+ });
15022
+ });
15023
+ return { tiddlerFileCache, tiddlerMemoryCache, tiddlerFiles, tiddlerHashes };
15024
+ }
15025
+ async function importTW5(twFolder, cacheFolder, type, $tw2) {
15026
+ const readLevel = /* @__PURE__ */ __name((d) => {
15027
+ return fs2.readdirSync(path3.join(twFolder, d)).filter((e) => !$tw2.boot.excludeRegExp.test(e)).map((e) => path3.join(d, e));
15028
+ }, "readLevel");
15029
+ const plugins = [
15030
+ ...[
15031
+ ...[
15032
+ "plugins",
15033
+ "themes"
15034
+ ].flatMap(readLevel),
15035
+ "languages"
15036
+ ].flatMap(readLevel),
15037
+ "core"
15038
+ ].map((e) => {
15039
+ const oldPath = path3.join(twFolder, e);
15040
+ const relativePluginPath = path3.normalize(path3.relative(twFolder, oldPath));
15041
+ return [oldPath, relativePluginPath];
15042
+ });
15043
+ plugins.push([
15044
+ dist_resolve("../plugins/client"),
15045
+ "plugins/mws/client"
15046
+ ]);
15047
+ const hashes = {};
15048
+ const tiddlerFiles = /* @__PURE__ */ new Map();
15049
+ const tiddlerHashes = /* @__PURE__ */ new Map();
15050
+ plugins.forEach(([oldPath, relativePluginPath]) => {
15051
+ const plugin = $tw2.loadPluginFolder(oldPath);
15052
+ const newPath = path3.join(cacheFolder, relativePluginPath);
15053
+ fs2.mkdirSync(newPath, { recursive: true });
15054
+ if (plugin && plugin.title) {
15055
+ plugin.text = JSON.stringify(JSON.parse(plugin.text));
15056
+ if (type === "server") {
15057
+ plugin.tiddlers = JSON.parse(plugin.text).tiddlers;
15058
+ delete plugin.text;
15059
+ fs2.writeFileSync(path3.join(newPath, "plugin.info"), JSON.stringify(plugin));
15060
+ } else if (type === "client") {
15061
+ let js = Buffer.from(`$tw.preloadTiddler(${JSON.stringify(plugin)});`, "utf8");
15062
+ let hash = crypto.createHash("sha384").update(js).digest("base64");
15063
+ fs2.writeFileSync(path3.join(newPath, "plugin.js"), js);
15064
+ tiddlerFiles.set(plugin.title, relativePluginPath);
15065
+ tiddlerHashes.set(plugin.title, "sha384-" + hash);
15066
+ }
15067
+ } else {
15068
+ console.log("Info: No plugin found at", oldPath);
15069
+ }
15070
+ });
15071
+ fs2.writeFileSync(path3.join(cacheFolder, "hashes.json"), JSON.stringify(hashes, null, 2));
15072
+ return { tiddlerFiles, tiddlerHashes };
14947
15073
  }
14948
15074
  var init_cache = __esm({
14949
15075
  "src/routes/cache.ts"() {
@@ -14951,6 +15077,7 @@ var init_cache = __esm({
14951
15077
  init_esm_shims();
14952
15078
  init_utils2();
14953
15079
  __name(startupCache, "startupCache");
15080
+ __name(importTW5, "importTW5");
14954
15081
  }
14955
15082
  });
14956
15083
 
@@ -14971,10 +15098,10 @@ function defineRoute(parent, route, handler) {
14971
15098
  route.handler = handler;
14972
15099
  return route;
14973
15100
  }
14974
- function zodRoute(method, path5, zodPathParams, bodyFormat, zodRequest, inner) {
15101
+ function zodRoute(method, path6, zodPathParams, bodyFormat, zodRequest, inner) {
14975
15102
  return {
14976
15103
  method,
14977
- path: path5,
15104
+ path: path6,
14978
15105
  bodyFormat,
14979
15106
  inner,
14980
15107
  zodRequest,
@@ -15045,7 +15172,8 @@ var init_router = __esm({
15045
15172
  });
15046
15173
  await commander2.SessionManager.defineRoutes(rootRoute2);
15047
15174
  await RootRoute(rootRoute2, commander2.siteConfig);
15048
- const cache = await startupCache(commander2);
15175
+ const cache = await startupCache(rootRoute2, commander2);
15176
+ await importEsbuild(rootRoute2);
15049
15177
  return new _Router(rootRoute2, commander2, cache);
15050
15178
  }
15051
15179
  get pathPrefix() {
@@ -15178,11 +15306,11 @@ var init_router = __esm({
15178
15306
  registerZodRoutes = /* @__PURE__ */ __name((root, router, keys) => {
15179
15307
  keys.forEach((key) => {
15180
15308
  const route = router[key];
15181
- const { method, path: path5, bodyFormat, zodPathParams, zodRequest, inner } = route;
15182
- const pathParams = path5.split("/").filter((e) => e.startsWith(":")).map((e) => e.substring(1));
15183
- if (!path5.startsWith("/")) throw new Error(`Path ${path5} must start with a forward slash`);
15309
+ const { method, path: path6, bodyFormat, zodPathParams, zodRequest, inner } = route;
15310
+ const pathParams = path6.split("/").filter((e) => e.startsWith(":")).map((e) => e.substring(1));
15311
+ if (!path6.startsWith("/")) throw new Error(`Path ${path6} must start with a forward slash`);
15184
15312
  if (key.startsWith(":")) throw new Error(`Key ${key} must not start with a colon`);
15185
- const pathregex = "^" + path5.split("/").map(
15313
+ const pathregex = "^" + path6.split("/").map(
15186
15314
  (e) => e === "$key" ? key : e.startsWith(":") ? "([^/]+)" : e
15187
15315
  ).join("\\/") + "$";
15188
15316
  root.defineRoute({
@@ -15287,13 +15415,13 @@ var init_tiddlywiki = __esm({
15287
15415
  });
15288
15416
 
15289
15417
  // src/services/sessions.ts
15290
- import { createHash as createHash4, randomBytes } from "node:crypto";
15291
- function zodSession(path5, zodRequest, inner) {
15418
+ import { createHash as createHash5, randomBytes } from "node:crypto";
15419
+ function zodSession(path6, zodRequest, inner) {
15292
15420
  return {
15293
- ...zodRoute(["POST"], path5, (z5) => ({}), "json", zodRequest, async (state) => {
15421
+ ...zodRoute(["POST"], path6, (z5) => ({}), "json", zodRequest, async (state) => {
15294
15422
  return state.$transaction(async (prisma) => await inner(state, prisma));
15295
15423
  }),
15296
- path: path5
15424
+ path: path6
15297
15425
  };
15298
15426
  }
15299
15427
  async function createSession(prisma, user_id, session_key) {
@@ -15308,7 +15436,7 @@ async function createSession(prisma, user_id, session_key) {
15308
15436
  }).then(({ session_id: session_id2 }) => session_id2);
15309
15437
  }
15310
15438
  function assertSignature({ session_id, signature, session_key }) {
15311
- const hash = createHash4("sha256").update(session_key + session_id).digest("base64");
15439
+ const hash = createHash5("sha256").update(session_key + session_id).digest("base64");
15312
15440
  if (hash !== signature) throw "Invalid session signature.";
15313
15441
  }
15314
15442
  var SessionKeyMap, _SessionManager, SessionManager;
@@ -15432,8 +15560,8 @@ var init_sessions = __esm({
15432
15560
  });
15433
15561
 
15434
15562
  // src/services/attachments.ts
15435
- import * as path3 from "path";
15436
- import * as fs2 from "fs";
15563
+ import * as path4 from "path";
15564
+ import * as fs3 from "fs";
15437
15565
  var import_sjcl2, $tw, _AttachmentService, AttachmentService;
15438
15566
  var init_attachments = __esm({
15439
15567
  "src/services/attachments.ts"() {
@@ -15532,15 +15660,15 @@ var init_attachments = __esm({
15532
15660
  async saveAttachment(options) {
15533
15661
  const contentHash = import_sjcl2.default.codec.hex.fromBits($tw.sjcl.hash.sha256.hash(options.text)).slice(0, 64).toString();
15534
15662
  const contentTypeInfo = this.config.contentTypeInfo[options.type] || this.config.contentTypeInfo["application/octet-stream"];
15535
- const attachmentPath = path3.resolve(this.config.storePath, "files", contentHash);
15663
+ const attachmentPath = path4.resolve(this.config.storePath, "files", contentHash);
15536
15664
  createDirectory(attachmentPath);
15537
15665
  const dataFilename = "data" + contentTypeInfo.extension;
15538
- fs2.writeFileSync(path3.resolve(attachmentPath, dataFilename), options.text, contentTypeInfo.encoding);
15539
- this.writeMetaFile(fs2, path3, attachmentPath, options, contentHash, dataFilename);
15666
+ fs3.writeFileSync(path4.resolve(attachmentPath, dataFilename), options.text, contentTypeInfo.encoding);
15667
+ this.writeMetaFile(fs3, path4, attachmentPath, options, contentHash, dataFilename);
15540
15668
  return contentHash;
15541
15669
  }
15542
- writeMetaFile(fs3, path5, attachmentPath, options, contentHash, dataFilename) {
15543
- fs3.writeFileSync(path5.resolve(attachmentPath, "meta.json"), JSON.stringify({
15670
+ writeMetaFile(fs4, path6, attachmentPath, options, contentHash, dataFilename) {
15671
+ fs4.writeFileSync(path6.resolve(attachmentPath, "meta.json"), JSON.stringify({
15544
15672
  _canonical_uri: options._canonical_uri,
15545
15673
  created: (/* @__PURE__ */ new Date()).toISOString(),
15546
15674
  modified: (/* @__PURE__ */ new Date()).toISOString(),
@@ -15554,11 +15682,11 @@ var init_attachments = __esm({
15554
15682
  */
15555
15683
  async adoptAttachment({ incomingFilepath, type, hash, _canonical_uri }) {
15556
15684
  const contentTypeInfo = this.config.contentTypeInfo[type] || this.config.contentTypeInfo["application/octet-stream"];
15557
- const attachmentPath = path3.resolve(this.config.storePath, "files", hash);
15685
+ const attachmentPath = path4.resolve(this.config.storePath, "files", hash);
15558
15686
  createDirectory(attachmentPath);
15559
- const dataFilename = "data" + contentTypeInfo.extension, dataFilepath = path3.resolve(attachmentPath, dataFilename);
15560
- fs2.renameSync(incomingFilepath, dataFilepath);
15561
- fs2.writeFileSync(path3.resolve(attachmentPath, "meta.json"), JSON.stringify({
15687
+ const dataFilename = "data" + contentTypeInfo.extension, dataFilepath = path4.resolve(attachmentPath, dataFilename);
15688
+ fs3.renameSync(incomingFilepath, dataFilepath);
15689
+ fs3.writeFileSync(path4.resolve(attachmentPath, "meta.json"), JSON.stringify({
15562
15690
  _canonical_uri,
15563
15691
  created: (/* @__PURE__ */ new Date()).toISOString(),
15564
15692
  modified: (/* @__PURE__ */ new Date()).toISOString(),
@@ -15575,15 +15703,15 @@ var init_attachments = __esm({
15575
15703
  */
15576
15704
  async getAttachmentStream(content_hash) {
15577
15705
  if (!this.isValidAttachmentName(content_hash)) return null;
15578
- const attachmentPath = path3.resolve(this.config.storePath, "files", content_hash);
15579
- const metaJsonPath = path3.resolve(attachmentPath, "meta.json");
15580
- if (!fs2.existsSync(metaJsonPath) || !fs2.statSync(metaJsonPath).isFile()) return null;
15581
- const meta = tryParseJSON(fs2.readFileSync(metaJsonPath, "utf8"));
15706
+ const attachmentPath = path4.resolve(this.config.storePath, "files", content_hash);
15707
+ const metaJsonPath = path4.resolve(attachmentPath, "meta.json");
15708
+ if (!fs3.existsSync(metaJsonPath) || !fs3.statSync(metaJsonPath).isFile()) return null;
15709
+ const meta = tryParseJSON(fs3.readFileSync(metaJsonPath, "utf8"));
15582
15710
  if (!meta) return null;
15583
- const dataFilepath = path3.resolve(attachmentPath, meta.filename);
15584
- if (!fs2.existsSync(dataFilepath) || !fs2.statSync(dataFilepath).isFile()) return null;
15711
+ const dataFilepath = path4.resolve(attachmentPath, meta.filename);
15712
+ if (!fs3.existsSync(dataFilepath) || !fs3.statSync(dataFilepath).isFile()) return null;
15585
15713
  return {
15586
- stream: fs2.createReadStream(dataFilepath),
15714
+ stream: fs3.createReadStream(dataFilepath),
15587
15715
  type: meta.type
15588
15716
  };
15589
15717
  }
@@ -15592,20 +15720,20 @@ var init_attachments = __esm({
15592
15720
  Returns the size in bytes, or null if the file doesn't exist.
15593
15721
  */
15594
15722
  async getAttachmentFileSize(content_hash) {
15595
- const attachmentPath = path3.resolve(this.config.storePath, "files", content_hash);
15596
- const metaJsonPath = path3.resolve(attachmentPath, "meta.json");
15597
- if (!(fs2.existsSync(metaJsonPath) && fs2.statSync(metaJsonPath).isFile())) return null;
15598
- const meta = tryParseJSON(fs2.readFileSync(metaJsonPath, "utf8"));
15723
+ const attachmentPath = path4.resolve(this.config.storePath, "files", content_hash);
15724
+ const metaJsonPath = path4.resolve(attachmentPath, "meta.json");
15725
+ if (!(fs3.existsSync(metaJsonPath) && fs3.statSync(metaJsonPath).isFile())) return null;
15726
+ const meta = tryParseJSON(fs3.readFileSync(metaJsonPath, "utf8"));
15599
15727
  if (!meta) return null;
15600
- const dataFilepath = path3.resolve(attachmentPath, meta.filename);
15601
- if (!(fs2.existsSync(dataFilepath) && fs2.statSync(dataFilepath).isFile())) return null;
15602
- return fs2.statSync(dataFilepath).size;
15728
+ const dataFilepath = path4.resolve(attachmentPath, meta.filename);
15729
+ if (!(fs3.existsSync(dataFilepath) && fs3.statSync(dataFilepath).isFile())) return null;
15730
+ return fs3.statSync(dataFilepath).size;
15603
15731
  }
15604
15732
  async getAttachmentMetadata(content_hash) {
15605
- const attachmentPath = path3.resolve(this.config.storePath, "files", content_hash);
15606
- const metaJsonPath = path3.resolve(attachmentPath, "meta.json");
15607
- if (!fs2.existsSync(metaJsonPath)) return null;
15608
- return JSON.parse(fs2.readFileSync(metaJsonPath, "utf8"));
15733
+ const attachmentPath = path4.resolve(this.config.storePath, "files", content_hash);
15734
+ const metaJsonPath = path4.resolve(attachmentPath, "meta.json");
15735
+ if (!fs3.existsSync(metaJsonPath)) return null;
15736
+ return JSON.parse(fs3.readFileSync(metaJsonPath, "utf8"));
15609
15737
  }
15610
15738
  };
15611
15739
  __name(_AttachmentService, "AttachmentService");
@@ -16761,8 +16889,8 @@ var require_command = __commonJS({
16761
16889
  init_esm_shims();
16762
16890
  var EventEmitter = __require("node:events").EventEmitter;
16763
16891
  var childProcess = __require("node:child_process");
16764
- var path5 = __require("node:path");
16765
- var fs3 = __require("node:fs");
16892
+ var path6 = __require("node:path");
16893
+ var fs4 = __require("node:fs");
16766
16894
  var process2 = __require("node:process");
16767
16895
  var { Argument: Argument2, humanReadableArgName } = require_argument();
16768
16896
  var { CommanderError: CommanderError2 } = require_error();
@@ -17743,7 +17871,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
17743
17871
  * @param {string} subcommandName
17744
17872
  */
17745
17873
  _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
17746
- if (fs3.existsSync(executableFile)) return;
17874
+ if (fs4.existsSync(executableFile)) return;
17747
17875
  const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
17748
17876
  const executableMissing = `'${executableFile}' does not exist
17749
17877
  - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
@@ -17761,11 +17889,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
17761
17889
  let launchWithNode = false;
17762
17890
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
17763
17891
  function findFile(baseDir, baseName) {
17764
- const localBin = path5.resolve(baseDir, baseName);
17765
- if (fs3.existsSync(localBin)) return localBin;
17766
- if (sourceExt.includes(path5.extname(baseName))) return void 0;
17892
+ const localBin = path6.resolve(baseDir, baseName);
17893
+ if (fs4.existsSync(localBin)) return localBin;
17894
+ if (sourceExt.includes(path6.extname(baseName))) return void 0;
17767
17895
  const foundExt = sourceExt.find(
17768
- (ext) => fs3.existsSync(`${localBin}${ext}`)
17896
+ (ext) => fs4.existsSync(`${localBin}${ext}`)
17769
17897
  );
17770
17898
  if (foundExt) return `${localBin}${foundExt}`;
17771
17899
  return void 0;
@@ -17778,21 +17906,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
17778
17906
  if (this._scriptPath) {
17779
17907
  let resolvedScriptPath;
17780
17908
  try {
17781
- resolvedScriptPath = fs3.realpathSync(this._scriptPath);
17909
+ resolvedScriptPath = fs4.realpathSync(this._scriptPath);
17782
17910
  } catch {
17783
17911
  resolvedScriptPath = this._scriptPath;
17784
17912
  }
17785
- executableDir = path5.resolve(
17786
- path5.dirname(resolvedScriptPath),
17913
+ executableDir = path6.resolve(
17914
+ path6.dirname(resolvedScriptPath),
17787
17915
  executableDir
17788
17916
  );
17789
17917
  }
17790
17918
  if (executableDir) {
17791
17919
  let localFile = findFile(executableDir, executableFile);
17792
17920
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
17793
- const legacyName = path5.basename(
17921
+ const legacyName = path6.basename(
17794
17922
  this._scriptPath,
17795
- path5.extname(this._scriptPath)
17923
+ path6.extname(this._scriptPath)
17796
17924
  );
17797
17925
  if (legacyName !== this._name) {
17798
17926
  localFile = findFile(
@@ -17803,7 +17931,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
17803
17931
  }
17804
17932
  executableFile = localFile || executableFile;
17805
17933
  }
17806
- launchWithNode = sourceExt.includes(path5.extname(executableFile));
17934
+ launchWithNode = sourceExt.includes(path6.extname(executableFile));
17807
17935
  let proc;
17808
17936
  if (process2.platform !== "win32") {
17809
17937
  if (launchWithNode) {
@@ -18651,7 +18779,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
18651
18779
  * @return {Command}
18652
18780
  */
18653
18781
  nameFromFilename(filename) {
18654
- this._name = path5.basename(filename, path5.extname(filename));
18782
+ this._name = path6.basename(filename, path6.extname(filename));
18655
18783
  return this;
18656
18784
  }
18657
18785
  /**
@@ -18665,9 +18793,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
18665
18793
  * @param {string} [path]
18666
18794
  * @return {(string|null|Command)}
18667
18795
  */
18668
- executableDir(path6) {
18669
- if (path6 === void 0) return this._executableDir;
18670
- this._executableDir = path6;
18796
+ executableDir(path7) {
18797
+ if (path7 === void 0) return this._executableDir;
18798
+ this._executableDir = path7;
18671
18799
  return this;
18672
18800
  }
18673
18801
  /**
@@ -19082,12 +19210,12 @@ __export(render_tiddlywiki5_exports, {
19082
19210
  info: () => info2
19083
19211
  });
19084
19212
  import { resolve as resolve6 } from "node:path";
19085
- var writeFileSync3, info2, _Command2, Command3;
19213
+ var writeFileSync4, info2, _Command2, Command3;
19086
19214
  var init_render_tiddlywiki5 = __esm({
19087
19215
  "src/commands/render-tiddlywiki5.ts"() {
19088
19216
  "use strict";
19089
19217
  init_esm_shims();
19090
- ({ writeFileSync: writeFileSync3 } = __require("fs"));
19218
+ ({ writeFileSync: writeFileSync4 } = __require("fs"));
19091
19219
  info2 = {
19092
19220
  name: "render-tiddlywiki5",
19093
19221
  description: "Render the TiddlyWiki5 HTML file",
@@ -19103,12 +19231,13 @@ var init_render_tiddlywiki5 = __esm({
19103
19231
  async execute() {
19104
19232
  const result = this.commander.$tw.wiki.renderTiddler("text/plain", "$:/core/templates/tiddlywiki5.html", {
19105
19233
  variables: {
19106
- saveTiddlerFilter: `
19107
- $:/boot/boot.css
19108
- $:/boot/boot.js
19109
- $:/boot/bootprefix.js
19234
+ // the boot and library tiddlers get rendered into the page
19235
+ // this list gets saved in the store array
19236
+ // we have to render at least one tiddler
19237
+ saveTiddlerFilter: this.commander.siteConfig.enablePluginCache ? `
19238
+ $:/temp/nothing
19239
+ ` : `
19110
19240
  $:/core
19111
- $:/library/sjcl.js
19112
19241
  $:/plugins/tiddlywiki/tiddlyweb
19113
19242
  $:/plugins/tiddlywiki/multiwikiclient
19114
19243
  $:/themes/tiddlywiki/snowwhite
@@ -19117,7 +19246,7 @@ var init_render_tiddlywiki5 = __esm({
19117
19246
  }
19118
19247
  });
19119
19248
  const filepath = resolve6(this.commander.wikiPath, "tiddlywiki5.html");
19120
- writeFileSync3(filepath, result);
19249
+ writeFileSync4(filepath, result);
19121
19250
  }
19122
19251
  };
19123
19252
  __name(_Command2, "Command");
@@ -19136,11 +19265,11 @@ function makePluginBagName(type, publisher, name) {
19136
19265
  return "$:/" + type + "/" + (publisher ? publisher + "/" : "") + name;
19137
19266
  }
19138
19267
  function loadWikiFolder({ $tw: $tw2, store, ...options }) {
19139
- const path5 = __require("path"), fs3 = __require("fs");
19140
- const wikiInfoPath = path5.resolve(options.wikiPath, $tw2.config.wikiInfo);
19268
+ const path6 = __require("path"), fs4 = __require("fs");
19269
+ const wikiInfoPath = path6.resolve(options.wikiPath, $tw2.config.wikiInfo);
19141
19270
  let wikiInfo;
19142
- if (fs3.existsSync(wikiInfoPath)) {
19143
- wikiInfo = $tw2.utils.parseJSONSafe(fs3.readFileSync(wikiInfoPath, "utf8"), function() {
19271
+ if (fs4.existsSync(wikiInfoPath)) {
19272
+ wikiInfo = $tw2.utils.parseJSONSafe(fs4.readFileSync(wikiInfoPath, "utf8"), function() {
19144
19273
  return null;
19145
19274
  });
19146
19275
  }
@@ -19167,7 +19296,7 @@ function loadWikiFolder({ $tw: $tw2, store, ...options }) {
19167
19296
  with_acl: true
19168
19297
  });
19169
19298
  recipeList.reverse();
19170
- const tiddler_files_path = path5.resolve(options.wikiPath, $tw2.config.wikiTiddlersSubDir);
19299
+ const tiddler_files_path = path6.resolve(options.wikiPath, $tw2.config.wikiTiddlersSubDir);
19171
19300
  const tiddlersFromPath = $tw2.loadTiddlersFromPath(
19172
19301
  resolve7($tw2.boot.corePath, $tw2.config.editionsPath, tiddler_files_path)
19173
19302
  );
@@ -19349,7 +19478,7 @@ __export(load_archive_exports, {
19349
19478
  Command: () => Command6,
19350
19479
  info: () => info5
19351
19480
  });
19352
- import { join as join2, resolve as resolve9 } from "path";
19481
+ import { join as join3, resolve as resolve9 } from "path";
19353
19482
  import * as _fsp2 from "fs/promises";
19354
19483
  import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library";
19355
19484
  import { existsSync as existsSync3 } from "fs";
@@ -19454,7 +19583,7 @@ var init_load_archive = __esm({
19454
19583
  });
19455
19584
  }
19456
19585
  async restoreBag(folder, prisma) {
19457
- const bagInfo = JSON.parse(await fsp2.readFile(join2(folder, "meta.json"), "utf8"));
19586
+ const bagInfo = JSON.parse(await fsp2.readFile(join3(folder, "meta.json"), "utf8"));
19458
19587
  await prisma.bags.create({
19459
19588
  data: {
19460
19589
  bag_id: bagInfo.bag_id,
@@ -19465,10 +19594,10 @@ var init_load_archive = __esm({
19465
19594
  acl: { createMany: { data: bagInfo.acl } }
19466
19595
  }
19467
19596
  });
19468
- const tiddlerFiles = await fsp2.readdir(join2(folder, "tiddlers"));
19597
+ const tiddlerFiles = await fsp2.readdir(join3(folder, "tiddlers"));
19469
19598
  const tiddlers = await Promise.all(tiddlerFiles.map(async (tiddlerFilename) => {
19470
19599
  if (!tiddlerFilename.endsWith(".json")) return;
19471
- const value = await fsp2.readFile(join2(folder, "tiddlers", tiddlerFilename), "utf8");
19600
+ const value = await fsp2.readFile(join3(folder, "tiddlers", tiddlerFilename), "utf8");
19472
19601
  return JSON.parse(value);
19473
19602
  }));
19474
19603
  await prisma.tiddlers.createMany({
@@ -19552,7 +19681,7 @@ var init_load_archive = __esm({
19552
19681
  });
19553
19682
  }
19554
19683
  async restoreBag(folder, prisma) {
19555
- const bagInfo = JSON.parse(await fsp2.readFile(join2(folder, "meta.json"), "utf8"));
19684
+ const bagInfo = JSON.parse(await fsp2.readFile(join3(folder, "meta.json"), "utf8"));
19556
19685
  await prisma.bags.create({
19557
19686
  data: {
19558
19687
  bag_id: bagInfo.bag_id,
@@ -19563,10 +19692,10 @@ var init_load_archive = __esm({
19563
19692
  acl: { createMany: { data: bagInfo.acl } }
19564
19693
  }
19565
19694
  });
19566
- const tiddlerFiles = await fsp2.readdir(join2(folder, "tiddlers"));
19695
+ const tiddlerFiles = await fsp2.readdir(join3(folder, "tiddlers"));
19567
19696
  const tiddlers = await Promise.all(tiddlerFiles.map(async (tiddlerFilename) => {
19568
19697
  if (!tiddlerFilename.endsWith(".json")) return;
19569
- const value = await fsp2.readFile(join2(folder, "tiddlers", tiddlerFilename), "utf8");
19698
+ const value = await fsp2.readFile(join3(folder, "tiddlers", tiddlerFilename), "utf8");
19570
19699
  return JSON.parse(value);
19571
19700
  }));
19572
19701
  await prisma.tiddlers.createMany({
@@ -19970,7 +20099,7 @@ var init_commands = __esm({
19970
20099
  // src/db/sqlite-adapter.ts
19971
20100
  import { PrismaBetterSQLite3 } from "@prisma/adapter-better-sqlite3";
19972
20101
  import { readdir, readFile as readFile2 } from "fs/promises";
19973
- import { createHash as createHash5, randomUUID } from "crypto";
20102
+ import { createHash as createHash6, randomUUID } from "crypto";
19974
20103
  import { existsSync as existsSync5 } from "fs";
19975
20104
  var _SqliteAdapter, SqliteAdapter;
19976
20105
  var init_sqlite_adapter = __esm({
@@ -20019,7 +20148,7 @@ var init_sqlite_adapter = __esm({
20019
20148
  const new_migrations = migrations.filter((m) => !applied_migrations.has(m) && m !== "migration_lock.toml");
20020
20149
  if (!new_migrations.length) return;
20021
20150
  function generateChecksum(fileContent) {
20022
- return createHash5("sha256").update(fileContent).digest("hex");
20151
+ return createHash6("sha256").update(fileContent).digest("hex");
20023
20152
  }
20024
20153
  __name(generateChecksum, "generateChecksum");
20025
20154
  console.log("New migrations found", new_migrations);
@@ -20049,9 +20178,9 @@ var init_sqlite_adapter = __esm({
20049
20178
  });
20050
20179
 
20051
20180
  // src/commander.ts
20052
- import * as path4 from "node:path";
20181
+ import * as path5 from "node:path";
20053
20182
  import { PrismaClient as PrismaClient2 } from "@prisma/client";
20054
- import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync4 } from "node:fs";
20183
+ import { existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync4 } from "node:fs";
20055
20184
  import { ok as ok7 } from "node:assert";
20056
20185
  var _StartupCommander, StartupCommander, _Commander, Commander;
20057
20186
  var init_commander = __esm({
@@ -20077,12 +20206,12 @@ var init_commander = __esm({
20077
20206
  ok7(!config.config.pathPrefix.endsWith("/"), "pathPrefix must not end with a slash");
20078
20207
  }
20079
20208
  this.wikiPath = config.wikiPath;
20080
- this.storePath = path4.resolve(this.wikiPath, "store");
20081
- this.databasePath = path4.resolve(this.storePath, "database.sqlite");
20082
- this.outputPath = path4.resolve($tw2.boot.wikiPath, $tw2.config.wikiOutputSubDir);
20083
- this.cachePath = path4.resolve(this.wikiPath, "cache");
20209
+ this.storePath = path5.resolve(this.wikiPath, "store");
20210
+ this.databasePath = path5.resolve(this.storePath, "database.sqlite");
20211
+ this.outputPath = path5.resolve($tw2.boot.wikiPath, $tw2.config.wikiOutputSubDir);
20212
+ this.cachePath = path5.resolve(this.wikiPath, "cache");
20084
20213
  if (!existsSync6(this.storePath)) {
20085
- mkdirSync2(this.storePath, { recursive: true });
20214
+ mkdirSync3(this.storePath, { recursive: true });
20086
20215
  this.setupRequired = true;
20087
20216
  }
20088
20217
  this.siteConfig = {
@@ -20364,7 +20493,7 @@ var init_PasswordService = __esm({
20364
20493
 
20365
20494
  // src/server.ts
20366
20495
  import * as opaque2 from "@serenity-kit/opaque";
20367
- import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "node:fs";
20496
+ import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "node:fs";
20368
20497
  import { resolve as resolve12 } from "node:path";
20369
20498
  async function startServer(config) {
20370
20499
  await opaque2.ready;
@@ -20372,7 +20501,7 @@ async function startServer(config) {
20372
20501
  throw new Error("passwordMasterKeyFile must be a string or number");
20373
20502
  }
20374
20503
  if (typeof config.passwordMasterKeyFile === "string" && config.passwordMasterKeyFile && !existsSync7(config.passwordMasterKeyFile)) {
20375
- writeFileSync4(config.passwordMasterKeyFile, opaque2.server.createSetup());
20504
+ writeFileSync5(config.passwordMasterKeyFile, opaque2.server.createSetup());
20376
20505
  console.log("Password master key created at", config.passwordMasterKeyFile);
20377
20506
  }
20378
20507
  const passwordMasterKey = readFileSync5(config.passwordMasterKeyFile, "utf8").trim();