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.
- package/dist/assets/{BatchPickerModal-CasfiwEQ.js → BatchPickerModal-CPmu_uF8.js} +1 -1
- package/dist/assets/{ClassesView-DIyJwydJ.js → ClassesView-TVobZ_Vs.js} +1 -1
- package/dist/assets/{CloudDriveModal-C6fpWLLE.js → CloudDriveModal-ul9v6wHK.js} +1 -1
- package/dist/assets/{CourseManagement-2o8YUTDb.js → CourseManagement-DFQsUxE1.js} +1 -1
- package/dist/assets/{CourseWizardModal-Clo7hCCp.js → CourseWizardModal-D92teHMD.js} +1 -1
- package/dist/assets/{Dashboard-CBIiLzje.js → Dashboard-CY138ODd.js} +1 -1
- package/dist/assets/{ExportWeightModal-DkDuPsiM.js → ExportWeightModal-BvoODxwp.js} +1 -1
- package/dist/assets/{HelpView-g1BzpeC9.js → HelpView-CHkXbtfB.js} +1 -1
- package/dist/assets/{ImportLessonsModal-DMyN1EmC.js → ImportLessonsModal-YuTV3mnv.js} +1 -1
- package/dist/assets/{InteractiveCoursewareViewer-DEicS9GQ.js → InteractiveCoursewareViewer-BBeuViik.js} +1 -1
- package/dist/assets/{InteractiveWhiteboard-DbpOL5pI.js → InteractiveWhiteboard-BASy3Ak8.js} +1 -1
- package/dist/assets/{LazyCourseware-Bjy3qJWw.js → LazyCourseware-Du9MgZyH.js} +1 -1
- package/dist/assets/{LazyWhiteboard-D4Bj3dzG.js → LazyWhiteboard-CpSzdON0.js} +1 -1
- package/dist/assets/{LessonEditorView-DpU2g0Uq.js → LessonEditorView-D9YYZQyP.js} +1 -1
- package/dist/assets/{LiveClassroomView-Bqrth_T2.js → LiveClassroomView-B2lKKiZK.js} +1 -1
- package/dist/assets/{NotificationDetailModal-DC3AYUtD.js → NotificationDetailModal-BthQNwyd.js} +1 -1
- package/dist/assets/{PluginView-S6TW3dLz.js → PluginView-CQLEVURc.js} +1 -1
- package/dist/assets/{QuizGeneratorModal-Bh6XOC83.js → QuizGeneratorModal-Bp4pUx-H.js} +1 -1
- package/dist/assets/{StudentAssignmentView-BCwbft0k.js → StudentAssignmentView-B-jN_m_B.js} +1 -1
- package/dist/assets/{StudentLessonView-CewqFUl5.js → StudentLessonView-8-zC7BLx.js} +1 -1
- package/dist/assets/{StudentPreviewModal-Blww1Gv5.js → StudentPreviewModal-DZdcKy1x.js} +1 -1
- package/dist/assets/{StudentView-CR-84lLY.js → StudentView-Cg5G4Guz.js} +1 -1
- package/dist/assets/{SystemResourceLibraryModal-Dyv2YJ7c.js → SystemResourceLibraryModal-CJ16MGxn.js} +1 -1
- package/dist/assets/{TeacherView-Cszhv8bO.js → TeacherView-_n9QWf7y.js} +1 -1
- package/dist/assets/{index-CnuEzAfQ.js → index-BApV4fuy.js} +3 -3
- package/dist/index.html +1 -1
- package/dist/server.cjs +75 -50
- 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-
|
|
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,
|
|
876
|
+
route(method, path22, handler) {
|
|
877
877
|
const upperMethod = method.toUpperCase();
|
|
878
|
-
const normalized =
|
|
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(
|
|
890
|
-
this.route("GET",
|
|
889
|
+
get(path22, handler) {
|
|
890
|
+
this.route("GET", path22, handler);
|
|
891
891
|
}
|
|
892
|
-
post(
|
|
893
|
-
this.route("POST",
|
|
892
|
+
post(path22, handler) {
|
|
893
|
+
this.route("POST", path22, handler);
|
|
894
894
|
}
|
|
895
|
-
put(
|
|
896
|
-
this.route("PUT",
|
|
895
|
+
put(path22, handler) {
|
|
896
|
+
this.route("PUT", path22, handler);
|
|
897
897
|
}
|
|
898
|
-
patch(
|
|
899
|
-
this.route("PATCH",
|
|
898
|
+
patch(path22, handler) {
|
|
899
|
+
this.route("PATCH", path22, handler);
|
|
900
900
|
}
|
|
901
|
-
delete(
|
|
902
|
-
this.route("DELETE",
|
|
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
|
|
906
|
+
const path22 = methodOrPath;
|
|
907
907
|
const handler = pathOrHandler;
|
|
908
|
-
this.registerStream("GET",
|
|
909
|
-
this.registerStream("POST",
|
|
908
|
+
this.registerStream("GET", path22, handler);
|
|
909
|
+
this.registerStream("POST", path22, handler);
|
|
910
910
|
} else {
|
|
911
911
|
const method = methodOrPath.toUpperCase();
|
|
912
|
-
const
|
|
912
|
+
const path22 = pathOrHandler;
|
|
913
913
|
const handler = maybeHandler;
|
|
914
|
-
this.registerStream(method,
|
|
914
|
+
this.registerStream(method, path22, handler);
|
|
915
915
|
}
|
|
916
916
|
}
|
|
917
|
-
registerStream(method,
|
|
918
|
-
const normalized =
|
|
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,
|
|
932
|
+
isStream(method, path22) {
|
|
933
933
|
const upperMethod = method.toUpperCase();
|
|
934
|
-
const normalized =
|
|
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,
|
|
946
|
+
match(method, path22) {
|
|
947
947
|
const upperMethod = method.toUpperCase();
|
|
948
|
-
const normalized =
|
|
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,
|
|
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
|
-
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
9659
|
-
if (!
|
|
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 =
|
|
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
|
|
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,
|
|
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,
|
|
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(
|
|
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,
|
|
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(
|
|
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,
|
|
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
|
|
11921
|
-
const newSourceCode = await
|
|
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
|
|
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 =
|
|
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}
|
|
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
|
}
|