openlearn-next 0.3.20 → 0.3.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.
Files changed (28) hide show
  1. package/dist/assets/{BatchPickerModal-CasfiwEQ.js → BatchPickerModal-CPmu_uF8.js} +1 -1
  2. package/dist/assets/{ClassesView-DIyJwydJ.js → ClassesView-TVobZ_Vs.js} +1 -1
  3. package/dist/assets/{CloudDriveModal-C6fpWLLE.js → CloudDriveModal-ul9v6wHK.js} +1 -1
  4. package/dist/assets/{CourseManagement-2o8YUTDb.js → CourseManagement-DFQsUxE1.js} +1 -1
  5. package/dist/assets/{CourseWizardModal-Clo7hCCp.js → CourseWizardModal-D92teHMD.js} +1 -1
  6. package/dist/assets/{Dashboard-CBIiLzje.js → Dashboard-CY138ODd.js} +1 -1
  7. package/dist/assets/{ExportWeightModal-DkDuPsiM.js → ExportWeightModal-BvoODxwp.js} +1 -1
  8. package/dist/assets/{HelpView-g1BzpeC9.js → HelpView-CHkXbtfB.js} +1 -1
  9. package/dist/assets/{ImportLessonsModal-DMyN1EmC.js → ImportLessonsModal-YuTV3mnv.js} +1 -1
  10. package/dist/assets/{InteractiveCoursewareViewer-DEicS9GQ.js → InteractiveCoursewareViewer-BBeuViik.js} +1 -1
  11. package/dist/assets/{InteractiveWhiteboard-DbpOL5pI.js → InteractiveWhiteboard-BASy3Ak8.js} +1 -1
  12. package/dist/assets/{LazyCourseware-Bjy3qJWw.js → LazyCourseware-Du9MgZyH.js} +1 -1
  13. package/dist/assets/{LazyWhiteboard-D4Bj3dzG.js → LazyWhiteboard-CpSzdON0.js} +1 -1
  14. package/dist/assets/{LessonEditorView-DpU2g0Uq.js → LessonEditorView-D9YYZQyP.js} +1 -1
  15. package/dist/assets/{LiveClassroomView-Bqrth_T2.js → LiveClassroomView-B2lKKiZK.js} +1 -1
  16. package/dist/assets/{NotificationDetailModal-DC3AYUtD.js → NotificationDetailModal-BthQNwyd.js} +1 -1
  17. package/dist/assets/{PluginView-S6TW3dLz.js → PluginView-CQLEVURc.js} +1 -1
  18. package/dist/assets/{QuizGeneratorModal-Bh6XOC83.js → QuizGeneratorModal-Bp4pUx-H.js} +1 -1
  19. package/dist/assets/{StudentAssignmentView-BCwbft0k.js → StudentAssignmentView-B-jN_m_B.js} +1 -1
  20. package/dist/assets/{StudentLessonView-CewqFUl5.js → StudentLessonView-8-zC7BLx.js} +1 -1
  21. package/dist/assets/{StudentPreviewModal-Blww1Gv5.js → StudentPreviewModal-DZdcKy1x.js} +1 -1
  22. package/dist/assets/{StudentView-CR-84lLY.js → StudentView-Cg5G4Guz.js} +1 -1
  23. package/dist/assets/{SystemResourceLibraryModal-Dyv2YJ7c.js → SystemResourceLibraryModal-CJ16MGxn.js} +1 -1
  24. package/dist/assets/{TeacherView-Cszhv8bO.js → TeacherView-_n9QWf7y.js} +1 -1
  25. package/dist/assets/{index-CnuEzAfQ.js → index-BApV4fuy.js} +3 -3
  26. package/dist/index.html +1 -1
  27. package/dist/server.cjs +75 -50
  28. package/package.json +1 -1
package/dist/index.html CHANGED
@@ -15,7 +15,7 @@
15
15
  }
16
16
  }
17
17
  </script>
18
- <script type="module" crossorigin src="/assets/index-CnuEzAfQ.js"></script>
18
+ <script type="module" crossorigin src="/assets/index-BApV4fuy.js"></script>
19
19
  <link rel="stylesheet" crossorigin href="/assets/index-Ch_mD6B0.css">
20
20
  </head>
21
21
  <body>
package/dist/server.cjs CHANGED
@@ -873,9 +873,9 @@ var init_http_router = __esm({
873
873
  /**
874
874
  * 注册指定动词与路径的 Handler
875
875
  */
876
- route(method, path21, handler) {
876
+ route(method, path22, handler) {
877
877
  const upperMethod = method.toUpperCase();
878
- const normalized = path21.startsWith("/") ? path21 : "/" + path21;
878
+ const normalized = path22.startsWith("/") ? path22 : "/" + path22;
879
879
  const { regex, paramNames } = compileRoutePattern(normalized);
880
880
  this.routes.push({
881
881
  method: upperMethod,
@@ -886,36 +886,36 @@ var init_http_router = __esm({
886
886
  isStream: false
887
887
  });
888
888
  }
889
- get(path21, handler) {
890
- this.route("GET", path21, handler);
889
+ get(path22, handler) {
890
+ this.route("GET", path22, handler);
891
891
  }
892
- post(path21, handler) {
893
- this.route("POST", path21, handler);
892
+ post(path22, handler) {
893
+ this.route("POST", path22, handler);
894
894
  }
895
- put(path21, handler) {
896
- this.route("PUT", path21, handler);
895
+ put(path22, handler) {
896
+ this.route("PUT", path22, handler);
897
897
  }
898
- patch(path21, handler) {
899
- this.route("PATCH", path21, handler);
898
+ patch(path22, handler) {
899
+ this.route("PATCH", path22, handler);
900
900
  }
901
- delete(path21, handler) {
902
- this.route("DELETE", path21, handler);
901
+ delete(path22, handler) {
902
+ this.route("DELETE", path22, handler);
903
903
  }
904
904
  stream(methodOrPath, pathOrHandler, maybeHandler) {
905
905
  if (typeof pathOrHandler === "function") {
906
- const path21 = methodOrPath;
906
+ const path22 = methodOrPath;
907
907
  const handler = pathOrHandler;
908
- this.registerStream("GET", path21, handler);
909
- this.registerStream("POST", path21, handler);
908
+ this.registerStream("GET", path22, handler);
909
+ this.registerStream("POST", path22, handler);
910
910
  } else {
911
911
  const method = methodOrPath.toUpperCase();
912
- const path21 = pathOrHandler;
912
+ const path22 = pathOrHandler;
913
913
  const handler = maybeHandler;
914
- this.registerStream(method, path21, handler);
914
+ this.registerStream(method, path22, handler);
915
915
  }
916
916
  }
917
- registerStream(method, path21, handler) {
918
- const normalized = path21.startsWith("/") ? path21 : "/" + path21;
917
+ registerStream(method, path22, handler) {
918
+ const normalized = path22.startsWith("/") ? path22 : "/" + path22;
919
919
  const { regex, paramNames } = compileRoutePattern(normalized);
920
920
  this.routes.push({
921
921
  method: method.toUpperCase(),
@@ -929,9 +929,9 @@ var init_http_router = __esm({
929
929
  /**
930
930
  * 检查指定动词与路径是否为流式路由
931
931
  */
932
- isStream(method, path21) {
932
+ isStream(method, path22) {
933
933
  const upperMethod = method.toUpperCase();
934
- const normalized = path21.startsWith("/") ? path21 : "/" + path21;
934
+ const normalized = path22.startsWith("/") ? path22 : "/" + path22;
935
935
  for (const entry of this.routes) {
936
936
  if (entry.method !== upperMethod) continue;
937
937
  if (entry.regex.test(normalized)) {
@@ -943,9 +943,9 @@ var init_http_router = __esm({
943
943
  /**
944
944
  * 匹配路由并提取路由参数
945
945
  */
946
- match(method, path21) {
946
+ match(method, path22) {
947
947
  const upperMethod = method.toUpperCase();
948
- const normalized = path21.startsWith("/") ? path21 : "/" + path21;
948
+ const normalized = path22.startsWith("/") ? path22 : "/" + path22;
949
949
  for (const entry of this.routes) {
950
950
  if (entry.method !== upperMethod) continue;
951
951
  const match = normalized.match(entry.regex);
@@ -3592,12 +3592,12 @@ parentPort.on('message', async function(msg) {
3592
3592
  });
3593
3593
  `;
3594
3594
  }
3595
- var import_node_worker_threads, import_fs4, import_node_path3, import_uuid12, ALL_SERVICE_TOKENS, MAX_WORKERS, ACTIVATE_TIMEOUT_MS, ACTIVATE_PROGRESS_SLIDE_MS, WorkerRegistry, WorkerManager;
3595
+ var import_node_worker_threads, import_fs4, import_node_path4, import_uuid12, ALL_SERVICE_TOKENS, MAX_WORKERS, ACTIVATE_TIMEOUT_MS, ACTIVATE_PROGRESS_SLIDE_MS, WorkerRegistry, WorkerManager;
3596
3596
  var init_worker_manager = __esm({
3597
3597
  "packages/core/worker-runtime/worker-manager.ts"() {
3598
3598
  import_node_worker_threads = require("node:worker_threads");
3599
3599
  import_fs4 = __toESM(require("fs"), 1);
3600
- import_node_path3 = __toESM(require("node:path"), 1);
3600
+ import_node_path4 = __toESM(require("node:path"), 1);
3601
3601
  init_transport();
3602
3602
  init_service_host();
3603
3603
  init_logger();
@@ -3885,7 +3885,7 @@ var init_worker_manager = __esm({
3885
3885
  const bootstrapDataUrl = `data:text/javascript;base64,${encodedBootstrap}`;
3886
3886
  let worker;
3887
3887
  try {
3888
- const resolvedPluginDir = pluginDir && import_fs4.default.existsSync(import_node_path3.default.join(pluginDir, "index.js")) ? pluginDir : void 0;
3888
+ const resolvedPluginDir = pluginDir && import_fs4.default.existsSync(import_node_path4.default.join(pluginDir, "index.js")) ? pluginDir : void 0;
3889
3889
  worker = new import_node_worker_threads.Worker(new URL(bootstrapDataUrl), {
3890
3890
  // Pass both the DB id (`pluginId` — used as the actor/registry key)
3891
3891
  // and `manifestId` (used as the namespace prefix for command types).
@@ -8782,7 +8782,7 @@ var import_jszip2 = __toESM(require("jszip"), 1);
8782
8782
  var import_path4 = __toESM(require("path"), 1);
8783
8783
  var import_express = __toESM(require("express"), 1);
8784
8784
  var import_node_module = require("node:module");
8785
- var import_node_url = require("node:url");
8785
+ var import_node_url2 = require("node:url");
8786
8786
 
8787
8787
  // packages/core/esm-loader/install-utils.ts
8788
8788
  var import_jszip = __toESM(require("jszip"), 1);
@@ -9350,7 +9350,34 @@ var HotReloadActivationError = class extends HotReloadError {
9350
9350
  init_interfaces();
9351
9351
 
9352
9352
  // packages/core/version.ts
9353
- var PLATFORM_VERSION = "0.3.18";
9353
+ var import_node_fs3 = __toESM(require("node:fs"), 1);
9354
+ var import_node_path3 = __toESM(require("node:path"), 1);
9355
+ var import_node_url = require("node:url");
9356
+ var import_meta2 = {};
9357
+ var FALLBACK_VERSION = "0.3.20";
9358
+ function readPlatformVersion() {
9359
+ const bases = [];
9360
+ if (typeof __dirname !== "undefined") bases.push(__dirname);
9361
+ try {
9362
+ bases.push(import_node_path3.default.dirname((0, import_node_url.fileURLToPath)(import_meta2.url)));
9363
+ } catch {
9364
+ }
9365
+ for (const base of bases) {
9366
+ let dir = base;
9367
+ for (; ; ) {
9368
+ try {
9369
+ const pkg = JSON.parse(import_node_fs3.default.readFileSync(import_node_path3.default.join(dir, "package.json"), "utf-8"));
9370
+ if (pkg.name === "openlearn-next" && typeof pkg.version === "string") return pkg.version;
9371
+ } catch {
9372
+ }
9373
+ const parent = import_node_path3.default.dirname(dir);
9374
+ if (parent === dir) break;
9375
+ dir = parent;
9376
+ }
9377
+ }
9378
+ return FALLBACK_VERSION;
9379
+ }
9380
+ var PLATFORM_VERSION = readPlatformVersion();
9354
9381
  var OPENLEARN_VERSION = PLATFORM_VERSION;
9355
9382
 
9356
9383
  // packages/core/plugin-host/plugin-runtime-composition.ts
@@ -9655,11 +9682,11 @@ var PluginDistributionManager = class {
9655
9682
  return;
9656
9683
  }
9657
9684
  const filePath = this.pluginHost.getPluginFilePath(this.pluginHost.resolvePluginUuid(pluginId));
9658
- const fs16 = await import("node:fs");
9659
- if (!fs16.existsSync(filePath)) {
9685
+ const fs17 = await import("node:fs");
9686
+ if (!fs17.existsSync(filePath)) {
9660
9687
  throw new Error(`Cannot reload plugin "${pluginId}": source file missing at ${filePath}`);
9661
9688
  }
9662
- const code = fs16.readFileSync(filePath, "utf-8");
9689
+ const code = fs17.readFileSync(filePath, "utf-8");
9663
9690
  await this.pluginHost.reloadPlugin(pluginId, code);
9664
9691
  }
9665
9692
  async updateFromZip(zipBuffer, options = {}) {
@@ -9689,7 +9716,7 @@ var PluginDistributionManager = class {
9689
9716
 
9690
9717
  // packages/core/plugin-host/index.ts
9691
9718
  init_http_router();
9692
- var import_meta2 = {};
9719
+ var import_meta3 = {};
9693
9720
  var VALID_TRANSITIONS = {
9694
9721
  ["installed" /* INSTALLED */]: ["activating" /* ACTIVATING */, "uninstalled" /* UNINSTALLED */],
9695
9722
  ["activating" /* ACTIVATING */]: ["active" /* ACTIVE */, "error" /* ERROR */],
@@ -9724,7 +9751,7 @@ function resolveHostSdkDir() {
9724
9751
  const bases = [];
9725
9752
  if (typeof __dirname !== "undefined") bases.push(__dirname);
9726
9753
  try {
9727
- bases.push(import_path4.default.dirname((0, import_node_url.fileURLToPath)(import_meta2.url)));
9754
+ bases.push(import_path4.default.dirname((0, import_node_url2.fileURLToPath)(import_meta3.url)));
9728
9755
  } catch {
9729
9756
  }
9730
9757
  for (const base of bases) {
@@ -9883,7 +9910,7 @@ var PluginHost = class {
9883
9910
  /**
9884
9911
  * 判断指定插件的某个请求路径是否为流式路由 (SSE)
9885
9912
  */
9886
- isStreamRoute(pluginIdOrManifestId, method, path21) {
9913
+ isStreamRoute(pluginIdOrManifestId, method, path22) {
9887
9914
  const upperMethod = method.toUpperCase();
9888
9915
  const resolvedId = this.resolvePluginUuid(pluginIdOrManifestId);
9889
9916
  const instance = this.pluginInstances.get(resolvedId) ?? this.pluginInstances.get(pluginIdOrManifestId);
@@ -9892,7 +9919,7 @@ var PluginHost = class {
9892
9919
  for (const r of manifest.api.routes) {
9893
9920
  if (r.method.toUpperCase() === upperMethod && r.streaming === true) {
9894
9921
  const compiled = compileRoutePattern(r.path);
9895
- if (compiled.regex.test(path21)) {
9922
+ if (compiled.regex.test(path22)) {
9896
9923
  return true;
9897
9924
  }
9898
9925
  }
@@ -9900,14 +9927,14 @@ var PluginHost = class {
9900
9927
  }
9901
9928
  if (!instance) return false;
9902
9929
  if (instance.context?.http) {
9903
- return instance.context.http.isStream(upperMethod, path21);
9930
+ return instance.context.http.isStream(upperMethod, path22);
9904
9931
  }
9905
9932
  if (instance.workerRef) {
9906
9933
  const routes = instance.workerRef.serviceHost.getRegisteredRoutes();
9907
9934
  for (const r of routes) {
9908
9935
  if (r.method === upperMethod && r.isStream) {
9909
9936
  const compiled = compileRoutePattern(r.pattern);
9910
- if (compiled.regex.test(path21)) {
9937
+ if (compiled.regex.test(path22)) {
9911
9938
  return true;
9912
9939
  }
9913
9940
  }
@@ -10550,7 +10577,7 @@ var PluginHost = class {
10550
10577
  let mod;
10551
10578
  if (process.env.NODE_ENV !== "test" && row.file_path && import_fs5.default.existsSync(row.file_path)) {
10552
10579
  this.ensureHostSdkResolution();
10553
- const fileUrl = (0, import_node_url.pathToFileURL)(row.file_path);
10580
+ const fileUrl = (0, import_node_url2.pathToFileURL)(row.file_path);
10554
10581
  mod = await import(`${fileUrl.href}?t=${Date.now()}`);
10555
10582
  } else {
10556
10583
  let sourceCode = "";
@@ -11917,8 +11944,8 @@ var HotReloadController = class {
11917
11944
  const timer = setTimeout(async () => {
11918
11945
  this.debounceTimers.delete(pluginId);
11919
11946
  try {
11920
- const fs16 = await import("fs/promises");
11921
- const newSourceCode = await fs16.readFile(filePath, "utf-8");
11947
+ const fs17 = await import("fs/promises");
11948
+ const newSourceCode = await fs17.readFile(filePath, "utf-8");
11922
11949
  console.log(`[HotReload] File changed: ${filePath} \u2192 triggering reload for "${pluginId}"`);
11923
11950
  await this.pluginHost.reloadPlugin(pluginId, newSourceCode);
11924
11951
  } catch (err) {
@@ -25517,7 +25544,7 @@ async function checkVersion(source, installedVersion) {
25517
25544
  }
25518
25545
 
25519
25546
  // server/routes/plugin-api-gateway.ts
25520
- var import_node_path4 = __toESM(require("node:path"), 1);
25547
+ var import_node_path5 = __toESM(require("node:path"), 1);
25521
25548
  init_http_router();
25522
25549
  var RESERVED_ACTIONS = /* @__PURE__ */ new Set(["config", "toggle", "contributions", "check-update", "one-click-update"]);
25523
25550
  var FORBIDDEN_RESPONSE_HEADERS = /* @__PURE__ */ new Set([
@@ -25651,7 +25678,7 @@ async function pluginApiGatewayMiddleware(req, res, next) {
25651
25678
  res.status(400).json({ success: false, error: "Path traversal attempt detected" });
25652
25679
  return;
25653
25680
  }
25654
- const normalizedSubPath = import_node_path4.default.posix.normalize("/" + rawSubPath);
25681
+ const normalizedSubPath = import_node_path5.default.posix.normalize("/" + rawSubPath);
25655
25682
  if (normalizedSubPath.includes("..")) {
25656
25683
  res.status(400).json({ success: false, error: "Path traversal attempt detected" });
25657
25684
  return;
@@ -26795,24 +26822,22 @@ async function startServer() {
26795
26822
  const green = "\x1B[32m";
26796
26823
  const cyan = "\x1B[36m";
26797
26824
  const dim = "\x1B[2m";
26825
+ const hyperlink = Boolean(process.stdout.isTTY) && process.env.TERM !== "dumb";
26826
+ const link = (url) => hyperlink ? `${OSC}${url}${ST}${url}${OSC}${ST}` : url;
26798
26827
  console.log(`
26799
- ${bold}${green}Educational OS Kernel${reset} v${PLATFORM_VERSION} ready:
26828
+ ${bold}${green}OpenLearn Next${reset} v${PLATFORM_VERSION} ready:
26800
26829
  `);
26801
- console.log(
26802
- ` ${dim}\u279C${reset} ${bold}Local:${reset} ${bold}${cyan}${OSC}${localUrl}${ST}${localUrl}${OSC}${ST}${reset}`
26803
- );
26830
+ console.log(` ${dim}\u279C${reset} ${bold}Local:${reset} ${bold}${cyan}${link(localUrl)}${reset}`);
26804
26831
  if (isAnyHost) {
26805
26832
  const netIps = getNetworkIps();
26806
26833
  for (const ip of netIps) {
26807
26834
  const netUrl = `http://${ip}:${PORT}`;
26808
- console.log(
26809
- ` ${dim}\u279C${reset} ${bold}Network:${reset} ${bold}${cyan}${OSC}${netUrl}${ST}${netUrl}${OSC}${ST}${reset}`
26810
- );
26835
+ console.log(` ${dim}\u279C${reset} ${bold}Network:${reset} ${bold}${cyan}${link(netUrl)}${reset}`);
26811
26836
  }
26812
26837
  }
26813
26838
  console.log("");
26814
26839
  if (process.env.OPEN_BROWSER === "true") {
26815
- console.log(` ${dim}\u279C Auto-opening browser: ${primaryUrl}${reset}
26840
+ console.log(` ${dim}\u279C Auto-opening browser: ${cyan}${link(primaryUrl)}${reset}
26816
26841
  `);
26817
26842
  openBrowser(primaryUrl);
26818
26843
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openlearn-next",
3
- "version": "0.3.20",
3
+ "version": "0.3.21",
4
4
  "private": false,
5
5
  "description": "A plugin-driven Educational OS / LMS platform with AI agent teaching assistant",
6
6
  "keywords": [