buckyos 0.7.127 → 0.7.131

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 (54) hide show
  1. package/cli/dist/cli.mjs +116 -31
  2. package/cli/dist/cli.mjs.map +1 -1
  3. package/cli/launcher.mjs +0 -0
  4. package/cli/modules/pikg.ts +5 -0
  5. package/cli/modules/pikg_protocol.ts +40 -0
  6. package/cli/runtime/host_deno.ts +16 -31
  7. package/cli/runtime/host_node.ts +15 -30
  8. package/cli/runtime/path_policy.ts +49 -0
  9. package/cli/version.ts +1 -1
  10. package/dist/app-frame.cjs +2 -0
  11. package/dist/app-frame.cjs.map +1 -0
  12. package/dist/app-frame.d.ts +82 -0
  13. package/dist/app-frame.d.ts.map +1 -0
  14. package/dist/app-frame.mjs +189 -0
  15. package/dist/app-frame.mjs.map +1 -0
  16. package/dist/browser.cjs +1 -1
  17. package/dist/browser.mjs +131 -109
  18. package/dist/content.cjs +2 -0
  19. package/dist/content.cjs.map +1 -0
  20. package/dist/content.d.ts +148 -0
  21. package/dist/content.d.ts.map +1 -0
  22. package/dist/content.mjs +361 -0
  23. package/dist/content.mjs.map +1 -0
  24. package/dist/content_mime.d.ts +4 -0
  25. package/dist/content_mime.d.ts.map +1 -0
  26. package/dist/index.cjs +1 -1
  27. package/dist/index.mjs +131 -109
  28. package/dist/msg_center_client.d.ts +228 -1
  29. package/dist/msg_center_client.d.ts.map +1 -1
  30. package/dist/ndm_proxy-28e72ddf.js +13 -0
  31. package/dist/ndm_proxy-28e72ddf.js.map +1 -0
  32. package/dist/{ndm_proxy-1b07ecf3.mjs → ndm_proxy-a167f2a4.mjs} +377 -109
  33. package/dist/ndm_proxy-a167f2a4.mjs.map +1 -0
  34. package/dist/nfsp.cjs +2 -0
  35. package/dist/nfsp.cjs.map +1 -0
  36. package/dist/nfsp.d.ts +553 -0
  37. package/dist/nfsp.d.ts.map +1 -0
  38. package/dist/nfsp.mjs +485 -0
  39. package/dist/nfsp.mjs.map +1 -0
  40. package/dist/node.cjs +1 -1
  41. package/dist/node.mjs +131 -109
  42. package/dist/provision.cjs +1 -1
  43. package/dist/provision.cjs.map +1 -1
  44. package/dist/provision.mjs +1 -1
  45. package/dist/provision.mjs.map +1 -1
  46. package/dist/runtime.d.ts.map +1 -1
  47. package/dist/sdk_core.d.ts +2 -2
  48. package/dist/sdk_core.d.ts.map +1 -1
  49. package/dist/task_mgr_client.d.ts +40 -0
  50. package/dist/task_mgr_client.d.ts.map +1 -1
  51. package/package.json +18 -2
  52. package/dist/ndm_proxy-1b07ecf3.mjs.map +0 -1
  53. package/dist/ndm_proxy-7b71deb4.js +0 -13
  54. package/dist/ndm_proxy-7b71deb4.js.map +0 -1
package/cli/dist/cli.mjs CHANGED
@@ -4594,6 +4594,7 @@ function validateAppDocShape(appDoc) {
4594
4594
  "sdk_version",
4595
4595
  "req_capbilities",
4596
4596
  "permissions",
4597
+ "content_handlers",
4597
4598
  "selector_type",
4598
4599
  "service_config_tips"
4599
4600
  ],
@@ -4660,6 +4661,9 @@ function validateAppDocShape(appDoc) {
4660
4661
  throw invalid("appdoc", "APPDOC.permissions must be an array");
4661
4662
  }
4662
4663
  validatePermissions(appDoc.permissions ?? [], "APPDOC.permissions");
4664
+ if (appDoc.content_handlers !== void 0 && !Array.isArray(appDoc.content_handlers)) {
4665
+ throw invalid("appdoc", "APPDOC.content_handlers must be an array");
4666
+ }
4663
4667
  validateServiceConfigTips(appDoc.service_config_tips, "APPDOC.service_config_tips");
4664
4668
  const pkgList = expectObject$3(appDoc.pkg_list, "APPDOC.pkg_list");
4665
4669
  if (Object.keys(pkgList).length === 0) {
@@ -4865,7 +4869,60 @@ function invalid(stage, message, entry) {
4865
4869
  function stableJsonDigest(value) {
4866
4870
  return sha256Bytes(new TextEncoder().encode(ndn.toCanonicalJsonString(value)));
4867
4871
  }
4868
- const PACKAGE_VERSION = "0.7.127";
4872
+ function validateContentHandlers(value, permissions) {
4873
+ if (!Array.isArray(value))
4874
+ throw invalid("appdoc", "content_handlers must be an array");
4875
+ const ids = /* @__PURE__ */ new Set();
4876
+ for (const raw of value) {
4877
+ const h = expectObject$3(raw, "content handler");
4878
+ const id = expectNonEmptyString(h.handler_id, "handler_id");
4879
+ if (!/^[a-zA-Z0-9_-]+$/.test(id) || ids.has(id))
4880
+ throw invalid("appdoc", "invalid or duplicate handler_id");
4881
+ ids.add(id);
4882
+ if (!Number.isSafeInteger(h.version) || Number(h.version) < 1)
4883
+ throw invalid("appdoc", "invalid handler version");
4884
+ if (!Array.isArray(h.selectors) || !h.selectors.length)
4885
+ throw invalid("appdoc", "missing selectors");
4886
+ for (const rawSelector of h.selectors) {
4887
+ const s = expectObject$3(rawSelector, "selector");
4888
+ if (!["mime", "objType", "schema", "ext"].some((k) => k in s))
4889
+ throw invalid("appdoc", "empty selector");
4890
+ for (const key of ["mime", "objType", "schema"]) {
4891
+ const v = s[key];
4892
+ if (v !== void 0 && !(typeof v === "string" && v.length) && !(Array.isArray(v) && v.length && v.every((i) => typeof i === "string" && i.length)))
4893
+ throw invalid("appdoc", "invalid selector field");
4894
+ }
4895
+ if (s.maxSize !== void 0 && (!Number.isSafeInteger(s.maxSize) || Number(s.maxSize) < 0))
4896
+ throw invalid("appdoc", "invalid maxSize");
4897
+ }
4898
+ const intents = expectObject$3(h.intents, "intents");
4899
+ if (Object.keys(intents).length !== 1 || !intents.open)
4900
+ throw invalid("appdoc", "only open intent is supported");
4901
+ const open2 = expectObject$3(intents.open, "open");
4902
+ const entry = expectObject$3(open2.entry, "entry");
4903
+ const path = expectNonEmptyString(entry.path, "entry.path");
4904
+ let decoded;
4905
+ try {
4906
+ decoded = decodeURIComponent(path);
4907
+ } catch {
4908
+ throw invalid("appdoc", "invalid entry path");
4909
+ }
4910
+ if (entry.type !== "web" || !decoded.startsWith("/") || decoded.startsWith("//") || decoded.includes("..") || decoded.includes("\\") || decoded.includes("://") || decoded.includes("#") || /[\r\n]/.test(decoded))
4911
+ throw invalid("appdoc", "unsafe Web entry");
4912
+ if (open2.priority !== void 0 && (!Number.isSafeInteger(open2.priority) || Number(open2.priority) < 0 || Number(open2.priority) > 80))
4913
+ throw invalid("appdoc", "priority must be 0..80");
4914
+ if (open2.window !== void 0 && open2.window !== "new" && open2.window !== "reuse")
4915
+ throw invalid("appdoc", "invalid window policy");
4916
+ if (open2.multiSource !== void 0 && typeof open2.multiSource !== "boolean")
4917
+ throw invalid("appdoc", "invalid multiSource");
4918
+ if (open2.modes !== void 0 && (!Array.isArray(open2.modes) || !open2.modes.length || open2.modes.some((m) => m !== "view" && m !== "edit")))
4919
+ throw invalid("appdoc", "invalid modes");
4920
+ if (h.permissions !== void 0 && (!Array.isArray(h.permissions) || h.permissions.some((scope) => !permissions.some((p) => p && typeof p === "object" && p.scope_path === scope))))
4921
+ throw invalid("appdoc", "handler permissions exceed App permissions");
4922
+ }
4923
+ return value;
4924
+ }
4925
+ const PACKAGE_VERSION = "0.7.131";
4869
4926
  const TOOL_VERSION = PACKAGE_VERSION;
4870
4927
  const SDK_VERSION = PACKAGE_VERSION;
4871
4928
  const PROTOCOL_VERSION = "1";
@@ -5428,6 +5485,7 @@ async function buildCommand(ctx, input, docker, now) {
5428
5485
  pkg_list: pkgList,
5429
5486
  show_name: appMeta.show_name,
5430
5487
  ...appMeta.permissions.length ? { permissions: appMeta.permissions } : {},
5488
+ ...appMeta.content_handlers?.length ? { content_handlers: appMeta.content_handlers } : {},
5431
5489
  selector_type: appMeta.selector_type,
5432
5490
  service_config_tips: appMeta.service_config_tips
5433
5491
  };
@@ -5591,6 +5649,7 @@ function parseAppMeta(value) {
5591
5649
  "show_name",
5592
5650
  "categories",
5593
5651
  "permissions",
5652
+ "content_handlers",
5594
5653
  "selector_type",
5595
5654
  "service_config_tips"
5596
5655
  ],
@@ -5632,6 +5691,7 @@ function parseAppMeta(value) {
5632
5691
  show_name: developmentString(value.show_name, "app.json.show_name"),
5633
5692
  categories,
5634
5693
  permissions,
5694
+ ...value.content_handlers === void 0 ? {} : { content_handlers: developmentValidation(() => validateContentHandlers(value.content_handlers, permissions)) },
5635
5695
  selector_type: developmentString(value.selector_type, "app.json.selector_type"),
5636
5696
  service_config_tips: serviceConfig
5637
5697
  };
@@ -9606,6 +9666,47 @@ async function runCli(host2, argv) {
9606
9666
  installHost(host2);
9607
9667
  return await new BuckyOSToolApplication().run(argv);
9608
9668
  }
9669
+ async function assertPathAccess(policy2, path, realPath, candidate, operation, resolveLinks = true) {
9670
+ const roots = operation === "read" ? policy2.readPaths : policy2.writePaths;
9671
+ const absolute = path.resolve(candidate);
9672
+ const physicalRoots = [];
9673
+ for (const root of roots) {
9674
+ try {
9675
+ physicalRoots.push(await realPath(path.resolve(root)));
9676
+ } catch (error) {
9677
+ if (!isHostError(error, "NotFound") && !isHostError(error, "PermissionDenied"))
9678
+ throw error;
9679
+ }
9680
+ }
9681
+ if (!insideAny(absolute, roots, path) && !insideAny(absolute, physicalRoots, path)) {
9682
+ throw new HostError(
9683
+ "PermissionDenied",
9684
+ `${operation} access is outside ${policy2.name}: ${absolute}`,
9685
+ absolute
9686
+ );
9687
+ }
9688
+ if (!resolveLinks)
9689
+ return;
9690
+ try {
9691
+ const physical = await realPath(absolute);
9692
+ if (!insideAny(physical, physicalRoots, path)) {
9693
+ throw new HostError(
9694
+ "PermissionDenied",
9695
+ `${operation} access escapes ${policy2.name}: ${absolute}`,
9696
+ absolute
9697
+ );
9698
+ }
9699
+ } catch (error) {
9700
+ if (!isHostError(error, "NotFound"))
9701
+ throw error;
9702
+ }
9703
+ }
9704
+ function insideAny(candidate, roots, path) {
9705
+ return roots.some((root) => {
9706
+ const relative2 = path.relative(path.resolve(root), candidate);
9707
+ return relative2 === "" || relative2 !== ".." && !relative2.startsWith(`..${path.sep}`) && !path.isAbsolute(relative2);
9708
+ });
9709
+ }
9609
9710
  class NodeHost {
9610
9711
  constructor(policy2) {
9611
9712
  this.kind = "node";
@@ -9916,30 +10017,20 @@ class NodeHost {
9916
10017
  }
9917
10018
  }
9918
10019
  async assertPath(candidate, operation, resolveLinks = true) {
9919
- const roots = operation === "read" ? this.policy.readPaths : this.policy.writePaths;
9920
- const absolute = nodePath.resolve(candidate);
9921
- if (!insideAny(absolute, roots)) {
9922
- throw new HostError(
9923
- "PermissionDenied",
9924
- `${operation} access is outside ${this.policy.name}: ${absolute}`,
9925
- absolute
9926
- );
9927
- }
9928
- if (!resolveLinks)
9929
- return;
9930
- try {
9931
- const physical = await realpath(absolute);
9932
- if (!insideAny(physical, roots)) {
9933
- throw new HostError(
9934
- "PermissionDenied",
9935
- `${operation} access escapes ${this.policy.name}: ${absolute}`,
9936
- absolute
9937
- );
9938
- }
9939
- } catch (error) {
9940
- if (error.code !== "ENOENT")
9941
- throw error;
9942
- }
10020
+ await assertPathAccess(
10021
+ this.policy,
10022
+ nodePath,
10023
+ async (path) => {
10024
+ try {
10025
+ return await realpath(path);
10026
+ } catch (error) {
10027
+ throw translateNodeError(error, path);
10028
+ }
10029
+ },
10030
+ candidate,
10031
+ operation,
10032
+ resolveLinks
10033
+ );
9943
10034
  }
9944
10035
  }
9945
10036
  async function* fixedChunks(source) {
@@ -10007,12 +10098,6 @@ function fileInfo(value) {
10007
10098
  ino: value.ino ?? null
10008
10099
  };
10009
10100
  }
10010
- function insideAny(candidate, roots) {
10011
- return roots.some((root) => {
10012
- const relative2 = nodePath.relative(nodePath.resolve(root), candidate);
10013
- return relative2 === "" || relative2 !== ".." && !relative2.startsWith(`..${nodePath.sep}`) && !nodePath.isAbsolute(relative2);
10014
- });
10015
- }
10016
10101
  async function capture(command, args) {
10017
10102
  return await new Promise((resolve2, reject) => {
10018
10103
  const child = spawn(command, args, { stdio: ["ignore", "pipe", "pipe"], shell: false });