@ethisyscore/vite-plugin 1.9.2 → 1.10.0

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/index.cjs CHANGED
@@ -3,6 +3,7 @@
3
3
  var fs = require('fs');
4
4
  var path = require('path');
5
5
  var protocol = require('@ethisyscore/protocol');
6
+ var crypto = require('crypto');
6
7
 
7
8
  // src/index.ts
8
9
  var KNOWN_PRIMITIVE_SET = new Set(protocol.KNOWN_PRIMITIVES);
@@ -123,7 +124,7 @@ function ethisysContractAPlugin(options = {}) {
123
124
  manifestAbsPath = path.isAbsolute(manifestRel) ? manifestRel : path.resolve(resolvedRoot, manifestRel);
124
125
  return resolvedRoot;
125
126
  }
126
- function readManifest() {
127
+ function readManifest2() {
127
128
  resolveRoot();
128
129
  if (!fs.existsSync(manifestAbsPath)) {
129
130
  return null;
@@ -140,7 +141,7 @@ function ethisysContractAPlugin(options = {}) {
140
141
  function validate() {
141
142
  validatedResources = [];
142
143
  resourcePayloads.clear();
143
- const manifest = readManifest();
144
+ const manifest = readManifest2();
144
145
  if (manifest === null) {
145
146
  return;
146
147
  }
@@ -386,7 +387,7 @@ function ethisysContractBPlugin(options = {}) {
386
387
  manifestAbsPath = path.isAbsolute(manifestRel) ? manifestRel : path.resolve(resolvedRoot, manifestRel);
387
388
  return resolvedRoot;
388
389
  }
389
- function readManifest() {
390
+ function readManifest2() {
390
391
  resolveRoot();
391
392
  if (!fs.existsSync(manifestAbsPath)) {
392
393
  return null;
@@ -403,7 +404,7 @@ function ethisysContractBPlugin(options = {}) {
403
404
  function validate() {
404
405
  workerEntryAbs = null;
405
406
  workerEntryRel = null;
406
- const manifest = readManifest();
407
+ const manifest = readManifest2();
407
408
  if (manifest === null) {
408
409
  return;
409
410
  }
@@ -634,7 +635,7 @@ function ethisysPlatformReactPlugin(options = {}) {
634
635
  manifestAbsPath = path.isAbsolute(manifestRel) ? manifestRel : path.resolve(resolvedRoot, manifestRel);
635
636
  return resolvedRoot;
636
637
  }
637
- function readManifest() {
638
+ function readManifest2() {
638
639
  resolveRoot();
639
640
  if (!fs.existsSync(manifestAbsPath)) {
640
641
  return null;
@@ -650,7 +651,7 @@ function ethisysPlatformReactPlugin(options = {}) {
650
651
  }
651
652
  function validate() {
652
653
  pages = [];
653
- const manifest = readManifest();
654
+ const manifest = readManifest2();
654
655
  if (manifest === null) {
655
656
  return;
656
657
  }
@@ -729,7 +730,11 @@ function ethisysPlatformReactPlugin(options = {}) {
729
730
  entryFileNames: `${outputPrefix}[name].js`,
730
731
  chunkFileNames: `${outputPrefix}[name]-[hash].js`,
731
732
  assetFileNames: `${outputPrefix}[name][extname]`
732
- }
733
+ },
734
+ // Auto-externalise the host-ui-externals specifier so the host's
735
+ // module-registry rewriter resolves it to the live `@coreconnect/gogo-ui`
736
+ // instance at runtime — Tier T remotes never ship their own Gogo copy.
737
+ external: ["@ethisyscore/host-ui-externals"]
733
738
  }
734
739
  }
735
740
  };
@@ -787,10 +792,20 @@ function ethisysPlatformReactPlugin(options = {}) {
787
792
  * this file to discover which page modules ship in the bundle without
788
793
  * having to re-parse the manifest.
789
794
  */
790
- generateBundle() {
795
+ generateBundle(_options, bundle) {
791
796
  if (pages.length === 0) {
792
797
  return;
793
798
  }
799
+ const digests = [];
800
+ for (const chunk of Object.values(bundle ?? {})) {
801
+ if (chunk.type !== "chunk") {
802
+ continue;
803
+ }
804
+ const code = chunk.code;
805
+ const fileName = chunk.fileName;
806
+ const hash = crypto.createHash("sha256").update(code, "utf8").digest("hex");
807
+ digests.push({ path: fileName, sha256: hash });
808
+ }
794
809
  const summary = {
795
810
  pages: pages.map((p) => ({
796
811
  id: p.id,
@@ -805,6 +820,11 @@ function ethisysPlatformReactPlugin(options = {}) {
805
820
  fileName: `${outputPrefix}platform-react-pages.json`,
806
821
  source: JSON.stringify(summary, null, 2)
807
822
  });
823
+ this.emitFile({
824
+ type: "asset",
825
+ fileName: `${outputPrefix}platform-react-digest-map.json`,
826
+ source: JSON.stringify({ digests }, null, 2)
827
+ });
808
828
  }
809
829
  };
810
830
  }
@@ -896,9 +916,116 @@ function parsePlatformReactPages(manifestPath, options = {}) {
896
916
  }
897
917
  return result;
898
918
  }
919
+ var DEFAULT_MANIFEST = "feature.manifest.json";
920
+ var DEFAULT_OUTPUT_DIR = "dist/iframe-sandbox";
921
+ var DIGEST_MAP_FILENAME = "iframe-sandbox-digest-map.json";
922
+ function slash3(p) {
923
+ return path.sep === "\\" ? p.replace(/\\/g, "/") : p;
924
+ }
925
+ function defaultWriteFile(path$1, contents) {
926
+ fs.mkdirSync(path.dirname(path$1), { recursive: true });
927
+ fs.writeFileSync(path$1, contents);
928
+ }
929
+ var defaultBuild = async (page) => {
930
+ const { build } = await import('vite');
931
+ const result = await build({
932
+ root: page.root,
933
+ logLevel: "warn",
934
+ build: {
935
+ outDir: page.outDir,
936
+ emptyOutDir: true,
937
+ rollupOptions: {
938
+ input: path.resolve(page.root, page.entryPath)
939
+ }
940
+ }
941
+ });
942
+ const out = Array.isArray(result) ? result[0] : result;
943
+ return { output: out.output };
944
+ };
945
+ function digestOf(item) {
946
+ const bytes = item.type === "chunk" ? item.code : item.source;
947
+ return crypto.createHash("sha256").update(bytes).digest("hex");
948
+ }
949
+ function readManifest(options, root) {
950
+ if (options.manifest !== void 0) {
951
+ return options.manifest;
952
+ }
953
+ const rel = options.manifestPath ?? DEFAULT_MANIFEST;
954
+ const abs = path.isAbsolute(rel) ? rel : path.resolve(root, rel);
955
+ if (!fs.existsSync(abs)) {
956
+ return null;
957
+ }
958
+ const raw = fs.readFileSync(abs, "utf8");
959
+ try {
960
+ return JSON.parse(raw);
961
+ } catch (e) {
962
+ throw new Error(`[ethisys-iframe-sandbox] Failed to parse manifest at "${abs}": ${e.message}`);
963
+ }
964
+ }
965
+ async function buildIframeSandboxPages(options = {}) {
966
+ const root = options.root ?? process.cwd();
967
+ const manifest = readManifest(options, root);
968
+ const declared = manifest?.ui?.iframeSandboxPages;
969
+ if (!Array.isArray(declared) || declared.length === 0) {
970
+ return { digests: [], digestMapPath: null };
971
+ }
972
+ const pages = declared.map((raw, i) => {
973
+ try {
974
+ return protocol.IframeSandboxPageDeclaration.parse(raw);
975
+ } catch (e) {
976
+ throw new Error(
977
+ `[ethisys-iframe-sandbox] ui.iframeSandboxPages[${i}] is invalid: ${e.message}`
978
+ );
979
+ }
980
+ });
981
+ const seen = /* @__PURE__ */ new Set();
982
+ for (const p of pages) {
983
+ if (seen.has(p.id)) {
984
+ throw new Error(`[ethisys-iframe-sandbox] Duplicate iframe-sandbox page id "${p.id}".`);
985
+ }
986
+ seen.add(p.id);
987
+ }
988
+ const build = options.build ?? defaultBuild;
989
+ const write = options.writeFile ?? defaultWriteFile;
990
+ const outputDir = options.outputDir ?? DEFAULT_OUTPUT_DIR;
991
+ const outDirAbs = path.isAbsolute(outputDir) ? outputDir : path.resolve(root, outputDir);
992
+ const digests = [];
993
+ for (const page of pages) {
994
+ const result = await build({
995
+ id: page.id,
996
+ title: page.title,
997
+ entryPath: page.entryPath,
998
+ root,
999
+ outDir: path.resolve(outDirAbs, page.id)
1000
+ });
1001
+ for (const item of result.output) {
1002
+ const entry = { path: `${page.id}/${item.fileName}`, sha256: digestOf(item) };
1003
+ protocol.AssetDigest.parse(entry);
1004
+ digests.push(entry);
1005
+ }
1006
+ }
1007
+ const digestMapPath = path.resolve(outDirAbs, DIGEST_MAP_FILENAME);
1008
+ write(slash3(digestMapPath), JSON.stringify({ digests }, null, 2));
1009
+ return { digests, digestMapPath };
1010
+ }
1011
+ function ethisysIframeSandboxPlugin(options = {}) {
1012
+ let resolvedRoot = options.root;
1013
+ return {
1014
+ name: "ethisys-iframe-sandbox",
1015
+ enforce: "pre",
1016
+ configResolved(config) {
1017
+ if (!options.root) {
1018
+ resolvedRoot = config.root;
1019
+ }
1020
+ },
1021
+ async closeBundle() {
1022
+ await buildIframeSandboxPages({ ...options, root: options.root ?? resolvedRoot });
1023
+ }
1024
+ };
1025
+ }
899
1026
 
900
1027
  // src/index.ts
901
- function slash3(p) {
1028
+ function slash4(p) {
902
1029
  return path.sep === "\\" ? p.replace(/\\/g, "/") : p;
903
1030
  }
904
1031
  function escapeHtml(str) {
@@ -957,7 +1084,7 @@ function ethisysManifestPlugin(options = {}) {
957
1084
  </body>
958
1085
  </html>`;
959
1086
  }
960
- function readManifest() {
1087
+ function readManifest2() {
961
1088
  if (!fs.existsSync(manifestAbsPath)) {
962
1089
  return [];
963
1090
  }
@@ -1009,7 +1136,7 @@ function ethisysManifestPlugin(options = {}) {
1009
1136
  config(config, { command }) {
1010
1137
  rootDir = config.root ?? process.cwd();
1011
1138
  manifestAbsPath = path.resolve(rootDir, manifestRelPath);
1012
- entries = readManifest();
1139
+ entries = readManifest2();
1013
1140
  if (entries.length === 0) {
1014
1141
  return;
1015
1142
  }
@@ -1023,7 +1150,7 @@ function ethisysManifestPlugin(options = {}) {
1023
1150
  }
1024
1151
  seen.add(entry.entrypoint);
1025
1152
  const name = entry.entrypoint.replace(/\.html$/, "");
1026
- input[name] = slash3(path.resolve(rootDir, entry.entrypoint));
1153
+ input[name] = slash4(path.resolve(rootDir, entry.entrypoint));
1027
1154
  }
1028
1155
  return {
1029
1156
  build: {
@@ -1088,9 +1215,9 @@ function ethisysManifestPlugin(options = {}) {
1088
1215
  // Entire handler is wrapped in try/catch so JSON syntax errors in the
1089
1216
  // manifest don't crash the dev server (common during active editing).
1090
1217
  handleHotUpdate({ file, server }) {
1091
- if (slash3(file) === slash3(manifestAbsPath)) {
1218
+ if (slash4(file) === slash4(manifestAbsPath)) {
1092
1219
  try {
1093
- entries = readManifest();
1220
+ entries = readManifest2();
1094
1221
  validateEntries();
1095
1222
  htmlCache.clear();
1096
1223
  } catch (e) {
@@ -1106,9 +1233,9 @@ function ethisysManifestPlugin(options = {}) {
1106
1233
  },
1107
1234
  // Build: resolve virtual HTML module IDs (no physical files exist on disk)
1108
1235
  resolveId(id) {
1109
- const normalizedId = slash3(id);
1236
+ const normalizedId = slash4(id);
1110
1237
  const match = entries.find(
1111
- (e) => slash3(path.resolve(rootDir, e.entrypoint)) === normalizedId
1238
+ (e) => slash4(path.resolve(rootDir, e.entrypoint)) === normalizedId
1112
1239
  );
1113
1240
  if (match) {
1114
1241
  return id;
@@ -1116,9 +1243,9 @@ function ethisysManifestPlugin(options = {}) {
1116
1243
  },
1117
1244
  // Build: provide virtual HTML content for Rollup
1118
1245
  load(id) {
1119
- const normalizedId = slash3(id);
1246
+ const normalizedId = slash4(id);
1120
1247
  const match = entries.find(
1121
- (e) => slash3(path.resolve(rootDir, e.entrypoint)) === normalizedId
1248
+ (e) => slash4(path.resolve(rootDir, e.entrypoint)) === normalizedId
1122
1249
  );
1123
1250
  if (match) {
1124
1251
  return generateHtml(match);
@@ -1130,8 +1257,10 @@ function ethisysManifestPlugin(options = {}) {
1130
1257
  exports.CONTRACT_B_IMPORT_MAP_ALLOWLIST = CONTRACT_B_IMPORT_MAP_ALLOWLIST;
1131
1258
  exports.CONTRACT_B_RUNTIME_IMPORTS = CONTRACT_B_RUNTIME_IMPORTS;
1132
1259
  exports.CONTRACT_B_SEMANTIC_PRIMITIVES = CONTRACT_B_SEMANTIC_PRIMITIVES;
1260
+ exports.buildIframeSandboxPages = buildIframeSandboxPages;
1133
1261
  exports.ethisysContractAPlugin = ethisysContractAPlugin;
1134
1262
  exports.ethisysContractBPlugin = ethisysContractBPlugin;
1263
+ exports.ethisysIframeSandboxPlugin = ethisysIframeSandboxPlugin;
1135
1264
  exports.ethisysManifestPlugin = ethisysManifestPlugin;
1136
1265
  exports.ethisysPlatformReactPlugin = ethisysPlatformReactPlugin;
1137
1266
  exports.parsePlatformReactPages = parsePlatformReactPages;